![]() | ![]() | ![]() |
Ten przewodnik uczy modelu sieci neuronowej, aby klasyfikować obrazy ubrań, takich jak tenisówki i koszule. W porządku, jeśli nie rozumiesz wszystkich szczegółów; jest to szybki przegląd pełnego programu TensorFlow ze szczegółami objaśnianymi na bieżąco.
Ten przewodnik używa tf.keras , interfejsu API wysokiego poziomu do tworzenia i trenowania modeli w TensorFlow.
# TensorFlow and tf.keras
import tensorflow as tf
# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
2.3.1
Zaimportuj zestaw danych Fashion MNIST
W tym przewodniku wykorzystano zbiór danych Fashion MNIST, który zawiera 70 000 obrazów w skali szarości w 10 kategoriach. Zdjęcia przedstawiają poszczególne elementy odzieży w niskiej rozdzielczości (28 na 28 pikseli), jak widać tutaj:
![]() |
Rysunek 1. Próbki Fashion-MNIST (firma Zalando, licencja MIT). |
Moda MNIST ma być bezpośrednim zamiennikiem klasycznego zbioru danych MNIST - często używanego jako „Hello, World” programów uczenia maszynowego do wizji komputerowej. Zbiór danych MNIST zawiera obrazy odręcznych cyfr (0, 1, 2 itd.) W formacie identycznym z formatem artykułów odzieżowych, których będziesz tu używać.
Ten przewodnik używa Fashion MNIST ze względu na różnorodność i ponieważ jest to nieco trudniejszy problem niż zwykły MNIST. Oba zestawy danych są stosunkowo małe i służą do weryfikacji, czy algorytm działa zgodnie z oczekiwaniami. Są dobrym punktem wyjścia do testowania i debugowania kodu.
Tutaj 60 000 obrazów jest używanych do uczenia sieci i 10 000 obrazów do oceny, jak dokładnie sieć nauczyła się klasyfikować obrazy. Dostęp do Fashion MNIST można uzyskać bezpośrednio z TensorFlow. Importuj i ładuj dane Fashion MNIST bezpośrednio z TensorFlow:
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step
Ładowanie zestawu danych zwraca cztery tablice NumPy:
-
train_images
itrain_labels
są zbioremtrain_labels
- danymi, których model używa do nauki. - Model jest testowany względem zestawu
test_images
, tablictest_labels
itest_labels
.
Obrazy mają wymiary 28x28 NumPy, z wartościami pikseli w zakresie od 0 do 255. Etykiety są tablicą liczb całkowitych z zakresu od 0 do 9. Odpowiadają one klasie odzieży, którą reprezentuje obraz:
Etykieta | Klasa |
---|---|
0 | T-shirt / top |
1 | Spodnie |
2 | Zjechać na pobocze |
3 | Sukienka |
4 | Płaszcz |
5 | Sandał |
6 | Koszula |
7 | Sneaker |
8 | Torba |
9 | But do kostki |
Każdy obraz jest przypisany do jednej etykiety. Ponieważ nazwy klas nie są zawarte w zestawie danych, należy je przechowywać tutaj, aby użyć ich później podczas drukowania obrazów:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
Przeglądaj dane
Przeanalizujmy format zbioru danych przed uczeniem modelu. Poniższy rysunek pokazuje, że w zestawie uczącym znajduje się 60000 obrazów, a każdy obraz jest reprezentowany jako 28 x 28 pikseli:
train_images.shape
(60000, 28, 28)
Podobnie w zestawie uczącym znajduje się 60000 etykiet:
len(train_labels)
60000
Każda etykieta jest liczbą całkowitą od 0 do 9:
train_labels
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
W zestawie testowym jest 10 000 obrazów. Ponownie, każdy obraz jest reprezentowany jako 28 x 28 pikseli:
test_images.shape
(10000, 28, 28)
A zestaw testowy zawiera 10000 etykiet obrazów:
len(test_labels)
10000
Przetwórz wstępnie dane
Dane muszą zostać wstępnie przetworzone przed uczeniem sieci. Jeśli przyjrzysz się pierwszemu obrazowi w zestawie uczącym, zobaczysz, że wartości pikseli mieszczą się w zakresie od 0 do 255:
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
Skaluj te wartości do zakresu od 0 do 1 przed przekazaniem ich do modelu sieci neuronowej. Aby to zrobić, podziel wartości przez 255. Ważne jest, aby zestaw uczący i zestaw testowy zostały wstępnie przetworzone w ten sam sposób:
train_images = train_images / 255.0
test_images = test_images / 255.0
Aby sprawdzić, czy dane są we właściwym formacie i czy jesteś gotowy do zbudowania i wytrenowania sieci, wyświetlmy pierwsze 25 obrazów z zestawu uczącego i wyświetlmy nazwę klasy pod każdym obrazem.
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i]])
plt.show()
Zbuduj model
Budowa sieci neuronowej wymaga skonfigurowania warstw modelu, a następnie skompilowania modelu.
Skonfiguruj warstwy
Podstawowym budulcem sieci neuronowej jest warstwa . Warstwy wyodrębniają reprezentacje z wprowadzonych do nich danych. Miejmy nadzieję, że te reprezentacje są znaczące dla rozpatrywanego problemu.
Większość uczenia głębokiego składa się z łączenia ze sobą prostych warstw. Większość warstw, takich jak tf.keras.layers.Dense
, ma parametry, których uczy się podczas treningu.
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10)
])
Pierwsza warstwa w tej sieci, tf.keras.layers.Flatten
, przekształca format obrazów z dwuwymiarowej tablicy (28 na 28 pikseli) na jednowymiarową tablicę (28 * 28 = 784 piksele). Pomyśl o tej warstwie jako o rozkładaniu rzędów pikseli na obrazku i ustawianiu ich w jednej linii. Ta warstwa nie ma parametrów do nauczenia; tylko formatuje dane.
Po spłaszczeniu pikseli sieć składa się z sekwencji dwóch warstw tf.keras.layers.Dense
. Są to gęsto połączone lub w pełni połączone warstwy neuronowe. Pierwsza Dense
warstwa ma 128 węzłów (lub neuronów). Druga (i ostatnia) warstwa zwraca tablicę logitów o długości 10. Każdy węzeł zawiera punktację wskazującą, że bieżący obraz należy do jednej z 10 klas.
Skompiluj model
Zanim model będzie gotowy do treningu, potrzebuje kilku dodatkowych ustawień. Są one dodawane podczas etapu kompilacji modelu:
- Funkcja utraty - mierzy dokładność modelu podczas treningu. Chcesz zminimalizować tę funkcję, aby „sterować” modelem we właściwym kierunku.
- Optymalizator - w ten sposób model jest aktualizowany na podstawie widzianych danych i funkcji utraty.
- Metryki - używane do monitorowania etapów szkolenia i testowania. Poniższy przykład używa dokładności , czyli ułamka obrazów, które są poprawnie sklasyfikowane.
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
Wytrenuj model
Uczenie modelu sieci neuronowej wymaga następujących kroków:
- Wprowadź dane szkoleniowe do modelu. W tym przykładzie dane szkoleniowe znajdują się w
train_images
itrain_labels
. - Model uczy się kojarzyć obrazy i etykiety.
- Poproś model, aby przewidywał zestaw testowy - w tym przykładzie tablicę
test_images
. - Sprawdź, czy prognozy są zgodne z etykietami z tablicy
test_labels
.
Nakarm model
Aby rozpocząć trenowanie, wywołaj metodę model.fit
- tak zwaną, ponieważ „dopasowuje” ona model do danych model.fit
:
model.fit(train_images, train_labels, epochs=10)
Epoch 1/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.4917 - accuracy: 0.8277 Epoch 2/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.3702 - accuracy: 0.8674 Epoch 3/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.3328 - accuracy: 0.8793 Epoch 4/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.3106 - accuracy: 0.8859 Epoch 5/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.2915 - accuracy: 0.8927 Epoch 6/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.2771 - accuracy: 0.8968 Epoch 7/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.2666 - accuracy: 0.9008 Epoch 8/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.2547 - accuracy: 0.9055 Epoch 9/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.2439 - accuracy: 0.9097 Epoch 10/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.2370 - accuracy: 0.9115 <tensorflow.python.keras.callbacks.History at 0x7fd5c7912b00>
Gdy model uczy się, wyświetlane są metryki strat i dokładności. Ten model osiąga dokładność około 0,91 (lub 91%) danych uczących.
Oceń dokładność
Następnie porównaj, jak model działa na testowym zestawie danych:
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
313/313 - 1s - loss: 0.3637 - accuracy: 0.8693 Test accuracy: 0.8693000078201294
Okazuje się, że dokładność zestawu danych testowych jest nieco mniejsza niż dokładność zestawu danych uczących. Ta luka między dokładnością treningu a dokładnością testu oznacza nadmierne dopasowanie . Do nadmiernego dopasowania dochodzi, gdy model uczenia maszynowego działa gorzej na nowych, wcześniej niewidocznych danych wejściowych, niż w przypadku danych szkoleniowych. Nadmiernie dopasowany model „zapamiętuje” szum i szczegóły w zbiorze danych uczących do punktu, w którym ma to negatywny wpływ na wydajność modelu w nowych danych. Więcej informacji można znaleźć w następujących artykułach:
Przewidywać
Po wyszkoleniu modelu można go użyć do prognozowania niektórych obrazów. Wyjścia liniowe modelu, logity . Dołącz warstwę softmax, aby przekonwertować logity na prawdopodobieństwa, które są łatwiejsze do zinterpretowania.
probability_model = tf.keras.Sequential([model,
tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)
Tutaj model przewidział etykietę dla każdego obrazu w zestawie testowym. Rzućmy okiem na pierwszą prognozę:
predictions[0]
array([5.1698703e-07, 5.0422708e-11, 1.0513627e-06, 4.2676376e-08, 4.1753174e-07, 8.8213873e-04, 1.4294442e-06, 8.9591898e-02, 3.7699414e-07, 9.0952224e-01], dtype=float32)
Przewidywanie to tablica 10 liczb. Reprezentują „pewność” modela, że obraz odpowiada każdemu z 10 różnych elementów garderoby. Możesz zobaczyć, która etykieta ma najwyższą wartość ufności:
np.argmax(predictions[0])
9
Tak więc model jest najbardziej pewny, że ten obraz to but za kostkę lub class_names[9]
. Analiza etykiety testowej pokazuje, że ta klasyfikacja jest poprawna:
test_labels[0]
9
Przedstaw to na wykresie, aby przyjrzeć się pełnemu zestawowi 10 prognoz klasowych.
def plot_image(i, predictions_array, true_label, img):
true_label, img = true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
true_label = true_label[i]
plt.grid(False)
plt.xticks(range(10))
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
Zweryfikuj prognozy
Po wyszkoleniu modelu można go użyć do prognozowania niektórych obrazów.
Spójrzmy na zerowy obraz, przewidywania i tablicę predykcji. Etykiety prawidłowych prognoz są niebieskie, a nieprawidłowe etykiety prognoz są czerwone. Liczba podaje procent (ze 100) przewidywanej etykiety.
i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i], test_labels)
plt.show()
i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i], test_labels)
plt.show()
Narysujmy kilka obrazów z ich przewidywaniami. Zwróć uwagę, że model może się mylić, nawet jeśli jest bardzo pewny.
# Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and incorrect predictions in red.
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()
Użyj wytrenowanego modelu
Na koniec użyj wytrenowanego modelu, aby przewidzieć pojedynczy obraz.
# Grab an image from the test dataset.
img = test_images[1]
print(img.shape)
(28, 28)
Modele tf.keras
są zoptymalizowane pod kątem tworzenia prognoz na partii lub kolekcji przykładów naraz. W związku z tym, nawet jeśli używasz pojedynczego obrazu, musisz dodać go do listy:
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))
print(img.shape)
(1, 28, 28)
Teraz wytypuj poprawną etykietę dla tego obrazu:
predictions_single = probability_model.predict(img)
print(predictions_single)
[[1.2673076e-05 1.9937504e-13 9.9978513e-01 1.8617269e-11 1.3060638e-04 2.2522463e-12 7.1663781e-05 1.4157123e-21 3.1792444e-11 1.6293697e-13]]
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
tf.keras.Model.predict
zwraca listę list - jedną listę dla każdego obrazu w tf.keras.Model.predict
danych. Pobierz prognozy dla naszego (jedynego) obrazu w partii:
np.argmax(predictions_single[0])
2
Model przewiduje etykietę zgodnie z oczekiwaniami.
# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.