文章目录

  • 前言
  • 代码实现
  • 调用方式

前言

本文基于chainer实现EfficientNet_V1网络结构,并基于torch的结构方式构建chainer版的,并计算EfficientNet_V1的参数量。


代码实现

注意此类就是EfficientNet_V1的实现过程,注意网络的前向传播过程中,分了训练以及测试。
训练过程中直接返回x,测试过程中会进入softmax得出概率
并且代码基于chainer实现drop_connect(droppath);SiLU激活函数


def drop_connect(inputs, p):if not configuration.config.train:return inputsxp = backend.get_array_module(inputs)keep_prob = 1 - pbatch_size = inputs.shape[0]random_tensor = keep_probrandom_tensor += xp.random.uniform(size=[batch_size, 1, 1, 1])binary_tensor = xp.floor(random_tensor)output = (inputs / keep_prob) * binary_tensorreturn outputdef _make_divisible(ch, divisor=8, min_ch=None):if min_ch is None:min_ch = divisornew_ch = max(min_ch, int(ch + divisor / 2) // divisor * divisor)if new_ch < 0.9 * ch:new_ch += divisorreturn new_chclass SiLU(chainer.Chain):def __init__(self):super(SiLU, self).__init__()def __call__(self, x):out = x * F.sigmoid(x)return outclass ConvBNActivation(chainer.Chain):def __init__(self, in_planes: int, out_planes: int, kernel_size: int = 3, stride: int = 1, groups: int = 1, norm_layer = None, activation_layer = SiLU()):padding = (kernel_size - 1) // 2if norm_layer is None:norm_layer = BatchNormalizationsuper(ConvBNActivation, self).__init__()self.layers = []self.layers += [('conv1',L.Convolution2D(in_channels=in_planes,out_channels=out_planes,ksize=kernel_size,stride=stride,pad=padding,groups=groups,nobias=True))]self.layers += [('bn',norm_layer(out_planes))]if activation_layer is not None:self.layers += [('act',activation_layer)]with self.init_scope():for n in self.layers:if not n[0].startswith('_'):setattr(self, n[0], n[1])def __call__(self, x):for n, f in self.layers:if not n.startswith('_'):x = getattr(self, n)(x)else:x = f.apply((x,))[0]return xclass SqueezeExcitation(chainer.Chain):def __init__(self, input_c: int, expand_c: int, squeeze_factor: int = 4):super(SqueezeExcitation, self).__init__()squeeze_c = input_c // squeeze_factorself.layers = []self.layers += [('fc1',L.Convolution2D(in_channels=expand_c,out_channels=squeeze_c,ksize=1))]self.layers += [('ac1',SiLU())]self.layers += [('fc2',L.Convolution2D(squeeze_c, expand_c, 1))]self.layers += [('_ac2',Sigmoid())]with self.init_scope():for n in self.layers:if not n[0].startswith('_'):setattr(self, n[0], n[1])def forward(self, x):short_cut = xx = F.average_pooling_2d(x, x.shape[2:], stride=1)for n, f in self.layers:if not n.startswith('_'):x = getattr(self, n)(x)else:x = f.apply((x,))[0]return x * short_cutclass InvertedResidualConfig:# kernel_size, in_channel, out_channel, exp_ratio, strides, use_SE, drop_connect_ratedef __init__(self,kernel: int,          # 3 or 5input_c: int,out_c: int,expanded_ratio: int,  # 1 or 6stride: int,          # 1 or 2use_se: bool,         # Truedrop_rate: float,index: str,           # 1a, 2a, 2b, ...width_coefficient: float):self.input_c = self.adjust_channels(input_c, width_coefficient)self.kernel = kernelself.expanded_c = self.input_c * expanded_ratioself.out_c = self.adjust_channels(out_c, width_coefficient)self.use_se = use_seself.stride = strideself.drop_rate = drop_rateself.index = index@staticmethoddef adjust_channels(channels: int, width_coefficient: float):return _make_divisible(channels * width_coefficient, 8)class InvertedResidual(chainer.Chain):def __init__(self, cnf: InvertedResidualConfig, norm_layer):super(InvertedResidual, self).__init__()if cnf.stride not in [1, 2]:raise ValueError("illegal stride value.")self.use_res_connect = (cnf.stride == 1 and cnf.input_c == cnf.out_c)self.layers = []activation_layer = SiLU()  # alias Swish# expandif cnf.expanded_c != cnf.input_c:self.layers += [('expand_conv',ConvBNActivation(cnf.input_c, cnf.expanded_c, kernel_size=1, norm_layer=norm_layer, activation_layer=activation_layer))]# depthwiseself.layers += [('dwconv',ConvBNActivation(cnf.expanded_c, cnf.expanded_c, kernel_size=cnf.kernel, stride=cnf.stride, groups=cnf.expanded_c, norm_layer=norm_layer, activation_layer=activation_layer))]if cnf.use_se:self.layers += [('se',SqueezeExcitation(cnf.input_c, cnf.expanded_c))]# projectself.layers += [('project_conv',ConvBNActivation(cnf.expanded_c, cnf.out_c, kernel_size=1, norm_layer=norm_layer, activation_layer=None))]self.out_channels = cnf.out_cself.is_strided = cnf.stride > 1# 只有在使用shortcut连接时才使用dropout层if self.use_res_connect and cnf.drop_rate > 0:self.dropout = cnf.drop_rateelse:self.dropout = Nonewith self.init_scope():for n in self.layers:if not n[0].startswith('_'):setattr(self, n[0], n[1])def forward(self, x):short_cut = xfor n, f in self.layers:if not n.startswith('_'):x = getattr(self, n)(x)else:x = f.apply((x,))[0]if self.dropout is not None:x = drop_connect(x,self.dropout)if self.use_res_connect:x += short_cutreturn xclass EfficientNet_V1(chainer.Chain):cfgs={'efficientnetv1_b0':{'image_size':224,'width_coefficient':1.0, 'depth_coefficient':1.0, 'drop_connect_rate':0.2,'dropout_rate':0.2},'efficientnetv1_b1':{'image_size':240,'width_coefficient':1.0, 'depth_coefficient':1.1, 'drop_connect_rate':0.2,'dropout_rate':0.2},'efficientnetv1_b2':{'image_size':260,'width_coefficient':1.1, 'depth_coefficient':1.2, 'drop_connect_rate':0.2,'dropout_rate':0.3},'efficientnetv1_b3':{'image_size':300,'width_coefficient':1.2, 'depth_coefficient':1.4, 'drop_connect_rate':0.2,'dropout_rate':0.3},'efficientnetv1_b4':{'image_size':380,'width_coefficient':1.4, 'depth_coefficient':1.8, 'drop_connect_rate':0.2,'dropout_rate':0.4},'efficientnetv1_b5':{'image_size':456,'width_coefficient':1.6, 'depth_coefficient':2.2, 'drop_connect_rate':0.2,'dropout_rate':0.4},'efficientnetv1_b6':{'image_size':528,'width_coefficient':1.8, 'depth_coefficient':2.6, 'drop_connect_rate':0.2,'dropout_rate':0.5},'efficientnetv1_b7':{'image_size':600,'width_coefficient':2.0, 'depth_coefficient':3.1, 'drop_connect_rate':0.2,'dropout_rate':0.5}}def __init__(self,model_name='efficientnetv1_b0',channels=3,num_classes: int = 1000,batch_size=4,image_size=224,block = None,norm_layer = None,**kwargs):super(EfficientNet_V1, self).__init__()self.model_name = model_nameself.image_size = image_size# kernel_size, in_channel, out_channel, exp_ratio, strides, use_SE, drop_connect_rate, repeatsdefault_cnf = [[3, 32, 16, 1, 1, True, self.cfgs[self.model_name]['drop_connect_rate'], 1],[3, 16, 24, 6, 2, True, self.cfgs[self.model_name]['drop_connect_rate'], 2],[5, 24, 40, 6, 2, True, self.cfgs[self.model_name]['drop_connect_rate'], 2],[3, 40, 80, 6, 2, True, self.cfgs[self.model_name]['drop_connect_rate'], 3],[5, 80, 112, 6, 1, True, self.cfgs[self.model_name]['drop_connect_rate'], 3],[5, 112, 192, 6, 2, True, self.cfgs[self.model_name]['drop_connect_rate'], 4],[3, 192, 320, 6, 1, True, self.cfgs[self.model_name]['drop_connect_rate'], 1]]def round_repeats(repeats):return int(math.ceil(self.cfgs[self.model_name]['depth_coefficient'] * repeats))if block is None:block = InvertedResidualif norm_layer is None:norm_layer = partial(BatchNormalization, eps=1e-3)adjust_channels = partial(InvertedResidualConfig.adjust_channels, width_coefficient=self.cfgs[self.model_name]['width_coefficient'])# build inverted_residual_settingbneck_conf = partial(InvertedResidualConfig, width_coefficient=self.cfgs[self.model_name]['width_coefficient'])b = 0num_blocks = float(sum(round_repeats(i[-1]) for i in default_cnf))inverted_residual_setting = []for stage, args in enumerate(default_cnf):cnf = copy.copy(args)for i in range(round_repeats(cnf.pop(-1))):if i > 0:# strides equal 1 except first cnfcnf[-3] = 1  # stridescnf[1] = cnf[2]  # input_channel equal output_channelcnf[-1] = args[-2] * b / num_blocks  # update dropout ratioindex = str(stage + 1) + chr(i + 97)  # 1a, 2a, 2b, ...inverted_residual_setting.append(bneck_conf(*cnf, index))b += 1# create layersself.layers = []# first convself.layers += [('stem_conv',ConvBNActivation(in_planes=channels, out_planes=adjust_channels(32), kernel_size=3, stride=2, norm_layer=norm_layer))]output_size = int((self.image_size-3+2*((3-1)//2))/2+1)# building inverted residual blocksfor cnf in inverted_residual_setting:self.layers += [(cnf.index,block(cnf, norm_layer))]output_size = math.ceil(output_size / cnf.stride)# build toplast_conv_input_c = inverted_residual_setting[-1].out_clast_conv_output_c = adjust_channels(1280)self.layers += [('top',ConvBNActivation(in_planes=last_conv_input_c, out_planes=last_conv_output_c, kernel_size=1, norm_layer=norm_layer))]output_size = int((output_size-1+2*((1-1)//2))/1+1)self.layers += [('_avgpool',AveragePooling2D(ksize=output_size,stride=1,pad=0))]self.layers += [('_reshape',Reshape((batch_size,last_conv_output_c)))]if self.cfgs[self.model_name]['dropout_rate'] > 0:self.layers += [("_dropout1",Dropout(self.cfgs[self.model_name]['dropout_rate']))]self.layers += [('fc',L.Linear(last_conv_output_c, num_classes))]with self.init_scope():for n in self.layers:if not n[0].startswith('_'):setattr(self, n[0], n[1])def forward(self, x):for n, f in self.layers:origin_size = x.shapeif not n.startswith('_'):x = getattr(self, n)(x)else:x = f.apply((x,))[0]print(n,origin_size,x.shape)if chainer.config.train:return xreturn F.softmax(x)

注意此类就是EfficientNet_V1的实现过程,注意网络的前向传播过程中,分了训练以及测试。
训练过程中直接返回x,测试过程中会进入softmax得出概率

调用方式

if __name__ == '__main__':batch_size = 4n_channels = 3image_size = 224num_classes = 123model = EfficientNet_V1(num_classes=num_classes, channels=n_channels,image_size=image_size,batch_size=batch_size)print("参数量",model.count_params())x = np.random.rand(batch_size, n_channels, image_size, image_size).astype(np.float32)t = np.random.randint(0, num_classes, size=(batch_size,)).astype(np.int32)with chainer.using_config('train', True):y1 = model(x)loss1 = F.softmax_cross_entropy(y1, t)

efficientnetv1_b0:一次前向传播参数量

efficientnetv1_b7:一次前向传播参数量

chainer-骨干网络backbone-EfficientNet_V1代码重构【附源码】相关推荐

  1. 生成对抗网络(GANs)的资料小结,另附:资源|17类对抗网络经典论文及开源代码(附源码)

    1.GANs的一些资料链接 ************************************************** *********************************** ...

  2. Java毕设项目钢材商贸公司网络购销管理系统计算机(附源码+系统+数据库+LW)

    Java毕设项目钢材商贸公司网络购销管理系统计算机(附源码+系统+数据库+LW) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也 ...

  3. 转用PHP开发企业Wifi网络Web认证系统(附源码)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://beastwu.blog.51cto.com/5091229/865707 本案是 ...

  4. 用PHP开发企业Wifi网络Web认证系统(附源码)

    文字转载自https://blog.51cto.com/beastwu/865707 本案是为客户的合作单位开发的无线网络的网页认证系统. 本系统实现基于Web的Windows Active Dire ...

  5. HTML浪漫动态表白代码+音乐(附源码)

    HTML浪漫表白求爱(附源码),内含4款浪漫的表白源码,可用于520,情人节,生日,求爱场景,下载直接使用. 直接上源码吧 一.红色爱心 1.效果 实际效果是动态的哦 2.源码 复制粘贴即可运行哦 & ...

  6. html div初始隐藏点击可见_3种CSS3移动手机隐藏菜单UI界面代码解析/附源码下载...

    这是一款效果非常酷的jQuery和CSS3移动手机隐藏菜单UI界面设计.这个UI设计共有三种不同的打开隐藏菜单的效果,分别为滑动显示,Material Design风格效果和展开式效果. 使用方法 H ...

  7. android 网络编程实现,Android开发使用HttpURLConnection进行网络编程详解【附源码下载】...

    本文实例讲述了Android开发使用HttpURLConnection进行网络编程.分享给大家供大家参考,具体如下: --HttpURLConnection URLConnection已经可以非常方便 ...

  8. 李峋同款爱心代码(附源码)

    李峋同款浪漫爱心代码(快拿去给爸爸妈妈,给男(女)朋友看!!!) 基于新建文件基础上.txt文档 <html> <head><meta charset="utf ...

  9. 李峋同款爱心代码(附源码,前端代码,python代码)

    Hello 大家好 如何浪漫的表白,作为程序员出身的小编,今天就带你实现热播剧<点燃我,温暖你>中超火的李峋同款爱心代码!前面是教程,怕麻烦的朋友可以直接划到文末,下载现成的,下载完成后打 ...

  10. 黑马旅游网项目详细思路和完整代码整理 -附源码

    黑马旅游网项目详细思路和完整代码整理 前言 由于新冠病毒的原因,无法上学.百无聊赖下自己开始看视频学习,跟着视频做完了这个项目来检验学习成果,顺便写篇博客来记录一下. 话不多说,开始正题. 文档及其源 ...

最新文章

  1. 移动网络安全不容忽视 对恶意程序打好防范补丁
  2. php fpm listen.owner,php-fpm配置解释
  3. mysql索引碎片产生原因_解析mysql 表中的碎片产生原因以及清理
  4. 黑苹果hp有声音hdmi无声音_黑科技!不戴耳机也能独享声音!以色列公司推出无耳机传输音乐...
  5. Sharepoint 2010使用手记(1)
  6. UVA272--TEX Quotes【字符串】
  7. 腾讯视频下载安装链接_腾讯视频怎么上传视频
  8. react-native 自定义 下拉刷新 / 上拉加载更多 组件
  9. C语言实现24点小游戏,C语言解24点游戏程序
  10. 推荐一款我私藏已久的串口示波神器
  11. gbk与gb2312的区别是什么?
  12. python诗歌文件格式处理_Python诗歌的依赖版本语法
  13. ios 隐藏app的插件_iPhone如何隐藏App图标?iOS9不越狱隐藏App小技巧
  14. Navicat导入mdf文件(用导入向导)
  15. uniapp使用企业微信SDK踩坑指南
  16. html链接变灰,怎么在HTML中设置点击超链接后变成灰色
  17. 国内手机号码11位的原因
  18. Access时间日期比较查询的方法总结
  19. PHP——四舍五入取整、向上取整、向下取整、小数截取
  20. 互联网早报:滴滴正式启动造车,滴滴副总裁、小桔车服总经理杨峻负责

热门文章

  1. python3 微博群关注 自动发群消息
  2. 动力环境集中监控系统的数据传输方式
  3. [学习笔记]dp凸优化/wqs二分[八省联考2018]林克卡特树lct
  4. python注释多行代码快捷键_python学习笔记(五)---sublime text 多行代码注释快捷键...
  5. WPS幻灯片保姆级制作教程
  6. Typora 的下载安装 简单使用
  7. 计算机基础比赛的相关主题,计算机基础知识应用竞赛策划书
  8. 新版iTunes Connect提交应用
  9. openoffice免费安装教程
  10. Adobe CC全线产品更新,优化Win8.1触控