Индивидуальное обучение: пошаговое руководство

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

В этом руководстве используется машинное обучение для классификации цветов ириса по видам. Он использует TensorFlow для:

  1. Постройте модель,
  2. Обучите эту модель на примерах данных и
  3. Используйте модель, чтобы делать прогнозы относительно неизвестных данных.

Программирование TensorFlow

В этом руководстве используются эти высокоуровневые концепции TensorFlow:

  • Используйте среду разработки активного выполнения TensorFlow по умолчанию,
  • Импортируйте данные с помощью Datasets API ,
  • Создавайте модели и слои с помощью API Keras от TensorFlow .

Это руководство построено так же, как и многие программы TensorFlow:

  1. Импортируйте и проанализируйте набор данных.
  2. Выберите тип модели.
  3. Обучите модель.
  4. Оцените эффективность модели.
  5. Используйте обученную модель, чтобы делать прогнозы.

Программа установки

Настроить импорт

Импортируйте TensorFlow и другие необходимые модули Python. По умолчанию TensorFlow использует активное выполнение для немедленной оценки операций, возвращая конкретные значения вместо создания вычислительного графа, который выполняется позже. Если вы привыкли к REPL или интерактивной консоли python , это покажется вам знакомым.

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.5.0
Eager execution: True

Проблема классификации радужной оболочки глаза

Представьте, что вы ботаник, ищущий автоматизированный способ классифицировать каждый найденный цветок ириса. Машинное обучение предоставляет множество алгоритмов для статистической классификации цветов. Например, сложная программа машинного обучения может классифицировать цветы на основе фотографий. Наши амбиции более скромные - мы собираемся классифицировать цветы ириса на основе длины и ширины их чашелистиков и лепестков .

Род Iris включает около 300 видов, но наша программа классифицирует только следующие три:

  • Ирис сетоса
  • Ирис вирджиника
  • Ирис разноцветный
Сравнение геометрии лепестков трех видов ирисов: Iris setosa, Iris virginica и Iris versicolor
Рисунок 1. Iris setosa (от Radomil , CC BY-SA 3.0), Iris versicolor (от Dlanglois , CC BY-SA 3.0) и Iris virginica (от Frank Mayfield , CC BY-SA 2.0).

К счастью, кто-то уже создал набор данных из 120 цветов ириса с размерами чашелистиков и лепестков. Это классический набор данных, который популярен для начинающих задач классификации машинного обучения.

Импортируйте и проанализируйте набор обучающих данных

Загрузите файл набора данных и преобразуйте его в структуру, которая может использоваться этой программой Python.

Скачать набор данных

Загрузите файл набора обучающих данных с tf.keras.utils.get_file функции tf.keras.utils.get_file . Это возвращает путь к загруженному файлу:

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

Проверить данные

Этот набор данных iris_training.csv представляет собой простой текстовый файл, в котором хранятся табличные данные, отформатированные как значения, разделенные запятыми (CSV). Используйте команду head -n5 чтобы взглянуть на первые пять записей:

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

С этого представления набора данных обратите внимание на следующее:

  1. Первая строка - это заголовок, содержащий информацию о наборе данных:
    • Всего 120 примеров. В каждом примере есть четыре функции и одно из трех возможных имен ярлыков.
  2. Последующие строки представляют собой записи данных, по одному примеру на строку, где:
    • Первые четыре поля являются характеристиками : это характеристики примера. Здесь поля содержат числа с плавающей запятой, представляющие размеры цветов.
    • Последний столбец - это метка : это значение, которое мы хотим предсказать. Для этого набора данных это целое число 0, 1 или 2, которое соответствует названию цветка.

Запишем это в коде:

# 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

Каждая метка связана с именем строки (например, «сетоса»), но машинное обучение обычно основывается на числовых значениях. Номера меток сопоставляются с именованным представлением, например:

  • 0 : Ирис сетоса
  • 1 : Ирис разноцветный
  • 2 : Ирис вирджинский

