หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

การจำแนกภาพ

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดสมุดบันทึก

บทช่วยสอนนี้แสดงวิธีจำแนกรูปภาพดอกไม้ มันสร้างลักษณนามภาพโดยใช้แบบจำลอง keras.Sequential และโหลดข้อมูลโดยใช้ preprocessing.image_dataset_from_directory คุณจะได้รับประสบการณ์จริงจากแนวคิดดังต่อไปนี้:

  • โหลดชุดข้อมูลอย่างมีประสิทธิภาพจากดิสก์
  • การระบุ overfitting และการประยุกต์ใช้เทคนิคต่าง ๆ เพื่อบรรเทารวมถึงการเพิ่มข้อมูลและ Dropout

บทช่วยสอนนี้ติดตามกระบวนการเรียนรู้ของเครื่องพื้นฐาน:

  1. ตรวจสอบและทำความเข้าใจข้อมูล
  2. สร้างไปป์ไลน์อินพุต
  3. สร้างแบบจำลอง
  4. ฝึกโมเดล
  5. ทดสอบรูปแบบ
  6. ปรับปรุงแบบจำลองและทำกระบวนการซ้ำ
pip install -q tf-nightly

นำเข้า 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 ภาพ ชุดข้อมูลมี 5 ไดเรกทอรีย่อยหนึ่งรายการต่อคลาส:

 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)
 
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
228818944/228813984 [==============================] - 4s 0us/step

หลังจากดาวน์โหลดคุณควรจะมีสำเนาของชุดข้อมูลที่มีอยู่ มีภาพทั้งหมด 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]))
 

PNG

 PIL.Image.open(str(roses[1]))
 

PNG

และทิวลิปบางส่วน:

 tulips = list(data_dir.glob('tulips/*'))
PIL.Image.open(str(tulips[0]))
 

PNG

 PIL.Image.open(str(tulips[1]))
 

PNG

โหลดโดยใช้ keras.preprocessing

มาโหลดอิมเมจเหล่านี้จากดิสก์โดยใช้ยูทิลิตี้ image_dataset_from_directory ที่ เป็นประโยชน์ สิ่งนี้จะนำคุณจากไดเรกทอรีรูปภาพบนดิสก์ไปยัง tf.data.Dataset ด้วย tf.data.Dataset สองสามบรรทัด หากคุณต้องการคุณยังสามารถเขียนโค้ดโหลดข้อมูลของคุณเองตั้งแต่ต้นโดยไปที่บทช่วยสอน โหลดรูปภาพ

สร้างชุดข้อมูล

กำหนดพารามิเตอร์บางอย่างสำหรับโหลดเดอร์:

 batch_size = 32
img_height = 180
img_width = 180
 

เป็นแนวปฏิบัติที่ดีที่จะใช้ตัวแยกการตรวจสอบความถูกต้องเมื่อพัฒนาโมเดล เราจะใช้รูปภาพ 80% สำหรับการฝึกอบรมและ 20% สำหรับการตรวจสอบ

 train_ds = tf.keras.preprocessing.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.preprocessing.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']

เห็นภาพข้อมูล

นี่คือ 9 ภาพแรกจากชุดข้อมูลการฝึกอบรม

 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")
 

PNG

คุณจะฝึกโมเดลโดยใช้ชุดข้อมูลเหล่านี้โดยส่งไปยัง 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) นี่เป็นชุดของรูปภาพ 32 รูปที่มีรูปร่าง 180x180x3 (มิติสุดท้ายอ้างอิงถึงช่องสี RGB) label_batch เป็นเทนเซอร์ของรูปร่าง (32,) เหล่านี้เป็นฉลากที่สอดคล้องกับภาพ 32

คุณสามารถเรียกใช้. .numpy() บนตัว image_batch และ labels_batch เพื่อแปลงเป็น numpy.ndarray

กำหนดค่าชุดข้อมูลสำหรับประสิทธิภาพ

ตรวจสอบให้แน่ใจว่าได้ใช้การดึงข้อมูลล่วงหน้าแบบบัฟเฟอร์เพื่อให้เราสามารถให้ข้อมูลจากดิสก์โดยไม่ทำให้ I / O กลายเป็นบล็อก นี่เป็นวิธีการสำคัญสองวิธีที่คุณควรใช้เมื่อโหลดข้อมูล

