определение:
короче,Сверточные нейронные сетиЭто модель глубокого обучения или многослойный персептрон, похожий на искусственную нейронную сеть, которая часто используется для анализа визуальных изображений. Основателем сверточной нейронной сети является известный ученый-компьютерщик Янн ЛеКун, в настоящее время работающий в Facebook, он первым применил сверточные нейронные сети вНабор данных MNISTчеловек решает проблему с рукописными числами.
Yann LeCunn
Появление сверточных нейронных сетей было вдохновлено биологической обработкой, поскольку структура связей между нейронами аналогична организации зрительной коры у животных.
Зрительное строение человеческого мозга
Отдельные корковые нейроны реагируют на стимулы только в ограниченных областях поля зрения, известных как рецептивные поля, а рецептивные поля разных нейронов частично перекрываются, позволяя им покрывать все поле зрения.
Компьютерное зрение и человеческое зрение
Как показано на изображении выше, невозможно говорить о каком-либо типе нейронной сети, не упомянув немного нейробиологии и знаний о человеческом теле (особенно о мозге) и его функциях, которые становятся основой для создания различных моделей глубокого обучения. источник вдохновения.
Архитектура сверточной нейронной сети:
Архитектура сверточной нейронной сети
Как показано на рисунке выше, архитектура сверточной нейронной сети очень похожа на архитектуру обычной искусственной нейронной сети, особенно на последнем слое сети, который полностью связан. Также обратите внимание, что сверточные нейронные сети могут принимать в качестве входных данных несколько карт объектов вместо векторов.
Давайте рассмотрим основные строительные блоки и связанные с ними математические операции, из которых состоит сверточная нейронная сеть, а также визуализируем и классифицируем изображения на основе признаков и атрибутов, изученных во время обучения.
Входной слой|Входной слой:
Входной слой в основном состоит из n×m×3 изображений RGB, что отличается от искусственной нейронной сети, вход которой представляет собой n×1-мерный вектор.
RGB-изображение
Слой свертки | Слой свертки:
В сверточном слое вычисляется скалярное произведение между областями входного изображения и матрицей весов фильтра, и результат используется в качестве вывода слоя. Фильтр будет скользить по всему изображению, повторяя ту же операцию скалярного произведения. Обратите внимание на две вещи:
- Фильтр должен иметь то же количество каналов, что и входное изображение;
- Чем глубже сеть, тем больше фильтров вы используете, чем больше у вас фильтров, тем больше обнаружений границ и функций вы получаете;
Операция прямой свертки
Размеры вывода сверточного слоя:
выходная ширина:
выходная высота:
в:
- W : ширина входного изображения
- H : высота входного изображения
- Fw : ширина фильтра или ядра
- Fh : высота фильтра
- P : заполнение
- S : Шаг движения
Количество каналов, выводимых сверточным слоем, равно количеству фильтров, используемых во время операции свертки.
Почему выбирают свертки?
Иногда вы можете спросить себя, зачем вообще использовать операции свертки? Почему бы не расширить матрицу входного изображения с самого начала? Чтобы дать ответ здесь, если мы это сделаем, мы получим большое количество параметров для обучения, и у большинства людей нет возможности решать вычислительно ресурсоемкие задачи самым быстрым способом. Кроме того, поскольку у сверточной нейронной сети меньше параметров, можно избежать переобучения.
Слой пула|Слой пула:
В настоящее время широко используются две операции пулинга — средний пул и максимальный пул, из которых максимальный пул является наиболее часто используемым из двух, и его эффект, как правило, лучше, чем у среднего пула. Слои объединения используются для уменьшения размерности пространства признаков в сверточных нейронных сетях, но не глубины. При использовании слоя максимального пула берется максимальное количество входных регионов, а при использовании среднего пула берется среднее значение входных регионов.
максимальное объединение
Почему бассейн?
Одной из основных целей объединения слоев является обеспечение пространственной дисперсии, что означает, что вы или машина сможете распознать объект, даже если его внешний вид каким-либо образом изменится.Статья Яна ЛеКуна.
Нелинейный слой|Нелинейный слой:
В нелинейных слоях обычно используются функции активации ReLU вместо традиционных функций активации Sigmoid или Tan-H. Функция активации ReLU возвращает значение 0 для каждого отрицательного значения во входном изображении и одно и то же значение для каждого положительного значения во входном изображении (более подробное объяснение функции активации см.Прочтите эту статью).
Функция активации ReLU
Полностью подключенный слой} Полностью подключенный слой:
В полносвязном слое мы сглаживаем выходные данные последнего сверточного слоя и соединяем каждый узел текущего слоя с другим узлом следующего слоя. Полносвязный слой — это просто другое слово для искусственной нейронной сети, как показано на рисунке ниже. Операции в полносвязном слое точно такие же, как и в обычной искусственной нейронной сети:
Расширение сверточного слоя
полносвязный слой
Уровни и операции, рассмотренные выше, являются основными компонентами каждой сверточной нейронной сети. Теперь, когда мы обсудили операции, которые сверточные нейронные сети выполняют при прямом распространении, давайте перейдем к свертывающим нейронным сетям в операциях обратного распространения.
Обратное распространение | Обратное распространение:
Полностью связанный слой:
В полносвязном слое обратное распространение точно такое же, как и в любой обычной искусственной нейронной сети.При обратном распространении (с использованием градиентного спуска в качестве алгоритма оптимизации) параметры обновляются с использованием частной производной функции потерь, т. е. производной функции потерь по весам, где Мы умножаем производную функции потерь на выход активации, производную выхода активации на неактивный выход и производную для неактивного выхода, соответствующую весу. Математическое выражение выглядит следующим образом:
Иллюстрация обратного распространения
После вычисления градиента мы вычитаем его из начальных весов, чтобы получить новую оптимизацию:
в:
- θi+ 1 : оптимизированные веса
- θi: начальный вес
- α: скорость обучения
- ∇J(θi): градиент функции потерь
градиентный спуск
На динамическом графике ниже это результат применения градиентного спуска к линейной регрессии. Из рисунка видно, что чем меньше функция стоимости, тем лучше линейная модель соответствует данным.
Градиентный спуск, примененный к линейной регрессии
Кроме того, обратите внимание, что значение скорости обучения следует выбирать тщательно, слишком высокая скорость обучения может привести к тому, что градиент превысит целевое минимальное значение, а слишком низкая скорость обучения может привести к медленной сходимости модели сети.
Малая скорость обучения против большой скорости обучения
Частные производные широко используются во всех задачах оптимизации, будь то в физике, экономике или информатике. Частные производные в основном используются для расчета скорости изменения зависимой переменной f(x, y, z) по отношению к одной из ее независимых переменных. Например, предположим, что вы владеете долей в компании, акции которой растут или падают в зависимости от ряда факторов (ценные бумаги, политика, выручка от продаж и т. д.), и в этом случае с помощью частных производных вы подсчитаете, сколько акций затронуто и другие Факторы остаются прежними, а акции меняются, как и цена компании.
Слой пула|Слой пула:
В векторном слое с максимальным пулом градиенты распространяются только обратно через максимум, поэтому небольшое их изменение не влияет на результат. Во время этого процесса мы заменяем максимальное значение перед операцией максимального объединения на 1 и устанавливаем все немаксимальные значения равными нулю, затем используем цепное правило, чтобы умножить величину градиента на предыдущую величину, чтобы получить новое значение параметра.
Обратное распространение слоя пула
В отличие от слоев максимального пула, в слоях среднего пула градиенты распространяются на все входные данные (до среднего пула).
Слой свертки | Слой свертки:
Вы можете спросить себя сейчас, если прямой проход сверточного слоя является сверткой, то каков его обратный проход? К счастью, его обратное распространение также является сверткой, поэтому вам не нужно беспокоиться об изучении новой сложной математики.
Обратное распространение свёрточного слоя
в:
- ∂hij: производная функции потерь
В двух словах, на приведенной выше диаграмме показано, как работает обратное распространение в сверточном слое. Теперь, предполагая, что у вас есть твердое теоретическое понимание сверточных нейронных сетей, давайте создадим первую сверточную нейронную сеть с помощью TensorFlow.
TensorFlow реализует сверточные нейронные сети:
Что такое Тензорфлоу?
TensorFlow— это программная библиотека с открытым исходным кодом для численных вычислений с использованием графов потока данных. Первоначально он был разработан командой Google Brain, исследовательским подразделением Google в области машинного интеллекта, для исследований в области машинного обучения и глубоких нейронных сетей.
Что такое тензор?
Тензорпредставляет собой организованный многомерный массив, а порядок тензоров — это количество измерений массива, необходимых для его представления.
тип тензора
Что такое вычислительный граф?
Вычислительный графЭто фундаментальный подход в вычислительной алгебре, который оказался очень плодотворным в нейронных сетях и других алгоритмах вывода моделей и программных пакетах для машинного обучения. Основная идея вычислительного графа состоит в том, чтобы выразить некоторую модель, такую как нейронная сеть с прямой связью, в виде ориентированного графа, представляющего последовательность вычислительных шагов. Каждый шаг в последовательности соответствует вершине вычислительного графа, каждый шаг соответствует простой операции, и каждая операция принимает некоторый ввод и производит некоторый вывод на основе своего ввода.
На приведенном ниже рисунке у нас есть два входа w1 = x и w2 = y, эти входные данные будут проходить через граф, где каждый узел в графе является математической операцией, что даст нам следующий результат:
- w3 = cos(x), косинусная тригонометрическая операция
- w4 = sin(x), синусоидальная тригонометрическая операция
- w5 = w3∙w4, операция умножения
- w6 = w1 / w2, операция деления
- w7 = w5 + w6, операция сложения
Теперь, когда мы понимаем, что такое вычислительный граф, давайте построим собственный вычислительный граф в TensorFlow.
Код:
# Import the deep learning library
import tensorflow as tf
# Define our compuational graph
W1 = tf.constant(5.0, name = "x")
W2 = tf.constant(3.0, name = "y")
W3 = tf.cos(W1, name = "cos")
W4 = tf.sin(W2, name = "sin")
W5 = tf.multiply(W3, W4, name = "mult")
W6 = tf.divide(W1, W2, name = "div")
W7 = tf.add(W5, W6, name = "add")
# Open the session
with tf.Session() as sess:
cos = sess.run(W3)
sin = sess.run(W4)
mult = sess.run(W5)
div = sess.run(W6)
add = sess.run(W7)
# Before running TensorBoard, make sure you have generated summary data in a log directory by creating a summary writer
writer = tf.summary.FileWriter("./Desktop/ComputationGraph", sess.graph)
# Once you have event files, run TensorBoard and provide the log directory
# Command: tensorboard --logdir="path/to/logs"
Визуализируйте с помощью Tensorboard:
Что такое Тензорборд?
TensorBoard — это набор веб-приложений для проверки и понимания запусков и графиков TensorFlow, который также является TensorFlow от Google, а не от Facebook.PytorchОдно из самых больших преимуществ.
Приведенный выше код визуализируется в Tensorboard.
Имея четкое представление о сверточных нейронных сетях, TensorFlow и TensorBoard, давайте создадим нашу первую сверточную нейронную сеть для распознавания рукописных цифр с использованием набора данных MNIST.
Набор данных MNIST
Наша модель сверточной нейронной сети будет выглядеть такLeNet-5Архитектура, состоящая из сверточных слоев, максимального пула и слоев нелинейных операций.
3D-моделирование сверточных нейронных сетей
код:
# Import the deep learning library
import tensorflow as tf
import time
# Import the MNIST dataset
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
# Network inputs and outputs
# The network's input is a 28×28 dimensional input
n = 28
m = 28
num_input = n * m # MNIST data input
num_classes = 10 # MNIST total classes (0-9 digits)
# tf Graph input
X = tf.placeholder(tf.float32, [None, num_input])
Y = tf.placeholder(tf.float32, [None, num_classes])
# Storing the parameters of our LeNET-5 inspired Convolutional Neural Network
weights = {
"W_ij": tf.Variable(tf.random_normal([5, 5, 1, 32])),
"W_jk": tf.Variable(tf.random_normal([5, 5, 32, 64])),
"W_kl": tf.Variable(tf.random_normal([7 * 7 * 64, 1024])),
"W_lm": tf.Variable(tf.random_normal([1024, num_classes]))
}
biases = {
"b_ij": tf.Variable(tf.random_normal([32])),
"b_jk": tf.Variable(tf.random_normal([64])),
"b_kl": tf.Variable(tf.random_normal([1024])),
"b_lm": tf.Variable(tf.random_normal([num_classes]))
}
# The hyper-parameters of our Convolutional Neural Network
learning_rate = 1e-3
num_steps = 500
batch_size = 128
display_step = 10
def ConvolutionLayer(x, W, b, strides=1):
# Convolution Layer
x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x, b)
return x
def ReLU(x):
# ReLU activation function
return tf.nn.relu(x)
def PoolingLayer(x, k=2, strides=2):
# Max Pooling layer
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, strides, strides, 1],
padding='SAME')
def Softmax(x):
# Softmax activation function for the CNN's final output
return tf.nn.softmax(x)
# Create model
def ConvolutionalNeuralNetwork(x, weights, biases):
# MNIST data input is a 1-D row vector of 784 features (28×28 pixels)
# Reshape to match picture format [Height x Width x Channel]
# Tensor input become 4-D: [Batch Size, Height, Width, Channel]
x = tf.reshape(x, shape=[-1, 28, 28, 1])
# Convolution Layer
Conv1 = ConvolutionLayer(x, weights["W_ij"], biases["b_ij"])
# Non-Linearity
ReLU1 = ReLU(Conv1)
# Max Pooling (down-sampling)
Pool1 = PoolingLayer(ReLU1, k=2)
# Convolution Layer
Conv2 = ConvolutionLayer(Pool1, weights["W_jk"], biases["b_jk"])
# Non-Linearity
ReLU2 = ReLU(Conv2)
# Max Pooling (down-sampling)
Pool2 = PoolingLayer(ReLU2, k=2)
# Fully connected layer
# Reshape conv2 output to fit fully connected layer input
FC = tf.reshape(Pool2, [-1, weights["W_kl"].get_shape().as_list()[0]])
FC = tf.add(tf.matmul(FC, weights["W_kl"]), biases["b_kl"])
FC = ReLU(FC)
# Output, class prediction
output = tf.add(tf.matmul(FC, weights["W_lm"]), biases["b_lm"])
return output
# Construct model
logits = ConvolutionalNeuralNetwork(X, weights, biases)
prediction = Softmax(logits)
# Softamx cross entropy loss function
loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=logits, labels=Y))
# Optimization using the Adam Gradient Descent optimizer
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_process = optimizer.minimize(loss_function)
# Evaluate model
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# recording how the loss functio varies over time during training
cost = tf.summary.scalar("cost", loss_function)
training_accuracy = tf.summary.scalar("accuracy", accuracy)
train_summary_op = tf.summary.merge([cost,training_accuracy])
train_writer = tf.summary.FileWriter("./Desktop/logs",
graph=tf.get_default_graph())
# Initialize the variables (i.e. assign their default value)
init = tf.global_variables_initializer()
# Start training
with tf.Session() as sess:
# Run the initializer
sess.run(init)
start_time = time.time()
for step in range(1, num_steps+1):
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Run optimization op (backprop)
sess.run(training_process, feed_dict={X: batch_x, Y: batch_y})
if step % display_step == 0 or step == 1:
# Calculate batch loss and accuracy
loss, acc, summary = sess.run([loss_function, accuracy, train_summary_op], feed_dict={X: batch_x,
Y: batch_y})
train_writer.add_summary(summary, step)
print("Step " + str(step) + ", Minibatch Loss= " + \
"{:.4f}".format(loss) + ", Training Accuracy= " + \
"{:.3f}".format(acc))
end_time = time.time()
print("Time duration: " + str(int(end_time-start_time)) + " seconds")
print("Optimization Finished!")
# Calculate accuracy for 256 MNIST test images
print("Testing Accuracy:", \
sess.run(accuracy, feed_dict={X: mnist.test.images[:256],
Y: mnist.test.labels[:256]}))
Приведенный выше код немного многословен, но если вы разберете его по частям, его будет несложно прочитать. После запуска программы соответствующий результат должен выглядеть так:
Step 1, Minibatch Loss= 74470.4844, Training Accuracy= 0.117
Step 10, Minibatch Loss= 20529.4141, Training Accuracy= 0.250
Step 20, Minibatch Loss= 14074.7539, Training Accuracy= 0.531
Step 30, Minibatch Loss= 7168.9839, Training Accuracy= 0.586
Step 40, Minibatch Loss= 4781.1060, Training Accuracy= 0.703
Step 50, Minibatch Loss= 3281.0979, Training Accuracy= 0.766
Step 60, Minibatch Loss= 2701.2451, Training Accuracy= 0.781
Step 70, Minibatch Loss= 2478.7153, Training Accuracy= 0.773
Step 80, Minibatch Loss= 2312.8320, Training Accuracy= 0.820
Step 90, Minibatch Loss= 2143.0774, Training Accuracy= 0.852
Step 100, Minibatch Loss= 1373.9169, Training Accuracy= 0.852
Step 110, Minibatch Loss= 1852.9535, Training Accuracy= 0.852
Step 120, Minibatch Loss= 1845.3500, Training Accuracy= 0.891
Step 130, Minibatch Loss= 1677.2566, Training Accuracy= 0.844
Step 140, Minibatch Loss= 1683.3661, Training Accuracy= 0.875
Step 150, Minibatch Loss= 1859.3821, Training Accuracy= 0.836
Step 160, Minibatch Loss= 1495.4796, Training Accuracy= 0.859
Step 170, Minibatch Loss= 609.3800, Training Accuracy= 0.914
Step 180, Minibatch Loss= 1376.5054, Training Accuracy= 0.891
Step 190, Minibatch Loss= 1085.0363, Training Accuracy= 0.891
Step 200, Minibatch Loss= 1129.7145, Training Accuracy= 0.914
Step 210, Minibatch Loss= 1488.5452, Training Accuracy= 0.906
Step 220, Minibatch Loss= 584.5027, Training Accuracy= 0.930
Step 230, Minibatch Loss= 619.9744, Training Accuracy= 0.914
Step 240, Minibatch Loss= 1575.8933, Training Accuracy= 0.891
Step 250, Minibatch Loss= 1558.5853, Training Accuracy= 0.891
Step 260, Minibatch Loss= 375.0371, Training Accuracy= 0.922
Step 270, Minibatch Loss= 1568.0758, Training Accuracy= 0.859
Step 280, Minibatch Loss= 1172.9205, Training Accuracy= 0.914
Step 290, Minibatch Loss= 1023.5415, Training Accuracy= 0.914
Step 300, Minibatch Loss= 475.9756, Training Accuracy= 0.945
Step 310, Minibatch Loss= 488.8930, Training Accuracy= 0.961
Step 320, Minibatch Loss= 1105.7720, Training Accuracy= 0.914
Step 330, Minibatch Loss= 1111.8589, Training Accuracy= 0.906
Step 340, Minibatch Loss= 842.7805, Training Accuracy= 0.930
Step 350, Minibatch Loss= 1514.0153, Training Accuracy= 0.914
Step 360, Minibatch Loss= 1722.1812, Training Accuracy= 0.875
Step 370, Minibatch Loss= 681.6041, Training Accuracy= 0.891
Step 380, Minibatch Loss= 902.8599, Training Accuracy= 0.930
Step 390, Minibatch Loss= 714.1541, Training Accuracy= 0.930
Step 400, Minibatch Loss= 1654.8883, Training Accuracy= 0.914
Step 410, Minibatch Loss= 696.6915, Training Accuracy= 0.906
Step 420, Minibatch Loss= 536.7183, Training Accuracy= 0.914
Step 430, Minibatch Loss= 1405.9148, Training Accuracy= 0.891
Step 440, Minibatch Loss= 199.4781, Training Accuracy= 0.953
Step 450, Minibatch Loss= 438.3784, Training Accuracy= 0.938
Step 460, Minibatch Loss= 409.6419, Training Accuracy= 0.969
Step 470, Minibatch Loss= 503.1216, Training Accuracy= 0.930
Step 480, Minibatch Loss= 482.6476, Training Accuracy= 0.922
Step 490, Minibatch Loss= 767.3893, Training Accuracy= 0.922
Step 500, Minibatch Loss= 626.8249, Training Accuracy= 0.930
Time duration: 657 seconds
Optimization Finished!
Testing Accuracy: 0.9453125
Подводя итог, мы только что завершили построение первой сверточной нейронной сети, как видно из результатов выше, точность модели была значительно улучшена от первого шага до последнего шага, но мы все еще много возможностей для улучшения сверточной нейронной сети.
Теперь давайте визуализируем построенную модель сверточной нейронной сети в Tensorboard:
Визуализация сверточных нейронных сетей
Точность и оценка повреждений
в заключении:
Сверточная нейронная сеть — это мощная модель глубокого обучения с широким спектром приложений и отличной производительностью. Использование сверточных нейронных сетей будет становиться все более сложным по мере увеличения объема данных и усложнения проблемы.
Добавить Автора
Для получения более технических галантерейных товаров, пожалуйста, обратите внимание на номер организации Yunqi Community Zhihu:Сообщество Alibaba Cloud Yunqi
Эта статья от «Команды переводчиков», партнера сообщества Yunqi. Если вам нужно перепечатать, пожалуйста, свяжитесь с первоначальным автором.