chainer-图像分类-ResNet【附源码】


前言

  在文章与之前编写的图像分类框架构建组合使用,这里只讲述基于chainer的模型构建,本次讲解如何使用chainer构建ResNet网络结构以及对应的其他版本:resnet50,resnet101,resnet152。并且考虑到有些电脑的显存不高,所以使用alpha降低通道数,但是效果经过测试后还是比较理想的。
主题框架链接,需要配合使用:主题框架博客介绍


一、ResNet网络结构

  这里直接上ResNet论文中的一张图:
在这里插入图片描述

  以及论文中的残差卷积块:
在这里插入图片描述
  从第一张图中我们可以看到resnet各个层级的层数的区别,因此我们构建完resnet50之后也可以完成resnet101和resnet152的构建。
  从第二张图中我们可以看到残差块,可以简单的理解为输入和经过卷积之后做一个堆叠进入下一层的输入,其实整个resnet网络架构中都是有这些残差卷积块进行堆叠的,下边我们从代码中进入网络构建的实战。

二、代码实现

1.引入必须要的库库

import numpy as np
import chainer,sys
import chainer.functions as F
from chainer import initializers
import chainer.links as L

2.模型构建

1.设置残差卷积块

在这里插入图片描述
注意:
  h += residual就是残差重点;
  se参数说明可以理解为做特征压缩与激发的意思,也就是人们常说的se-resnet,这里不会用新篇描述此网络结果。

2.残差块的堆叠

这里以没压缩图像为一个模块来构建,也就是上边图中显示resnet50:3、4、6、3;resnet101:3,4,23,3;resnet152:3,8,36,3
在这里插入图片描述
这里的for循环就是对应:3,4,6,3

3.ResNet网络结构的构建

  这里构建的时候直接resnet50、resnet101、resnet152同时构建,根据参数n_layer决定网络的选择,代码如下:

class ResNet(PickableSequentialChain):
    _blocks = {
        50: [3, 4, 6, 3],
        101: [3, 4, 23, 3],
        152: [3, 8, 36, 3]
    }

    def __init__(self, n_layer, n_class=None, alpha=1, zeroInit=False, fc_kwargs={}, arch='fb'):
        self.alpha = alpha
        if arch == 'fb':
            stride_first = False
            conv1_no_bias = True
        elif arch == 'he':
            stride_first = True
            conv1_no_bias = n_layer != 50
        else:
            raise ValueError('arch is expected to be one of [\'he\', \'fb\']')
        blocks = self._blocks[n_layer]

        if zeroInit:
            initialW = initializers.constant.Zero()
            fc_kwargs['initialW'] = initializers.constant.Zero()
        else:
            initialW = initializers.HeNormal(scale=1., fan_option='fan_out')
            fc_kwargs['initialW'] = initializers.Normal(scale=0.01)
        kwargs = {'initialW': initialW, 'stride_first': stride_first}

        super(ResNet, self).__init__()
        with self.init_scope():
            # self.conv1 = Conv2DBNActiv(None, 64//self.alpha, 3, 2, 3, nobias=conv1_no_bias, initialW=initialW)
            self.conv1 = Conv2DBNActiv(None, 64//self.alpha, 7, 2, 3, nobias=conv1_no_bias, initialW=initialW)
            self.pool1 = lambda x: F.max_pooling_2d(x, ksize=3, stride=2)
            self.res2 = ResBlock(blocks[0], None, 64//self.alpha, 256//self.alpha, 1, **kwargs)
            self.res3 = ResBlock(blocks[1], None, 128//self.alpha, 512//self.alpha, 2, **kwargs)
            self.res4 = ResBlock(blocks[2], None, 256//self.alpha, 1024//self.alpha, 2, **kwargs)
            self.res5 = ResBlock(blocks[3], None, 512//self.alpha, 2048//self.alpha, 2, **kwargs)
            self.pool5 = lambda x: F.average(x, axis=(2, 3))
            self.fc6 = L.Linear(None, n_class, **fc_kwargs)

这里的参数需要解释一下:
n_class:类别个数
n_layer:设置选择50,101,152
alpha:根据自己电脑自身情况修改通道数

3.结合之前构建的分类框架调用

self.extractor = ResNet(n_layer=50, n_class=14, alpha=1)
self.model = Classifier(self.extractor)
if self.gpu_devices >= 0:
    self.model.to_gpu()

三、训练效果展示

1.resnet50训练结果展示

  从这里的图片可以看到效果还是比较可观的,下边这张图为训练的损失值的变化:

在这里插入图片描述
在这里插入图片描述

2.resnet101训练结果展示

  从这里的图片可以看到效果还是比较可观的,下边这张图为训练的损失值的变化:

在这里插入图片描述
在这里插入图片描述

3.resnet152训练结果展示

在这里插入图片描述
在这里插入图片描述
备注:因为代码是以前训练,但是没有验证集的可视化。不过效果也是可以通过loss和acc可以得到


总结

  本次使用ResNet网络结构以及对应他的一些不同深度的结构进行测试,效果对比,调用只需要在图像分类框架篇中替换model即可。
源码:chainer-resnet网络结构源码

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的广东仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值