Дополнительные сведения о функциях и метках см. В разделе Терминология машинного обучения ускоренного курса машинного обучения .

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

Создайтеtf.data.Dataset

API набора данных TensorFlow обрабатывает множество распространенных случаев загрузки данных в модель. Это высокоуровневый API для чтения данных и их преобразования в форму, используемую для обучения.

Поскольку набор данных представляет собой текстовый файл в формате CSV, используйте функцию tf.data.experimental.make_csv_dataset чтобы преобразовать данные в подходящий формат. Поскольку эта функция генерирует данные для обучающих моделей, поведение по умолчанию - перетасовать данные ( shuffle=True, shuffle_buffer_size=10000 ) и бесконечно повторять набор данных ( num_epochs=None ). Также устанавливаем параметр 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)

Функция make_csv_dataset возвращаетtf.data.Dataset (features, label) , где features - словарь: {'feature_name': value}

Эти объекты Dataset можно повторять. Давайте посмотрим на набор функций:

features, labels = next(iter(train_dataset))

print(features)
OrderedDict([('sepal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([6.3, 5.9, 7.2, 4.9, 6.4, 4.6, 4.8, 7.3, 6.4, 5.7, 5.4, 7.7, 6.3,

       5. , 6.2, 6. , 6.3, 7.2, 6.5, 5.1, 5.5, 7.7, 7.4, 6.6, 5.6, 6.7,
       7.7, 6.4, 5.5, 6. , 5.7, 6.8], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([2.5, 3. , 3. , 3.1, 3.1, 3.1, 3.1, 2.9, 3.2, 3.8, 3. , 3. , 2.3,
       2. , 2.2, 3. , 3.3, 3.2, 3. , 3.7, 3.5, 2.8, 2.8, 2.9, 2.7, 3.1,
       3.8, 2.7, 2.4, 2.2, 4.4, 3.2], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([5. , 5.1, 5.8, 1.5, 5.5, 1.5, 1.6, 6.3, 5.3, 1.7, 4.5, 6.1, 4.4,
       3.5, 4.5, 4.8, 4.7, 6. , 5.2, 1.5, 1.3, 6.7, 6.1, 4.6, 4.2, 5.6,
       6.7, 5.3, 3.8, 5. , 1.5, 5.9], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([1.9, 1.8, 1.6, 0.1, 1.8, 0.2, 0.2, 1.8, 2.3, 0.3, 1.5, 2.3, 1.3,
       1. , 1.5, 1.8, 1.6, 1.8, 2. , 0.4, 0.2, 2. , 1.9, 1.3, 1.3, 2.4,
       2.2, 1.9, 1.1, 1.5, 0.4, 2.3], dtype=float32)>)])

Обратите внимание, что похожие функции сгруппированы или объединены в пакеты . Поля каждой строки примера добавляются к соответствующему массиву функций. Измените batch_size чтобы установить количество примеров, хранящихся в этих массивах функций.

Вы можете начать видеть некоторые кластеры, построив несколько функций из пакета:

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

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

PNG

Чтобы упростить этап построения модели, создайте функцию для переупаковки словаря функций в единый массив с формой: (batch_size, num_features) .

Эта функция использует метод tf.stack который принимает значения из списка тензоров и создает комбинированный тензор в указанном измерении:

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

Затем используйте tf.data.Dataset#map чтобы упаковать features каждой пары (features,label) в набор обучающих данных:

train_dataset = train_dataset.map(pack_features_vector)

(batch_size, num_features) Dataset теперь являются массивы с формой (batch_size, num_features) . Давайте посмотрим на несколько первых примеров:

features, labels = next(iter(train_dataset))

print(features[:5])
tf.Tensor(
[[6.4 3.1 5.5 1.8]
 [4.9 2.5 4.5 1.7]
 [5.4 3.7 1.5 0.2]
 [6.9 3.1 4.9 1.5]
 [6.1 2.8 4.  1.3]], shape=(5, 4), dtype=float32)

Выберите тип модели

Почему именно модель?

Модель - это связь между элементами и меткой. Для задачи классификации радужной оболочки модель определяет взаимосвязь между размерами чашелистиков и лепестков и прогнозируемыми видами ирисов. Некоторые простые модели можно описать с помощью нескольких строк алгебры, но сложные модели машинного обучения имеют большое количество параметров, которые сложно суммировать.

Не могли бы вы определить взаимосвязь между четырьмя особенностями и видами ирисов без использования машинного обучения? То есть, можете ли вы использовать традиционные методы программирования (например, множество условных операторов) для создания модели? Возможно, если вы проанализировали набор данных достаточно долго, чтобы определить взаимосвязь между размерами лепестков и чашелистиков для конкретного вида. И это становится трудным - возможно, невозможным - для более сложных наборов данных. Хороший подход к машинному обучению определяет модель за вас . Если вы загрузите достаточно репрезентативных примеров в правильный тип модели машинного обучения, программа сама определит взаимосвязи.

Выберите модель

Нам нужно выбрать модель для обучения. Есть много типов моделей, и чтобы выбрать хорошую, нужен опыт. В этом руководстве для решения проблемы классификации радужной оболочки глаза используется нейронная сеть. Нейронные сети могут находить сложные отношения между функциями и меткой. Это сильно структурированный граф, организованный в один или несколько скрытых слоев . Каждый скрытый слой состоит из одного или нескольких нейронов . Существует несколько категорий нейронных сетей, и эта программа использует плотную или полностью связанную нейронную сеть : нейроны в одном слое получают входные соединения от каждого нейрона в предыдущем слое. Например, на рисунке 2 показана плотная нейронная сеть, состоящая из входного слоя, двух скрытых слоев и выходного слоя:

Схема сетевой архитектуры: входы, 2 скрытых слоя и выходы.
Рис. 2. Нейронная сеть с функциями, скрытыми слоями и прогнозами.

Когда модель с рисунка 2 обучается и подается на немаркированный пример, она дает три прогноза: вероятность того, что этот цветок принадлежит данному виду ириса. Это предсказание называется выводом . В этом примере сумма прогнозов на выходе равна 1,0. На рисунке 2 этот прогноз распадается как: 0.02 для Iris setosa , 0.95 для Iris versicolor и 0.03 для Iris virginica . Это означает, что модель предсказывает - с вероятностью 95% - что пример цветка без надписи - это ирис разноцветный .

Создайте модель с помощью Keras

API-интерфейс tf.keras является предпочтительным способом создания моделей и слоев. Это позволяет легко создавать модели и экспериментировать, в то время как Keras справляется со сложностью соединения всего вместе.

Модель tf.keras.Sequential представляет собой линейный набор слоев. Его конструктор принимает список экземпляров слоя, в данном случае два слоя tf.keras.layers.Dense с 10 узлами в каждом и выходной слой с 3 узлами, представляющими наши прогнозы меток. Параметр input_shape первого слоя соответствует количеству объектов из набора данных и является обязательным:

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

Функция активации определяет выходную форму каждого узла в слое. Эти нелинейности важны - без них модель была бы эквивалентна единственному слою. Существует множество tf.keras.activations , но ReLU является общим для скрытых слоев.

Идеальное количество скрытых слоев и нейронов зависит от проблемы и набора данных. Как и многие другие аспекты машинного обучения, выбор оптимальной формы нейронной сети требует сочетания знаний и экспериментов. Как показывает практика, увеличение количества скрытых слоев и нейронов обычно создает более мощную модель, которая требует большего количества данных для эффективного обучения.

Использование модели

Давайте быстро посмотрим, что эта модель делает с рядом функций:

predictions = model(features)
predictions[:5]
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[2.074555  , 0.5493162 , 2.742274  ],
       [1.8101712 , 0.35136193, 2.251296  ],
       [2.0027401 , 1.3819529 , 2.4660559 ],
       [1.7304668 , 0.5538071 , 2.6995382 ],
       [1.5272804 , 0.5366443 , 2.418514  ]], dtype=float32)>

