在这篇文章中,咱们将讨论一种新的网络模型GoogleNet,它和我前面所讨论的模型有所不一样,表如今:git
GoogLeNet模型于2014年的一篇论文《Going Deeper With Convolutions》提出,其最大的贡献在于Inception模块(Inception有起初、开端的含义),这是一个适合卷积神经网络的构建模块,它选用多个过滤器大小的卷积,将模块转换为多级特征提取器。github
Inception模块是一种微架构模块,所谓微架构,就是由深度学习从业者设计的小型构建块,它使得网络可以在增长网络深度的前提下更快地学习,并且更高效。而这些微架构构建块与诸如CONV、POOL等传统类型的层堆叠在一块儿,能够造成宏架构(macro-architecture)。bash
Inception模块背后的思想有两层含义:微信
GoogleNet最初引入的Inception模块以下图所示:网络
注: 在每一个CONV层以后都紧跟一个激活函数(ReLU)。为节省空间,此激活函数并没包含在上面的网络图中。架构
从图中能够看到,输入层以后有四个不一样的路径分支。Inception模块中的第一个分支只是从输入中学习一系列1×1局部特征。框架
第二条路径首先应用1×1卷积,不只做为学习局部特征的一种形式,还能够减小维数。较大的卷积(即3×3和5×5)须要更多的计算。所以,若是咱们能够经过应用1×1卷积来减小这些较大过滤器的输入维数,就能够减小网络所需的计算量。机器学习
第三个分支与第二个分支的逻辑相同,区别在于为了学习5×5过滤器。咱们再次经过1×1卷积下降维数,而后将输出馈送到5×5过滤器。ide
Inception模块的第四个分支以1×1的步幅执行3×3最大池化 - 该分支一般被称为池投影分支。函数
最后,Inception模块的全部四个分支汇聚在一块儿,它们沿着通道维度链接在一块儿。在实现过程当中要特别当心(经过零填充)以确保每一个分支的输出具备相同的卷大小,从而容许链接输出。
最初的Inception模块是为GoogLeNet设计的,在ImageNet数据集上训练(其中每一个输入图像假设为224×224×3)并得到最好的精度。对于较小的数据集(具备较小的图像空间维度),咱们能够简化Inception模块,只须要较少的网络参数。好比下图表示的Miniception:
左:卷积模块,负责执行卷积、批量正则化和激活。
中:Miniception模块执行两组卷积,一组用于1×1滤波器,另外一组用于3×3滤波器,而后链接结果。在3×3滤波器以前不执行降维,由于咱们将使用CIFAR-10数据集,输入已经很小。
右:下采样模块,它同时应用卷积和最大池化以下降维度,而后在过滤器维度上链接。
将这些模块堆叠起来,能够组成称之为MiniGoogleNet的模型结构,以下图所示:
有了上面的模型定义,接下来咱们就可使用Keras框架来实现之。但在编码以前,咱们先了解一下Keras中的两种类型的模型。
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dropout(0.25))
复制代码
inputs = Input(shape=(784,))
# 输入inputs,输出x
x = Dense(64, activation='relu')(inputs)
# 输入x,输出x
x = Dense(64, activation='relu')(x)
复制代码
由于MiniGoogleNet并非那种一条路走到黑的模型,因此咱们不能选择序列模型,而应该选择函数式API来构建,代码以下:
class MiniGoogleNet:
@staticmethod
def conv_module(x, k, kx, ky, stride, channel_dim, padding="same"):
# define a CONV => BN => RELU pattern
x = Conv2D(k, (kx, ky), strides=stride, padding=padding)(x)
x = BatchNormalization(axis=channel_dim)(x)
x = Activation("relu")(x)
return x
@staticmethod
def inception_module(x, num_k1x1, num_k3x3, channel_dim):
# define two CONV module, then concatenate across the channel dimension
conv_1x1 = MiniGoogleNet.conv_module(x, num_k1x1, 1, 1, (1, 1), channel_dim=channel_dim)
conv_3x3 = MiniGoogleNet.conv_module(x, num_k3x3, 3, 3, (1, 1), channel_dim=channel_dim)
x = concatenate([conv_1x1, conv_3x3], axis=channel_dim)
return x
@staticmethod
def downsample_module(x, k, channel_dim):
# define the CONV module and POOL, then concatenate across the channel dimension
conv_3x3 = MiniGoogleNet.conv_module(x, k, 3, 3, (2, 2), channel_dim=channel_dim, padding="valid")
pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
x = concatenate([conv_3x3, pool], axis=channel_dim)
return x
@staticmethod
def build(width, height, depth, classes):
input_shape = (width, height, depth)
channel_dim = -1
if K.image_data_format() == "channels_first":
input_shape = (depth, width, height)
channel_dim = 1
inputs = Input(shape=input_shape)
x = MiniGoogleNet.conv_module(inputs, 96, 3, 3, (1, 1), channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 32, 32, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 32, 48, channel_dim=channel_dim)
x = MiniGoogleNet.downsample_module(x, 80, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 112, 48, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 96, 64, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 80, 80, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 48, 96, channel_dim=channel_dim)
x = MiniGoogleNet.downsample_module(x, 96, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 176, 160, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 176, 160, channel_dim=channel_dim)
x = AveragePooling2D((7, 7))(x)
x = Dropout(0.5)(x)
# softmax classifier
x = Flatten()(x)
x = Dense(classes)(x)
x = Activation("softmax")(x)
model = Model(inputs, x, name="googlenet")
return model
复制代码
接下来就是训练和测试模型,这个在前面的文章中介绍过,其步骤都差很少,因此在这里我也再也不罗嗦,有兴趣的同窗能够参考我在github上的完整代码。
写下这篇文章,我完成了《Deep Learning for Computer Vision with Python》的学习,其实后面还有一章节是讲残差网络(ResNet),但考虑到ResNet也是采用微架构,其实和GoogleNet差很少,就是模块构建块有些区别,因此就不打算写了。
其实这套书还有第三部,称为ImageNet Bundle,里面有更多大型项目的例子,考虑到我这边的硬件条件有限,就先不去研究这些复杂的例子。在后面的时间里,我将专一于移动终端上的机器学习,敬请关注。
以上实例均有完整的代码,点击阅读原文,跳转到我在github上建的示例代码。 另外,我在阅读《Deep Learning for Computer Vision with Python》这本书,在微信公众号后台回复“计算机视觉”关键字,能够免费下载这本书的电子版。