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 छवियों का एक बैच है (अंतिम आयाम रंग चैनल आरजीबी को संदर्भित करता है)। label_batch
आकार (32,)
का एक टेंसर है, ये 32 छवियों के अनुरूप लेबल हैं।
आप image_batch
और labels_batch
टेंसर पर .numpy()
को 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]
रेंज में हैं। यह एक तंत्रिका नेटवर्क के लिए आदर्श नहीं है; सामान्य तौर पर आपको अपने इनपुट मूल्यों को छोटा बनाना चाहिए।
यहां, आप tf.keras.layers.Rescaling
का उपयोग करके मानों को [0, 1]
श्रेणी में मानकीकृत करेंगे:
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
या, आप अपनी मॉडल परिभाषा के अंदर परत शामिल कर सकते हैं, जो परिनियोजन को सरल बना सकता है। आइए यहां दूसरे दृष्टिकोण का उपयोग करें।
मॉडल बनाएं
अनुक्रमिक मॉडल में तीन कनवल्शन ब्लॉक होते हैं ( 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 function चुनें। प्रत्येक प्रशिक्षण युग के लिए प्रशिक्षण और सत्यापन सटीकता देखने के लिए, 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% रुक जाती है। इसके अलावा, प्रशिक्षण और सत्यापन सटीकता के बीच सटीकता में अंतर ध्यान देने योग्य है - ओवरफिटिंग का संकेत।
जब प्रशिक्षण उदाहरणों की एक छोटी संख्या होती है, तो मॉडल कभी-कभी शोर या प्रशिक्षण उदाहरणों से अवांछित विवरणों से सीखता है - इस हद तक कि यह नए उदाहरणों पर मॉडल के प्रदर्शन को नकारात्मक रूप से प्रभावित करता है। इस घटना को ओवरफिटिंग के रूप में जाना जाता है। इसका मतलब है कि मॉडल को नए डेटासेट पर सामान्यीकरण करने में मुश्किल होगी।
प्रशिक्षण प्रक्रिया में ओवरफिटिंग से लड़ने के कई तरीके हैं। इस ट्यूटोरियल में, आप डेटा वृद्धि का उपयोग करेंगे और अपने मॉडल में ड्रॉपआउट जोड़ेंगे।
डेटा वृद्धि
ओवरफिटिंग आमतौर पर तब होती है जब कम संख्या में प्रशिक्षण उदाहरण होते हैं। डेटा संवर्द्धन आपके मौजूदा उदाहरणों से अतिरिक्त प्रशिक्षण डेटा उत्पन्न करने के दृष्टिकोण को यादृच्छिक परिवर्तनों का उपयोग करके बढ़ाता है जो विश्वसनीय दिखने वाली छवियां उत्पन्न करते हैं। यह मॉडल को डेटा के अधिक पहलुओं को उजागर करने और बेहतर सामान्यीकरण करने में मदद करता है।
आप निम्न केरस प्रीप्रोसेसिंग परतों का उपयोग करके डेटा वृद्धि लागू करेंगे: 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")
आप किसी मॉडल को एक पल में प्रशिक्षित करने के लिए डेटा वृद्धि का उपयोग करेंगे।
ड्रॉप आउट
ओवरफिटिंग को कम करने की एक अन्य तकनीक नेटवर्क में ड्रॉपआउट नियमितीकरण की शुरुआत करना है।
जब आप ड्रॉपआउट को एक परत पर लागू करते हैं, तो यह प्रशिक्षण प्रक्रिया के दौरान परत से कई आउटपुट इकाइयों को बेतरतीब ढंग से (सक्रियण को शून्य पर सेट करके) छोड़ देता है। ड्रॉपआउट अपने इनपुट मान के रूप में एक भिन्नात्मक संख्या लेता है, जैसे कि 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
प्रशिक्षण परिणामों की कल्पना करें
डेटा संवर्द्धन और tf.keras.layers.Dropout
लागू करने के बाद, पहले की तुलना में कम ओवरफिटिंग है, और प्रशिक्षण और सत्यापन सटीकता करीब संरेखित हैं:
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.