前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于gluon的Inception结构Inception结构代码

基于gluon的Inception结构Inception结构代码

作者头像
月见樽
发布2018-04-27 11:06:19
7550
发布2018-04-27 11:06:19
举报

Inception结构

初级Inception

结构

初级Inception结构如下所示:

inception_naive.png

其前向传播分为4个部分:

  • 通过1x1卷积
  • 通过3x3卷积,padding为1(不改变图片大小)
  • 通过5x5卷积,padding为2(不改变图片大小)
  • 通过3x3池化,为了保证图片大小与以上相同,stride应为1,padding应为1

最后,将以上四个部分在feature这一维度堆叠起来,即获得最终输出

分析

假设输入feature,每个层(卷积和池化)输出feature分别为$N_i,N_o$(即最终输出feature为$4 \times N_o$);输入图片的尺寸为WxL,对于每一层,有:

  • 1x1卷积层:有参数$1 \times 1 \times N_i \times N_o = N_iN_o$,需要进行计算的次数为$N_o \times W \times L \times 1 \times 1 \times N_i = WLN_iN_o$
  • 3x3卷积层:有参数$3 \times 3 \times N_i \times N_o = 9N_iN_o$,需要计算次数为$N_o \times W \times L \times 3 \times 3 \times N_i = 9WLN_iN_o$
  • 5x5卷积层,同上,参数为$25N_iN_o$,需要计算次数为$25WLN_iN_o$

因此,总的参数量为$(1+9+25)N_iN_o = 35N_iN_o$,需要的运算量为$(1+9+25)WLN_iN_o = 35WLN_iN_o$。考虑一个输入输出相同尺寸的3x3卷积,需要的参数量为$3 \times 3 \times N_i \times 4N_o = 36N_iN_o$,需要的运算量是$4N_o \times W \times L \times 3 \times 3 \times N_i = 36WLN_iN_o$,可以发现该结构在运算量和参数量近乎不变的情况下实现了多种感受野的连接。

改进Inception结构

结构

改进的Inception结构如下图所示

inception.png

同样具有四条前向传播通路,如下所示:

  • 1x1卷积
  • 先通过1x1卷积降维,再通过3x3卷积
  • 先通过1x1卷积降维,再通过5x5卷积
  • 先通过3x3maxpool,再通过1x1调整维度

最后,将以上四个部分在feature这一维度堆叠起来,即获得最终输出

分析

假设同上一部分,假设每个降维将降维降到原来维度的一半,对每一部分有如下所示:

  • 每个降维的1x1层,需要的参数量是$\cfrac{1}{2}N_i2$,运算参数量$\cfrac{1}{2}WLN_i2$
  • 1x1卷积层:有参数$1 \times 1 \times \cfrac{1}{2}N_i \times N_o = \cfrac{1}{2}N_iN_o$,需要进行计算的次数为$N_o \times W \times L \times 1 \times 1 \times \cfrac{1}{2}N_i = \cfrac{1}{2}WLN_iN_o$
  • 3x3卷积层:有参数$3 \times 3 \times \cfrac{1}{2}N_i \times N_o = 9N_iN_o$,需要计算次数为$N_o \times W \times L \times 3 \times 3 \times \cfrac{1}{2}N_i = \cfrac{9}{2}WLN_iN_o$
  • 5x5卷积层,同上,参数为$\cfrac{25}{2}N_iN_o$,需要计算次数为$\cfrac{25}{2}WLN_iN_o$

假设$N_i = N_o$,参数量一共是$3 \times \cfrac{1}{2}N_i^2 + \cfrac{35}{2}N_i^2 = 19N_i2$,需要运算的数量为$19WLN_i2$。可以发现无论是运算量还是参数量都小于原结构

代码

代码语言:javascript
复制
import mxnet as mx
import numpy as np

Inception结构搭建

Inception结构