Dataset.cache() เก็บภาพในหน่วยความจำหลังจากที่พวกเขาถูกโหลดออกจากดิสก์ในช่วงยุคแรก สิ่งนี้จะช่วยให้แน่ใจว่าชุดข้อมูลจะไม่กลายเป็นคอขวดในขณะที่ฝึกฝนแบบจำลองของคุณ หากชุดข้อมูลของคุณมีขนาดใหญ่เกินไปที่จะใส่ลงในหน่วยความจำคุณสามารถใช้วิธีนี้เพื่อสร้างแคชบนดิสก์ของนักแสดง

Dataset.prefetch() ทับซ้อนการประมวลผลข้อมูลล่วงหน้าและเรียกใช้โมเดลขณะฝึกอบรม

ผู้อ่านที่สนใจสามารถเรียนรู้เพิ่มเติมเกี่ยวกับทั้งสองวิธีรวมถึงวิธีแคชข้อมูลลงดิสก์ใน คู่มือประสิทธิภาพข้อมูล

 AUTOTUNE = tf.data.experimental.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] โดยใช้เลเยอร์ Rescaling

 normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)
 

มีสองวิธีในการใช้เลเยอร์นี้ คุณสามารถนำไปใช้กับชุดข้อมูลโดยเรียกแผนที่:

 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 pixels values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image)) 
 
0.0 1.0

หรือคุณสามารถรวมเลเยอร์ไว้ในข้อกำหนดรุ่นของคุณซึ่งสามารถทำให้การปรับใช้ง่ายขึ้น เราจะใช้วิธีที่สองที่นี่

สร้างแบบจำลอง

โมเดลประกอบด้วยบล็อกการแปลงสามบล็อกที่มีเลเยอร์พูลสูงสุดในแต่ละบล็อก มีเลเยอร์ที่เชื่อมต่ออย่างเต็มที่โดยมี 128 ยูนิตอยู่ด้านบนซึ่งเปิดใช้งานโดยฟังก์ชั่นการเปิดใช้งาน relu รุ่นนี้ยังไม่ได้รับการปรับเพื่อความแม่นยำสูงเป้าหมายของการสอนนี้คือการแสดงวิธีการมาตรฐาน

 num_classes = 5

model = Sequential([
  layers.experimental.preprocessing.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)
])
 

รวบรวมรูปแบบ

สำหรับบทช่วยสอนนี้ให้เลือก optimizers.Adam เพิ่มประสิทธิภาพและเครื่องมือเพิ่มประสิทธิภาพการสูญเสียการ losses.SparseCategoricalCrossentropy ฟังก์ชั่นการสูญเสียแบบ losses.SparseCategoricalCrossentropy หากต้องการดูความแม่นยำในการฝึกอบรมและการตรวจสอบความถูกต้องสำหรับแต่ละช่วงการฝึกอบรมให้ส่งอาร์กิวเมนต์ metrics

 model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
 

สรุปแบบจำลอง

