2016-11-03 29 views
3

我正在尝试使用5个卷积图层的CNN - 2个隐藏图层 - 1个Softmax。如何避免Theano计算渐变朝着NaN

的体系结构是:

cv0->relu->cv1->relu-cv2->relu->cv3->relu->cv4->relu->cv5->hid1->relu->hid2->relu->logistic softmax 

通过施加随机梯度用66个补丁从图像令牌。该训练仅适用于具有20个时期的单个图像用于测试目的。

从网络中可以看出,在每次迭代中误差都是爆炸性的,所以梯度在第四个时期后第二次计算。

  • 划时代1个学习成本:4.702012
  • 划时代2学习成本:45338036.000000
  • 划时代3学习成本:74726722389225987403008805175296.000000
  • 划时代4学习成本:nan

正如你可以看到后该误差被分解为非常高的值,并且传播到所有网络中的梯度产生的南。

看从不同层的权重值的单个节点看看会发生什么:

layer8(SOFTMAX):

  • Intiali值[ 0.05436778 0.02379715]
  • 划时代1 [ 0.28402206 -0.20585714]
  • 划时代2 [ -5.27361184e-02 9.52038541e-02]
  • epoch 3 [-7330.04199219 7330.12011719]
  • 划时代4 [ nan nan]

layer6(HID1):

  • Intiali值[-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309]
  • 划时代1 [-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309]
  • 划时代2 [-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309
  • 划时代3 [ -2.54468974e-02 1.79247314e+16 ..., -5.87915350e-03 2.61985492e-02 -2.06307964e+19]
  • 划时代4 [ nan nan ..., nan nan nan]

层0(CV0):

在初始化是

[[-0.01704694 -0.01683052 -0.0894756 ] 
[ 0.12275343 -0.05518051 -0.09202443] 
[-0.11599202 -0.04718829 -0.04359322]] 

,而在第三时期是

[[-24165.15234375 -26490.89257812 -24820.1484375 ] 
[-27381.8203125 -26653.3359375 -24762.28710938] 
[-23120.56835938 -21189.44921875 -24513.65039062]] 

很显然,权重值是爆炸。

学习率为0.01所以为了解决这个问题,我把学习率改为0。001和Nan有时会消失,网络会聚,有时甚至不会,并且网络与NaN饱和。再次用0.0001尝试较小的学习率,但我还没有看到NaN。我从我有充分的时间我的结果看重新运行该代码的结果是真的不同,我认为这是摆在首位的权重初始化相关。

所以我尝试了不同的权重初始化:

的转化率层RELU

W_bound_6 = numpy.sqrt(6./(fan_in + fan_out)) 
W_bound_2 = numpy.sqrt(2./(fan_in + fan_out)) 
W_values = numpy.asarray(
       numpy.random.randn(filter_shape[0], filter_shape[1], filter_shape[2], filter_shape[3]) * W_bound_2, 
       dtype=theano.config.floatX) 

和隐层和softamx层

W_bound_2 = numpy.sqrt(2./(filter_shape[0] + filter_shape[1])) 
W_values = numpy.asarray(
       numpy.random.randn(filter_shape[0], filter_shape[1]) * W_bound_2, 
       dtype=theano.config.floatX 
      ) 

并启动B中的所有为零。

的差别并不大,我仍然没有看到的结果不同。

我在这里张贴了我的问题:

  • disccuess如果我在做什么关于权重初始化 正确与编码
  • ,看看我们是否我能避免学习率非常小,至少在前几次迭代时保持高位,因为在我的情况下,它在第四次迭代中传播了Nan。
  • 我想知道的是L1,L2正因为我使用Theano我应该在哪里实施成本函数的代码或我应该改变的更新功能。

成本函数

-T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y]) 

更新功能

updates = [ 
     (param_i, param_i - learning_rate * grad_i) 
     for param_i, grad_i in zip(classifier.params, grads) 
    ] 
  • 它是纠正我的结构RELU实现每一层之后,但不是在SOFTMAX?
+0

我对CNN并不了解很多,但是您是否尝试过修剪渐变?在某些时候,你可能有'grads = T.grad(cost,classifier.params)'。尝试使用'grads_clipped = [T.clip(g,-2,2] for g in grads')添加一个新行,并用'grads_clipped'替换zip内的'grads',即zip(classifier.params ,grads_clipped)' –

+0

我已经看到这项工作提议在谷歌组,以避免梯度爆炸。我不记得究竟是什么讨论,如果它是好技术或不。 – Feras

+1

值得一试。关于L1,L2正规化,你可以在损失函数的结尾贴上它:cost = -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape [0]),y] + L1 + L2)' –

回答

2

我一直在寻找到不同的方法来避免这个问题,但找别人提出一个正式的解决方案,并阅读一些理论框架解决方案,我会在这里写我的答案,以帮助有同样的问题等。

这个问题背后的原因是使用SOFTMAX和crossentropy。所以当你计算梯度和潜水的零或inf你越来越南传播backword扔所有网络参数。

几个建议,如果错误开始,然后增加NaN的出现之后,以避免这个问题

  • :发散由于 过高学习率
  • 如果NaN的突然出现:饱和单位产生不可微 梯度的NaN由于log(0)
  • NaN由于浮点问题(对于高权重)或激活 输出0/0,inf/inf,inf *权重...

解决方案:

  1. 降低学习速度
  2. 更改权重初始化
  3. 使用L2标准
  4. 安全SOFTMAX(小值添加到日志(X))
  5. 梯度裁剪

在我的情况下学习率解决了这个问题,但我仍然在努力优化e更多

0

我想这可能是导致数学错误的“死亡relu”问题。负对数似然成本函数会引起不期望为零的自然对数计算。 Relu函数可以输出零,并且零的自然对数被定义,因此它返回NaN。在最后一层尝试使用不输出负数和零的函数,或尝试另一个成本函数。

+0

负对数似然将计算它在softmax的概率分布上的梯度,所以我不认为它是一个死的Relu。问题是传播inf并在所有网络中产生NaN的高成本错误。 – Feras