Здесь каждый пример возвращает логит для каждого класса.

Чтобы преобразовать эти логиты в вероятность для каждого класса, используйте функцию softmax :

tf.nn.softmax(predictions[:5])
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[0.31572092, 0.06869112, 0.61558795],
       [0.35881293, 0.08342866, 0.5577584 ],
       [0.31981003, 0.17190465, 0.5082853 ],
       [0.25356236, 0.07817502, 0.66826266],
       [0.2625033 , 0.09747808, 0.6400186 ]], dtype=float32)>

Взятие tf.argmax по классам дает нам прогнозируемый индекс класса. Но модель еще не обучена, так что это плохие прогнозы:

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

Обучите модель

Обучение - это этап машинного обучения, когда модель постепенно оптимизируется или модель изучает набор данных. Цель состоит в том, чтобы узнать достаточно о структуре набора обучающих данных, чтобы делать прогнозы относительно невидимых данных. Если вы слишком много узнаете об обучающем наборе данных, тогда прогнозы будут работать только для тех данных, которые он видел, и не будут обобщены. Эта проблема называется переобучением - это похоже на запоминание ответов вместо понимания того, как решить проблему.

Проблема классификации Iris - это пример машинного обучения с учителем: модель обучается на примерах, содержащих метки. В неконтролируемом машинном обучении примеры не содержат ярлыков. Вместо этого модель обычно находит закономерности среди функций.

