Что такое сверточная нейронная сеть?
Сверточная нейронная сеть, также известная как свертки или CNN, является хорошо известным методом в приложениях компьютерного зрения. Этот тип архитектуры является доминирующим для распознавания объектов на картинке или видео.
В этом руководстве вы узнаете, как создать свертку и как использовать TensorFlow для решения рукописного набора данных.
В этом руководстве вы узнаете
- Сверточная нейронная сеть
- Архитектура сверточной нейронной сети
- Компоненты Convnets
- Тренируйте CNN с помощью TensorFlow
- Шаг 1. Загрузите набор данных
- Шаг 2: входной слой
- Шаг 3: сверточный слой
- Шаг 4: слой объединения
- Шаг 5: второй сверточный уровень и уровень пула
- Шаг 6: плотный слой
- Шаг 7: уровень Logit
Архитектура сверточной нейронной сети
Вспомните Facebook, несколько лет назад после того, как вы загрузили изображение в свой профиль, вас попросили вручную добавить имя к лицу на изображении. В настоящее время Facebook использует convnet, чтобы автоматически отмечать вашего друга на картинке.
Сверточную нейронную сеть понять несложно. Входное изображение обрабатывается на этапе свертки, а затем ему присваивается метка.
Типичная архитектура convnet может быть представлена на рисунке ниже. Прежде всего, изображение отправляется в сеть; это называется входным изображением. Затем входное изображение проходит бесконечное количество шагов; это сверточная часть сети. Наконец, нейронная сеть может предсказать цифру на изображении.
Изображение состоит из массива пикселей с высотой и шириной. Изображение в градациях серого имеет только один канал, в то время как цветное изображение имеет три канала (каждый для красного, зеленого и синего). Каналы накладываются друг на друга. В этом уроке вы будете использовать изображение в градациях серого только с одним каналом. Каждый пиксель имеет значение от 0 до 255, чтобы отразить интенсивность цвета. Например, пиксель, равный 0, будет иметь белый цвет, а пиксель со значением, близким к 255, будет темнее.
Давайте посмотрим на изображение, хранящееся в наборе данных MNIST. На рисунке ниже показано, как представить картинку слева в матричном формате. Обратите внимание, что исходная матрица была стандартизирована и составляла от 0 до 1. Для более темного цвета значение в матрице составляет около 0,9, в то время как белые пиксели имеют значение 0.
Сверточная операция
Наиболее важным компонентом модели является сверточный слой. Эта часть направлена на уменьшение размера изображения для более быстрого вычисления весов и улучшения его обобщения.
Во время сверточной части сеть сохраняет основные характеристики изображения и исключает ненужный шум. Например, модель учится распознавать слона на фотографии с горой на заднем плане. Если вы используете традиционную нейронную сеть, модель назначит вес всем пикселям, включая пиксели с горы, что не является существенным и может ввести сеть в заблуждение.
Вместо этого сверточная нейронная сеть будет использовать математический метод для извлечения только наиболее релевантных пикселей. Эта математическая операция называется сверткой. Этот метод позволяет сети изучать все более сложные функции на каждом уровне. Свертка делит матрицу на маленькие части, чтобы изучить наиболее важные элементы в каждой части.
Компоненты Convnets
Convnets состоит из четырех компонентов.
- Свертка
- Нелинейность (ReLU)
- Объединение или подвыборка
- Классификация (полностью связанный слой)
- Свертка
Цель свертки - локально выделить особенности объекта на изображении. Это означает, что сеть будет изучать определенные закономерности на изображении и сможет распознать их повсюду на изображении.
Свертка - это поэлементное умножение. Концепцию легко понять. Компьютер отсканирует часть изображения, обычно размером 3x3, и умножит ее на фильтр. Результат поэлементного умножения называется картой характеристик. Этот шаг повторяется до тех пор, пока все изображение не будет отсканировано. Обратите внимание, что после свертки размер изображения уменьшается.
Ниже приведен URL-адрес, по которому можно в действии увидеть, как работает свертка.
Доступно множество каналов. Ниже мы перечислили некоторые из каналов. Вы можете видеть, что каждый фильтр имеет определенную цель. Обратите внимание, на картинке ниже; Ядро - это синоним фильтра.
Источник
Арифметика за сверткой
Сверточная фаза применяет фильтр к небольшому массиву пикселей в изображении. Фильтр будет перемещаться по входному изображению с общей формой 3x3 или 5x5. Это означает, что сеть будет перемещать эти окна по всему входному изображению и вычислять свертку. На изображении ниже показано, как работает свертка. Размер патча составляет 3x3, а выходная матрица является результатом поэлементной операции между матрицей изображения и фильтром.
Источник
Вы заметили, что ширина и высота вывода могут отличаться от ширины и высоты ввода. Это происходит из-за эффекта границы.
Эффект границы
Изображение имеет карту функций 5x5 и фильтр 3x3. В центре есть только одно окно, в котором фильтр может экранировать сетку 3x3. Выходная карта объектов сократится на две плитки вместе с размером 3x3.
Чтобы получить тот же выходной размер, что и входной, вам нужно добавить отступ. Заполнение состоит из добавления нужного количества строк и столбцов с каждой стороны матрицы. Это позволит центрировать свертку для каждой входной плитки. На изображении ниже матрица ввода / вывода имеет одинаковый размер 5x5.
Когда вы определяете сеть, свернутые функции управляются тремя параметрами:
- Глубина: определяет количество фильтров, применяемых во время свертки. В предыдущем примере вы видели глубину 1, что означает, что используется только один фильтр. В большинстве случаев используется более одного фильтра. На рисунке ниже показаны операции, выполненные в ситуации с тремя фильтрами.
- Шаг: определяет количество «скачка пикселя» между двумя срезами. Если шаг равен 1, окна будут перемещаться с размахом в один пиксель. Если шаг равен двум, окна переместятся на 2 пикселя. Если вы увеличите шаг, у вас будут более мелкие карты характеристик.
Пример шага 1
Изображение шага 2
- Нулевое заполнение: заполнение - это операция добавления соответствующего количества строк и столбцов с каждой стороны входных карт объектов. В этом случае выход имеет тот же размер, что и вход.
- Нелинейность (ReLU)
В конце операции свертки выходной сигнал подвергается функции активации, чтобы обеспечить нелинейность. Обычной функцией активации для convnet является Relu. Весь пиксель с отрицательным значением будет заменен на ноль.
- Операция максимального объединения
Этот шаг легко понять. Цель объединения - уменьшить размерность входного изображения. Шаги сделаны, чтобы уменьшить вычислительную сложность операции. Уменьшая размерность, сеть имеет меньшие веса для вычисления, что предотвращает переоснащение.
На этом этапе вам нужно определить размер и шаг. Стандартный способ объединить входное изображение - использовать максимальное значение карты функций. Посмотрите на картинку ниже. «Объединение» отобразит четыре подматрицы карты функций 4x4 и вернет максимальное значение. Пул принимает максимальное значение массива 2x2, а затем перемещает эти окна на два пикселя. Например, первая подматрица [3,1,3,2], объединение вернет максимум, равный 3.
Есть еще одна операция объединения, например среднее значение.
Эта операция агрессивно уменьшает размер карты функций.
- Полностью связанные слои
Последний шаг состоит из построения традиционной искусственной нейронной сети, как вы делали в предыдущем уроке. Вы соединяете все нейроны предыдущего слоя со следующим слоем. Вы используете функцию активации softmax для классификации числа на входном изображении.
Резюме:
Сверточная нейронная сеть компилирует разные слои перед тем, как сделать прогноз. В нейронной сети есть:
- Сверточный слой
- Функция активации реле
- Уровень объединения
- Плотно связанный слой
Сверточные слои применяют различные фильтры к подобласти изображения. Функция активации Relu добавляет нелинейность, а слои объединения уменьшают размерность карт объектов.
Все эти слои извлекают важную информацию из изображений. Наконец, карта объектов передается на первичный полностью связанный слой с функцией softmax, чтобы сделать прогноз.
Тренируйте CNN с помощью TensorFlow
Теперь, когда вы знакомы со строительным блоком свертков, вы готовы создать их с помощью TensorFlow. Мы будем использовать набор данных MNIST для классификации изображений.
Подготовка данных такая же, как и в предыдущем руководстве. Вы можете запустить коды и сразу перейти к архитектуре CNN.
Вы выполните следующие шаги:
Шаг 1. Загрузите набор данных
Шаг 2: входной слой
Шаг 3: сверточный слой
Шаг 4: слой объединения
Шаг 5: второй сверточный уровень и уровень пула
Шаг 6: плотный слой
Шаг 7: уровень Logit
Шаг 1. Загрузите набор данных
Набор данных MNIST доступен в scikit для изучения по этому URL-адресу. Загрузите его и сохраните в разделе «Загрузки». Вы можете загрузить его с помощью fetch_mldata ('MNIST original').
Создать поезд / тестовый набор
Вам нужно разделить набор данных с помощью train_test_split
Масштабируйте функции
Наконец, вы можете масштабировать функцию с помощью MinMaxScaler.
import numpy as npimport tensorflow as tffrom sklearn.datasets import fetch_mldata#Change USERNAME by the username of your machine## Windows USERmnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')## Mac Usermnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')print(mnist.data.shape)print(mnist.target.shape)from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)y_train = y_train.astype(int)y_test = y_test.astype(int)batch_size =len(X_train)print(X_train.shape, y_train.shape,y_test.shape )## resclaefrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()# TrainX_train_scaled = scaler.fit_transform(X_train.astype(np.float64))# testX_test_scaled = scaler.fit_transform(X_test.astype(np.float64))feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])]X_train_scaled.shape[1:]
Определите CNN
CNN использует фильтры на необработанном пикселе изображения, чтобы узнать подробности шаблона по сравнению с глобальным шаблоном с традиционной нейронной сетью. Чтобы построить CNN, вам необходимо определить:
- Сверточный слой: примените n фильтров к карте объектов. После свертки вам нужно использовать функцию активации Relu, чтобы добавить нелинейности в сеть.
- Слой объединения: следующим шагом после свертки является уменьшение максимального значения функции. Цель состоит в том, чтобы уменьшить размерность карты функций, чтобы предотвратить переоснащение и повысить скорость вычислений. Максимальное объединение - это традиционный метод, который разделяет карты функций на подобласти (обычно размером 2x2) и сохраняет только максимальные значения.
- Полностью связанные слои: все нейроны из предыдущих слоев подключены к следующим слоям. CNN классифицирует метку в соответствии с характеристиками сверточных слоев и сокращает их вместе со слоем объединения.
Архитектура CNN
- Сверточный слой: применяет 14 фильтров 5x5 (извлечение подобластей 5x5 пикселей) с функцией активации ReLU
- Уровень объединения: выполняет максимальное объединение с фильтром 2x2 и шагом 2 (что указывает, что объединенные области не перекрываются)
- Сверточный слой: применяет 36 фильтров 5x5 с функцией активации ReLU
- Уровень объединения # 2: снова выполняется максимальное объединение с фильтром 2x2 и шагом 2.
- 1764 нейрона с коэффициентом регуляризации выпадения 0,4 (вероятность 0,4, что любой данный элемент будет отброшен во время обучения)
- Плотный слой (логитовый уровень): 10 нейронов, по одному для каждого целевого класса цифр (0-9).
Для создания CNN необходимо использовать три важных модуля:
- conv2d (). Создает двумерный сверточный слой с количеством фильтров, размером ядра фильтра, заполнением и функцией активации в качестве аргументов.
- max_pooling2d (). Создает двумерный слой объединения с использованием алгоритма максимального объединения.
- плотный(). Создает плотный слой со скрытыми слоями и блоками
Вы определите функцию для построения CNN. Давайте посмотрим подробно, как построить каждый строительный блок, прежде чем объединять все вместе в функции.
Шаг 2: входной слой
def cnn_model_fn(features, labels, mode):input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Вам нужно определить тензор с формой данных. Для этого вы можете использовать модуль tf.reshape. В этом модуле вам нужно объявить тензор для изменения формы и форму тензора. Первый аргумент - это характеристики данных, которые определены в аргументе функции.
Картинка имеет высоту, ширину и канал. Набор данных MNIST представляет собой монохромное изображение размером 28x28. Мы устанавливаем размер пакета равным -1 в аргументе shape, чтобы он принял форму функций ["x"]. Преимущество состоит в том, чтобы настраивать гиперпараметры размера партии. Если размер пакета установлен на 7, то тензор будет передавать 5 488 значений (28 * 28 * 7).
Step 3: Convolutional layer
# first Convolutional Layerconv1 = tf.layers.conv2d(inputs=input_layer,filters=14,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)
Первый сверточный слой имеет 14 фильтров с размером ядра 5x5 с таким же заполнением. Одинаковое заполнение означает, что и выходной тензор, и входной тензор должны иметь одинаковую высоту и ширину. Tensorflow добавит нули в строки и столбцы, чтобы обеспечить одинаковый размер.
Вы используете функцию активации Relu. Размер вывода будет [28, 28, 14].
Шаг 4: слой объединения
Следующим шагом после свертки является вычисление пула. Вычисление пула уменьшит размерность данных. Вы можете использовать модуль max_pooling2d с размером 2x2 и шагом 2. Вы используете предыдущий слой в качестве входных. Размер вывода будет [batch_size, 14, 14, 14].
# first Pooling Layerpool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Шаг 5: второй сверточный уровень и уровень пула
Второй сверточный слой имеет 32 фильтра с размером вывода [batch_size, 14, 14, 32]. Уровень объединения имеет тот же размер, что и раньше, а форма вывода - [batch_size, 14, 14, 18].
conv2 = tf.layers.conv2d(inputs=pool1,filters=36,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
Шаг 6: плотный слой
Затем вам нужно определить полностью связанный слой. Чтобы связать с плотным слоем, карту объектов необходимо выровнять. Можно использовать модуль reshape размером 7 * 7 * 36.
Плотный слой соединит 1764 нейрона. Вы добавляете функцию активации Relu. Кроме того, вы добавляете термин регуляризации отсева со скоростью 0,3, что означает, что 30 процентов весов будут установлены на 0. Обратите внимание, что отсев происходит только во время фазы обучения. Функция cnn_model_fn имеет режим аргументов, чтобы объявить, нужно ли обучать модель или оценивать.
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
Шаг 7: уровень Logit
Наконец, вы можете определить последний слой с предсказанием модели. Форма вывода равна размеру пакета и 10 - общему количеству изображений.
# Logits Layerlogits = tf.layers.dense(inputs=dropout, units=10)
Вы можете создать словарь, содержащий классы и вероятность каждого класса. Модуль tf.argmax () с возвратом наивысшего значения, если логит слоев. Функция softmax возвращает вероятность каждого класса.
predictions = {# Generate predictions"classes": tf.argmax(input=logits, axis=1),"probabilities": tf.nn.softmax(logits, name="softmax_tensor") }
Вы хотите вернуть словарное предсказание, только когда установлен режим предсказания. Вы добавляете эти коды, чтобы отображать прогнозы
if mode == tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
Следующим шагом является вычисление потерь модели. В последнем руководстве вы узнали, что функцией потерь для мультиклассовой модели является перекрестная энтропия. Потери легко вычислить с помощью следующего кода:
# Calculate Loss (for both TRAIN and EVAL modes)loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
Последний шаг - оптимизировать модель, то есть найти наилучшие значения весов. Для этого вы используете оптимизатор градиентного спуска со скоростью обучения 0,001. Цель - минимизировать потери
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)train_op = optimizer.minimize(loss=loss,global_step=tf.train.get_global_step())
Вы закончили с CNN. Однако вы хотите отображать показатели производительности в режиме оценки. Метрики производительности для мультиклассовой модели - это метрики точности. Tensorflow оснащен модулем точности с двумя аргументами, метками и прогнозируемыми значениями.
eval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
Вот и все. Вы создали свою первую CNN и готовы обернуть все в функцию, чтобы использовать ее для обучения и оценки модели.
def cnn_model_fn(features, labels, mode):"""Model function for CNN."""# Input Layerinput_layer = tf.reshape(features["x"], [-1, 28, 28, 1])# Convolutional Layerconv1 = tf.layers.conv2d(inputs=input_layer,filters=32,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)# Pooling Layerpool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)# Convolutional Layer #2 and Pooling Layerconv2 = tf.layers.conv2d(inputs=pool1,filters=36,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)# Dense Layerpool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)# Logits Layerlogits = tf.layers.dense(inputs=dropout, units=10)predictions = {# Generate predictions (for PREDICT and EVAL mode)"classes": tf.argmax(input=logits, axis=1),"probabilities": tf.nn.softmax(logits, name="softmax_tensor")}if mode == tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)# Calculate Lossloss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)# Configure the Training Op (for TRAIN mode)if mode == tf.estimator.ModeKeys.TRAIN:optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)train_op = optimizer.minimize(loss=loss,global_step=tf.train.get_global_step())return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)# Add evaluation metrics Evaluation modeeval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
Приведенные ниже шаги такие же, как и в предыдущих уроках.
Прежде всего, вы определяете оценщик с моделью CNN.
# Create the Estimatormnist_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")
CNN требует много раз для обучения, поэтому вы создаете ловушку Logging для хранения значений слоев softmax каждые 50 итераций.
# Set up logging for predictionstensors_to_log = {"probabilities": "softmax_tensor"}logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)
Вы готовы оценить модель. Вы устанавливаете размер пакета 100 и перемешиваете данные. Обратите внимание, что мы установили количество шагов обучения 16000, это может занять много времени. Потерпи.
# Train the modeltrain_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": X_train_scaled},y=y_train,batch_size=100,num_epochs=None,shuffle=True)mnist_classifier.train(input_fn=train_input_fn,steps=16000,hooks=[logging_hook])
Теперь, когда модель обучена, вы можете оценить ее и распечатать результаты.
# Evaluate the model and print resultseval_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": X_test_scaled},y=y_test,num_epochs=1,shuffle=False)eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)print(eval_results)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269{'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}
С текущей архитектурой вы получаете точность 97%. Вы можете изменить архитектуру, размер пакета и количество итераций для повышения точности. Нейронная сеть CNN работает намного лучше, чем ANN или логистическая регрессия. В учебнике по искусственной нейронной сети у вас была точность 96%, что ниже CNN. Производительность CNN впечатляет благодаря большему набору изображений , как с точки зрения скорости вычислений, так и точности.
Резюме
Сверточная нейронная сеть очень хорошо работает для оценки изображения. Этот тип архитектуры является доминирующим для распознавания объектов на картинке или видео.
Чтобы построить CNN, вам нужно выполнить шесть шагов:
Шаг 1: Входной слой:
Этот шаг меняет форму данных. Форма равна квадратному корню из числа пикселей. Например, если изображение имеет 156 пикселей, то его форма будет 26x26. Вам необходимо указать, цветной рисунок или нет. Если да, то у вас было 3 для формы - 3 для RGB-, в противном случае 1.
input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Шаг 2: сверточный слой
Далее вам нужно создать сверточные слои. Вы применяете различные фильтры, чтобы позволить сети изучить важную функцию. Вы указываете размер ядра и количество фильтров.
conv1 = tf.layers.conv2d(inputs=input_layer,filters=14,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)
Шаг 3: слой объединения
На третьем этапе вы добавляете слой объединения. Этот слой уменьшает размер ввода. Это достигается за счет максимального значения подматрицы. Например, если подматрица [3,1,3,2], объединение вернет максимум, равный 3.
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Шаг 4: добавьте сверточный слой и слой пула
На этом этапе вы можете добавить столько сверточных слоев и слоев объединения, сколько захотите. Google использует архитектуру с более чем 20 сверточными слоями.
Шаг 5: плотный слой
Шаг 5 сглаживает предыдущий, чтобы создать полностью связанные слои. На этом этапе вы можете использовать другую функцию активации и добавить эффект отключения.
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
Шаг 6: уровень Logit
Последний шаг - это предсказание.
logits = tf.layers.dense(inputs=dropout, units=10)