网络中的网络(NiN) 讨论区


#21

1x1 减少训练参数在Going Deeper with Convolutions这篇文章内有说明,主要是从工程角度说明了1x1卷起的作用。


#22

acc一直处于0.1,到底是什么鬼, 1080 ti


#23

是的,需要resize到96*96就可以啦


#24

引用MXNetError Traceback (most recent call last)
in ()
15 ‘sgd’, {‘learning_rate’: 0.1})
16 utils.train(train_data, test_data, net, loss,
—> 17 trainer, ctx, num_epochs=1)

D:\deeplearning\utils.py in train(train_data, test_data, net, loss, trainer, ctx, num_epochs, print_batches)
129 losses = []
130 with autograd.record():
–> 131 outputs = [net(X) for X in data]
132 losses = [loss(yhat, y) for yhat, y in zip(outputs, label)]
133 for l in losses:

D:\deeplearning\utils.py in (.0)
129 losses = []
130 with autograd.record():
–> 131 outputs = [net(X) for X in data]
132 losses = [loss(yhat, y) for yhat, y in zip(outputs, label)]
133 for l in losses:

~\Anaconda3\lib\site-packages\mxnet\gluon\block.py in call(self, *args)
302 def call(self, *args):
303 “”“Calls forward. Only accepts positional arguments.”""
–> 304 return self.forward(*args)
305
306 def forward(self, *args):

~\Anaconda3\lib\site-packages\mxnet\gluon\nn\basic_layers.py in forward(self, x)
51 def forward(self, x):
52 for block in self._children:
—> 53 x = block(x)
54 return x
55

~\Anaconda3\lib\site-packages\mxnet\gluon\block.py in call(self, *args)
302 def call(self, *args):
303 “”“Calls forward. Only accepts positional arguments.”""
–> 304 return self.forward(*args)
305
306 def forward(self, *args):

~\Anaconda3\lib\site-packages\mxnet\gluon\block.py in forward(self, x, *args)
512 return self._call_cached_op(x, *args)
513 params = {i: j.data(ctx) for i, j in self._reg_params.items()}
–> 514 return self.hybrid_forward(ndarray, x, *args, **params)
515
516 assert isinstance(x, Symbol), \

~\Anaconda3\lib\site-packages\mxnet\gluon\nn\conv_layers.py in hybrid_forward(self, F, x)
670
671 def hybrid_forward(self, F, x):
–> 672 return F.Pooling(x, name=‘fwd’, **self._kwargs)
673
674 def repr(self):

~\Anaconda3\lib\site-packages\mxnet\ndarray\register.py in Pooling(data, global_pool, cudnn_off, kernel, pool_type, pooling_convention, stride, pad, out, name, **kwargs)

~\Anaconda3\lib\site-packages\mxnet_ctypes\ndarray.py in _imperative_invoke(handle, ndargs, keys, vals, out)
90 c_str_array(keys),
91 c_str_array([str(s) for s in vals]),
—> 92 ctypes.byref(out_stypes)))
93
94 if original_output is not None:

~\Anaconda3\lib\site-packages\mxnet\base.py in check_call(ret)
144 “”"
145 if ret != 0:
–> 146 raise MXNetError(py_str(_LIB.MXGetLastError()))
147
148

MXNetError: [12:00:03] d:\program files (x86)\jenkins\workspace\mxnet-tag\mxnet\src\operator./pooling-inl.h:215: Check failed: param_.kernel[0] <= dshape[2] + 2 * param_.pad[0] kernel size (5) exceeds input (1 padded to 1)

resize改成96的话出现这种错误, 怎么办呢


#27

nn.AvgPool2D(pool_size=5) 改成 GlobalMaxPool2D


#28

224确实不收敛,为什么需要改到96*96呢,是跟第一个kernel有关,还是跟channel有关?


#29

主要是这样跑起来快点。。。


#30

对最终计算得到的形状有疑问。

x = nd.random.uniform(shape=(32, 3, 16, 16))
y = blk(x)
y.shape

输出(2, 64, 6, 6)

后面形状为什么是6*6是呢?

(input_size+2*padding-kernel_size)/stride+1=output_size

第一层(16+2*0-3)/1+1=14,第二层(13-1)/1+1=13,第三层(13-1)/1+1=13

13*13才对啊?为什么最后是6*6呢???


#31

最后有个stride2的3x3池化


#32

假如想打印整个网络使用的参数数量,要怎么做?


#33

首先计算公式是

output_size = (input_size - kernel_size + 2 * padding) / stride + 1

因此,第一层为14,第二三层仍是14。记住最后还有个池化操作,最终结果为:

(14 - 3 + 2 * 0) / 2 + 1 = 6


#34

net.collect_params()


#35

为什么NiN收敛速度慢这么多呢?


#36

看了NiN的论文,我觉得这里说的

mlpconv中的第一个1x1的CNN层可以看成是对前一层的所有feature map信息进行线性组合,因为是1x1的kernel,所以可以看成是一种变相的全连接层,再使用Relu进行非线性变换,就实现了一次特征的整合和非线性抽象。但是这和传统的CNN层并没有什么区别,也没有实现作者说的要对input data patch做高度的非线性变换的目的。

有一点不妥的地方。因为前一层的CNN也是用的Relu作为激活函数,所以加了1x1的CNN层之后,其实已经对前一层的所有的feature map信息进行了非线性整合,因此实现了对input data patch做非线性变换的目的,和传统的CNN层还是有区别的。文章中的图片中画了两个1x1的CNN层,我觉得只是一个示例,实际上为了进行更好的非线性变换,mlpconv中的1x1的CNN层数可以继续增加。从直观的角度上来说,1个1x1的CNN层性能应该没有2个1x1的CNN层性能好,如果继续增加1x1的CNN层数,性能应该会更好,但是相应的复杂度也会提高,所以应该会找一个balance吧。

另外,第四行的公式应该是 f_{i,j,k} = \max(w_k^Tx_{i, j}, 0) :joy:


#37

我觉得zjn21hx说的不错
两层1x1的CNN层可以一是增加参数空间,二是多增加一层非线性转换。如果再多一层,达到效果应该会更甚。


#38

NIN中最后一层输数的不是一个样本在各个类别上的概率值吗,为什么相加不是1呢


#39

为什么我去掉一个1x1, 效果还变好了。。。


#40

网络输出要经过softmax,或者别的归一化方法,得到的值和才为1.程序里并没有这句,所以相加肯定不为1.


#41

谢谢你的解释,相当直观又合理的推论,可以帮助大家记忆和学习
至于正确性我觉得不必太纠结,至少暂时不用

之前看过jeremy的deep learning教程,他的说法是目前人类其实还无法很好的理解
“为何深度学习的网路,这样设计的效果会比较好”,大家依然停留在猜测的阶段


#42