全卷积网络(FCN)讨论区


#1

http://zh.diveintodeeplearning.org/chapter_computer-vision/fcn.html


于置顶 #2

#3

FCN那篇论文中好像多次提到了双线性插值,这和卷积转置层有什么联系


#4

还有代码里面为什么反卷积的学习率设成了0…


#5

@wangzhe 就是当upsampling layer 用 不当deconv 用


#6

所以学习率设成了0?那它是怎么起作用的,能麻烦详细解释下吗


#7

啊 具体我要看公式 基本就是bilinear upsample的话其实是可以用deconvolution + 特定weight 来表示的,nearest neighbor 也是。。所以估计就是当bilinear upsample 用。mxnet 的bilinear upsample其实底层call 的deconvolution


#8

绕了一大圈就是用反卷积实现了双线性插值?好吧…感觉还是skip-connection对细节信息提取好一点


#9

试了下 训练部分代码跑的时候会报错 cpu和gpu都会报错 windows和Linux上也都试了 无法运行


警告信息

错误信息


#10

要提取细节首先你得把特征图给扩大了然后再skip 要不然tensor shape不一样


#11

是啊,确实是这样


#12

再看了遍网站的教程,它是用双线性插值做转置卷积的初始化,可算是懂了。。而且,这里面转置卷积层的学习率还是和前面一样的。


#13

关于双线性插值的问题

教程代码如下:
def bilinear_kernel(in_channels, out_channels, kernel_size):
factor = (kernel_size + 1) // 2
if kernel_size % 2 == 1:
center = factor - 1
else:
center = factor - 0.5
og = np.ogrid[:kernel_size, :kernel_size]
filt = (1 - abs(og[0] - center) / factor) *
(1 - abs(og[1] - center) / factor)
weight = np.zeros(
(in_channels, out_channels, kernel_size, kernel_size),
dtype=‘float32’)
weight[range(in_channels), range(out_channels), :, :] = filt
return nd.array(weight)

问题:
为啥输出weight的dimensions是 (in_channels, out_channels, kernel_size, kernel_size),而不是(out_channels, in_channels, kernel_size, kernel_size)?
之前out_channels一直在最前面,现在叫交换out_channels和in_channels肯定有原因。
我的理解是:结合Con2DTranspose的名称一起考虑,如果是Con2DTranspose操作就要想dimensions、strides等在脑子里都要变变(dimensions要交换最前面两维,strides则变为1/strides)。这理解对吗?


#14

最新的work基本上都不用transpose convolution,都是直接bilinear upsample


#15

查了一下mxnet.gluon.nn.Conv2DTranspose得文档,Conv2DTranspose的输出size是这样计算的:
out_height = (height-1)strides[0]-2padding[0]+kernel_size[0]+output_padding[0]
out_width = (width-1)strides[1]-2padding[1]+kernel_size[1]+output_padding[1]

这里面padding和output_padding分别指什么?
输入的参数不包括output_padding.
class mxnet.gluon.nn.Conv2DTranspose(channels, kernel_size, strides=(1, 1), padding=(0, 0), output_padding=(0, 0), dilation=(1, 1), groups=1, layout=‘NCHW’, activation=None, use_bias=True, weight_initializer=None, bias_initializer=‘zeros’, in_channels=0, **kwargs)

请大神指点,不胜感激


#16

这个问题怎么解决呢,我也遇到了,您解决了吗?


#17

没有呢 不知道问题的原因:disappointed_relieved:


#18

@szha 弱弱问一下教程里的代码有人成功运行了吗?


#19

FCN教程错误
由于版本更新之后,net.output会报错,而且net.features得到的结果和教程并不相同。
原教程中pretrained_net.features[-4:]得到的结果:

([BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, in_channels=512),
Activation(relu),
GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True),
Flatten],
Dense(512 -> 1000, linear))

在新版本中,此部分的内容在net.classifier中,因此使用原有方法就会出错。在运行net(x).shape之后,输出层的shape只减少了8倍。。。
@szha @mli 希望假期过后能尽快看一下是不是除了问题,谢谢。


#20

对示例中的代码进行修改之后,可以顺利跑起来了。
下述代码中加黑部分为修改的部分

更改了net添加层的方法:
pretrained_net = models.resnet18_v2(pretrained=True)
net = nn.HybridSequential()
for layer in pretrained_net.features:
net.add(layer)

net.add(nn.BatchNorm(axis=1, in_channels=512))
net.add(nn.Activation(activation=‘relu’))

初始化过程中,添加对上述新加层的初始化:
conv_trans = net[-1]
conv_trans.initialize(init=init.Zero())
net[-2].initialize()
net[-4].initialize(init=init.Xavier())

经过上述的修改之后模型可以顺利的跑起来
(原有的方法会直接导致kernel died)