Введение
Нейронные сети используются как метод глубокого обучения, один из многих подотраслей искусственного интеллекта. Они были первые предлагаемые вокруг 70 лет назад как попытка моделирования как человеческий мозг работает, хотя и в гораздо более упрощенной форме. Индивидуальные «нейронов» связаны в слоях, с весами, поручено определить как нейрон отвечает, когда сигналы передаются через сеть. Ранее нейронные сети были ограничены в количество нейронов, которые они смогли моделировать и поэтому сложности обучения, которую они могли бы достичь. Но в последние годы, из-за достижения в разработке оборудования, мы смогли построить очень глубокие сетей и обучать их на огромных наборов данных для достижения прорыва в машина разведки.
Эти успехи позволили машины матч и превышают возможности людей на выполнение определенных задач. Одной из таких задач является распознавание объекта. Хотя исторически машины были не в состоянии соответствовать человеческого зрения, последние достижения в глубоких обучения сделали возможным построить нейронных сетей, которые может распознать объекты, лица, текст и даже эмоции.
В этом учебнике будет осуществлять небольшие подраздел распознавания объектов — цифра признание. С помощью TensorFlow, библиотеку Python открытым исходным кодом, разработанный мозга Google labs для глубокого изучения исследований, вы будете принимать рисованной изображения цифры 0-9 и построения и обучение нейронной сети для признания и предсказать правильные метки для цифра отображается.
Хотя не требуется предварительного опыта в практических глубокого обучения или TensorFlow следовать вместе с учебником, мы предполагаем, что некоторое знакомство с машина обучения термины и концепции, такие, как обучение и тестирование, функции и ярлыки, оптимизация, и оценки. Вы можете узнать больше об этих понятиях в Введение в машинное обучение.
Необходимые условия
Чтобы завершить этот учебник, вы должны:
Локальную среду разработки Python 3, включая ПМС, инструмент для установки пакетов Python и venv, для создания виртуальных сред.
Шаг 1-Настройка проекта
Прежде чем вы можете разработать программу распознавания, вам будет нужно установить несколько зависимостей и создать рабочую область для хранения ваших файлов.
Мы будем использовать Python 3 виртуальной среды для управления зависимостями нашего проекта. Создайте новый каталог для вашего проекта и перейдите в новый каталог:
mkdir tensorflow-demo
cd tensorflow-demo
Выполните следующие команды для настройки виртуальной среды для этого учебника:
python3 -m venv tensorflow-demo
source tensorflow-demo/bin/activate
Далее установите библиотеки, которую вы будете использовать в этом учебнике. Мы будем использовать конкретные версии этих библиотек, создав файл requirements.txt в каталог проекта, который определяет требования и версия, что нам нужно. Создайте файл requirements.txt :
touch requirements.txt
Откройте файл в текстовом редакторе и добавьте следующие строки для указания изображения, NumPy и TensorFlow библиотек и их версии:
Requirements.txt
image==1.5.20
numpy==1.14.3
tensorflow==1.4.0
Сохраните файл и выйдите из редактора. Затем установите эти библиотеки с помощью следующей команды:
pip install -r requirements.txt
С установлены зависимости мы сможем начать работу над нашим проектом.
Шаг 2-Импорт набора данных MNIST
Набор данных, которые мы будем использовать в этом руководстве называется набор данных MNIST , и это классика в машинного обучения сообщества. Этот набор данных состоит из изображения рукописной цифр, 28 х 28 пикселов. Вот некоторые примеры цифры включены в наборе данных:
Examples of MNIST images
Давайте создадим программу Python для работы с этим набором данных. Мы будем использовать один файл для всей нашей деятельности в этом учебнике. Создайте новый файл под названием main.py:
touch main.py
Теперь откройте этот файл в любом текстовом редакторе выбора и добавьте эту строку кода в файл для импорта библиотеки TensorFlow:
Main.py
import tensorflow as tf
Добавьте следующие строки кода в файл для импорта набора MNIST данных и хранить данные изображения в переменной mnist:
Main.py
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True) # y labels are oh-encoded
При чтении данных, мы используем один горячий кодировки для представления этикетки (фактическая цифра нарисованы, например «3») изображений. Один горячий кодирования использует вектор двоичных значений для представления значения: числовые или категорически. Как наши этикетки для цифр 0-9, вектор содержит десять значения, по одному для каждой возможной цифры. Одно из этих значений имеет значение 1, для цифры в этом индексе вектора, и остальные устанавливаются в 0. Например цифра 3 представляется с помощью вектора [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]. Как значение с индексом 3 хранится в виде 1, вектор поэтому представляет цифру 3.
Представлять фактические изображения сами, 28 х 28 Пиксели сводятся в 1D вектор, который составляет 784 пикселов. Каждый из 784 пикселей, составляющих изображение хранится в виде значения между 0 и 255. Это определяет серого пикселя, как наши изображения представлены в только черный и белый. Таким образом Черный пиксел представлен 255 и белый пиксель на 0, с различными оттенками серого цвета, где-то между ними.
Мы можем использовать переменную mnist , чтобы узнать размер набора данных, который мы только что импортировали. Глядя на num_examples для каждого из трех подмножеств, мы можем определить, что набор данных был разбит на 55 000 изображений для обучения, 5000 для проверки и 10000 для тестирования. Добавьте следующие строки в ваш файл:
Main.py
n_train = mnist.train.num_examples # 55,000
n_validation = mnist.validation.num_examples # 5000
n_test = mnist.test.num_examples # 10,000
Теперь у нас есть наши данные импортируются, пришло время подумать о нейронной сети.
Шаг 3-Определение архитектуры нейронной сети
Архитектура нейронной сети относится к элементов, таких как количество слоев в сети, количество единиц в каждом слое, и как единицы связаны между слоями. Как нейронные сети слабо вдохновлен работой человеческого мозга, здесь термин группа используется для представления, мы бы биологически как думают о нейрона. Как нейроны передачи сигналов вокруг мозга подразделения принимать некоторые значения из предыдущих единиц в качестве входных данных, выполнить вычисления и затем передать на новое значение в качестве выходных данных в другие единицы. Эти подразделения являются слоистых для формирования сети, начиная как минимум с одним слоем для ввода значений и один слой для вывода значений. Для всех слоев между ввода и вывода слоев, т.е. те «скрытые» от реального мира используется термин скрытого слоя .
Различные архитектуры может принести радикально разные результаты, поскольку производительность можно рассматривать как функцию архитектуры, среди прочего, такие как параметры, данные и продолжительность обучения.
Добавьте следующие строки кода в ваш файл для хранения количество единиц на слой в глобальных переменных. Это позволяет нам изменить сетевой архитектуры в одном месте и в конце учебника можно проверить для себя как различное количество слоев и подразделения будут влиять на результаты нашей модели:
Main.py
n_input = 784 # input layer (28×28 pixels)
n_hidden1 = 512 # 1st hidden layer
n_hidden2 = 256 # 2nd hidden layer
n_hidden3 = 128 # 3rd hidden layer
n_output = 10 # output layer (0-9 digits)
На следующей схеме показана визуализация архитектуры, которую мы разработали, с каждым слоем, полностью подключен к окружающих слоёв:
Diagram of a neural network
Термин «глубоко нейронной сети» относится к число скрытых слоев, с «мелкий» обычно означает только один скрытый слой и «deep», ссылаясь на несколько скрытых слоев. Учитывая достаточно обучающих данных, мелкой нейронную сеть с достаточное количество единиц теоретически должны иметь возможность представлять любую функцию, которая глубоко нейронной сети может. Но часто бывает вычислительно эффективно использовать меньше глубоко нейронной сети для достижения той же задачи, которые потребуют мелкой сети с экспоненциально более скрытые единиц. Мелкой нейронных сетей также часто сталкиваются с переобучение, где сеть по существу запоминает обучающих данных, что он видел и не умеет обобщать знания к новым данным. Вот почему глубоко нейронных сетей более широко используются: несколько слоев между необработанных входных данных и вывода метки позволяют в сети, чтобы узнать особенности на различных уровнях абстракции, делая самой сети лучше возможность обобщить.
Другие элементы нейронной сети, которые должны быть определены здесь являются hyperparameters. В отличие от параметров, которые будут получать обновления во время обучения эти значения устанавливаются первоначально и остаются постоянными на протяжении всего процесса. В вашем файле установите следующие переменные и значения:
Main.py
learning_rate = 1e-4
n_iterations = 1000
batch_size = 128
dropout = 0.5
Учебный курс представляет ВЛ много параметров будет настроить на каждом шаге процесса обучения. Эти изменения являются ключевым компонентом обучения: после каждого прохода через сеть мы настроить немного, чтобы попытаться уменьшить потери веса. Большие курсы обучения может сходятся быстрее, но также имеют потенциал, чтобы выброс оптимальные значения как они обновляются. Количество итераций соответствует сколько раз мы идем через шаг подготовки и размер пакета относится сколько учебных примеров мы используем на каждом шагу. dropout переменная представляет порог, при котором мы elimanate некоторые подразделения наугад. Мы будем использовать dropout в нашей окончательной скрытый слой дать каждой единицы шанс 50% устраняются на каждом этапе обучения. Это помогает предотвратить переобучение.
Теперь мы определили архитектура нашей нейронной сети и hyperparameters, которые влияют на процесс обучения. Следующий шаг заключается в создании сети как граф TensorFlow.
Шаг 4-Создание графа TensorFlow
Для построения нашей сети, мы настроим сети как вычислительного графа для TensorFlow для выполнения. Основная концепция TensorFlow является тензор, структуры данных, аналогичные массив или список. инициализации, манипулировать, как они передаются через графа и обновление с помощью процесса обучения.
Мы начнем с определения трех тензоров как заполнители, которые являются тензоров, которые мы будем кормить значения в позднее. Добавьте следующую строку в ваш файл:
Main.py
X = tf.placeholder(“float”, [None, n_input])
Y = tf.placeholder(“float”, [None, n_output])
keep_prob = tf.placeholder(tf.float32)
Единственный параметр, который нужно указать в своей Декларации является размер данных, которые мы будет кормления в. Для X мы используем форму [None, 784], где None представляет любую сумму, как мы будет кормления в неопределенное количество 784-пиксела изображения. Форма Y — [None, 10] , как мы будем использовать его для неопределенное количество выходов этикетки, с 10 возможных классов. Тензор keep_prob используется для управления отсева, и мы инициализировать его как местозаполнитель, а не переменной неизменяемым, потому что мы хотим использовать тензор же как для обучения (когда dropout равным 0.5) и тестирования (когда dropout равным 1.0).
Параметры, которые сеть будет обновляться в процессе обучения являются weight и bias значений, поэтому для них необходимо задать начальное значение, а не пустой заполнитель. Эти значения являются по существу где сети делает его обучения, как они используются в функциях активации нейронов, выражающей связей между подразделениями.
Поскольку значения оптимизированы в процессе обучения, мы могли бы установить их на ноль сейчас. Но начальное значение на самом деле имеет значительное влияние на окончательный точность модели. Мы будем использовать случайные значения от усеченного нормального распределения для весов. Мы хотим, чтобы быть близко к нулю, так что они могут настроить в любом направлении, положительный или отрицательный и немного отличаются, так что они генерируют различные ошибки. Это будет гарантировать, что модель узнает что-то полезное. Добавьте следующие строки:
Main.py
weights = {
‘w1’: tf.Variable(tf.truncated_normal([n_input, n_hidden1], stddev=0.1)),
‘w2’: tf.Variable(tf.truncated_normal([n_hidden1, n_hidden2], stddev=0.1)),
‘w3’: tf.Variable(tf.truncated_normal([n_hidden2, n_hidden3], stddev=0.1)),
‘out’: tf.Variable(tf.truncated_normal([n_hidden3, n_output], stddev=0.1)),
}
Для смещения мы используем небольшое постоянное значение для обеспечения что тензоров активировать на первоначальной стадии и таким образом способствовать распространению. Веса и смещения тензоров и хранятся в объектах словарь для удобства доступа. Добавьте этот код в ваш файл, чтобы определить склонности:
Main.py
biases = {
‘b1’: tf.Variable(tf.constant(0.1, shape=[n_hidden1])),
‘b2’: tf.Variable(tf.constant(0.1, shape=[n_hidden2])),
‘b3’: tf.Variable(tf.constant(0.1, shape=[n_hidden3])),
‘out’: tf.Variable(tf.constant(0.1, shape=[n_output]))
}
Далее настройте слои сети путем определения операций, которые будут манипулировать тензоров. Добавьте следующие строки в ваш файл:
Main.py
layer_1 = tf.add(tf.matmul(X, weights[‘w1’]), biases[‘b1’])
layer_2 = tf.add(tf.matmul(layer_1, weights[‘w2’]), biases[‘b2’])
layer_3 = tf.add(tf.matmul(layer_2, weights[‘w3’]), biases[‘b3’])
layer_drop = tf.nn.dropout(layer_3, keep_prob)
output_layer = tf.matmul(layer_3, weights[‘out’]) + biases[‘out’]
Каждый скрытый слой будет выполнять умножение матриц результатов предыдущего слоя и веса текущего слоя и добавьте предвзятость этих ценностей. В последний скрытый слой мы будем применять операцию отсева, используя наш keep_prob значение 0.5.
Последний шаг при построении графа заключается в том, чтобы определить функцию потерь, который мы хотим оптимизировать. Популярный выбор потери функции в программах TensorFlow является кросс энтропия, также известный как лог потери, который измеряет разницу между двух распределений вероятностей (предсказания и этикетки). Идеальный классификации приведет к кросс энтропия 0, с потерей полностью сведены к минимуму.
Нам также необходимо выбрать алгоритм оптимизации, который будет использоваться для сведения к минимуму потери функции. Процесс оптимизации градиентного спуска с именем является общий метод для поиска (локальный) минимум функции путем итеративного шаги вдоль градиента в отрицательном направлении (по убыванию). Существует несколько вариантов алгоритмов оптимизации градиентного спуска, уже реализованы в TensorFlow, и в этом руководстве мы будем использовать оптимизатор Адам. Это распространяется на оптимизации градиентного спуска с помощью импульса для ускорения процесса путем вычисления экспоненциально взвешенное среднее градиенты и использовать их в корректировке. Добавьте следующий код в ваш файл:
Main.py
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=output_layer))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
Мы теперь определены сети и построил его с TensorFlow. Следующий шаг — кормить данных через граф тренировать его, а затем проверить, что он на самом деле узнали что-то.
Шаг 5 — Обучение и тестирование
Учебный процесс включает в себя питание учебном наборе данных через графа и оптимизации функция потерь. Каждый раз, когда сеть итерацию партии больше подготовки изображений, он обновляет параметры для снижения потерь для того, чтобы более точно предсказать цифры, указанные. Процесс тестирования включает в себя запуск нашего тестирования набора данных через подготовку графа и отслеживать количество изображений, которые правильно предсказал, так что мы можем вычислить точность.
Перед началом процесса обучения, мы определим наш метод оценки точности, поэтому мы можем распечатать его на мини пакеты данных в то время как мы тренируемся. Эти печатные заявления позволит нам проверить, что из первой итерации до последнего, уменьшает потерю и увеличивает точность; Они также позволяют нам отслеживать ли мы побежали достаточно итераций, чтобы достигнуть последовательной и оптимального результата:
Main.py
correct_pred = tf.equal(tf.argmax(output_layer, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
В correct_predмы используем функцию arg_max для сравнения, какие изображения будучи правильно предсказать, глядя на output_layer (прогнозы) и Y (этикетки), и мы используем функцию equal для возврата Это как список [Булев] (ТЭС: / /www.digitalocean.com/community/tutorials/understanding-data-types-in-python-3#booleans). Мы можем затем бросили этот список для поплавков и вычислить среднее получить оценка общей точности.
Теперь мы готовы для инициализации сеанса для запуска графа. В ходе этой сессии мы будет кормить сети с примерами нашей подготовки, и пройдя подготовку, мы кормить же граф с новыми примерами тест для определения точности модели. Добавьте следующие строки кода в ваш файл:
Main.py
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
Суть процесса обучения в глубокое обучение является оптимизация потери функции. Здесь мы стремимся свести к минимуму разницу между предсказал этикетках изображения и истинный этикетках изображения. Этот процесс включает в себя четыре шага, которые повторяются на определенное количество итераций:
Пропаганда ценностей вперед через сеть
Вычислить потери
Пропаганда ценностей назад через сеть
Обновить параметры
На каждом этапе обучения параметры корректируются слегка, чтобы попытаться уменьшить потери для следующего шага. В процессе обучения мы должны увидеть снижение потерь, и в конечном итоге мы можем остановить подготовку и использовать сеть в качестве модели для тестирования наших новых данных.
Добавьте этот код в файл:
Main.py
# train on mini batches
for i in range(n_iterations):
batch_x, batch_y = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={X: batch_x, Y: batch_y, keep_prob:dropout})
# print loss and accuracy (per minibatch)
if i%100==0:
minibatch_loss, minibatch_accuracy = sess.run([cross_entropy, accuracy], feed_dict={X: batch_x, Y: batch_y, keep_prob:1.0})
print(“Iteration”, str(i), “\t| Loss =”, str(minibatch_loss), “\t| Accuracy =”, str(minibatch_accuracy))
После 100 итераций каждого шага подготовки, в котором мы подаем мини-партии изображений через сеть мы распечатать потери и точность этого пакета. Обратите внимание, что мы должны не ожидали снижения потерь и повышения точности здесь, как значения находятся в пакете, не для всей модели. Мы используем мини серий изображений, а не кормить их через индивидуально, чтобы ускорить процесс обучения и позволяет сети, чтобы увидеть целый ряд различных примеров перед обновлением параметров.
После завершения обучения, мы можем запустить сессии на тестовых изображений. На этот раз мы используем keep_prob отсева 1.0 , чтобы убедиться, что все подразделения принимают активное участие в процессе тестирования.
Добавьте этот код в файл:
Main.py
test_accuracy = sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob:1.0})
print(“\nAccuracy on test set:”, test_accuracy)
Настало время запустить нашу программу и посмотреть, как точно нашей нейросети можно признать эти рукописные цифр. Сохраните файл main.py и выполните следующую команду в терминале, чтобы запустить скрипт:
python3 main.py
Вы увидите результат, похожий на следующих, хотя индивидуальные потери и точность результаты могут немного отличаться:
Output
Iteration 0 | Loss = 3.67079 | Accuracy = 0.140625
Iteration 100 | Loss = 0.492122 | Accuracy = 0.84375
Iteration 200 | Loss = 0.421595 | Accuracy = 0.882812
Iteration 300 | Loss = 0.307726 | Accuracy = 0.921875
Iteration 400 | Loss = 0.392948 | Accuracy = 0.882812
Iteration 500 | Loss = 0.371461 | Accuracy = 0.90625
Iteration 600 | Loss = 0.378425 | Accuracy = 0.882812
Iteration 700 | Loss = 0.338605 | Accuracy = 0.914062
Iteration 800 | Loss = 0.379697 | Accuracy = 0.875
Iteration 900 | Loss = 0.444303 | Accuracy = 0.90625
Accuracy on test set: 0.9206
Чтобы попытаться улучшить точность нашей модели, или узнать больше о влиянии тюнинг hyperparameters, мы можем проверить эффект изменения курса обучения, порог отсева, размер пакета и количество итераций. Мы можем также изменить число единиц в наших скрытых слоях и изменить количество скрытых слоев, себя, чтобы увидеть, как различные архитектуры увеличить или уменьшить точность модели.
Чтобы продемонстрировать, что сеть является фактически признавая рисованной изображения, давайте проверить его на одно изображение наших собственных.
Сначала либо скачать этот Пример тестового изображения или открыть графический редактор и создать свой собственный образ пиксель 28 х 28 цифр.
Откройте файл main.py в редакторе и добавьте следующие строки кода в верхней части файла для импорта две библиотеки, необходимые для обработки изображений.
Main.py
import numpy as np
from PIL import Image
…
Затем в конце файла, добавьте следующую строку кода для загрузки тестовое изображение рукописной цифры:
Main.py
img = np.invert(Image.open(“test_img.png”).convert(‘L’)).ravel()
open функцию библиотеки Image загружает изображение тест как 4 D массив, содержащий три цветовых каналов RGB и альфа-прозрачность. Это не то же представление, что мы использовали ранее при чтении в наборе с TensorFlow, поэтому мы должны сделать некоторую дополнительную работу в соответствии с форматом.
Во-первых мы используем функция convert с параметром L для уменьшения 4 D RGBA представление на один канал оттенков серого цвета. Мы храним это как массива numpy и инвертировать его с помощью np.invert, потому что текущая матрица представляет черный 0 и белый как 255, тогда как нам нужно наоборот. Наконец мы призываем, ravel , чтобы сгладить массив.
Теперь, когда изображение данные структурированы правильно, мы можем запустить сеанс в так же, как ранее, но на этот раз, только кормления в единый образ для тестирования. Добавьте следующий код в ваш файл для проверки изображения и распечатать выводимый метки.
Main.py
prediction = sess.run(tf.argmax(output_layer,1), feed_dict={X: [img]})
print (“Prediction for test image:”, np.squeeze(prediction))
Функция np.squeeze вызывается на предсказание для возврата одного целого числа из массива (т.е. для перехода от [2] на 2). Результат показывает, что сеть признала этот образ как цифра 2.
Output
Prediction for test image: 2
Вы можете попробовать тестирование сети с более сложных изображений – – цифры, которые выглядят как другие цифры, например, или цифры, которые были разработаны плохо или неправильно – – чтобы увидеть, насколько хорошо он тарифов.
Заключение
В этом учебнике вы успешно прошли обучение нейронной сети для классификации MNIST dataset с около 92% точность и испытал его на свой собственный образ. Текущее состояние искусства исследований достигает около 99% по этой же проблеме, с использованием более сложных сетевых архитектурах с участием сверточных слои. Эти использовать структуру 2D изображения лучше представляет содержимое, в отличие от нашего метода, который выравнивается все пиксели в один вектор 784 единиц. Вы можете прочитать больше об этой теме на сайте TensorFlowи посмотреть исследования документы подробно наиболее точные результаты на сайте MNIST.
Теперь, когда вы знаете, как для создания и обучения нейронной сети, можно попробовать и использовать эту реализацию на ваших собственных данных или проверить его на других популярных наборов данных, таких как Google StreetView дом чисел, или CIFAR-10 dataset для более общего изображения Распознавание.
Leave a Reply