Определите функцию потерь и градиента

На этапах обучения и оценки необходимо рассчитать потери модели. Это измеряет, насколько прогнозы модели отличаются от желаемой метки, другими словами, насколько плохо модель работает. Мы хотим минимизировать или оптимизировать это значение.

Наша модель рассчитает свои потери с tf.keras.losses.SparseCategoricalCrossentropy функции tf.keras.losses.SparseCategoricalCrossentropy которая принимает прогнозы вероятностей классов модели и желаемую метку и возвращает средние потери по примерам.

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.1150981187820435

Используйте контекстtf.GradientTape для вычисления градиентов, используемых для оптимизации вашей модели:

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)

Создать оптимизатор

Оптимизатор применяет вычисленные градиенты к переменным модели, чтобы минимизировать функцию loss . Вы можете представить себе функцию потерь как изогнутую поверхность (см. Рисунок 3), и мы хотим найти ее самую низкую точку, пройдя вокруг. Градиенты указывают на направление наискорейшего подъема, поэтому мы пойдем в обратном направлении и спустимся с холма. Итеративно вычисляя потери и градиент для каждой партии, мы скорректируем модель во время обучения. Постепенно модель найдет наилучшее сочетание весов и смещения, чтобы минимизировать потери. И чем меньше убыток, тем лучше прогнозы модели.

Алгоритмы оптимизации визуализируются с течением времени в трехмерном пространстве.
Рисунок 3. Алгоритмы оптимизации, визуализированные во времени в трехмерном пространстве.
(Источник: Стэнфордский класс CS231n , лицензия MIT, Изображение предоставлено Алеком Рэдфордом )

В TensorFlow есть множество алгоритмов оптимизации, доступных для обучения. В этой модели используется tf.keras.optimizers.SGD , реализующий алгоритмстохастического градиентного спуска (SGD). learning_rate устанавливает размер шага для каждой итерации вниз по склону. Это гиперпараметр, который вы обычно настраиваете для достижения лучших результатов.

Настроим оптимизатор:

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

Мы будем использовать это для расчета одного шага оптимизации:

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.1150981187820435
Step: 1,         Loss: 1.0687495470046997

Цикл обучения

