Rfb-Net(代码解读慢慢啃).

接上一篇

Rfb-Net目标检测算法特征提取模块流程设计及原理文档

论文链接:论文
翻译:CSDN博客
个人记录.有错请指导~

1.Module and structure

在这里插入图片描述
该模块为Rfb-Net主要内容.该模块是模拟人的视觉的eccentricity(偏心率)

1.1Basic - RFB

class BasicRFB(nn.Module):

    def __init__(self, in_planes, out_planes, stride=1, scale = 0.1, visual = 1):
	'''
	:param in_planes:输入尺寸
	:param out_planes:输出尺寸
	:param stride:步长
	:param scale:权重比例
	:param visual:rate
	'''

	super(BasicRFB, self).__init__()
	self.scale = scale
	self.out_channels = out_planes
	inter_planes = in_planes // 8#(为什么除以8取整数?????)(可能是因为效果好?随意?.)
	self.branch0 = nn.Sequential(
	        BasicConv(in_planes, 2*inter_planes, kernel_size=1, stride=stride),
	        BasicConv(2*inter_planes, 2*inter_planes, kernel_size=3, stride=1, padding=visual, dilation=visual, relu=False)
	        )
	self.branch1 = nn.Sequential(
	        BasicConv(in_planes, inter_planes, kernel_size=1, stride=1),
	        BasicConv(inter_planes, 2*inter_planes, kernel_size=(3,3), stride=stride, padding=(1,1)),
	        BasicConv(2*inter_planes, 2*inter_planes, kernel_size=3, stride=1, padding=visual+1, dilation=visual+1, relu=False)
	        )
	self.branch2 = nn.Sequential(
	        BasicConv(in_planes, inter_planes, kernel_size=1, stride=1),
	        BasicConv(inter_planes, (inter_planes//2)*3, kernel_size=3, stride=1, padding=1),
	        BasicConv((inter_planes//2)*3, 2*inter_planes, kernel_size=3, stride=stride, padding=1),
	        BasicConv(2*inter_planes, 2*inter_planes, kernel_size=3, stride=1, padding=2*visual+1, dilation=2*visual+1, relu=False)
	        )

	self.ConvLinear = BasicConv(6*inter_planes, out_planes, kernel_size=1, stride=1, relu=False)
	self.shortcut = BasicConv(in_planes, out_planes, kernel_size=1, stride=stride, relu=False)
	self.relu = nn.ReLU(inplace=False)

    def forward(self,x):
	x0 = self.branch0(x)#经过一个1*1卷积,一个3*3卷积(dilation)
	x1 = self.branch1(x)#经过一个1*1 3*3 3*3(dilation)
	x2 = self.branch2(x)#经过一个1*1 3*3 3*3 3*3(dilation)

	out = torch.cat((x0,x1,x2),1)#cat三个branch的features
	out = self.ConvLinear(out)#1*1卷积
	short = self.shortcut(x)#残差网络 1*1
	out = out*self.scale + short#残差网络
#从这看出 输入经过RFB模块 输出和输入的尺寸一样. scale设置为1
	out = self.relu(out)#激活函数

	return out

从代码看出,代码与图所示的有一点小小区别,第一个是将5x5分为2个3x3,第二个是rate的值,也就是代码中dilation.这部分后面再讨论.
  从代码可以看出该模块为图(a)RFB模块 但是稍有改动,如图所示: 自己随意画了下

在这里插入图片描述
从图中可以看出branch0的分支为2(通过后续代码得到输入visual第一个值为2).仔细查看branch012之间的visual关系为 v:v+1:2v+1是无法达到1:3:5的.还有个就是第三分支中,55改成了两个33,这里论文中提到过了,所以代码还是稍微有点改动的.(或者是论文实验部分提到)
我们再研究下为什么这个模块可以当作模拟人的视觉的偏心率.首先我们来看一下什么叫偏心率:这是一个医学上面的理念,原文是这样解释的:
During the past few decades, it has come true that functional Magnetic Resonance Imaging (fMRI) non-invasively measures human brain activities at a resolution in millimeter, and RF modeling has become an important sensory science tool used to predict responses and clarify brain computations. Since human neuroscience instruments often observe the pooled responses of many neurons,
these models are thus commonly called pRF models [36]. Based on fMRI and pRF modeling, it is possible to investigate the relation across many visual field maps in the cortex. At each cortical map, researchers find a positive correlation between pRF size and eccentricity [36], while the coefficient of correlation varies in visual field maps, as shown in Fig. 1

总结就是:处理视野受限区域中的信息的感受野(RF)是视觉系统神经元的关键属性。

1.2 Basic-RFB-a

模块代码如下

class BasicRFB_a(nn.Module):

    def __init__(self, in_planes, out_planes, stride=1, scale = 0.1):
		super(BasicRFB_a, self).__init__()
		self.scale = scale
		self.out_channels = out_planes
		inter_planes = in_planes //4#???

		self.branch0 = nn.Sequential(
			BasicConv(in_planes, inter_planes, kernel_size=1, stride=1),
			BasicConv(inter_planes, inter_planes, kernel_size=3, stride=1, padding=1,relu=False)
			)
		self.branch1 = nn.Sequential(
			BasicConv(in_planes, inter_planes, kernel_size=1, stride=1),
			BasicConv(inter_planes, inter_planes, kernel_size=(3,1), stride=1, padding=(1,0)),
			BasicConv(inter_planes, inter_planes, kernel_size=3, stride=1, padding=3, dilation=3, relu=False)
			)
		self.branch2 = nn.Sequential(
			BasicConv(in_planes, inter_planes, kernel_size=1, stride=1),
			BasicConv(inter_planes, inter_planes, kernel_size=(1,3), stride=stride, padding=(0,1)),
			BasicConv(inter_planes, inter_planes, kernel_size=3, stride=1, padding=3, dilation=3, relu=False)
			)
		self.branch3 = nn.Sequential(
			BasicConv(in_planes, inter_planes//2, kernel_size=1, stride=1),
			BasicConv(inter_planes//2, (inter_planes//4)*3, kernel_size=(1,3), stride=1, padding=(0,1)),extras
			BasicConv((inter_planes//4)*3, inter_planes, kernel_size=(3,1), stride=stride, padding=(1,0)),
			BasicConv(inter_planes, inter_planes, kernel_size=3, stride=1, padding=5, dilation=5, relu=False)
			)

		self.ConvLinear = BasicConv(4*inter_planes, out_planes, kernel_size=1, stride=1, relu=False)extras
		self.shortcut = BasicConv(in_planes, out_planes, kernel_size=1, stride=stride, relu=False)
		self.relu = nn.ReLU(inplace=False)

    def forward(self,x):
		x0 = self.branch0(x)#经过 1*1 3*3
		x1 = self.branch1(x)#经过 1*1 3*1 3*3(dilation=3) 
		x2 = self.branch2(x)#经过 1*1 1*3 3*3(dilation=3)
		x3 = self.branch3(x)#经过 1*1 1*3 3*1 3*3(dilation=5)

		out = torch.cat((x0,x1,x2,x3),1)#合并分支
		out = self.ConvLinear(out)#经过1*1
		short = self.shortcut(x)#残差网络 1*1
		out = out*self.scale + short#残差网络
		out = self.relu(out)

	return out

下周再研究研究,总感觉代码和论文有点不一样.

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值