Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Szkolenie niestandardowe: opis przejścia

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik

W tym przewodniku zastosowano systemy uczące się, aby podzielić kwiaty tęczówki na kategorie według gatunków. Wykorzystuje TensorFlow do:

  1. Zbudować model,
  2. Wytrenuj ten model na przykładowych danych i
  3. Użyj modelu, aby przewidzieć nieznane dane.

Programowanie TensorFlow

W tym przewodniku zastosowano następujące koncepcje TensorFlow wysokiego poziomu:

Ten samouczek ma strukturę wielu programów TensorFlow:

  1. Zaimportuj i przeanalizuj zestaw danych.
  2. Wybierz typ modelu.
  3. Wytrenuj model.
  4. Oceń skuteczność modelu.
  5. Użyj wytrenowanego modelu do tworzenia prognoz.

Program instalacyjny

Skonfiguruj import

Zaimportuj TensorFlow i inne wymagane moduły Pythona. Domyślnie TensorFlow używa przyspieszonego wykonania do natychmiastowej oceny operacji, zwracając konkretne wartości zamiast tworzyć wykres obliczeniowy, który jest wykonywany później. Jeśli jesteś przyzwyczajony do REPL lub interaktywnej konsoli python , wydaje się to znajome.

 import os
import matplotlib.pyplot as plt
 
 import tensorflow as tf
 
 print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution: {}".format(tf.executing_eagerly()))
 
TensorFlow version: 2.2.0
Eager execution: True

Problem klasyfikacji Iris

Wyobraź sobie, że jesteś botanikiem szukającym automatycznego sposobu kategoryzowania każdego znalezionego kwiatu irysa. Uczenie maszynowe zapewnia wiele algorytmów do statystycznej klasyfikacji kwiatów. Na przykład zaawansowany program do uczenia maszynowego mógłby klasyfikować kwiaty na podstawie zdjęć. Nasze ambicje są skromniejsze - będziemy klasyfikować kwiaty tęczówki na podstawie pomiarów długości i szerokości ich działek i płatków .

Rodzaj Iris obejmuje około 300 gatunków, ale nasz program sklasyfikuje tylko następujące trzy:

  • Iris setosa
  • Iris virginica
  • Iris versicolor
Porównanie geometrii płatków dla trzech gatunków tęczówki: Iris setosa, Iris virginica i Iris versicolor
Rycina 1. Iris setosa (autorstwa Radomil , CC BY-SA 3,0), Iris versicolor (autorstwa Dlanglois , CC BY-SA 3,0) i Iris virginica (autorstwa Franka Mayfielda , CC BY-SA 2,0).

Na szczęście ktoś już stworzył zbiór danych 120 kwiatów tęczówki z wymiarami działek i płatków. Jest to klasyczny zbiór danych popularny w przypadku początkujących problemów z klasyfikacją systemów uczących się.

Zaimportuj i przeanalizuj zestaw danych szkoleniowych

Pobierz plik zestawu danych i przekonwertuj go na strukturę, której może używać ten program w języku Python.

Pobierz zestaw danych

Pobierz plik zestawu danych szkoleniowych za pomocą funkcji tf.keras.utils.get_file . Zwraca ścieżkę do pobranego pliku:

 train_dataset_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv"

train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),
                                           origin=train_dataset_url)

print("Local copy of the dataset file: {}".format(train_dataset_fp))
 
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv
8192/2194 [================================================================================================================] - 0s 0us/step
Local copy of the dataset file: /home/kbuilder/.keras/datasets/iris_training.csv

Sprawdź dane

Ten zbiór danych, iris_training.csv , jest zwykłym plikiem tekstowym, w którym są przechowywane dane tabelaryczne sformatowane jako wartości rozdzielane przecinkami (CSV). Użyj polecenia head -n5 aby zerknąć na pierwsze pięć wpisów:

head -n5 {train_dataset_fp}
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
4.9,3.1,1.5,0.1,0

