# Inception结构

## 初级Inception

### 结构

inception_naive.png

• 通过1x1卷积

### 分析

• 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$

## 改进Inception结构

### 结构

inception.png

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

### 分析

• 每个降维的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$

# 代码

import mxnet as mx
import numpy as np

## Inception结构搭建

### Inception结构

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.conv5_pre = mx.gluon.nn.Conv2D(out_channel//2,1)
self.pool_post = mx.gluon.nn.Conv2D(out_channel,1,activation='relu')

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结构测试

inception_model = inception(10)
print(inception_model)
inception_model.collect_params().initialize(mx.init.Normal(sigma=.1), ctx=mx.gpu())
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))
)
indata = mx.ndarray.zeros((1,5,10,10),mx.gpu())
inception_model(indata).shape
(1, 40, 10, 10)

## 整体网络结构

class network(mx.gluon.Block):
def __init__(self):
super(network,self).__init__()
with self.name_scope():
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)
model = network()
print(model)
model.collect_params().initialize(mx.init.Normal(sigma=.1), ctx=mx.gpu())
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))
)
)
​python
indata = mx.ndarray.zeros((1,1,28,28),mx.gpu())
model(indata).shape
(1, 10)

## 训练准备

### 数据集——MNIST数据集

def transform(data, label):
return mx.nd.transpose(data,axes=(2,0,1)).astype(np.float32)/255, label.astype(np.float32)
gluon_test_data = mx.gluon.data.DataLoader(mx.gluon.data.vision.MNIST(train=False, transform=transform),100, shuffle=False)

### 代价函数——交叉熵

softmax_cross_entropy = mx.gluon.loss.SoftmaxCrossEntropyLoss()

### 优化器——sgd

trainer = mx.gluon.Trainer(model.collect_params(), 'sgd', {'learning_rate': .1})

### 准确率计算

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)
0.050200000000000002

## 训练

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())
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])
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
evaluate_accuracy(model)
0.98829999999999996`

0 条评论

• ### 宇宙法则

聊下AI。 ? 还是先从游戏开始吧。 有一条『常识』需要先抛出来，大部分人都承认，网络游戏的游戏性不如单机。 『胡扯！我觉得网游比单机好玩多了。』 『好，本文到...

• ### K-Means算法的10个有趣用例

源 | AI Zone K-means算法具有悠久的历史，并且也是最常用的聚类算法之一。K-means算法实施起来非常简单，因此，它非常适用于机器学习新手爱好者...

• ### 用C# (.NET Core) 实现抽象工厂设计模式

本文的概念性内容来自深入浅出设计模式一书. 上一篇文章讲了简单工厂和工厂方法设计模式 http://www.cnblogs.com/cgzl/p/8760250...

• ### 『AI』人工智能 - 禁忌的人体炼成

很久以前，人工智能和AI被一部分人当作两种不同的东西。他们认为，应用在科技或生活的机器人身上的那些才配叫『人工智能』，而应用在游戏里的只配叫『AI』。 至于『很...

• ### “没有IoT我就睡不着！”：医疗保健领域的物联网

我不太清楚IoT技术在我们的日常生活中渗透到多快和多深，直到我的朋友告诉我有关他的打鼾和他失眠的夜。

• ### 叫醒你的观众

台上的主持人慷慨激昂，台下的观众却昏昏欲睡；“麦霸”们互相争夺着话筒不肯撒手，听众却一脸惬意的玩弄着自己的手机；每当主持人提问时，原本人声嘈杂的会议室，仿佛是被...

• ### Caffe源码---Blob基本使用

看到这个的时候，估计你也在学习caffe，嘿嘿！Blob在内存中表示4维数组，维度从低到高为（width_，height_，channels_,num_）。Bl...

• ### 论文阅读——Selective Search for Object Recognition

今天认真把Selective Search for Object Recognition这篇文章阅读完，想来写写自己的见解与想法。如果有错，希望得到大牛们的指点...

• ### 月千之夜

这个是2012年做的一个游戏。 ======== 主角的控制方式： 右键移动， 按Q键角色会朝鼠标方向冲刺，冲刺位移距离大，但是冲刺过程不是无敌的，且伤害一般...

• ### (三)Lua脚本语言入门

又要找工作了,变的忧虑了,唯有学习才让内心变得踏实,今天玩了一下午的王者荣耀,正事都忘了...... 如果认为所谓的毅力是每分每秒的“艰苦忍耐”式的奋斗，那这是...