ดูเลเยอร์ทั้งหมดของเครือข่ายโดยใช้วิธี 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 (MaxPooling2 (None, 45, 45, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 45, 45, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 22, 22, 64)        0         
_________________________________________________________________
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 [==============================] - 4s 47ms/step - loss: 1.9328 - accuracy: 0.2896 - val_loss: 1.1022 - val_accuracy: 0.5245
Epoch 2/10
92/92 [==============================] - 1s 10ms/step - loss: 1.0441 - accuracy: 0.5761 - val_loss: 1.0057 - val_accuracy: 0.5913
Epoch 3/10
92/92 [==============================] - 1s 10ms/step - loss: 0.8640 - accuracy: 0.6763 - val_loss: 0.8951 - val_accuracy: 0.6499
Epoch 4/10
92/92 [==============================] - 1s 10ms/step - loss: 0.7106 - accuracy: 0.7472 - val_loss: 0.8992 - val_accuracy: 0.6621
Epoch 5/10
92/92 [==============================] - 1s 10ms/step - loss: 0.4817 - accuracy: 0.8285 - val_loss: 0.8997 - val_accuracy: 0.6662
Epoch 6/10
92/92 [==============================] - 1s 10ms/step - loss: 0.3131 - accuracy: 0.8903 - val_loss: 1.0014 - val_accuracy: 0.6567
Epoch 7/10
92/92 [==============================] - 1s 10ms/step - loss: 0.1782 - accuracy: 0.9436 - val_loss: 1.2140 - val_accuracy: 0.6431
Epoch 8/10
92/92 [==============================] - 1s 10ms/step - loss: 0.1024 - accuracy: 0.9703 - val_loss: 1.5144 - val_accuracy: 0.6240
Epoch 9/10
92/92 [==============================] - 1s 10ms/step - loss: 0.0736 - accuracy: 0.9815 - val_loss: 1.7651 - val_accuracy: 0.5926
Epoch 10/10
92/92 [==============================] - 1s 10ms/step - loss: 0.0761 - accuracy: 0.9775 - val_loss: 2.0429 - val_accuracy: 0.5967

เห็นผลการฝึกอบรม

สร้างแผนการสูญเสียและความแม่นยำในชุดฝึกอบรมและการตรวจสอบ

 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()
 

PNG

ดังที่คุณเห็นจากแปลงความแม่นยำในการฝึกอบรมและความถูกต้องของการตรวจสอบความถูกต้องจะถูกปิดโดยขอบขนาดใหญ่และรูปแบบได้รับความแม่นยำเพียงประมาณ 60% ในชุดการตรวจสอบ

ลองดูสิ่งที่ผิดพลาดและพยายามเพิ่มประสิทธิภาพโดยรวมของตัวแบบ

overfitting

ในแปลงข้างต้นความแม่นยำในการฝึกอบรมเพิ่มขึ้นเป็นเส้นตรงตลอดเวลาในขณะที่ความแม่นยำในการตรวจสอบจะลดลงประมาณ 60% ในกระบวนการฝึกอบรม นอกจากนี้ความแตกต่างของความแม่นยำระหว่างการฝึกอบรมและความแม่นยำในการตรวจสอบนั้นเป็นสิ่งที่เห็นได้ชัดเจนซึ่งเป็นสัญญาณบ่งบอกถึง การมีน้ำหนัก เกิน

เมื่อมีตัวอย่างการฝึกอบรมจำนวนเล็กน้อยบางครั้งตัวแบบจะเรียนรู้จากเสียงหรือรายละเอียดที่ไม่ต้องการจากตัวอย่างการฝึกอบรมจนถึงระดับที่ส่งผลเสียต่อประสิทธิภาพของแบบจำลองในตัวอย่างใหม่ ปรากฏการณ์นี้เป็นที่รู้จักกันในชื่อ overfitting หมายความว่าแบบจำลองจะมีช่วงเวลาที่ยากลำบากในการสรุปชุดข้อมูลใหม่

การต่อสู้มากเกินไปมีหลายวิธีในกระบวนการฝึกอบรม ในบทช่วยสอนนี้คุณจะใช้ การเพิ่มข้อมูล และเพิ่ม Dropout ให้กับแบบจำลองของคุณ

การเพิ่มข้อมูล

โดยทั่วไปแล้วการบรรจุมากเกินไปเกิดขึ้นเมื่อมีตัวอย่างการฝึกจำนวนน้อย การเพิ่มข้อมูล ใช้วิธีการสร้างข้อมูลการฝึกอบรมเพิ่มเติมจากตัวอย่างที่มีอยู่ของคุณโดยการเพิ่มจากนั้นใช้การแปลงแบบสุ่มที่ให้ภาพที่ดูน่าเชื่อถือ สิ่งนี้จะช่วยให้โมเดลเปิดเผยข้อมูลในมุมมองที่กว้างขึ้นและสรุปได้ดีขึ้น

เราจะใช้การเพิ่มข้อมูลโดยใช้ Keras Preprocessing Layers สิ่งเหล่านี้สามารถรวมอยู่ในแบบจำลองของคุณเช่นเลเยอร์อื่น ๆ และทำงานบน GPU

 data_augmentation = keras.Sequential(
  [
    layers.experimental.preprocessing.RandomFlip("horizontal", 
                                                 input_shape=(img_height, 
                                                              img_width,
                                                              3)),
    layers.experimental.preprocessing.RandomRotation(0.1),
    layers.experimental.preprocessing.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")
 

PNG

เราจะใช้การเพิ่มข้อมูลเพื่อฝึกฝนแบบจำลองในไม่ช้า

การออกกลางคัน

อีกเทคนิคหนึ่งในการลดการ overfitting คือการแนะนำ Dropout ให้กับเครือข่ายซึ่งเป็นรูปแบบของการ ทำให้เป็นปกติ

เมื่อคุณใช้ Dropout กับเลเยอร์มันจะสุ่มลดลง (โดยการตั้งค่าการเปิดใช้งานเป็นศูนย์) จำนวนของหน่วยเอาต์พุตจากเลเยอร์ในระหว่างกระบวนการฝึกอบรม การออกกลางคันใช้จำนวนเศษส่วนเป็นค่าอินพุตในรูปแบบเช่น 0.1, 0.2, 0.4 และอื่น ๆ ซึ่งหมายความว่าการปล่อย 10%, 20% หรือ 40% ของหน่วยเอาท์พุทแบบสุ่มจากชั้นที่ใช้

มาสร้างเครือข่ายประสาทใหม่โดยใช้ layers.Dropout แล้วฝึกมันโดยใช้ภาพที่เติม

 model = Sequential([
  data_augmentation,
  layers.experimental.preprocessing.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 (MaxPooling2 (None, 90, 90, 16)        0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 90, 90, 32)        4640      
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 45, 45, 32)        0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 45, 45, 64)        18496     
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 22, 22, 64)        0         
_________________________________________________________________
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 20ms/step - loss: 1.4842 - accuracy: 0.3279 - val_loss: 1.0863 - val_accuracy: 0.5640
Epoch 2/15
92/92 [==============================] - 1s 12ms/step - loss: 1.1215 - accuracy: 0.5284 - val_loss: 1.0374 - val_accuracy: 0.6022
Epoch 3/15
92/92 [==============================] - 1s 12ms/step - loss: 0.9680 - accuracy: 0.6117 - val_loss: 0.9200 - val_accuracy: 0.6485
Epoch 4/15
92/92 [==============================] - 1s 12ms/step - loss: 0.8538 - accuracy: 0.6753 - val_loss: 0.9206 - val_accuracy: 0.6417
Epoch 5/15
92/92 [==============================] - 1s 12ms/step - loss: 0.7744 - accuracy: 0.6977 - val_loss: 0.8169 - val_accuracy: 0.6839
Epoch 6/15
92/92 [==============================] - 1s 13ms/step - loss: 0.7758 - accuracy: 0.7093 - val_loss: 0.7743 - val_accuracy: 0.6880
Epoch 7/15
92/92 [==============================] - 1s 13ms/step - loss: 0.6805 - accuracy: 0.7481 - val_loss: 0.8598 - val_accuracy: 0.6540
Epoch 8/15
92/92 [==============================] - 1s 13ms/step - loss: 0.7132 - accuracy: 0.7278 - val_loss: 0.7177 - val_accuracy: 0.7207
Epoch 9/15
92/92 [==============================] - 1s 13ms/step - loss: 0.6634 - accuracy: 0.7580 - val_loss: 0.7152 - val_accuracy: 0.7166
Epoch 10/15
92/92 [==============================] - 1s 13ms/step - loss: 0.6562 - accuracy: 0.7538 - val_loss: 0.7251 - val_accuracy: 0.7248
Epoch 11/15
92/92 [==============================] - 1s 13ms/step - loss: 0.5798 - accuracy: 0.7840 - val_loss: 0.7016 - val_accuracy: 0.7357
Epoch 12/15
92/92 [==============================] - 1s 13ms/step - loss: 0.5635 - accuracy: 0.7913 - val_loss: 0.7755 - val_accuracy: 0.7248
Epoch 13/15
92/92 [==============================] - 1s 13ms/step - loss: 0.5361 - accuracy: 0.7982 - val_loss: 0.7575 - val_accuracy: 0.7153
Epoch 14/15
92/92 [==============================] - 1s 13ms/step - loss: 0.5420 - accuracy: 0.8022 - val_loss: 0.7375 - val_accuracy: 0.7302
Epoch 15/15
92/92 [==============================] - 1s 12ms/step - loss: 0.5132 - accuracy: 0.8120 - val_loss: 0.7561 - val_accuracy: 0.7289

เห็นผลการฝึกอบรม

หลังจากใช้การเพิ่มข้อมูลและการออกกลางคันจะมีการจัดเรียงข้อมูลที่น้อยกว่าก่อนหน้านี้และความแม่นยำในการฝึกอบรมและการตรวจสอบความถูกต้องจะสอดคล้องกันมากขึ้น

 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()
 

PNG

ทำนายข้อมูลใหม่

สุดท้ายเรามาใช้แบบจำลองของเราเพื่อจำแนกรูปภาพที่ไม่ได้รวมอยู่ในชุดฝึกอบรมหรือการตรวจสอบ

 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 = keras.preprocessing.image.load_img(
    sunflower_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.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
This image most likely belongs to sunflowers with a 89.39 percent confidence.