Z tego widoku zbioru danych zwróć uwagę na następujące kwestie:

  1. Pierwsza linia to nagłówek zawierający informacje o zbiorze danych:
    • Łącznie jest 120 przykładów. Każdy przykład ma cztery funkcje i jedną z trzech możliwych nazw etykiet.
  2. Kolejne wiersze to rekordy danych, jeden przykład na wiersz, gdzie:
    • Pierwsze cztery pola to cechy : są to cechy przykładu. W tym przypadku pola zawierają liczby zmiennoprzecinkowe reprezentujące wymiary kwiatów.
    • Ostatnia kolumna to etykieta : to wartość, którą chcemy przewidzieć. W przypadku tego zbioru danych jest to liczba całkowita równa 0, 1 lub 2, która odpowiada nazwie kwiatu.

Napiszmy to w kodzie:

 # column order in CSV file
column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']

feature_names = column_names[:-1]
label_name = column_names[-1]

print("Features: {}".format(feature_names))
print("Label: {}".format(label_name))
 
Features: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
Label: species

Każda etykieta jest powiązana z nazwą ciągu (na przykład „setosa”), ale systemy uczące się zwykle opierają się na wartościach liczbowych. Numery etykiet są mapowane do nazwanej reprezentacji, takiej jak:

  • 0 : Iris setosa
  • 1 : Iris versicolor
  • 2 : Iris virginica

Aby uzyskać więcej informacji o funkcjach i etykietach, zobacz sekcję Terminologia ML kursu Machine Learning Crash Course .

 class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']
 

Utwórz plik tf.data.Dataset

Interfejs API zestawu danych TensorFlow obsługuje wiele typowych przypadków ładowania danych do modelu. Jest to wysokopoziomowy interfejs API do odczytywania danych i przekształcania ich w formę używaną do szkolenia.

Ponieważ zbiór danych jest plikiem tekstowym w formacie CSV, użyj funkcji tf.data.experimental.make_csv_dataset aby przeanalizować dane do odpowiedniego formatu. Ponieważ ta funkcja generuje dane do modeli shuffle=True, shuffle_buffer_size=10000 , domyślnym zachowaniem jest tasowanie danych ( shuffle=True, shuffle_buffer_size=10000 ) i powtarzanie zestawu danych w nieskończoność ( num_epochs=None ). Ustawiamy również parametr batch_size :

 batch_size = 32

train_dataset = tf.data.experimental.make_csv_dataset(
    train_dataset_fp,
    batch_size,
    column_names=column_names,
    label_name=label_name,
    num_epochs=1)
 

Funkcja make_csv_dataset zwraca tf.data.Dataset (features, label) , gdzie features to słownik: {'feature_name': value}

Te obiekty Dataset są iterowalne. Spójrzmy na zestaw funkcji:

 features, labels = next(iter(train_dataset))

print(features)
 
