Jak vytvořit konvoluční neuronovou síť (CNN) pro klasifikaci obrázků pomocí TensorFlow a Keras? V tomto příkladu budeme používat dataset CIFAR-10, který obsahuje 60 000 barevných obrázků v 10 třídách, s 6000 obrázky na třídu. Dataset je rozdělen na 50000 trénovacích obrázků a 10000 testovacích obrázků.
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
# Načtení datasetu CIFAR10
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# Normalizace pixelových hodnot do rozsahu 0 až 1
train_images, test_images = train_images / 255.0, test_images / 255.0
# Vytvoření konvolučního základu
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
# Přidání plně propojených vrstev
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
# Kompilace a trénování modelu
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
# Vyhodnocení modelu
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
Tento kód vytvoří konvoluční neuronovou síť s třemi konvolučními vrstvami a dvěma plně propojenými vrstvami. Model je trénován na 10 epoch a nakonec je vyhodnocen na testovacím datasetu.
Tento kód můžete použít tak, že ho vložíte do skriptu Pythonu nebo do notebooku Jupyter a spustíte ho. Aby tento kód fungoval, musíte mít nainstalované knihovny TensorFlow a matplotlib. Tyto knihovny můžete nainstalovat pomocí nástroje pip pro správu balíčků Pythonu:
pip install tensorflow matplotlib
Když spustíte tento kód, stáhne se dataset CIFAR-10 a trénovací obrázky budou normalizovány na rozsah 0 až 1. Poté se vytvoří konvoluční neuronová síť s třemi konvolučními vrstvami a dvěma plně propojenými vrstvami. Model se poté zkompiluje a natrénuje na 10 epoch. Nakonec se model vyhodnotí na testovacích datech a vypíše se přesnost testování.
Výstupem bude přesnost modelu na testovacích datech, která ukazuje, jak dobře model klasifikuje obrázky, které nikdy předtím neviděl. Můžete také experimentovat s různými nastaveními, jako je počet epoch, počet vrstev v modelu nebo typy aktivace, abyste zlepšili přesnost svého modelu.
A jak vložit obrázek na možnost testování?
Abychom mohli vložit obrázek pro testování, budeme muset upravit náš kód tak, aby obsahoval funkci pro načítání a předzpracování obrázku. Následující kód ukazuje, jak to lze udělat:
import numpy as np
from tensorflow.keras.preprocessing import image as kp_image
def load_and_process_image(image_path):
# Load image
img = kp_image.load_img(image_path, target_size=(32, 32))
# Convert image to array and preprocess for mobilenet
img_array = kp_image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = img_array / 255.0 # normalize to [0,1]
return img_array
# Load your image
image_path = 'path_to_your_image.jpg' # replace with your image path
img_array = load_and_process_image(image_path)
# Use the model to predict the class
prediction = model.predict(img_array)
predicted_class = np.argmax(prediction[0], axis=-1)
print('Predicted class:', predicted_class)
Tento kód vloží obrázek, který chcete testovat, načte ho, převede na pole numpy, normalizuje ho na rozsah [0,1], pak použije model pro předpověď třídy obrázku. Výstupem je index třídy s nejvyšší pravděpodobností.
Upozorňuji, že musíte nahradit 'path_to_your_image.jpg'
skutečnou cestou k obrázku, který chcete testovat. Navíc tento kód předpokládá, že vaše obrázky jsou stejných rozměrů, jako obrázky, na kterých byl model trénován (v tomto případě 32×32 pixelů). Pokud nejsou, musíte je přeškálovat na správnou velikost.
Zde je celý kód s přidanou funkcí pro načítání a testování obrázku:
import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.losses import sparse_categorical_crossentropy
from tensorflow.keras.optimizers import Adam
import numpy as np
from tensorflow.keras.preprocessing import image as kp_image
# Model configuration
batch_size = 50
img_width, img_height, img_num_channels = 32, 32, 3
loss_function = sparse_categorical_crossentropy
no_classes = 10
no_epochs = 25
optimizer = Adam()
validation_split = 0.2
verbosity = 1
# Load CIFAR-10 data
(input_train, target_train), (input_test, target_test) = cifar10.load_data()
# Determine shape of the data
input_shape = (img_width, img_height, img_num_channels)
# Parse numbers as floats
input_train = input_train.astype('float32')
input_test = input_test.astype('float32')
# Normalize data
input_train = input_train / 255
input_test = input_test / 255
# Create the model
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(no_classes, activation='softmax'))
# Compile the model
model.compile(loss=loss_function,
optimizer=optimizer,
metrics=['accuracy'])
# Fit data to model
model.fit(input_train, target_train,
batch_size=batch_size,
epochs=no_epochs,
verbose=verbosity,
validation_split=validation_split)
# Generate generalization metrics
score = model.evaluate(input_test, target_test, verbose=0)
print(f'Test loss: {score[0]} / Test accuracy: {score[1]}')
# Define the function to load and preprocess the image
def load_and_process_image(image_path):
# Load image
img = kp_image.load_img(image_path, target_size=(32, 32))
# Convert image to array and preprocess for mobilenet
img_array = kp_image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = img_array / 255.0 # normalize to [0,1]
return img_array
# Load your image for testing
image_path = 'path_to_your_image.jpg' # replace with your image path
img_array = load_and_process_image(image_path)
# Use the model to predict the class
prediction = model.predict(img_array)
predicted_class = np.argmax(prediction[0], axis=-1)
print('Predicted class:', predicted_class)
Upozorňuji, že musíte nahradit 'path_to_your_image.jpg'
skutečnou cestou k obrázku, který chcete testovat.
A nakonec rychlá ukázka výstupu (pouze 2 epochy):
V našem případě používáme dataset CIFAR-10, který se skládá z obrázků 10 tříd:
0: letadlo 1: automobil 2: pták 3: kočka 4: jelen 5: pes 6: žába 7: kůň 8: loď 9: nákladní auto
Takže pokud výstup říká “Predicted class: 5”, model predikoval, že obrázek patří do třídy “pes”.