Когда все детали на месте, модель готова к обучению! Цикл обучения передает в модель примеры наборов данных, чтобы помочь ей делать более точные прогнозы. Следующий блок кода устанавливает эти шаги обучения:

  1. Повторяйте каждую эпоху . Эпоха - это один проход по набору данных.
  2. В течение эпохи перебирайте каждый пример в обучающем Dataset захватывая его функции ( x ) и метку ( y ).
  3. Используя особенности примера, сделайте прогноз и сравните его с этикеткой. Измерьте неточность прогноза и используйте ее для расчета потерь и градиентов модели.
  4. Используйте optimizer для обновления переменных модели.
  5. Следите за статистикой для визуализации.
  6. Повторите для каждой эпохи.

Переменная num_epochs - это количество циклов для цикла по коллекции набора данных. Как ни странно, более длительное обучение модели не гарантирует получение лучшей модели. num_epochs - гиперпараметр, который вы можете настроить. Выбор правильного числа обычно требует как опыта, так и экспериментов:

## 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.112, Accuracy: 62.500%
Epoch 050: Loss: 0.299, Accuracy: 97.500%
Epoch 100: Loss: 0.189, Accuracy: 96.667%
Epoch 150: Loss: 0.152, Accuracy: 97.500%
Epoch 200: Loss: 0.109, Accuracy: 98.333%

Визуализируйте функцию потерь с течением времени

Хотя это полезно , чтобы распечатать прогресс обучения в модели, часто более полезно , чтобы увидеть этот прогресс. TensorBoard - хороший инструмент визуализации, который входит в состав TensorFlow, но мы можем создавать базовые диаграммы с matplotlib модуля matplotlib .

Интерпретация этих графиков требует некоторого опыта, но вы действительно хотите, чтобы потери уменьшались, а точность повышалась:

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

Оцените эффективность модели

Теперь, когда модель обучена, мы можем получить некоторую статистику ее производительности.

Оценка означает определение того, насколько эффективно модель делает прогнозы. Чтобы определить эффективность модели при классификации радужки, передайте модели некоторые измерения чашелистиков и лепестков и попросите модель предсказать, какие виды ирисов они представляют. Затем сравните прогнозы модели с фактическими данными. Например, модель, которая выбрала правильный вид на половине входных примеров, имеет точность 0.5 . На рисунке 4 показана немного более эффективная модель, в которой 4 из 5 прогнозов верны с точностью 80%:

Примеры функций Этикетка Прогноз модели
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
Рис. 4. Классификатор Iris с точностью 80%.

Настройте тестовый набор данных

Оценка модели аналогична обучению модели. Самая большая разница в том, что примеры взяты из отдельного набора тестов, а не из набора для обучения. Чтобы достоверно оценить эффективность модели, примеры, используемые для оценки модели, должны отличаться от примеров, используемых для обучения модели.

Настройка тестового Dataset аналогична настройке для обучающего Dataset . Загрузите текстовый файл CSV и проанализируйте эти значения, а затем немного перемешайте:

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)

Оцените модель на тестовом наборе данных

В отличие от этапа обучения, модель оценивает только одну эпоху тестовых данных. В следующей ячейке кода мы перебираем каждый пример в наборе тестов и сравниваем прогноз модели с фактической меткой. Это используется для измерения точности модели по всему набору тестов:

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%

Например, на последней партии мы видим, что модель обычно правильная:

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

Используйте обученную модель, чтобы делать прогнозы

Мы обучили модель и «доказали», что она хороша - но не идеальна - для классификации видов ирисов. Теперь давайте воспользуемся обученной моделью, чтобы сделать некоторые прогнозы на немаркированных примерах ; то есть на примерах, которые содержат функции, но не содержат метку.

В реальной жизни примеры без меток могут быть получены из множества различных источников, включая приложения, файлы CSV и каналы данных. А пока мы собираемся вручную предоставить три немаркированных примера, чтобы предсказать их метки. Напомним, номера меток отображаются в именованное представление как:

  • 0 : Ирис сетоса
  • 1 : Ирис разноцветный
  • 2 : Ирис вирджинский
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 (98.1%)
Example 1 prediction: Iris versicolor (93.0%)
Example 2 prediction: Iris virginica (81.3%)