OrderedDict([('sepal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([6.5, 5.5, 5.3, 5.8, 4.6, 5.6, 6.8, 6. , 5.4, 4.8, 7.3, 6.2, 5.8,
       6.7, 5.5, 5.4, 7.7, 5.8, 5.2, 5. , 5.7, 5.7, 4.9, 6.1, 5.2, 6.3,
       4.4, 6.7, 6.1, 6.3, 4.4, 6.5], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([3. , 3.5, 3.7, 2.8, 3.6, 2.5, 3.2, 3. , 3.4, 3. , 2.9, 2.2, 2.7,

       3. , 2.4, 3.9, 3. , 4. , 3.4, 3.6, 3.8, 4.4, 3.1, 2.9, 3.5, 2.5,
       3. , 3.1, 2.8, 2.3, 2.9, 3.2], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([5.2, 1.3, 1.5, 5.1, 1. , 3.9, 5.9, 4.8, 1.5, 1.4, 6.3, 4.5, 4.1,
       5.2, 3.7, 1.7, 6.1, 1.2, 1.4, 1.4, 1.7, 1.5, 1.5, 4.7, 1.5, 5. ,
       1.3, 5.6, 4. , 4.4, 1.4, 5.1], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([2. , 0.2, 0.2, 2.4, 0.2, 1.1, 2.3, 1.8, 0.4, 0.3, 1.8, 1.5, 1. ,
       2.3, 1. , 0.4, 2.3, 0.2, 0.2, 0.2, 0.3, 0.4, 0.1, 1.4, 0.2, 1.9,
       0.2, 2.4, 1.3, 1.3, 0.2, 2. ], dtype=float32)>)])

Zauważ, że podobne funkcje są zgrupowane razem lub wsadowo . Pola każdego przykładowego wiersza są dołączane do odpowiedniej tablicy cech. Zmień batch_size aby ustawić liczbę przykładów przechowywanych w tych tablicach funkcji.

Możesz zacząć widzieć kilka klastrów, wykreślając kilka elementów z partii:

 plt.scatter(features['petal_length'],
            features['sepal_length'],
            c=labels,
            cmap='viridis')

plt.xlabel("Petal length")
plt.ylabel("Sepal length")
plt.show()
 

png

Aby uprościć etap budowania modelu, utwórz funkcję przepakowania słownika cech do pojedynczej tablicy o kształcie: (batch_size, num_features) .

Ta funkcja wykorzystuje metodę tf.stack , która pobiera wartości z listy tensorów i tworzy połączony tensor o określonym wymiarze:

 def pack_features_vector(features, labels):
  """Pack the features into a single array."""
  features = tf.stack(list(features.values()), axis=1)
  return features, labels
 

Następnie użyj metody tf.data.Dataset#map , aby spakować features każdej pary (features,label) do zbioru danych szkoleniowych:

 train_dataset = train_dataset.map(pack_features_vector)
 

Elementem (batch_size, num_features) Dataset są teraz tablice z kształtem (batch_size, num_features) . Spójrzmy na kilka pierwszych przykładów:

 features, labels = next(iter(train_dataset))

print(features[:5])
 
tf.Tensor(
[[5.7 4.4 1.5 0.4]
 [5.1 3.8 1.9 0.4]
 [4.9 2.4 3.3 1. ]
 [5.7 2.9 4.2 1.3]
 [5.4 3.4 1.5 0.4]], shape=(5, 4), dtype=float32)

Wybierz typ modelu

Dlaczego modelować?

Model to relacja między elementami a etykietą. W przypadku problemu klasyfikacji tęczówki model definiuje związek między wymiarami działki i płatka a przewidywanym gatunkiem tęczówki. Niektóre proste modele można opisać kilkoma liniami algebry, ale złożone modele uczenia maszynowego mają dużą liczbę parametrów, które są trudne do podsumowania.

Czy możesz określić związek między czterema cechami a gatunkiem Iris bez korzystania z uczenia maszynowego? To znaczy, czy mógłbyś użyć tradycyjnych technik programowania (na przykład wielu instrukcji warunkowych) do stworzenia modelu? Być może - jeśli przeanalizowałeś zbiór danych wystarczająco długo, aby określić relacje między pomiarami płatków i działek działek a konkretnym gatunkiem. A to staje się trudne - może niemożliwe - w przypadku bardziej skomplikowanych zbiorów danych. Dobre podejście do uczenia maszynowego określa model za Ciebie . Jeśli wprowadzisz wystarczającą liczbę reprezentatywnych przykładów do odpowiedniego typu modelu uczenia maszynowego, program wykryje relacje za Ciebie.

Wybierz model

Musimy wybrać rodzaj modelu do trenowania. Istnieje wiele rodzajów modeli, a wybór dobrego wymaga doświadczenia. Ten samouczek wykorzystuje sieć neuronową do rozwiązania problemu klasyfikacji Iris. Sieci neuronowe mogą znajdować złożone relacje między cechami a etykietą. Jest to wysoce ustrukturyzowany wykres, podzielony na jedną lub więcej ukrytych warstw . Każda ukryta warstwa składa się z jednego lub więcej neuronów . Istnieje kilka kategorii sieci neuronowych, a ten program wykorzystuje gęstą lub w pełni połączoną sieć neuronową : neurony w jednej warstwie otrzymują połączenia wejściowe z każdego neuronu w warstwie poprzedniej. Na przykład rysunek 2 ilustruje gęstą sieć neuronową składającą się z warstwy wejściowej, dwóch warstw ukrytych i warstwy wyjściowej:

Schemat architektury sieci: wejścia, 2 ukryte warstwy i wyjścia
Rysunek 2. Sieć neuronowa z funkcjami, ukrytymi warstwami i prognozami.

Kiedy model z rysunku 2 jest trenowany i karmiony nieznakowanym przykładem, daje on trzy prognozy: prawdopodobieństwo, że ten kwiat to dany gatunek Iris. To przewidywanie nazywa się wnioskiem . W tym przykładzie suma prognoz wyjściowych wynosi 1,0. Na rycinie 2 prognoza ta rozkłada się jako: 0.02 dla Iris setosa , 0.95 dla Iris versicolor i 0.03 dla Iris virginica . Oznacza to, że model przewiduje - z 95% prawdopodobieństwem - że przykładowy kwiat bez etykiety to Iris versicolor .

Utwórz model za pomocą Keras

tf.keras API TensorFlow tf.keras jest preferowanym sposobem tworzenia modeli i warstw. Ułatwia to budowanie modeli i eksperymentowanie, podczas gdy Keras radzi sobie ze złożonością łączenia wszystkiego razem.

Model tf.keras.Sequential to liniowy stos warstw. Jego konstruktor pobiera listę instancji warstw, w tym przypadku dwie warstwy tf.keras.layers.Dense z 10 węzłami w każdym i warstwę wyjściową z 3 węzłami reprezentującymi nasze przewidywania dotyczące etykiet. Parametr input_shape pierwszej warstwy odpowiada liczbie cech z zestawu danych i jest wymagany:

 model = tf.keras.Sequential([
  tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)),  # input shape required
  tf.keras.layers.Dense(10, activation=tf.nn.relu),
  tf.keras.layers.Dense(3)
])
 

