如何防止懒惰的卷积神经网络?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止懒惰的卷积神经网络?相关的知识,希望对你有一定的参考价值。

如何防止懒惰的卷积神经网络?在用KERAS训练之后,我以'懒惰的CNN'结束。无论输入是什么,输出都是恒定的。您认为问题是什么?

我尝试重复NVIDIA的自动驾驶汽车the paper的端到端学习实验。当然,我没有真正的汽车,而是Udacity的simulator。模拟器生成有关汽车前景的数据。

enter image description here

CNN接收该图,并给出转向角以使汽车保持在轨道中。游戏规则是让模拟赛车安全地在赛道上运行。这不是很困难。

奇怪的是,有时候我会用KERAS训练懒惰的CNN结束,这会给出恒定的转向角度。模拟汽车将脱离技巧,但CNN的输出没有变化。特别是该层变得更深,例如在the paper的CNN。

如果我使用这样的CNN,我可以在训练后得到一个有用的模型。

model = Sequential()
model.add(Lambda(lambda x: x/255.0 - 0.5, input_shape = (160,320,3)))
model.add(Cropping2D(cropping=((70,25),(0,0))))
model.add(Conv2D(24, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(36, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(48, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dense(10))
model.add(Activation('sigmoid'))
model.add(Dense(1))

但是,如果我使用更深的CNN,我有更多机会接收懒惰的CNN。具体来说,如果我使用喜欢NVIDIA的CNN,我每次训练后都会收到懒惰的CNN。

model = Sequential()
model.add(Lambda(lambda x: x/255.0 - 0.5, input_shape = (160,320,3)))
model.add(Cropping2D(cropping=((70,25),(0,0))))
model.add(Conv2D(24, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(36, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(48, 5, strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(64, 3, strides=(1, 1)))
model.add(Activation('relu'))
model.add(Conv2D(64, 3, strides=(1, 1)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(1164))
model.add(Activation('sigmoid'))
model.add(Dense(100))
model.add(Activation('sigmoid'))
model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dense(10))
model.add(Activation('sigmoid'))
model.add(Dense(1))

我使用'relu'作为卷积层,完全连接层的激活函数是'sigmoid'。我尝试更改激活功能,但没有效果。

有我的分析。我不同意我的程序中的错误,因为我可以使用相同的代码和更简单的CNN成功驾驶汽车。我认为原因是模拟器或神经网络的结构。在真正的自动驾驶汽车中,训练信号即转向角应包含噪音;因此,驾驶员永远不会将车轮保持在真正的道路上。但在模拟器中,训练信号非常干净。几乎60%的转向角为零。优化器可以通过将CNN的输出接近零来轻松完成工作。似乎优化器也很懒惰。但是,当我们真的想要这个CNN输出时,它也会给出零。因此,我为这些零转向角添加了小噪音。我得到一个懒惰的CNN的机会较小,但它并没有消失。

您如何看待我的分析?我可以使用其他策略吗?我想知道在CNN研究的悠久历史中是否已经解决了类似的问题。

资源:

相关文件已上传至GitHub。您可以使用这些文件重复整个实验。

答案

我无法运行您的模型,因为GitHub repo的问题都不包含数据。这就是为什么我90%肯定我的答案。

但我认为你的网络的主要问题是密集层之后的sigmoid激活功能。我认为,当只有两个时,它会很好地训练,但是四个太多了。

不幸的是,NVidia的End to End Learning for Self-Driving Cars论文没有明确指出,但是现在默认激活不再是sigmoid(就像以前一样),而是relu。如果您对此感兴趣,请参阅this discussion。所以我建议的解决方案是尝试这个模型:

model = Sequential()
model.add(Lambda(lambda x: x/255.0 - 0.5, input_shape = (160,320,3)))
model.add(Cropping2D(cropping=((70,25),(0,0))))
model.add(Conv2D(24, (5, 5), strides=(2, 2), activation="relu"))
model.add(Conv2D(36, (5, 5), strides=(2, 2), activation="relu"))
model.add(Conv2D(48, (5, 5), strides=(2, 2), activation="relu"))
model.add(Conv2D(64, (3, 3), strides=(1, 1), activation="relu"))
model.add(Conv2D(64, (3, 3), strides=(1, 1), activation="relu"))
model.add(Flatten())
model.add(Dense(1164, activation="relu"))
model.add(Dense(100, activation="relu"))
model.add(Dense(50, activation="relu"))
model.add(Dense(10, activation="relu"))
model.add(Dense(1))

它模仿NVidia的网络架构,不会受到消失的渐变的影响。

以上是关于如何防止懒惰的卷积神经网络?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止在背面片段导航上再次设置视图模型

在 IOS 中,如何乱序播放音频片段的一部分?

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

深度卷积生成对抗网络(DCGAN)简介及图像生成仿真(附代码)

防止 Hibernate 加载懒惰的 ManyToOne