предисловие
В последнем примечании мы использовали набор данных MNIST для обучения модели распознавания рукописных цифр, но уровень точности очень низкий, поддерживается на уровне около 91%, мы можем попытаться увеличить уровень точности до более чем 96%, нам нужно Разберитесь перед экспериментом Некоторые основные понятия, эта статья может быть немного скучной, потому что большинство из них являются теоретическими знаниями.
В центре внимания этой статьи
- функция активации
- функция стоимости
- соответствовать
Что такое активационная функция? Для чего нужна функция активации?
Чтобы понять, что такое функция активации, вы должны сначала понять базовую модель нейронной сети, На следующем рисунке показана базовая модель одной искусственной нейронной сети:
Каждый нейронный узел в нейронной сети принимает выходное значение предыдущего слоя нейронов в качестве входного значения этого нейрона и передает входное значение следующему слою, а узел нейрона входного слоя будет напрямую передавать значение входного атрибута в следующий слой Один слой (скрытый или выходной). В многослойной нейронной сети существует функциональная связь между выходом верхнего узла и входом нижнего узла, которая называется функцией активации (также известной как функция активации).
Если бы мы не использовали функцию активации, выходной сигнал был бы простой линейной функцией. Линейная функция является полиномом первого порядка. В наши дни линейные уравнения легко решать, но они имеют ограниченную сложность и меньше возможностей для изучения сложных отображений функций на основе данных. Нейронная сеть без функции активации была бы не чем иным, как моделью линейной регрессии, которая имеет ограниченную мощность и большую часть времени работает плохо. Мы хотим, чтобы наша нейронная сеть не только обучалась и вычисляла линейные функции, но и была намного сложнее. Также потому, что без функции активации наша нейронная сеть не сможет изучать и моделировать другие сложные типы данных, такие как изображения, видео, аудио, речь и т. д. Вот почему мы используем методы искусственных нейронных сетей, такие как глубокое обучение, чтобы понять некоторые сложные вещи, некоторые нелинейные проблемы со многими скрытыми слоями между собой, и это также может помочь нам понять сложные данные.
Так зачем же нам нужны нелинейные функции?
Нелинейные функции — это функции выше одного порядка, и они имеют кривизну при построении графика. Теперь нам нужна модель нейронной сети, которая может обучаться и представлять почти что угодно, и сколь угодно сложная функция, которая может отображать входные данные в выходные данные. Нейронные сети считаются аппроксиматорами универсальных функций. Это означает, что они могут вычислить и изучить любую функцию. Почти любой процесс, о котором мы можем думать, может быть представлен как вычисление функции в нейронной сети.
И все сводится к тому, что нам нужно применить функцию активации f(x), чтобы сделать сеть более мощной, повысить ее способность изучать сложные вещи, данные сложной формы и представлять невмешательство между входными и output Линейное комплексное отображение произвольных функций. Следовательно, используя нелинейную функцию активации, мы можем генерировать нелинейные отображения от входа к выходу.
Другая важная особенность функции активации состоит в том, что она должна быть различимой. Нам нужно сделать это, чтобы выполнить стратегию обратной оптимизации при продвижении назад в сети, чтобы вычислить градиент ошибки (потери) по отношению к весам, а затем оптимизировать веса соответственно, чтобы уменьшить ошибку, используя градиентный спуск или любую другую оптимизацию. техника.
квадратичная функция стоимости
Формула квадратичной функции стоимости выглядит следующим образом:
Среди них C представляет стоимость, x представляет образец, y представляет фактическое значение, a представляет выходное значение, а n представляет общее количество образцов. Для простоты возьмем образец в качестве примера для иллюстрации, в настоящее время квадратичная функция стоимости:
в,это функция активации
Добавьте, что мы используем метод градиентного спуска для настройки размера параметра веса, градиент веса w и смещения b получаются следующим образом:
где z представляет собой вход в нейрон,представляет функцию активации. Из приведенной выше формулы видно, что градиенты w и b пропорциональны градиенту функции активации, и чем больше градиент функции активации,иЧем быстрее вы настраиваете размер , тем быстрее сходится обучение. Функция активации, обычно используемая в нейронных сетях, имеет видсигмовидная функция, кривая функции выглядит так:
Таким образом, в этом случае изменения весов и смещений будут аномальными следующим образом:
Предположим, наша цель — сойтись к 1. Точка 0,82 далека от цели, градиент относительно велик, а корректировка веса относительно велика. Точка B составляет 0,98, что относительно близко к цели, градиент относительно мал, а корректировка веса относительно невелика. План корректировки разумный. Если нашей целью является сходимость к 0. Точка А равна 0,82, она относительно близка к цели, градиент относительно велик, а корректировка веса относительно велика. Точка B составляет 0,98, далеко от цели, градиент относительно мал, а регулировка веса относительно невелика. План корректировки необоснован.
Тогда некоторые люди могут сказать, что если мы хотим решить вышеупомянутую проблему, разве это не решит проблему, выбрав функцию активации, градиент которой не меняется или изменяется незначительно? Шаблон нарушен, поэтому, хотя эта проблема решается просто и грубо, она может вызвать другие, более неприятные проблемы. Кроме того, такие функции, как сигмоид (например, функция tanh), имеют много преимуществ и очень подходят для функций активации.Пожалуйста, гуглите их для деталей.
Здесь мы не меняем функцию активации и решили изменить функцию стоимости на функцию кросс-энтропийной стоимости.
Кросс-энтропийная функция стоимости
Сначала поставьте формулу: ?C=-\frac{1}{n}\sum_{x}^{ }[ylna+(1-y)ln(1-a)]? Среди них C представляет стоимость, x представляет образец, y представляет фактическое значение, a представляет выходное значение, а n представляет общее количество образцов. Затем пересчитайте градиент параметра w:
Где: ? {\ сигма} '(z) = \ сигма (z) (1- \ сигма (z))? Следовательно, исходная формула для градиента wисключается, кроме того, в формуле градиентаУказывает на расхождение между выходным значением и фактическим значением. Таким образом, когда ошибка больше, градиент больше, чем быстрее регулируется параметр w, тем выше скорость обучения. Точно так же градиент b:
Реальная ситуация показала, что эффект обучения, вызванный функцией стоимости кросс-энтропии, часто лучше, чем эффект квадратичной функции стоимости.
- Регулировка весов и смещений такая же, какне имеет значения, кроме того, в формуле градиентаУказывает на расхождение между выходным значением и фактическим значением. Таким образом, когда ошибка больше, градиент больше, параметры w и b настраиваются быстрее, а скорость обучения выше.
- Если выходной нейрон является линейным, то подходящим выбором является квадратичная функция стоимости. Если выходной нейрон представляет собой сигмовидную функцию, то более подходящим является использование кросс-энтропийной функции стоимости.
логарифмическая стоимость правдоподобия
- Логарифмическая функция рельефа часто используется в качестве функции стоимости регрессии softmax, а затем нейроны выходного слоя представляют собой сигмоидальные функции, которые могут использовать функцию стоимости перекрестной энтропии. Более распространенной практикой в глубоком обучении является использование softmax в качестве последнего слоя, а обычно используемой функцией стоимости в настоящее время является логарифмическая функция стоимости облегчения.
- Функция стоимости логарифмического правдоподобия в сочетании с softmax и кросс-энтропия в сочетании с сигмовидной функцией очень похожи. Функция стоимости логарифмического рельефа может быть упрощена до формы кросс-энтропийной функции стоимости в бинарной классификации. В тензорном потоке используйте:
tf.nn.sigmoid_cross_entropy_with_logits()来表示跟sigmoid搭配使用的交叉熵。
tf.nn.softmax_cross_entropy_with_logits()来表示跟softmax搭配使用的交叉熵。
Сравнение эффектов двух функций стоимости с использованием TensorFlow
В качестве примера можно привести модель распознавания рукописных цифр из предыдущей статьи Вот код модели, использующей кросс-энтропийную функцию:
import datetime
# 4.1 交叉熵代价函数
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
start = datetime.datetime.now()
# 载入数据
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
# 每个批次的大小
batch_size = 50
# 计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size
# 定义两个placeholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
# 创建一个简单的神经网络
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x, W)+b)
# 二次代价函数
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
# 结果存放在一个布尔型列表中
# argmax返回一维张量中最大的值所在的位置
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
# 求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(30):
for batch in range(n_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys})
acc = sess.run(accuracy, feed_dict={
x: mnist.test.images, y: mnist.test.labels})
print("Iter "+str(epoch)+",Testing Accuracy "+str(acc))
end = datetime.datetime.now()
print((end-start).seconds)
Здесь мы меняем квадратичную функцию стоимости на кросс-энтропийную функцию стоимости:
# 二次代价函数
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
Далее сравним результаты обучения:
Как видно из приведенного выше рисунка, точность использования квадратичной функции стоимости для обучения в 10-й раз составляет 0,9063, а точность использования кросс-энтропийной функции стоимости для обучения во второй раз превысила 0,9, а результат очевидно.
соответствовать
Существует три типа подгонки: 1. Недоподгонка, 2. В самый раз, 3. Переподгонка, как показано на следующем рисунке:
каждый из нихx
представляет образец, а каждая кривая представляет модель.
На рисунке ниже показана подходящая ситуация в задаче классификации, аналогичной приведенной выше.
Здесь вводится подгонка, а ниже приводится объяснение Википедии для переобучения. В статистике и машинном обучении Overfitting обычно используется при описании случайных ошибок или шума статистической модели. Обычно это происходит, когда модель слишком сложна, например, с избыточными параметрами. Переобучение ослабляет прогностическую эффективность модели и увеличивает волатильность данных.
Переобучение происходит из-за того, что критерии оценки обученной модели не подходят в качестве критерия оценки качества модели, а модель обычно повышает прогностическую эффективность модели во время обучения модели. Но производительность модели не определяется производительностью модели на обучающем наборе, она определяется производительностью модели на неизвестном наборе данных. Переобучение происходит, когда модель начинает «запоминать» обучающие данные вместо того, чтобы «учиться» на них. Например, если параметры модели больше или равны количеству наблюдений, эта модель будет казаться слишком простой.Хотя модель может отлично работать во время обучения, она в основном запоминает все характеристики данных, но эта модель производительность на неизвестных данных будет сильно снижена, потому что способность простых моделей к обобщению обычно очень слаба.
На приведенном выше рисунке эти точки данных соответствуют линейной функции и полиномиальной функции, Очевидно, что полиномиальная функция идеально подходит, включая все точки, в то время как линейная функция теряет большинство точек. Но на самом деле линейные функции обладают хорошей способностью к обобщению, и если вы используете эти точки для построения линии регрессии, ситуация переобучения полиномиальной функции становится еще хуже.
Переоснащение связано не только с количеством параметров и данных, но и с согласованностью структуры модели формы данных.
Чтобы избежать переобучения, необходимо использовать некоторые дополнительные методы (такие как перекрестная проверка, регуляризация, ранняя остановка, информационный критерий Басса, информационный критерий Акаике или сравнение моделей), чтобы указать, когда будет больше обучения, не вызывая лучшего обобщения.
Концепция переобучения важна в машинном обучении. Обычно алгоритм обучения обучается на обучающих выборках, что при обучении будет сопровождаться ошибкой обучения. Когда модель тестируется на неизвестных данных, соответственно будет выдана ошибка проверки. Ниже приводится подробный анализ переобучения из-за ошибки обучения и ошибки проверки. Как показано ниже:
На рисунке выше синий цвет представляет ошибку обучения, а красный — ошибку проверки. Когда ошибка обучения достигает точки вертикальной линии посередине, модель должна быть оптимальной.Если вы продолжите уменьшать ошибку обучения модели, произойдет переоснащение.
На самом деле переоснащение можно понять таким образом: информация в наборе данных разделена на две части, одна часть — это данные, относящиеся к прогнозированию будущих данных, а другая часть не имеет значения, и статус двух равен. Чем менее точен критерий, используемый в качестве прогноза, тем больше зашумленных данных и тем больше данных необходимо игнорировать, и ключевой момент заключается в том, какую часть следует игнорировать. Поэтому мы называем способность алгоритма обучения уменьшать шум его надежностью. Нам нужен надежный алгоритм обучения
В качестве простого примера, база данных розничных покупок включает в себя купленные товары, тех, кто купил, дату и время покупки. На основе этих данных можно легко создать модель, и эффект подгонки на обучающем наборе будет очень хорошим.Используя дату и время покупки для прогнозирования значений других столбцов атрибутов, способность этой модели к обобщению новые данные очень высокие. Слабые, потому что эти прошлые данные больше не повторятся.
Несколько способов предотвратить переоснащение
Рекомендуем прочитать здесьКакие методы используются в машинном обучении для предотвращения переобучения?, сказал более подробно.
- добавить набор данных Ваша модель может хранить много информации, а это означает, что чем больше обучающих данных вы вводите в модель, тем меньше вероятность того, что она будет соответствовать модели. Причина в том, что по мере добавления новых данных модель не может соответствовать всем образцам данных и вынуждена обобщать, чтобы добиться прогресса. Сбор большего количества выборок данных должен быть первым шагом в любой задаче по науке о данных.Больше данных сделает модель более точной, что также снизит вероятность переобучения.
Это делает нейронную сеть утомительной и повторяющейся, потому что она больше не может полагаться на определенные нейроны или соединения для извлечения определенных признаков. После завершения обучения модели все нейроны и связи будут сохранены. Эксперименты показывают, что этот метод может иметь тот же эффект, что и метод ансамбля нейронных сетей, что может помочь обобщить модель, что может уменьшить проблему переобучения.
Давайте испытаем отсев с кодом:
import datetime
# 4.2 Dropout
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
start = datetime.datetime.now()
# 载入数据
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
# 每个批次的大小
batch_size = 50
# 计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size
# 定义两个placeholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
# 创建一个神经网络
W1 = tf.Variable(tf.truncated_normal([784, 2000], stddev=0.1))
b1 = tf.Variable(tf.zeros([2000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x, W1)+b1)
L1_drop = tf.nn.dropout(L1, keep_prob)
W2 = tf.Variable(tf.truncated_normal([2000, 2000], stddev=0.1))
b2 = tf.Variable(tf.zeros([2000])+0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop, W2)+b2)
L2_drop = tf.nn.dropout(L2, keep_prob)
W3 = tf.Variable(tf.truncated_normal([2000, 1000], stddev=0.1))
b3 = tf.Variable(tf.zeros([1000])+0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop, W3)+b3)
L3_drop = tf.nn.dropout(L3, keep_prob)
W4 = tf.Variable(tf.truncated_normal([1000, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10])+0.1)
prediction = tf.nn.softmax(tf.matmul(L3_drop, W4)+b4)
# 二次代价函数
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
# 结果存放在一个布尔型列表中
# argmax返回一维张量中最大的值所在的位置
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
# 求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(20):
for batch in range(n_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={
x: batch_xs, y: batch_ys, keep_prob: 1.0})
test_acc = sess.run(accuracy, feed_dict={
x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
train_acc = sess.run(accuracy, feed_dict={
x: mnist.train.images, y: mnist.train.labels, keep_prob: 1.0})
print("Iter "+str(epoch)+",Testing Accuracy " +
str(test_acc)+",Train Accuracy"+str(train_acc))
end = datetime.datetime.now()
print((end-start).seconds)
По сравнению с предыдущим кодом мы изменили следующие места:
W1 = tf.Variable(tf.truncated_normal([784, 2000], stddev=0.1))
b1 = tf.Variable(tf.zeros([2000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x, W1)+b1)
L1_drop = tf.nn.dropout(L1, keep_prob)
W2 = tf.Variable(tf.truncated_normal([2000, 2000], stddev=0.1))
b2 = tf.Variable(tf.zeros([2000])+0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop, W2)+b2)
L2_drop = tf.nn.dropout(L2, keep_prob)
W3 = tf.Variable(tf.truncated_normal([2000, 1000], stddev=0.1))
b3 = tf.Variable(tf.zeros([1000])+0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop, W3)+b3)
L3_drop = tf.nn.dropout(L3, keep_prob)
W4 = tf.Variable(tf.truncated_normal([1000, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10])+0.1)
prediction = tf.nn.softmax(tf.matmul(L3_drop, W4)+b4)
Я добавил в нейронную сеть два дополнительных скрытых слоя.Чтобы легко отразить разницу, я установил большее количество нейронов в каждом скрытом слое. Затем во время тренировки,
for epoch in range(10):
for batch in range(n_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={
x: batch_xs, y: batch_ys, keep_prob: 1.0})
test_acc = sess.run(accuracy, feed_dict={
x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
train_acc = sess.run(accuracy, feed_dict={
x: mnist.train.images, y: mnist.train.labels, keep_prob: 1.0})
print("Iter "+str(epoch)+",Testing Accuracy " +
str(test_acc)+",Train Accuracy"+str(train_acc))
вkeep_prob
Указывает процент включенных нейронов от общего числа нейронов (1,0 означает, что все используются),train_acc
Указывает, что обучающие выборки используются для проверки точности обученной модели.test_acc
Указывает, что тестовые образцы используются для проверки точности обученной модели, а эти два данных используются для отражения степени соответствия. Результаты обучения представлены на следующем рисунке:
Суммировать
В этой статье для повышения точности вводится понятие функции стоимости, чтобы лучше понять функцию стоимости, что такое функция активации и зачем функция активации нужна заранее. Изменяя функцию стоимости при использовании только одного слоя нейронной сети, можно добиться точности около 93% (при большом количестве раз обучения), но этого недостаточно, поэтому пробуем добавить еще несколько слоев нейронов, но на этот раз это будет Появилась новая проблема «переобучения», и обычно есть три способа решить проблему переобучения. В последующих статьях будут представлены следующие оптимизаторы на этой основе и рассказано, как использовать бесплатную службу графического процессора Google для ускорения обучения модели глубокого обучения.