Funkcja aktywacji określa wyjściowy kształt każdego węzła w warstwie. Te nieliniowości są ważne - bez nich model byłby odpowiednikiem pojedynczej warstwy. Istnieje wiele tf.keras.activations , ale ReLU jest wspólny dla ukrytych warstw.

Idealna liczba ukrytych warstw i neuronów zależy od problemu i zbioru danych. Podobnie jak w przypadku wielu aspektów uczenia maszynowego, wybranie najlepszego kształtu sieci neuronowej wymaga połączenia wiedzy i eksperymentów. Z reguły zwiększenie liczby ukrytych warstw i neuronów zazwyczaj tworzy potężniejszy model, który wymaga więcej danych, aby efektywnie trenować.

Korzystanie z modelu

Rzućmy okiem na to, co ten model robi z zestawem funkcji:

 predictions = model(features)
predictions[:5]
 
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[-2.440686  , -0.505643  , -0.7849147 ],
       [-2.2451866 , -0.38838753, -0.6216379 ],
       [-2.0306284 , -0.682266  , -0.07513025],
       [-2.4925961 , -0.79613   , -0.11894353],
       [-2.2060363 , -0.46993554, -0.578328  ]], dtype=float32)>

Tutaj każdy przykład zwraca logit dla każdej klasy.

Aby przekonwertować te logity na prawdopodobieństwo dla każdej klasy, użyj funkcji softmax :

 tf.nn.softmax(predictions[:5])
 
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[0.07597942, 0.5261075 , 0.39791316],
       [0.08016507, 0.51331353, 0.40652135],
       [0.08390281, 0.32311925, 0.592978  ],
       [0.05816938, 0.31729287, 0.62453777],
       [0.0849808 , 0.48228064, 0.43273854]], dtype=float32)>

Biorąc tf.argmax między klasami, otrzymujemy przewidywany indeks klas. Ale model nie został jeszcze wytrenowany, więc nie są to dobre prognozy:

 print("Prediction: {}".format(tf.argmax(predictions, axis=1)))
print("    Labels: {}".format(labels))
 
Prediction: [1 1 2 2 1 2 1 1 1 2 2 1 2 1 1 2 1 2 2 2 2 1 2 2 2 1 2 2 2 2 2 2]
    Labels: [0 0 1 1 0 2 0 0 0 1 1 0 2 0 0 2 0 1 2 1 2 0 2 1 2 0 0 2 1 2 1 1]

Wytrenuj model

