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

«Элементы статистического обучения» - фантастическая книга. Если вы сумеете пройти через это, вы немного узнаете, но это не имеет большого значения, если вы не можете применить что-либо на практике. TensorFlow - это платформа для создания, обучения и развертывания моделей машинного обучения. Keras - это оболочка, построенная поверх TensorFlow, что делает ее более доступной, простой и понятной для работы.

Приведенный ниже блок кода является эквивалентом «Hello World» в TensorFlow. Несмотря на то, что это первый шаг к использованию TensorFlow, здесь есть что распаковать. Итак, приступим к делу.

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

Данные

import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()

Набор данных MNIST состоит из рукописных цифр; 60 000 обучающих изображений и 10 000 тестовых изображений. обучающий набор - это набор, в котором нам дается результат наблюдаемой нами функции. характеристика - это характеристика объекта, которую можно измерить. Более привычным термином для характеристики может быть переменная или атрибут.

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

Набор для тестирования - это то, что мы (как вы уже догадались) будем использовать для тестирования модели, созданной с помощью набора для обучения.

В строках выше мы сообщаем TensorFlow, что нам нужны файлы из набора данных MNIST, а затем загружаем данные в переменные для обучения и тестирования.

print(x_train.shape)
(60000, 28, 28)

Мы уже знали, что в нашем обучающем наборе 60 000 изображений. 28,28 относятся к размерам каждого изображения, 28 пикселей на 28 пикселей. Итак, давайте еще раз исследуем данные.

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure()
plt.imshow(x_train[5])
plt.colorbar()
plt.grid(False)
plt.show()

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

x_train, x_test = x_train / 255.0, x_test / 255.0

Это стандартизирует все ценности в наших наборах для обучения и тестирования.

Хорошо, время для крутых вещей:

Модель

model = tf.keras.models.Sequential([
 tf.keras.layers.Flatten(input_shape=(28, 28)),
 tf.keras.layers.Dense(512, activation=tf.nn.relu),
 tf.keras.layers.Dropout(0.2),
 tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer=’adam’,
 loss=’sparse_categorical_crossentropy’,
 metrics=[‘accuracy’])

Наша первая строка назначает модель, которую мы используем:

tf.keras.models.Sequential

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

tf.keras.layers.Flatten(input_shape=(28, 28)),

Теперь мы берем загружаемое изображение и «сглаживаем» его в 2D-массив. Форма ввода - это размер изображения, загружаемого в слой. Думайте об этом как о переформатировании изображения для модели.

tf.keras.layers.Dense(512, activation=tf.nn.relu)

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

tf.keras.layers.Dropout(0.2),

Слой исключения - это метод регуляризации, при котором случайно выбранные нейроны игнорируются при обучении. Здесь у нас есть набор 20%, который будет отбрасывать один из каждых пяти входов для следующего цикла обучения.

tf.keras.layers.Dense(10, activation=tf.nn.softmax)

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

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

Теперь составим модель.
Прежде всего, кто, черт возьми, такой Адам? Не человек. По-видимому, это было получено из «оценки адаптивного момента». Парень по имени Адам должен был придумать это, сделал бы абзац получше.
В любом случае оптимизатор делает именно то, что кажется. Алгоритм оптимизации Адама используется для обновления весов сети на основе данных обучения.
Функция потерь используется для измерения вариации между прогнозируемым значением и тем, что оно есть на самом деле. Цель состоит в том, чтобы минимизировать функцию потерь.

Полученные результаты

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

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

Обучение этой модели в любом случае не очень хорошее, но это было только из учебника TensorFlow.

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
Epoch 1/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 126us/step - loss: 9.9728 - acc: 0.3813

Epoch 2/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.1151 - acc: 0.3724

Epoch 3/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.0101 - acc: 0.3789

Epoch 4/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 126us/step - loss: 10.0149 - acc: 0.3786

Epoch 5/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.0893 - acc: 0.3740

10000/10000 [==============================]10000/10000 [==============================] - 0s 32us/step
[10.388112817382812, 0.3555]

И вот оно! Первое знакомство с TensorFlow. Хотя это было всего несколько строк кода, еще многое предстоит распаковать, но это просто превратилось бы в книгу. Если вы прочитали все это, я надеюсь, вы кое-что узнали!