从神经网络的不同成本函数和激活函数中进行选择
machine-learning
neural-network
python
svm
6
0

最近,我开始玩弄神经网络。我正在尝试使用Tensorflow实现AND门。我无法理解何时使用不同的费用和激活功能。这是一个基本的神经网络,只有输入和输出层,没有隐藏层。

首先,我尝试以这种方式实现它。如您所见,这是一个较差的实现,但我认为它至少可以以某种方式完成工作。因此,我只尝试了真实的输出,没有人尝试过真实的输出。对于激活函数,我使用了S型函数,对于成本函数,我使用了平方误差成本函数(我认为是这样,如果我错了,请更正我)。

我已经尝试过使用ReLU和Softmax作为激活函数(具有相同的cost函数),但是它不起作用。我弄清楚了为什么它们不起作用。我还尝试了使用交叉熵成本函数的S型函数,它也无法正常工作。

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我注意到,要收敛到接近准确的预测需要花费很多迭代。我认为融合率取决于学习率(使用太多会丢失解决方案)和成本函数(如果我错了,请纠正我)。那么,有没有最佳方法(意味着最快)或成本函数收敛到正确的解决方案?

参考资料:
Stack Overflow
收藏
评论
共 1 个回答
高赞 时间 活跃

我将以较笼统的答案开始,最后以针对您特定实验的问题为答案,以一点点的顺序回答您的问题。

激活功能实际上,不同的激活功能确实具有不同的属性。首先让我们考虑神经网络两层之间的激活函数。激活函数的唯一目的是充当非线性。如果您没有在两层之间放置激活函数,那么两层在一起将不会比一层更好,因为它们的效果仍然只是线性变换。在很长一段时间里,人们一直在使用S形函数和tanh,随心所欲地选择S形函数,直到最近,ReLU成为主要的非宽容度。人们在各层之间使用ReLU的原因是因为它不饱和(并且计算速度也更快)。考虑一下S形函数图。如果x的绝对值大,则S型函数的导数就小,这意味着当我们向后传播误差时,误差的梯度将在我们返回图层时迅速消失。使用ReLU时,所有正输入的导数均为1 ,因此,被激活的那些神经元的梯度不会被激活单元完全改变,也不会减慢梯度下降的速度。

对于网络的最后一层,激活单元还取决于任务。对于回归,您将需要使用S型或tanh激活,因为您希望结果在0到1之间。对于分类,您将只希望输出之一为1,其他所有零,但是没有可实现的不同方法正是这样,所以您将需要使用softmax对其进行近似。

你的例子 。现在让我们看一下您的示例。您的第一个示例尝试以以下形式计算AND的输出:

sigmoid(W1 * x1 + W2 * x2 + B)

请注意, W1W2将始终收敛到相同的值,因为( x1x2 )的输出应等于( x2x1 )的输出。因此,您适合的模型是:

sigmoid(W * (x1 + x2) + B)

x1 + x2只能取三个值(0、1或2)之一,对于x1 + x2 < 2的情况,您想返回0对于x1 + x2 = 2的情况,您想返回1。由于S形函数相当平滑,因此将需要非常大的WB值才能使输出接近所需值,但是由于学习率较低,因此它们无法快速达到较大的值。在您的第一个示例中,提高学习速度将提高收敛速度。

您的第二个示例收敛得更好,因为softmax函数擅长使一个输出等于1而所有其他输出等于0 。由于这正是您的情况,因此确实可以迅速收敛。请注意, sigmoid最终也将收敛为良好的值,但是它将需要更多的迭代(或更高的学习率)。

使用什么 。现在到最后一个问题,如何选择要使用的激活和成本函数。这些建议适用于大多数情况:

  1. 如果进行分类,则将softmax用于最后一层的非线性和cross entropy作为成本函数。

  2. 如果进行回归,则将sigmoidtanh用于最后一层的非线性和squared error作为成本函数。

  3. 将ReLU用作图层之间的非线性。

  4. 使用更好的优化器( AdamOptimizerAdagradOptimizer )代替GradientDescentOptimizer ,或使用动量来加快收敛速度,

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号