Szkolenie to etap uczenia maszynowego, na którym model jest stopniowo optymalizowany lub model uczy się zestawu danych. Celem jest uzyskanie wystarczającej wiedzy na temat struktury zbioru danych szkoleniowych, aby móc przewidywać niewidoczne dane. Jeśli dowiesz się zbyt wiele o zbiorze danych szkoleniowych, prognozy będą działać tylko dla danych, które widział i nie będzie można ich uogólniać. Ten problem nazywa się overfittingiem - to jak zapamiętywanie odpowiedzi zamiast zrozumienia, jak rozwiązać problem.

Problem klasyfikacji Iris jest przykładem nadzorowanego uczenia maszynowego : model jest szkolony na podstawie przykładów zawierających etykiety. W uczeniu maszynowym bez nadzoru przykłady nie zawierają etykiet. Zamiast tego model zazwyczaj znajduje wzorce wśród funkcji.

Zdefiniuj funkcję strat i gradientu

Zarówno etap szkolenia, jak i oceny wymagają obliczenia utraty modelu. Mierzy to, jak odbiegają przewidywania modelu od pożądanej etykiety, innymi słowy, jak źle działa model. Chcemy zminimalizować lub zoptymalizować tę wartość.

Nasz model obliczy stratę za pomocą funkcji tf.keras.losses.SparseCategoricalCrossentropy która pobiera prognozy prawdopodobieństwa klasy modelu oraz żądaną etykietę i zwraca średnią stratę w przykładach.

 loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
 
 def loss(model, x, y, training):
  # training=training is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  y_ = model(x, training=training)

  return loss_object(y_true=y, y_pred=y_)


l = loss(model, features, labels, training=False)
print("Loss test: {}".format(l))
 
Loss test: 1.452463150024414

Użyj kontekstu tf.GradientTape aby obliczyć gradienty użyte do optymalizacji modelu:

 def grad(model, inputs, targets):
  with tf.GradientTape() as tape:
    loss_value = loss(model, inputs, targets, training=True)
  return loss_value, tape.gradient(loss_value, model.trainable_variables)
 

Skonfigurujmy optymalizator:

 optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
 

Wykorzystamy to do obliczenia pojedynczego kroku optymalizacji:

 loss_value, grads = grad(model, features, labels)

print("Step: {}, Initial Loss: {}".format(optimizer.iterations.numpy(),
                                          loss_value.numpy()))

optimizer.apply_gradients(zip(grads, model.trainable_variables))

print("Step: {},         Loss: {}".format(optimizer.iterations.numpy(),
                                          loss(model, features, labels, training=True).numpy()))
 
Step: 0, Initial Loss: 1.452463150024414
Step: 1,         Loss: 1.3602795600891113

Pętla treningowa

Gdy wszystkie elementy są na miejscu, model jest gotowy do treningu! Pętla szkoleniowa dostarcza przykłady zestawów danych do modelu, aby pomóc mu w tworzeniu lepszych prognoz. Poniższy blok kodu konfiguruje te kroki szkoleniowe:

  1. Powtarzaj każdą epokę . Epoka to jedno przejście przez zbiór danych.
  2. W ramach epoki iteruj po każdym przykładzie w zestawie Dataset szkoleniowych, Dataset jego cechy ( x ) i etykietę ( y ).
  3. Korzystając z funkcji przykładu, wykonaj prognozę i porównaj ją z etykietą. Zmierz niedokładność prognozy i użyj jej do obliczenia strat i gradientów modelu.
  4. Użyj optimizer aby zaktualizować zmienne modelu.
  5. Śledź niektóre statystyki do wizualizacji.
  6. Powtórz dla każdej epoki.

Zmienna num_epochs określa, ile razy należy wykonać pętlę w zbiorze danych. Wbrew intuicji, dłuższe trenowanie modelu nie gwarantuje lepszego modelu. num_epochs to hiperparametr , który możesz dostroić. Wybór odpowiedniej liczby zwykle wymaga zarówno doświadczenia, jak i eksperymentów:

 ## Note: Rerunning this cell uses the same model variables

# Keep results for plotting
train_loss_results = []
train_accuracy_results = []

