残差网络(ResNet) 讨论区


#21

沐神,论文里面,最后一层要加sigmoid,我查dense的文档,发现如果不指定activation,默认是不加激活函数。
当我显式的加上sigmoid激活函数后,发现和不加,对最终的结果几乎没有任何影响,不太明白为什么?


#22

如果我没看错的话你在residual block里面的卷积层中间是没加激活函数的?


#23

forward函数里面最后一行,用的relu激活函数


#24

但是你在CONV 和BN之后得加激活函数吧 不然好几层卷积和一层卷积就没什么区别了啊。。


#25

确实,loss下降了不少,看论文不仔细,谢谢指点!


#26

(BN->relu->weight)的实现方式 ,loss和教程里面的没有多大差别,而且最后一层不加activation=sgimoid, loss就变成Nan了。求指正!(若有mxnet 版本的各种深度模型的实现资源,望不吝赐教)

class Residual(nn.Block):
def init(self, channels, same_shape=True, **kwargs):
super(Residual, self).init(**kwargs)

        self.same_shape = same_shape
        strides = 1 if same_shape else 2

        self.bn1 = nn.BatchNorm()
        self.conv1 = nn.Conv2D(channels=channels, kernel_size=3, padding=1, strides=strides)
        self.bn2 = nn.BatchNorm()
        self.conv2 = nn.Conv2D(channels=channels, kernel_size=3, padding=1, strides=1)

        if not self.same_shape:
            self.conv3 = nn.Conv2D(channels=channels, kernel_size=1, strides=strides)
    def forward(self, x):
        out = (self.conv1(nd.relu(self.bn1(x))))
        out = (self.conv2(nd.relu(self.bn2(out))))
        if not self.same_shape:
            x = self.conv3(x)
        return out + x


class ResNet(nn.Block):
    def __init__(self, num_classes, verbose=False, **kwargs):
        super(ResNet, self).__init__(**kwargs)
        self.verbose = verbose
        # add name_scope on the outermost Sequential
        with self.name_scope():
            # block 1
            b1 = nn.Conv2D(64, kernel_size=7, strides=2)
            # block 2
            b2 = nn.Sequential()
            b2.add(
                nn.MaxPool2D(pool_size=3, strides=2),
                Residual(64),
                Residual(64)
            )
            # block 3
            b3 = nn.Sequential()
            b3.add(
                Residual(128, same_shape=False),
                Residual(128)
            )
            # block 4
            b4 = nn.Sequential()
            b4.add(
                Residual(256, same_shape=False),
                Residual(256)
            )
            # block 5
            b5 = nn.Sequential()
            b5.add(
                Residual(512, same_shape=False),
                Residual(512)
            )
            # block 6
            b6 = nn.Sequential()
            b6.add(
                nn.AvgPool2D(pool_size=3),
                # nn.LeakyReLU(),
                # nn.Flatten(),
                nn.Dense(num_classes, activation="sigmoid")#, activation="sigmoid"
            )
            # chain all blocks together
            self.net = nn.Sequential()
            self.net.add(b1, b2, b3, b4, b5, b6)

    def forward(self, x):
        out = x
        for i, b in enumerate(self.net):
            out = b(out)
            if self.verbose:
                print('Block %d output: %s'%(i+1, out.shape))
        return out

#27

你在block 6的开头应该加一层BN和ACTIVATION
否则就相当于数据从前面的卷积层出来没加激活


#28

谢谢大神指点!


#29

红框内的 “输入” 是不是应该为“输出”?


#30

亲测了下 加ReLU效果会更好。


#31

跑了resnet101,top监控发现,virt达到了70+G,data也快70G,主要是在forward_backward和update这两步,请问有没有跑过resnet101的伙伴,资源占用怎样?这里爆内存主要是什么原因?


#32

virtual mem无所谓吧。为了节省内存可以吧batch size变小点


#33

ok,谢谢大神指点


#34

为什么不加激活函数的情况下几层卷积和一层卷积没有区别呢


#36

如何使用自己的数据集x,y来使用resnet训练呢?自己的数据集如何做成traindata和testdata丢到utils.train里面训练?


#37

卷积是线性变换,n个叠加还是线性。通过非线性激活可以打断这个。


#38

可以参考那个自己写一个,不难


#39

1核 2GB 这样的云Linux服务器跑不起来啊,跑一会就内核就崩溃,怎么办


#40

是内存使用量太大了么?2GB确实比较受限,感觉跟手机差不多了,跑不动resnet不意外


#41

在ResNet中,每个block中的单元数是固定的吗?就像论文中那样?还是无所谓?看很多人实现的都不太一样