ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูแหล่งที่มาบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
บทช่วยสอนนี้แสดงวิธีจำแนกรูปภาพดอกไม้ มันสร้างตัวแยกประเภทรูปภาพโดยใช้โมเดล tf.keras.Sequential
และโหลดข้อมูลโดยใช้ tf.keras.utils.image_dataset_from_directory
คุณจะได้รับประสบการณ์เชิงปฏิบัติด้วยแนวคิดต่อไปนี้:
- โหลดชุดข้อมูลออกจากดิสก์อย่างมีประสิทธิภาพ
- ระบุการใช้เทคนิคมากเกินไปเพื่อบรรเทาปัญหา รวมถึงการเสริมข้อมูลและการออกกลางคัน
บทช่วยสอนนี้เป็นไปตามเวิร์กโฟลว์การเรียนรู้ของเครื่องขั้นพื้นฐาน:
- ตรวจสอบและทำความเข้าใจข้อมูล
- สร้างไปป์ไลน์อินพุต
- สร้างแบบจำลอง
- ฝึกโมเดล
- ทดสอบโมเดล
- ปรับปรุงแบบจำลองและทำซ้ำกระบวนการ
นำเข้า TensorFlow และไลบรารีอื่นๆ
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
ดาวน์โหลดและสำรวจชุดข้อมูล
บทช่วยสอนนี้ใช้ชุดข้อมูลภาพถ่ายดอกไม้ประมาณ 3,700 ภาพ ชุดข้อมูลประกอบด้วยไดเร็กทอรีย่อยห้าไดเร็กทอรี หนึ่งไดเร็กทอรีต่อคลาส:
flower_photo/
daisy/
dandelion/
roses/
sunflowers/
tulips/
import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
data_dir = pathlib.Path(data_dir)
หลังจากดาวน์โหลด คุณควรมีสำเนาของชุดข้อมูลที่พร้อมใช้งาน มีทั้งหมด 3,670 ภาพ:
image_count = len(list(data_dir.glob('*/*.jpg')))
print(image_count)
3670
นี่คือดอกกุหลาบบางส่วน:
roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[0]))
PIL.Image.open(str(roses[1]))
และดอกทิวลิปบางส่วน:
tulips = list(data_dir.glob('tulips/*'))
PIL.Image.open(str(tulips[0]))
PIL.Image.open(str(tulips[1]))
โหลดข้อมูลโดยใช้ยูทิลิตี้ Keras
มาโหลดอิมเมจเหล่านี้จากดิสก์โดยใช้ยูทิลิตี้ tf.keras.utils.image_dataset_from_directory
ที่เป็นประโยชน์ ซึ่งจะนำคุณจากไดเร็กทอรีของรูปภาพบนดิสก์ไปยัง tf.data.Dataset
ในโค้ดเพียงไม่กี่บรรทัด หากต้องการ คุณยังสามารถเขียนโค้ดการโหลดข้อมูลของคุณเองตั้งแต่ต้นโดยไปที่บทแนะนำการ โหลดและประมวลผลภาพล่วงหน้า
สร้างชุดข้อมูล
กำหนดพารามิเตอร์บางอย่างสำหรับตัวโหลด:
batch_size = 32
img_height = 180
img_width = 180
แนวทางปฏิบัติที่ดีในการใช้การแยกการตรวจสอบความถูกต้องเมื่อพัฒนาแบบจำลองของคุณ ลองใช้รูปภาพ 80% สำหรับการฝึกอบรมและ 20% สำหรับการตรวจสอบ
train_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
Found 3670 files belonging to 5 classes. Using 2936 files for training.
val_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
Found 3670 files belonging to 5 classes. Using 734 files for validation.
คุณสามารถค้นหาชื่อคลาสได้ในแอตทริบิวต์ class_names
บนชุดข้อมูลเหล่านี้ ซึ่งสอดคล้องกับชื่อไดเร็กทอรีตามลำดับตัวอักษร
class_names = train_ds.class_names
print(class_names)
['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
เห็นภาพข้อมูล
นี่คือภาพเก้าภาพแรกจากชุดข้อมูลการฝึกอบรม:
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
คุณจะฝึกโมเดลโดยใช้ชุดข้อมูลเหล่านี้โดยส่งต่อไปยัง Model.fit
ในอีกสักครู่ หากต้องการ คุณยังสามารถวนซ้ำชุดข้อมูลด้วยตนเองและเรียกค้นชุดรูปภาพ:
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
print(labels_batch.shape)
break
(32, 180, 180, 3) (32,)
image_batch
คือเทนเซอร์ของรูปร่าง (32, 180, 180, 3)
นี่คือชุดรูปภาพขนาด 180x180x3
จำนวน 32 รูป (ขนาดสุดท้ายหมายถึงช่องสี RGB) label_batch
คือเทนเซอร์ของรูปร่าง (32,)
ซึ่งเป็นป้ายกำกับที่สอดคล้องกับรูปภาพ 32 รูป
คุณสามารถเรียก .numpy()
บน image_batch
และ labels_batch
เพื่อแปลงเป็น numpy.ndarray
กำหนดค่าชุดข้อมูลสำหรับประสิทธิภาพ
ตรวจสอบให้แน่ใจว่าได้ใช้การดึงข้อมูลล่วงหน้าแบบบัฟเฟอร์ เพื่อให้คุณสามารถส่งข้อมูลจากดิสก์โดยไม่ต้องให้ I/O ถูกบล็อก นี่เป็นวิธีสำคัญสองวิธีที่คุณควรใช้เมื่อโหลดข้อมูล:
-
Dataset.cache
เก็บภาพไว้ในหน่วยความจำหลังจากที่โหลดออกจากดิสก์ในช่วงยุคแรก เพื่อให้แน่ใจว่าชุดข้อมูลจะไม่กลายเป็นคอขวดขณะฝึกโมเดลของคุณ หากชุดข้อมูลของคุณใหญ่เกินไปที่จะใส่ลงในหน่วยความจำ คุณสามารถใช้วิธีนี้เพื่อสร้างแคชบนดิสก์ที่มีประสิทธิภาพ -
Dataset.prefetch
ทับซ้อนการประมวลผลข้อมูลล่วงหน้าและการดำเนินการโมเดลขณะฝึก
ผู้อ่านที่สนใจสามารถเรียนรู้เพิ่มเติมเกี่ยวกับทั้งสองวิธี รวมถึงวิธีการแคชข้อมูลไปยังดิสก์ในส่วนการ ดึงข้อมูลล่วงหน้า ของประสิทธิภาพที่ ดีขึ้นด้วยคู่มือ tf.data API
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
สร้างมาตรฐานข้อมูล
ค่าช่อง RGB อยู่ในช่วง [0, 255]
ไม่เหมาะสำหรับโครงข่ายประสาทเทียม โดยทั่วไป คุณควรพยายามทำให้ค่าอินพุตของคุณมีขนาดเล็ก
ที่นี่ คุณจะกำหนดค่ามาตรฐานให้อยู่ในช่วง [0, 1]
โดยใช้ tf.keras.layers.Rescaling
:
normalization_layer = layers.Rescaling(1./255)
มีสองวิธีในการใช้เลเยอร์นี้ คุณสามารถใช้กับชุดข้อมูลได้โดยเรียก Dataset.map
:
normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
# Notice the pixel values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image))
0.0 1.0ตัวยึดตำแหน่ง23
หรือคุณสามารถรวมเลเยอร์ไว้ในการกำหนดโมเดลของคุณ ซึ่งจะทำให้การปรับใช้ง่ายขึ้น ลองใช้แนวทางที่สองที่นี่
สร้างแบบจำลอง
โมเดล Sequential ประกอบด้วยบล็อกการบิดสามบล็อก ( tf.keras.layers.Conv2D
) ที่มีเลเยอร์การรวมสูงสุด ( tf.keras.layers.MaxPooling2D
) ในแต่ละอัน มีเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ ( tf.keras.layers.Dense
) โดยมี 128 ยูนิตอยู่ด้านบนซึ่งเปิดใช้งานโดยฟังก์ชันการเปิดใช้งาน ReLU ( 'relu'
) โมเดลนี้ไม่ได้รับการปรับแต่งให้มีความแม่นยำสูง เป้าหมายของบทช่วยสอนนี้คือการแสดงแนวทางมาตรฐาน
num_classes = len(class_names)
model = Sequential([
layers.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
รวบรวมโมเดล
สำหรับบทช่วยสอนนี้ ให้เลือกฟังก์ชันเพิ่มประสิทธิภาพ tf.keras.optimizers.Adam
และ tf.keras.losses.SparseCategoricalCrossentropy
loss ในการดูการฝึกอบรมและการตรวจสอบความถูกต้องสำหรับช่วงการฝึกแต่ละครั้ง ให้ส่งอาร์กิวเมนต์ metrics
ไปที่ Model.compile
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
สรุปโมเดล
ดูเลเยอร์ทั้งหมดของเครือข่ายโดยใช้เมธอด Model.summary
ของโมเดล:
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= rescaling_1 (Rescaling) (None, 180, 180, 3) 0 conv2d (Conv2D) (None, 180, 180, 16) 448 max_pooling2d (MaxPooling2D (None, 90, 90, 16) 0 ) conv2d_1 (Conv2D) (None, 90, 90, 32) 4640 max_pooling2d_1 (MaxPooling (None, 45, 45, 32) 0 2D) conv2d_2 (Conv2D) (None, 45, 45, 64) 18496 max_pooling2d_2 (MaxPooling (None, 22, 22, 64) 0 2D) flatten (Flatten) (None, 30976) 0 dense (Dense) (None, 128) 3965056 dense_1 (Dense) (None, 5) 645 ================================================================= Total params: 3,989,285 Trainable params: 3,989,285 Non-trainable params: 0 _________________________________________________________________
ฝึกโมเดล
epochs=10
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
Epoch 1/10 92/92 [==============================] - 3s 16ms/step - loss: 1.2769 - accuracy: 0.4489 - val_loss: 1.0457 - val_accuracy: 0.5804 Epoch 2/10 92/92 [==============================] - 1s 11ms/step - loss: 0.9386 - accuracy: 0.6328 - val_loss: 0.9665 - val_accuracy: 0.6158 Epoch 3/10 92/92 [==============================] - 1s 11ms/step - loss: 0.7390 - accuracy: 0.7200 - val_loss: 0.8768 - val_accuracy: 0.6540 Epoch 4/10 92/92 [==============================] - 1s 11ms/step - loss: 0.5649 - accuracy: 0.7963 - val_loss: 0.9258 - val_accuracy: 0.6540 Epoch 5/10 92/92 [==============================] - 1s 11ms/step - loss: 0.3662 - accuracy: 0.8733 - val_loss: 1.1734 - val_accuracy: 0.6267 Epoch 6/10 92/92 [==============================] - 1s 11ms/step - loss: 0.2169 - accuracy: 0.9343 - val_loss: 1.3728 - val_accuracy: 0.6499 Epoch 7/10 92/92 [==============================] - 1s 11ms/step - loss: 0.1191 - accuracy: 0.9629 - val_loss: 1.3791 - val_accuracy: 0.6471 Epoch 8/10 92/92 [==============================] - 1s 11ms/step - loss: 0.0497 - accuracy: 0.9871 - val_loss: 1.8002 - val_accuracy: 0.6390 Epoch 9/10 92/92 [==============================] - 1s 11ms/step - loss: 0.0372 - accuracy: 0.9922 - val_loss: 1.8545 - val_accuracy: 0.6390 Epoch 10/10 92/92 [==============================] - 1s 11ms/step - loss: 0.0715 - accuracy: 0.9813 - val_loss: 2.0656 - val_accuracy: 0.6049
เห็นภาพผลการฝึก
สร้างแผนการสูญเสียและความแม่นยำในชุดการฝึกอบรมและการตรวจสอบ:
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
แผนภาพแสดงให้เห็นว่าความแม่นยำในการฝึกและความแม่นยำในการตรวจสอบนั้นลดลงอย่างมาก และโมเดลได้รับความแม่นยำเพียง 60% ในชุดการตรวจสอบ
ตรวจสอบสิ่งที่ผิดพลาดและพยายามเพิ่มประสิทธิภาพโดยรวมของโมเดล
ฟิตเกินไป
ในแผนภาพด้านบน ความแม่นยำในการฝึกอบรมเพิ่มขึ้นเป็นเส้นตรงเมื่อเวลาผ่านไป ในขณะที่ความแม่นยำในการตรวจสอบความถูกต้องหยุดอยู่ที่ประมาณ 60% ในกระบวนการฝึกอบรม นอกจากนี้ จะเห็นความแตกต่างในความแม่นยำระหว่างความแม่นยำในการฝึกและการตรวจสอบ ซึ่งเป็นสัญญาณของ การใส่ มากเกินไป
เมื่อมีตัวอย่างการฝึกอบรมจำนวนเล็กน้อย ในบางครั้ง โมเดลจะเรียนรู้จากเสียงรบกวนหรือรายละเอียดที่ไม่ต้องการจากตัวอย่างการฝึก จนถึงขนาดที่ส่งผลเสียต่อประสิทธิภาพของโมเดลต่อตัวอย่างใหม่ ปรากฏการณ์นี้เรียกว่ามากเกินไป หมายความว่าโมเดลจะมีช่วงเวลาที่ยากลำบากในการสรุปชุดข้อมูลใหม่
มีหลายวิธีในการต่อสู้กับการใส่มากเกินไปในกระบวนการฝึกอบรม ในบทช่วยสอนนี้ คุณจะใช้ การเพิ่มข้อมูล และเพิ่ม Dropout ให้กับโมเดลของคุณ
การเสริมข้อมูล
Overfitting มักเกิดขึ้นเมื่อมีตัวอย่างการฝึกอบรมจำนวนน้อย การเสริมข้อมูล ใช้แนวทางในการสร้างข้อมูลการฝึกอบรมเพิ่มเติมจากตัวอย่างที่มีอยู่ของคุณโดยการเพิ่มโดยใช้การแปลงแบบสุ่มที่ให้ภาพที่ดูน่าเชื่อ ซึ่งช่วยให้โมเดลเปิดเผยข้อมูลในแง่มุมต่างๆ มากขึ้นและสรุปได้ดีขึ้น
คุณจะใช้การเพิ่มข้อมูลโดยใช้เลเยอร์การประมวลผลล่วงหน้าของ Keras ต่อไปนี้: tf.keras.layers.RandomFlip
, tf.keras.layers.RandomRotation
และ tf.keras.layers.RandomZoom
สิ่งเหล่านี้สามารถรวมอยู่ในโมเดลของคุณเหมือนกับเลเยอร์อื่นๆ และรันบน GPU
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal",
input_shape=(img_height,
img_width,
3)),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
]
)
มาลองนึกภาพว่าตัวอย่างบางส่วนเป็นอย่างไรโดยใช้การเสริมข้อมูลกับรูปภาพเดียวกันหลายๆ ครั้ง:
plt.figure(figsize=(10, 10))
for images, _ in train_ds.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
คุณจะใช้การเสริมข้อมูลเพื่อฝึกโมเดลในอีกสักครู่
ถอนออก
อีกเทคนิคหนึ่งในการลดการ overfitting คือการแนะนำการทำให้เครือข่ายเป็นแบบมาตรฐาน
เมื่อคุณปรับใช้ dropout กับเลเยอร์ มันจะสุ่มเอาออก (โดยการตั้งค่าการเปิดใช้งานเป็นศูนย์) จำนวนหน่วยเอาท์พุตจากเลเยอร์ในระหว่างกระบวนการฝึกอบรม Dropout จะใช้ตัวเลขที่เป็นเศษส่วนเป็นค่าอินพุต ในรูปแบบเช่น 0.1, 0.2, 0.4 เป็นต้น ซึ่งหมายถึงการปล่อยหน่วยเอาต์พุต 10%, 20% หรือ 40% แบบสุ่มจากเลเยอร์ที่ใช้
มาสร้างโครงข่ายประสาทเทียมใหม่ด้วย tf.keras.layers.Dropout
ก่อนฝึกโดยใช้รูปภาพเสริม:
model = Sequential([
data_augmentation,
layers.Rescaling(1./255),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
รวบรวมและฝึกโมเดล
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
Model: "sequential_2" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= sequential_1 (Sequential) (None, 180, 180, 3) 0 rescaling_2 (Rescaling) (None, 180, 180, 3) 0 conv2d_3 (Conv2D) (None, 180, 180, 16) 448 max_pooling2d_3 (MaxPooling (None, 90, 90, 16) 0 2D) conv2d_4 (Conv2D) (None, 90, 90, 32) 4640 max_pooling2d_4 (MaxPooling (None, 45, 45, 32) 0 2D) conv2d_5 (Conv2D) (None, 45, 45, 64) 18496 max_pooling2d_5 (MaxPooling (None, 22, 22, 64) 0 2D) dropout (Dropout) (None, 22, 22, 64) 0 flatten_1 (Flatten) (None, 30976) 0 dense_2 (Dense) (None, 128) 3965056 dense_3 (Dense) (None, 5) 645 ================================================================= Total params: 3,989,285 Trainable params: 3,989,285 Non-trainable params: 0 _________________________________________________________________
epochs = 15
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
Epoch 1/15 92/92 [==============================] - 2s 14ms/step - loss: 1.3840 - accuracy: 0.3999 - val_loss: 1.0967 - val_accuracy: 0.5518 Epoch 2/15 92/92 [==============================] - 1s 12ms/step - loss: 1.1152 - accuracy: 0.5395 - val_loss: 1.1123 - val_accuracy: 0.5545 Epoch 3/15 92/92 [==============================] - 1s 12ms/step - loss: 1.0049 - accuracy: 0.6052 - val_loss: 0.9544 - val_accuracy: 0.6253 Epoch 4/15 92/92 [==============================] - 1s 12ms/step - loss: 0.9452 - accuracy: 0.6257 - val_loss: 0.9681 - val_accuracy: 0.6213 Epoch 5/15 92/92 [==============================] - 1s 12ms/step - loss: 0.8804 - accuracy: 0.6591 - val_loss: 0.8450 - val_accuracy: 0.6798 Epoch 6/15 92/92 [==============================] - 1s 12ms/step - loss: 0.8001 - accuracy: 0.6945 - val_loss: 0.8715 - val_accuracy: 0.6594 Epoch 7/15 92/92 [==============================] - 1s 12ms/step - loss: 0.7736 - accuracy: 0.6965 - val_loss: 0.8059 - val_accuracy: 0.6935 Epoch 8/15 92/92 [==============================] - 1s 12ms/step - loss: 0.7477 - accuracy: 0.7078 - val_loss: 0.8292 - val_accuracy: 0.6812 Epoch 9/15 92/92 [==============================] - 1s 12ms/step - loss: 0.7053 - accuracy: 0.7251 - val_loss: 0.7743 - val_accuracy: 0.6989 Epoch 10/15 92/92 [==============================] - 1s 12ms/step - loss: 0.6884 - accuracy: 0.7340 - val_loss: 0.7867 - val_accuracy: 0.6907 Epoch 11/15 92/92 [==============================] - 1s 12ms/step - loss: 0.6536 - accuracy: 0.7469 - val_loss: 0.7732 - val_accuracy: 0.6785 Epoch 12/15 92/92 [==============================] - 1s 12ms/step - loss: 0.6456 - accuracy: 0.7500 - val_loss: 0.7801 - val_accuracy: 0.6907 Epoch 13/15 92/92 [==============================] - 1s 12ms/step - loss: 0.5941 - accuracy: 0.7735 - val_loss: 0.7185 - val_accuracy: 0.7330 Epoch 14/15 92/92 [==============================] - 1s 12ms/step - loss: 0.5824 - accuracy: 0.7735 - val_loss: 0.7282 - val_accuracy: 0.7357 Epoch 15/15 92/92 [==============================] - 1s 12ms/step - loss: 0.5771 - accuracy: 0.7851 - val_loss: 0.7308 - val_accuracy: 0.7343
เห็นภาพผลการฝึก
หลังจากใช้ data augmentation และ tf.keras.layers.Dropout
แล้ว มี overfitting น้อยกว่าเมื่อก่อน และการฝึกอบรมและการตรวจสอบความถูกต้องมีความสอดคล้องกันมากขึ้น:
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
คาดการณ์ข้อมูลใหม่
สุดท้าย ลองใช้แบบจำลองของเราเพื่อจำแนกรูปภาพที่ไม่รวมอยู่ในชุดการฝึกหรือการตรวจสอบ
sunflower_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg"
sunflower_path = tf.keras.utils.get_file('Red_sunflower', origin=sunflower_url)
img = tf.keras.utils.load_img(
sunflower_path, target_size=(img_height, img_width)
)
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print(
"This image most likely belongs to {} with a {:.2f} percent confidence."
.format(class_names[np.argmax(score)], 100 * np.max(score))
)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg 122880/117948 [===============================] - 0s 0us/step 131072/117948 [=================================] - 0s 0us/step This image most likely belongs to sunflowers with a 89.13 percent confidence.ตัวยึดตำแหน่ง41