num_epochs = 201

for epoch in range(num_epochs):
  epoch_loss_avg = tf.keras.metrics.Mean()
  epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()

  # Training loop - using batches of 32
  for x, y in train_dataset:
    # Optimize the model
    loss_value, grads = grad(model, x, y)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))

    # Track progress
    epoch_loss_avg.update_state(loss_value)  # Add current batch loss
    # Compare predicted label to actual label
    # training=True is needed only if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    epoch_accuracy.update_state(y, model(x, training=True))

  # End epoch
  train_loss_results.append(epoch_loss_avg.result())
  train_accuracy_results.append(epoch_accuracy.result())

  if epoch % 50 == 0:
    print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
                                                                epoch_loss_avg.result(),
                                                                epoch_accuracy.result()))
 
Epoch 000: Loss: 1.185, Accuracy: 35.000%
Epoch 050: Loss: 0.374, Accuracy: 92.500%
Epoch 100: Loss: 0.234, Accuracy: 97.500%
Epoch 150: Loss: 0.161, Accuracy: 98.333%
Epoch 200: Loss: 0.120, Accuracy: 98.333%

Wizualizuj funkcję strat w czasie

Chociaż pomocne jest wydrukowanie postępów treningu modelu, często bardziej pomocne jest zobaczenie tego postępu. TensorBoard to przyjemne narzędzie do wizualizacji, które jest dostarczane z TensorFlow, ale możemy tworzyć podstawowe wykresy za pomocą modułu matplotlib .

Interpretacja tych wykresów wymaga pewnego doświadczenia, ale naprawdę chcesz zobaczyć, jak strata spada, a dokładność rośnie:

 fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')

axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)

axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()
 

png

Oceń skuteczność modelu

Teraz, gdy model jest wytrenowany, możemy uzyskać statystyki dotyczące jego wydajności.

Ocenianie oznacza określenie, jak skutecznie model tworzy prognozy. Aby określić skuteczność modelu w klasyfikacji tęczówki, prześlij do modelu pewne pomiary działek i płatków i poproś model o przewidzenie, jakie gatunki tęczówki reprezentują. Następnie porównaj przewidywania modelu z rzeczywistą etykietą. Na przykład model, który wybrał właściwy gatunek z połowy przykładów wejściowych, ma dokładność 0.5 . Rysunek 4 przedstawia nieco bardziej efektywny model, w którym 4 z 5 prognoz są poprawne z 80% dokładnością:

Przykładowe funkcje Etykieta Przewidywanie modelu
5.9 3.0 4.3 1.5 1 1
6.9 3.1 5.4 2.1 2 2
5.1 3.3 1.7 0.5 0 0
6.0 3.4 4.5 1.6 1 2
5.5 2.5 4.0 1.3 1 1
Rysunek 4. Klasyfikator Iris, który jest dokładny w 80%.

Skonfiguruj testowy zestaw danych

Ocena modelu jest podobna do uczenia modelu. Największą różnicą jest to, że przykłady pochodzą z oddzielnego zestawu testowego, a nie zestawu uczącego. Aby rzetelnie ocenić skuteczność modelu, przykłady użyte do oceny modelu muszą różnić się od przykładów użytych do trenowania modelu.

Konfiguracja testowego Dataset jest podobna do konfiguracji szkolenia Dataset . Pobierz plik tekstowy CSV i przeanalizuj te wartości, a następnie potasuj go trochę:

 test_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv"

test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),
                                  origin=test_url)
 
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv
8192/573 [============================================================================================================================================================================================================================================================================================================================================================================================================================================] - 0s 0us/step

 test_dataset = tf.data.experimental.make_csv_dataset(
    test_fp,
    batch_size,
    column_names=column_names,
    label_name='species',
    num_epochs=1,
    shuffle=False)

test_dataset = test_dataset.map(pack_features_vector)
 

Oceń model w testowym zestawie danych

W przeciwieństwie do etapu uczenia model ocenia tylko jedną epokę danych testowych. W poniższej komórce kodu iterujemy po każdym przykładzie w zestawie testowym i porównujemy przewidywania modelu z rzeczywistą etykietą. Służy do pomiaru dokładności modelu w całym zestawie testowym:

 test_accuracy = tf.keras.metrics.Accuracy()

