最近我开始玩神经网络.我试图AND
用Tensorflow 实现一个门.我无法理解何时使用不同的成本和激活功能.这是一个基本的神经网络,只有输入和输出层,没有隐藏层.
首先,我尝试以这种方式实现它.正如您所看到的,这是一个糟糕的实现,但我认为它完成了工作,至少在某种程度上.所以,我只尝试了真正的输出,没有一个真正的输出.对于激活函数,我使用了sigmoid函数,对于成本函数,我使用了平方误差成本函数(我认为它称之为,如果我错了,请纠正我).
我尝试使用ReLU和Softmax作为激活功能(具有相同的成本函数),但它不起作用.我弄清楚他们为什么不工作.我也尝试过使用交叉熵成本函数的sigmoid函数,它也不起作用.
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激活函数,交叉熵作为成本函数.作为激活功能的Sigmoid功能失败.
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我注意到需要多次迭代才能收敛到接近准确的预测.我认为融合率取决于学习率(使用太多会错过解决方案)和成本函数(如果我错了,请纠正我).那么,是否有任何最佳方式(意味着最快)或成本函数来收敛到正确的解决方案?
我将稍微回答您的问题,从更一般的答案开始,然后完成特定于您的特定实验的那些问题.
激活功能事实上,不同的激活功能确实具有不同的属性.我们首先考虑神经网络的两层之间的激活函数.激活函数的唯一目的是作为非线性.如果你没有在两个图层之间放置一个激活函数,那么两个图层将不会比一个更好,因为它们的效果仍然只是一个线性变换.很长一段时间人们使用sigmoid功能和tanh,几乎任意选择,sigmoid更受欢迎,直到最近,当ReLU成为主导的非同一性.人们在层之间使用ReLU的原因是因为它是非饱和的(并且计算速度也更快).考虑一个sigmoid函数的图形.如果绝对值x
很大,则sigmoid函数的导数很小,这意味着当我们向后传播误差时,当我们返回层时,误差的梯度将很快消失.对于ReLU,衍生物适用1
于所有正输入,因此激活单元根本不会改变所发射的神经元的梯度,并且不会减慢梯度下降.
对于网络的最后一层,激活单元也依赖于任务.对于回归,你需要使用sigmoid或tanh激活,因为你希望结果在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
,或使用动量来加快收敛速度,