本文参考文献:
Network In Network
今天介绍的是2014年一篇很火的文章:Network in Network。
经典的卷积神经网络是由卷积层、池化层以及全连接层构成,最终经过softmax分类器得到输出类别的概率分布。这就会引发一个疑问,由于卷积网络参数较少,因此深度卷积网络的参数其实大部分集中在了全连接层,那么这个时候,到底是卷积层对结果贡献大还是全连接层贡献大?本文提出的模型尝试赋予卷积层更强大的表征能力,同时去掉了全连接层,使用了平均池化层来代替全连接层进行分类,这样做的好处就是一方面减少了参数,另一方面避免了由全连接层导致的过拟合的问题,因为池化层本身就充当了避免过拟合的功能,从而也就不需要采用dropout了。
卷积层是一个线性层,如果遇到特征是高度非线性的,那么此线性卷积就不足以表达了,传统的做法是通过多个特征图来增强卷积层的表达能力,但是这样做又会对下一个卷积层造成较大的压力,因为下一层要考虑如何组合这些特征图得到更高级的特征抽象。
本文提出的NIN实际上就是在局部卷积的基础上增加了一个多层感知器,多层感知器是一个通用的函数模拟器,因它可以拟合一切函数,在局部的卷积层基础上增加了多层感知器可以增强局部特征的抽象能力和非线性表达能力,作者在多层感知器中采用的激活函数是ReLU。这样的局部多层感知器恰好也可以使用1*1的卷积核来实现。
从池化的角度看,增加的多层感知器相当于是一个含参的池化层,通过对多个特征图进行含参池化,再传递到下一层继续含参池化,这种级联的跨通道的含参池化让网络有了更复杂的表征能力。
本文的另外一个贡献就是提出了全局平均池化,以此来替代传统的全连接层作为分类的做法。具体做法就是假如我们要进行cifar-10分类任务,那么设计的NIN最后一个卷积层需要的特征图数量为10,然后依次对这10个特征图进行平均池化即可得到分类概率,是不是简洁呢?比全连接层参数要少很多!
好了,模型介绍完了,接下来我们动手基于TensorFlow来实现下面这个NIN网络。
import tensorflow as tfdef nin_cell(input):
conv1_filter = tf.get_variable('conv1_filter', shape=[5, 5, 3, 192])
conv1 = tf.nn.relu(tf.nn.conv2d(input, conv1_filter))
mlpconv1_filter = tf.get_variable('mlpconv1_filter', shape=[1, 1, 192, 160])
mlpconv1 = tf.nn.relu(tf.nn.conv2d(conv1, mlpconv1_filter))
mlpconv2_filter = tf.get_variable('mlpconv2_filter', shape=[1, 1, 160, 96])
mlpconv2 = tf.nn.relu(tf.nn.conv2d(mlpconv1, mlpconv2_filter))
max_pool1 = tf.nn.max_pool(mlpconv2, ksize = [1,3,3,1], strides=[1,2,2,1])
conv2_filter = tf.get_variable('conv2_filter', shape=[5, 5, 96, 192])
conv2 = tf.nn.relu(tf.nn.conv2d(max_pool1, conv2_filter))
mlpconv3_filter = tf.get_variable('mlpconv3_filter', shape=[1, 1, 192, 192])
mlpconv3 = tf.nn.relu(tf.nn.conv2d(conv2, mlpconv3_filter))
mlpconv4_filter = tf.get_variable('mlpconv4_filter', shape=[1, 1, 192, 192])
mlpconv4 = tf.nn.relu(tf.nn.conv2d(mlpconv3, mlpconv4_filter))
max_pool2 = tf.nn.max_pool(mlpconv4, ksize = [1,3,3,1], strides=[1,2,2,1])
conv3_filter = tf.get_variable('conv3_filter', shape=[3, 3, 192, 192])
conv3 = tf.nn.relu(tf.nn.conv2d(max_pool2, conv3_filter))
mlpconv4_filter = tf.get_variable('mlpconv4_filter', shape=[1, 1, 192, 192])
mlpconv4 = tf.nn.relu(tf.nn.conv2d(conv3, mlpconv4_filter))
mlpconv5_filter = tf.get_variable('mlpconv5_filter', shape=[1, 1, 192, 10])
mlpconv5 = tf.nn.relu(tf.nn.conv2d(mlpconv4, mlpconv5_filter))
global_avg_pool = tf.nn.avg_pool(mlpconv5, ksize=[1,8,8,1])
return global_avg_pool
题图:Crystal Liu
拥有近1400 star的Automaitc Speech Recognition项目已经更新至v0.10.0 release 版本,欢迎点击阅读原文查看。该项目将会加入更多模型与优化细节,1.0版本将同时支持python2.7、python3.5以及pip安装,敬请关注!如果有意愿加入此项目一起开发并成为collaborator的朋友,欢迎后台勾搭小编。
开源让世界更美好!
你可能会感兴趣的文章有:
如何基于TensorFlow实现ResNet和HighwayNet
深度残差学习框架(Deep Residual Learning)
ICLR2017 参会论文导读(机器理解、注意力、记忆网络)
推荐阅读 | 如何让TensorFlow模型运行提速36.8%
推荐阅读 | 如何让TensorFlow模型运行提速36.8%(续)
深度学习每日摘要|坚持技术,追求原创