for (x, y) in test_dataset:
  # training=False is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  logits = model(x, training=False)
  prediction = tf.argmax(logits, axis=1, output_type=tf.int32)
  test_accuracy(prediction, y)

print("Test set accuracy: {:.3%}".format(test_accuracy.result()))
 
Test set accuracy: 96.667%

Widzimy na przykład, że na ostatniej partii model jest zwykle poprawny:

 tf.stack([y,prediction],axis=1)
 
<tf.Tensor: shape=(30, 2), dtype=int32, numpy=
array([[1, 1],
       [2, 2],
       [0, 0],
       [1, 1],
       [1, 1],
       [1, 1],
       [0, 0],
       [2, 2],
       [1, 1],
       [2, 2],
       [2, 2],
       [0, 0],
       [2, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [0, 0],
       [0, 0],
       [2, 2],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 1]], dtype=int32)>

Użyj wytrenowanego modelu do tworzenia prognoz

Wyszkoliliśmy model i „udowodniliśmy”, że jest dobry - ale nie doskonały - w klasyfikowaniu gatunków Iris. Teraz użyjmy wytrenowanego modelu, aby dokonać pewnych prognoz na nieoznaczonych przykładach ; to znaczy na przykładach, które zawierają funkcje, ale nie mają etykiety.

W rzeczywistości nieoznakowane przykłady mogą pochodzić z wielu różnych źródeł, w tym aplikacji, plików CSV i źródeł danych. Na razie mamy zamiar ręcznie podać trzy nieoznakowane przykłady, aby przewidzieć ich etykiety. Przypomnijmy, numery etykiet są mapowane do nazwanej reprezentacji jako:

  • 0 : Iris setosa
  • 1 : Iris versicolor
  • 2 : Iris virginica
 predict_dataset = tf.convert_to_tensor([
    [5.1, 3.3, 1.7, 0.5,],
    [5.9, 3.0, 4.2, 1.5,],
    [6.9, 3.1, 5.4, 2.1]
])

# training=False is needed only if there are layers with different
# behavior during training versus inference (e.g. Dropout).
predictions = model(predict_dataset, training=False)

for i, logits in enumerate(predictions):
  class_idx = tf.argmax(logits).numpy()
  p = tf.nn.softmax(logits)[class_idx]
  name = class_names[class_idx]
  print("Example {} prediction: {} ({:4.1f}%)".format(i, name, 100*p))
 
Example 0 prediction: Iris setosa (97.3%)
Example 1 prediction: Iris versicolor (90.5%)
Example 2 prediction: Iris virginica (83.5%)

Utwórz optymalizator

Optymalizator stosuje obliczone gradienty do zmiennych modelu, aby zminimalizować funkcję loss . Możesz myśleć o funkcji straty jako zakrzywionej powierzchni (patrz Rysunek 3) i chcemy znaleźć jej najniższy punkt, spacerując po okolicy. Gradienty wskazują kierunek najbardziej stromego wzniesienia - więc pojedziemy w przeciwnym kierunku i zejdziemy w dół. Poprzez iteracyjne obliczanie strat i gradientu dla każdej partii dostosujemy model podczas uczenia. Stopniowo model znajdzie najlepszą kombinację wag i odchylenia, aby zminimalizować straty. Im mniejsza strata, tym lepsze przewidywania modelu.

Algorytmy optymalizacji wizualizowane w czasie w przestrzeni 3D.
Rysunek 3. Algorytmy optymalizacji wizualizowane w czasie w przestrzeni 3D.
(Źródło: Stanford class CS231n , licencja MIT, zdjęcie: Alec Radford )

TensorFlow ma wiele algorytmów optymalizacji dostępnych do uczenia. Ten model używa tf.keras.optimizers.SGD który implementuje algorytm stochastycznego zstępowania gradientu (SGD). learning_rate ustawia rozmiar kroku do wykonania dla każdej iteracji w dół. Jest to hiperparametr , który zwykle dostosowujesz, aby osiągnąć lepsze wyniki.