代码语言:javascript
复制
class inception(mx.gluon.Block):
    def __init__(self,out_channel):
        super(inception,self).__init__()
        with self.name_scope():
            self.conv1 = mx.gluon.nn.Conv2D(out_channel,1,activation='relu')
            self.conv3_pre = mx.gluon.nn.Conv2D(out_channel//2,1)
            self.conv3 = mx.gluon.nn.Conv2D(out_channel,3,activation='relu',padding=1)
            self.conv5_pre = mx.gluon.nn.Conv2D(out_channel//2,1)            
            self.conv5 = mx.gluon.nn.Conv2D(out_channel,5,activation='relu',padding=2)
            self.pool_post = mx.gluon.nn.Conv2D(out_channel,1,activation='relu')
            self.pool = mx.gluon.nn.MaxPool2D(pool_size=3,strides=1,padding=1)
            
    def forward(self,x):
        result = [
            self.conv1(x),
            self.conv3(self.conv3_pre(x)),
            self.conv5(self.conv5_pre(x)),
            self.pool_post(self.pool(x))]
        return mx.ndarray.concat(dim=1,*result)

Inception结构测试

代码语言:javascript
复制
inception_model = inception(10)
print(inception_model)
inception_model.collect_params().initialize(mx.init.Normal(sigma=.1), ctx=mx.gpu())
代码语言:javascript
复制
inception(
  (pool_post): Conv2D(None -> 10, kernel_size=(1, 1), stride=(1, 1))
  (pool): MaxPool2D(size=(3, 3), stride=(1, 1), padding=(1, 1), ceil_mode=False)
  (conv1): Conv2D(None -> 10, kernel_size=(1, 1), stride=(1, 1))
  (conv3): Conv2D(None -> 10, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (conv5_pre): Conv2D(None -> 5, kernel_size=(1, 1), stride=(1, 1))
  (conv5): Conv2D(None -> 10, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
  (conv3_pre): Conv2D(None -> 5, kernel_size=(1, 1), stride=(1, 1))
)
代码语言:javascript
复制
indata = mx.ndarray.zeros((1,5,10,10),mx.gpu())
inception_model(indata).shape
代码语言:javascript
复制
(1, 40, 10, 10)

整体网络结构

代码语言:javascript
复制
class network(mx.gluon.Block):
    def __init__(self):
        super(network,self).__init__()
        with self.name_scope():
            self.conv1 = mx.gluon.nn.Conv2D(channels=8,kernel_size=3,padding=1)
            self.conv2 = inception(8)
            self.conv3 = inception(16)
            self.conv4 = inception(16)
            self.fc = mx.gluon.nn.Dense(10)
            self.pool = mx.gluon.nn.MaxPool2D(pool_size=3,strides=2)
            
    def forward(self,x):
        x = self.conv2(self.conv1(x))
        x = self.conv3(self.pool(x))
        x = self.conv4(self.pool(x))
        return self.fc(x)
代码语言:javascript
复制
model = network()
print(model)
model.collect_params().initialize(mx.init.Normal(sigma=.1), ctx=mx.gpu())
代码语言:javascript
复制
network(
  (pool): MaxPool2D(size=(3, 3), stride=(2, 2), padding=(0, 0), ceil_mode=False)
  (conv1): Conv2D(None -> 8, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (conv3): inception(
    (pool_post): Conv2D(None -> 16, kernel_size=(1, 1), stride=(1, 1))
    (pool): MaxPool2D(size=(3, 3), stride=(1, 1), padding=(1, 1), ceil_mode=False)
    (conv1): Conv2D(None -> 16, kernel_size=(1, 1), stride=(1, 1))
    (conv3): Conv2D(None -> 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (conv5_pre): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
    (conv5): Conv2D(None -> 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (conv3_pre): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
  )
  (conv2): inception(
    (pool_post): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
    (pool): MaxPool2D(size=(3, 3), stride=(1, 1), padding=(1, 1), ceil_mode=False)
    (conv1): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
    (conv3): Conv2D(None -> 8, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (conv5_pre): Conv2D(None -> 4, kernel_size=(1, 1), stride=(1, 1))
    (conv5): Conv2D(None -> 8, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (conv3_pre): Conv2D(None -> 4, kernel_size=(1, 1), stride=(1, 1))
  )
  (fc): Dense(None -> 10, linear)
  (conv4): inception(
    (pool_post): Conv2D(None -> 16, kernel_size=(1, 1), stride=(1, 1))
    (pool): MaxPool2D(size=(3, 3), stride=(1, 1), padding=(1, 1), ceil_mode=False)
    (conv1): Conv2D(None -> 16, kernel_size=(1, 1), stride=(1, 1))
    (conv3): Conv2D(None -> 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (conv5_pre): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
    (conv5): Conv2D(None -> 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (conv3_pre): Conv2D(None -> 8, kernel_size=(1, 1), stride=(1, 1))
  )
)
代码语言:javascript
复制
​```python
indata = mx.ndarray.zeros((1,1,28,28),mx.gpu())
model(indata).shape
代码语言:javascript
复制
(1, 10)

训练准备

数据集——MNIST数据集

代码语言:javascript
复制
def transform(data, label):
    return mx.nd.transpose(data,axes=(2,0,1)).astype(np.float32)/255, label.astype(np.float32)
gluon_train_data = mx.gluon.data.DataLoader(mx.gluon.data.vision.MNIST(train=True, transform=transform),100, shuffle=True)
gluon_test_data = mx.gluon.data.DataLoader(mx.gluon.data.vision.MNIST(train=False, transform=transform),100, shuffle=False)

代价函数——交叉熵

代码语言:javascript
复制
softmax_cross_entropy = mx.gluon.loss.SoftmaxCrossEntropyLoss()

优化器——sgd

代码语言:javascript
复制
trainer = mx.gluon.Trainer(model.collect_params(), 'sgd', {'learning_rate': .1})

准确率计算

代码语言:javascript
复制
def evaluate_accuracy(model):
    acc = mx.metric.Accuracy()
    for i, (data, lable) in enumerate(gluon_test_data):
        data = data.as_in_context(mx.gpu())
        lable = lable.as_in_context(mx.gpu())
        output = model(data)
        predictions = mx.nd.argmax(output, axis=1)
        acc.update(preds=predictions, labels=lable)
    return acc.get()[1]
evaluate_accuracy(model)
代码语言:javascript
复制
0.050200000000000002

训练

代码语言:javascript
复制
for _ in range(2):
    for i,(data,lable) in enumerate(gluon_train_data):
        data = data.as_in_context(mx.gpu())
        lable = lable.as_in_context(mx.gpu())
        with mx.autograd.record():
            outputs = model(data)
            loss = softmax_cross_entropy(outputs,lable)
        loss.backward()
        trainer.step(data.shape[0])
        if i % 100 == 1:
            print(i,loss.mean().asnumpy()[0])
代码语言:javascript
复制
1 0.16968
101 0.104242
201 0.093354
301 0.07079
401 0.123301
501 0.086882
1 0.0325385
101 0.0510763
201 0.0242231
301 0.0454984
401 0.0788167
501 0.0591589
代码语言:javascript
复制
evaluate_accuracy(model)
代码语言:javascript
复制
0.98829999999999996
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.03.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Inception结构
    • 初级Inception
      • 结构
      • 分析
    • 改进Inception结构
      • 结构
      • 分析
  • 代码
    • Inception结构搭建
      • Inception结构
      • Inception结构测试
    • 整体网络结构
      • 训练准备
        • 数据集——MNIST数据集
        • 代价函数——交叉熵
        • 优化器——sgd
        • 准确率计算
      • 训练
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档