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

如何防止卷积神经网络变得懒惰?我在使用KERAS训练后得到一个“懒惰的CNN”。无论输入是什么,输出都是恒定的。你认为问题出在哪里?

我试图重复NVIDIA的《自主驾驶汽车的端到端学习》实验论文。当然,我没有真实的汽车,而是一个Udacity的模拟器。模拟器生成汽车前景的图像。

enter image description here

CNN接收图像,并给出保持汽车在轨道上的转向角度。游戏规则是让模拟汽车安全地在轨道上行驶。这并不难。

奇怪的是,有时在使用KERAS训练后,我得到一个懒惰的CNN,它给出恒定的转向角度。模拟汽车会偏离轨道,但CNN的输出没有变化。特别是当层数加深时,例如论文中的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’。我尝试更改激活函数,但没有效果。

这是我的分析。我不认为我的程序有bug,因为我可以用相同的代码和一个更简单的CNN成功驾驶汽车。我认为原因在于模拟器或神经网络的结构。在真实的自主驾驶汽车中,训练信号,即转向角度,应该包含噪声;因此,驾驶员在真实道路上永远不会保持方向盘不动。但在模拟器中,训练信号非常干净。几乎60%的转向角度为零。优化器可以通过将CNN的输出接近零来轻松完成任务。优化器似乎也很懒惰。然而,当我们真正希望这个CNN输出一些东西时,它也给出零。因此,我为这些零转向角度添加了少量噪声。我得到懒惰CNN的几率变小了,但并没有消失。

你对我分析的看法如何?还有其他我可以使用的策略吗?我想知道在CNN研究的漫长历史中是否已经解决了类似的问题。

资源

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


回答:

我无法运行你的模型,因为问题和GitHub仓库都没有包含数据。这就是为什么我对我的答案有90%的把握。

但我认为你的网络的主要问题是密集层后的sigmoid激活函数。我假设,当只有两个这样的层时,它会训练得很好,但四个就太多了。

不幸的是,NVIDIA的《自主驾驶汽车的端到端学习》论文没有明确指定,但如今默认的激活函数不再是sigmoid(曾经是),而是relu。如果你对为什么会这样感兴趣,可以查看这个讨论。所以我提出的解决方案是尝试这个模型:

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的网络架构,并且不会受到梯度消失的影响。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注