Выбор из другой функции стоимости и функции активации нейронной сети
Недавно я начал заниматься нейронными сетями. Я пытался реализовать затворы AND
с Tensorflow. У меня возникли проблемы с пониманием того, когда использовать разные функции затрат и активации. Это базовая нейронная сеть с только входными и выходными уровнями, без скрытых слоев.
Сначала я попытался реализовать его таким образом. Как вы видите, это плохая реализация, но я думаю, что она выполняет свою работу, по крайней мере, в некотором роде. Итак, я пробовал только реальные выходы, ни одного горячего истинного выхода. Для функций активации я использовал сигмоидную функцию, а для функции стоимости я использовал функцию вычисления квадратов ошибок (я думаю, ее называли так, исправьте меня, если я ошибаюсь).
Я пытался использовать ReLU и Softmax в качестве функций активации (с той же функцией стоимости), и это не работает. Я понял, почему они не работают. Я также попробовал сигмоидную функцию с функцией стоимости Cross Entropy, она также не работает.
import tensorflow as tf
import numpy
train_X = numpy.asarray([[0,0],[0,1],[1,0],[1,1]])
train_Y = numpy.asarray([[0],[0],[0],[1]])
x = tf.placeholder("float",[None, 2])
y = tf.placeholder("float",[None, 1])
W = tf.Variable(tf.zeros([2, 1]))
b = tf.Variable(tf.zeros([1, 1]))
activation = tf.nn.sigmoid(tf.matmul(x, W)+b)
cost = tf.reduce_sum(tf.square(activation - y))/4
optimizer = tf.train.GradientDescentOptimizer(.1).minimize(cost)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
for i in range(5000):
train_data = sess.run(optimizer, feed_dict={x: train_X, y: train_Y})
result = sess.run(activation, feed_dict={x:train_X})
print(result)
после 5000 итераций:
[[ 0.0031316 ]
[ 0.12012422]
[ 0.12012422]
[ 0.85576665]]
Вопрос 1. Есть ли какая-либо другая функция активации и функция стоимости, которая может работать (учиться) для вышеуказанной сети, не изменяя параметры (что означает без изменения W, x, b).
Вопрос 2 - я прочитал из сообщения StackOverflow здесь:
[Функция активации] зависит от проблемы.
Таким образом, нет никаких функций затрат, которые можно использовать где угодно? Я имею в виду, что нет стандартной функции стоимости, которая может использоваться в любой нейронной сети. Правильно? Пожалуйста, поправьте меня на это.
Я также реализовал ворота AND
с другим подходом, причем выход был как один горячий. Как видите, train_Y
[1,0]
означает, что 0-й индекс равен 1, поэтому ответ равен 0. Надеюсь, вы его получите.
Здесь я использовал функцию активации softmax, с кросс-энтропией как функцию стоимости. Сигмоидная функция как функция активации терпит неудачу.
import tensorflow as tf
import numpy
train_X = numpy.asarray([[0,0],[0,1],[1,0],[1,1]])
train_Y = numpy.asarray([[1,0],[1,0],[1,0],[0,1]])
x = tf.placeholder("float",[None, 2])
y = tf.placeholder("float",[None, 2])
W = tf.Variable(tf.zeros([2, 2]))
b = tf.Variable(tf.zeros([2]))
activation = tf.nn.softmax(tf.matmul(x, W)+b)
cost = -tf.reduce_sum(y*tf.log(activation))
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cost)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
for i in range(5000):
train_data = sess.run(optimizer, feed_dict={x: train_X, y: train_Y})
result = sess.run(activation, feed_dict={x:train_X})
print(result)
после 5000 итераций
[[ 1.00000000e+00 1.41971401e-09]
[ 9.98996437e-01 1.00352429e-03]
[ 9.98996437e-01 1.00352429e-03]
[ 1.40495342e-03 9.98595059e-01]]
Вопрос 3. В этом случае, какую функцию затрат и функцию активации я могу использовать? Как я понимаю, какой тип затрат и функций активации я должен использовать? Есть ли стандартный способ или правило или просто опыт? Должен ли я попытаться выполнить все затраты и активировать функцию в грубой форме? Я нашел ответ здесь. Но я надеюсь на более подробное объяснение.
Вопрос 4 Я заметил, что для сближения с почти точным предсказанием требуется много итераций. Я думаю, что скорость конвергенции зависит от скорости обучения (с использованием слишком большого количества пропущенных решений) и функции стоимости (исправьте меня, если я ошибаюсь). Итак, есть ли оптимальный способ (что означает самая быстрая) или функция стоимости для перехода к правильному решению?
Ответы
Ответ 1
Я отвечу на ваши вопросы немного не по порядку, начиная с более общих ответов и заканчивая тем, которые специфичны для вашего конкретного эксперимента.
Функции активации. Различные функции активации фактически имеют разные свойства. Сначала рассмотрим функцию активации между двумя слоями нейронной сети. Единственная цель функции активации - служить нелинейностью. Если вы не поместите функцию активации между двумя слоями, то два слоя вместе будут служить не лучше, чем один, потому что их эффект по-прежнему будет всего лишь линейным преобразованием. Долгое время люди использовали сигмоидную функцию и tanh, выбирая довольно много произвольно, причем сигмоид стал более популярным, до недавнего времени, когда ReLU стала доминирующей несладкостью. Причина, по которой люди используют ReLU между слоями, состоит в том, что она не насыщается (а также быстрее вычисляется). Подумайте о графике сигмовидной функции. Если абсолютное значение x
велико, то производная от сигмоидной функции мала, а это означает, что при распространении ошибки назад градиент ошибки будет исчезать очень быстро, когда мы возвращаемся через слои. С ReLU производная 1
для всех положительных входов, поэтому градиент для тех нейронов, которые стреляли, не будет полностью изменен блоком активации и не замедлит спуск градиента.
Для последнего слоя сети блок активации также зависит от задачи. Для регрессии вы захотите использовать сигмоидную или танную активацию, потому что вы хотите, чтобы результат находился между 0 и 1. Для классификации вам нужно, чтобы только один из ваших выходов был одним и всеми другими нулями, но нет никакого дифференцируемого способа достижения именно это, поэтому вы захотите использовать softmax для его приближения.
Ваш пример. Теперь посмотрим на ваш пример. В первом примере мы попытаемся вычислить вывод AND
в следующем виде:
sigmoid(W1 * x1 + W2 * x2 + B)
Обратите внимание, что W1
и W2
всегда будут сходиться к одному значению, потому что вывод для (x1
, x2
) должен быть равен выходу (x2
, x1
). Поэтому подходящая модель:
sigmoid(W * (x1 + x2) + B)
x1 + x2
может принимать только одно из трех значений (0, 1 или 2), и вы хотите вернуть 0
для случая, когда x1 + x2 < 2
и 1 для случая, когда x1 + x2 = 2
. Поскольку сигмоидальная функция довольно гладкая, для получения результата близки к желаемому, очень большие значения W
и B
, но из-за небольшой скорости обучения они не могут быстро добраться до этих больших значений. Увеличение скорости обучения в вашем первом примере увеличит скорость конвергенции.
Второй пример сходится лучше, потому что функция softmax
хороша в том, чтобы точно один выход был равен 1
, а все остальные - 0
. Поскольку это именно ваш случай, он быстро сходится. Обратите внимание, что sigmoid
также со временем будет сходиться к хорошим значениям, но для этого потребуется значительно больше итераций (или более высокая скорость обучения).
Что использовать. Теперь к последнему вопросу, как выбрать, какие функции активации и стоимости использовать. Эти советы будут работать в большинстве случаев:
-
Если вы классифицируете, используйте softmax
для нелинейности последнего слоя и cross entropy
как функцию стоимости.
-
Если вы выполняете регрессию, используйте sigmoid
или tanh
для нелинейности последнего слоя и squared error
как функцию стоимости.
-
Используйте ReLU как неличность между слоями.
-
Используйте лучшие оптимизаторы (AdamOptimizer
, AdagradOptimizer
) вместо GradientDescentOptimizer
или используйте импульс для более быстрой сходимости,