DenNet⽹络结构的讲解与代码实现
⽬录
1.概念
DenNet:采⽤密集连接机制,即互相连接所有的层,每个层都会与前⾯的层在channel(通道)维度上连接道⼀起,实现特征重⽤,作为下
⼀层的输⼊。
这样操作的好处在于不仅减缓了梯度消失的问题,也可使其在参数与计算量更少的情况下实现⽐Resnet更优的性能。
2.公式
在DenNet中,会连接前⾯所有层作为输⼊,它的公式为
其中H(.)代表的是⾮线性转化函数,它是⼀个组合操作,其可能包括⼀系列的BN,ReLU,Pooling及Conv的操作。
特征传递⽅式是直接将前⾯所有层的特征concat后传到下⼀个层,⽽不是前⾯层都要有⼀个箭头指向后⾯的所有层。
3.⽹络结构
DenNet⽹络中模块主要由**DenBlock+Transition**组成
3.1DenBlock
1.其中DenBlock其中的每⼀个“圆点”代表的使⽤BN+ReLU+Conv(3*3)层的组成。
2.假定输⼊层的特征层的channel为k0。DenBlock中各个卷积之后均输出k个特征图。即得到得特征图的channel数为k。那么L层输
⼊的channel为k0+(L-1)k.
3.采⽤的是BN+ReLU+Conv的pre-position的结构。作者验证过这种反⽅向的组合效果更好。
neck
由于后⾯的层输⼊channel会⾮常⼤,DenBlock有其扩展版,即DensBlock_B。其和普通版的区别在于DenBlock_B在前⾯使
⽤了bottleneck
(BN+ReLU+(1*1)Conv)的1*1的卷积层⽤于降维。(即DensBlock_B的结构为(BN+ReLU+Conv(1*
1)+BN+ReLU+Conv(3*3))
1*1卷积输出的通道数通常是GrowthRate的4倍。(GrowthRate即为增长率,⼀般为16、32.....)
附:
若不适⽤1*1的卷积层进⾏降维,则到后⾯输出的通道数可能会很⼤。
例如:
输⼊通道数为64,增长率为32,经过15个bottleneck,则通道数输出为64+32X15=544
若不适⽤1X1的卷积进⾏降维,则第16个bottleneck层的参数量是3X3X544X32=156672
若使⽤1X1的卷积进⾏降维,则第16个bottleneck层的参数为1X1X544X128+3X3X128X32=106496
可以看到参数量减少了1/3。
3.2Transition层
1.主要作⽤在于连接两个相邻的Denblock,并且降低特征图的⼤⼩
Transition层包括⼀个1X1的卷积与2X2的AvgPooling的结构。
ion的主要起到压缩模型的作⽤
Transition层可以输出[xm]个特征,其中x是压缩系数。当x=1时,表⽰⽆压缩,特征个数经过Transition层没有变化。
当x⼩于1时,这种结构称为DenNet-C,⼀般使⽤x=0.5
对于使⽤Bottleneck层的DenBlock结构压缩系数⼩于1的Transition组合结构成为Dennet-BC。
4DenNet的主要优点与缺点
优点
1.更强的梯度流动,减轻了梯度消失在⽹络深度越深的时候越容易出现。
2.减少了参数量
3.保存了低维度的特征
缺点
运⾏时容易占⽤显存的⼤⼩
5代码实现
DenNet的⽹络结构图,代码主要是实现**DenNet-121层⽹络结构**
5.1Denblock代码实现
#构建DenBlock中的内部结构
#通过语法结构,把这个当成⼀个layer即可.
#bottleneck+DenBlock==>DenNet-B
class_DenLayer(tial):
#num_input_features作为输⼊特征层的通道数,growth_rate增长率,bn_size输出的倍数⼀般都是4,drop_rate判断是都进⾏dropout层进⾏处理
def__init__(lf,num_input_features,growth_rate,bn_size,drop_rate):
super(_DenLayer,lf).__init__()
_module('norm1',orm2d(num_input_features))
_module('relu1',(inplace=True))
_module('conv1',2d(num_input_features,bn_size*growth_rate,kernel_size=1,stride=1,bias=Fal))
_module('norm2',orm2d(bn_size*growth_rate))
_module('relu2',(inplace=True))
_module('conv2',2d(bn_size*growth_rate,growth_rate,kernel_size=3,stride=1,padding=1,bias=Fal))
_rate=drop_rate
defforward(lf,x):
new_features=super(_DenLayer,lf).forward(x)
_rate>0:
new_features=t(new_features,p=_rate,training=ng)
([x,new_features],1)
#定义Denblock模块
class_DenBlock(tial):
def__init__(lf,num_layers,num_input_features,bn_size,growth_rate,drop_rate):
super(_DenBlock,lf).__init__()
foriinrange(num_layers):
layer=_DenLayer(num_input_features+i*growth_rate,growth_rate,bn_size,drop_rate)
_module("denlayer%d"%(i+1),layer)
5.2Transition代码实现
#定义Transition层
#负责将Denblock连接起来,⼀般都有0.5的维道(通道数)的压缩
class_Transition(tial):
def__init__(lf,num_input_features,num_output_features):
super(_Transition,lf).__init__()
_module('norm',orm2d(num_input_features))
_module('relu',(inplace=True))
_module('conv',2d(num_input_features,num_output_features,kernel_size=1,stride=1,bias=Fal))
_module('pool',l2d(2,stride=2))
5.3DenNet-121完整代码实现
importtorch
onalasF
fromtorchsummaryimportsummary
fromtorchstatimportstat
fromcollectionsimportOrderedDict
#构建DenBlock中的内部结构
#通过语法结构,把这个当成⼀个layer即可.
#bottleneck+DenBlock==>DenNet-B
class_DenLayer(tial):
#num_input_features作为输⼊特征层的通道数,growth_rate增长率,bn_size输出的倍数⼀般都是4,drop_rate判断是都进⾏dropout层进⾏处理
def__init__(lf,num_input_features,growth_rate,bn_size,drop_rate):
super(_DenLayer,lf).__init__()
_module('norm1',orm2d(num_input_features))
_module('relu1',(inplace=True))
_module('conv1',2d(num_input_features,bn_size*growth_rate,kernel_size=1,stride=1,bias=Fal))
_module('norm2',orm2d(bn_size*growth_rate))
_module('relu2',(inplace=True))
_module('conv2',2d(bn_size*growth_rate,growth_rate,kernel_size=3,stride=1,padding=1,bias=Fal))
_rate=drop_rate
defforward(lf,x):
new_features=super(_DenLayer,lf).forward(x)
_rate>0:
new_features=t(new_features,p=_rate,training=ng)
([x,new_features],1)
#定义Denblock模块
class_DenBlock(tial):
def__init__(lf,num_layers,num_input_features,bn_size,growth_rate,drop_rate):
super(_DenBlock,lf).__init__()
foriinrange(num_layers):
layer=_DenLayer(num_input_features+i*growth_rate,growth_rate,bn_size,drop_rate)
_module("denlayer%d"%(i+1),layer)
#定义Transition层
#负责将Denblock连接起来,⼀般都有0.5的维道(通道数)的压缩
class_Transition(tial):
def__init__(lf,num_input_features,num_output_features):
super(_Transition,lf).__init__()
_module('norm',orm2d(num_input_features))
_module('relu',(inplace=True))
_module('conv',2d(num_input_features,num_output_features,kernel_size=1,stride=1,bias=Fal))
_module('pool',l2d(2,stride=2))
#实现DenNet⽹络
#实现DenNet⽹络
classDenNet():
def__init__(lf,growth_rate=32,block_config=(6,12,24,26),num_init_features=64,bn_size=4,comparession_rate=0.5,drop_rate=0,num_class=1000):
super(DenNet,lf).__init__()
#前⾯卷积层+最⼤池化
es=tial(OrderedDict([
('conv0',2d(3,num_init_features,kernel_size=7,stride=2,padding=3,bias=Fal)),
('norm0',orm2d(num_init_features)),
('relu0',(inplace=True)),
('pool0',l2d(3,stride=2,padding=1))
]))
#Denblock
num_features=num_init_features
fori,num_layersinenumerate(block_config):
block=_DenBlock(num_layers,num_features,bn_size,growth_rate,drop_rate)
_module("denblock%d"%(i+1),block)
num_features+=num_layers*growth_rate#确定⼀个DenBlock输出的通道数
ifi!=len(block_config)-1:#判断是不是最后⼀个Denblock
transition=_Transition(num_features,int(num_features*comparession_rate))
_module("transition%d"%(i+1),transition)
num_features=int(num_features*comparession_rate)#为下⼀个DenBlock的输出做准备
#Finalbn+ReLu
_module('norm5',orm2d(num_features))
_module('relu5',(inplace=True))
#classificationlayer
fier=(num_features,num_class)
#paramsinitalization
s():
ifisinstance(m,2d):
g_normal_()
elifisinstance(m,orm2d):
nt_(,0)
nt_(,1)
elifisinstance(m,):
nt_(,0)
defforward(lf,x):
features=es(x)
out=_pool2d(features,7,stride=1).view((0),-1)
out=fier(out)
returnout
defdennet121(pretrained=Fal,**kwargs):
"""DenNet121"""
model=DenNet(num_init_features=64,growth_rate=32,block_config=(6,12,24,16),
**kwargs)
returnmodel
if__name__=='__main__':
#输出模型的结构
den=dennet121()
#输出模型每层的输出
device=('cuda'_available()el'cpu')
den=(device)
#summary(den,input_size=(3,416,416),batch_size=3)
#每层模型的输⼊输出(这个能同时显⽰输⼊输出)
#stat(den,(3,416,416))
本文发布于:2023-01-03 19:03:42,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/86010.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |