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

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

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

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

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

В этом руководстве используются следующие высокоуровневые концепции 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.8.0-rc1
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 . Это возвращает путь к загруженному файлу:

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

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

  • 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([5. , 7.4, 6. , 7.2, 5.9, 5.8, 5. , 5. , 7.7, 5.7, 6.3, 5.8, 5. ,
       4.8, 6.6, 6.3, 5.4, 6.9, 4.8, 6.6, 5.8, 7.7, 6.7, 7.6, 5.5, 6.4,
       5.6, 6.4, 4.4, 4.5, 6.5, 6.3], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([3.5, 2.8, 2.7, 3.2, 3. , 2.6, 2. , 3.4, 3. , 2.8, 2.3, 2.7, 3.6,
       3.1, 2.9, 3.3, 3. , 3.1, 3. , 3. , 4. , 2.6, 3. , 3. , 2.4, 2.7,
       2.7, 2.8, 3. , 2.3, 2.8, 2.5], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([1.6, 6.1, 5.1, 6. , 5.1, 4. , 3.5, 1.6, 6.1, 4.5, 4.4, 5.1, 1.4,
       1.6, 4.6, 4.7, 4.5, 5.1, 1.4, 4.4, 1.2, 6.9, 5. , 6.6, 3.7, 5.3,
       4.2, 5.6, 1.3, 1.3, 4.6, 5. ], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([0.6, 1.9, 1.6, 1.8, 1.8, 1.2, 1. , 0.4, 2.3, 1.3, 1.3, 1.9, 0.2,
       0.2, 1.3, 1.6, 1.5, 2.3, 0.3, 1.4, 0.2, 2.3, 1.7, 2.1, 1. , 1.9,
       1.3, 2.1, 0.2, 0.3, 1.5, 1.9], 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)

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

features, labels = next(iter(train_dataset))

print(features[:5])
tf.Tensor(
[[4.9 3.  1.4 0.2]
 [6.1 3.  4.9 1.8]
 [6.1 2.6 5.6 1.4]
 [6.9 3.2 5.7 2.3]
 [6.7 3.1 4.4 1.4]], 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 % — что немаркированный пример цветка — это Iris versicolor .

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

tf.keras API — предпочтительный способ создания моделей и слоев. Это позволяет легко создавать модели и экспериментировать, в то время как 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([[-4.0874639e+00,  1.5199981e-03, -9.9991310e-01],
       [-5.3246369e+00, -1.8366380e-01, -1.3161827e+00],
       [-5.1154275e+00, -2.8129923e-01, -1.3305402e+00],
       [-6.0694785e+00, -2.1251860e-01, -1.5091233e+00],
       [-5.6730523e+00, -1.4321266e-01, -1.4437559e+00]], dtype=float32)>

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

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

tf.nn.softmax(predictions[:5])
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[0.01210616, 0.7224865 , 0.26540732],
       [0.00440638, 0.75297093, 0.24262273],
       [0.00585618, 0.7362918 , 0.25785193],
       [0.00224076, 0.7835035 , 0.21425581],
       [0.00310779, 0.7834839 , 0.21340834]], dtype=float32)>

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

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

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

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

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

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

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

Наша модель рассчитает свои потери с помощью функции 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.6059828996658325

Используйте контекст 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 , лицензия Массачусетского технологического института, изображение предоставлено Алеком Рэдфордом )

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.6059828996658325
Step: 1,         Loss: 1.3759253025054932

Тренировочный цикл

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

  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.766, Accuracy: 43.333%
Epoch 050: Loss: 0.579, Accuracy: 71.667%
Epoch 100: Loss: 0.398, Accuracy: 82.500%
Epoch 150: Loss: 0.307, Accuracy: 92.500%
Epoch 200: Loss: 0.224, Accuracy: 95.833%

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

Хотя полезно распечатать ход обучения модели, часто полезнее видеть этот прогресс. TensorBoard — хороший инструмент визуализации, упакованный с TensorFlow, но мы можем создавать базовые диаграммы с помощью модуля 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)
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 (97.6%)
Example 1 prediction: Iris versicolor (82.0%)
Example 2 prediction: Iris virginica (56.4%)