【图像分类】用最简单的代码复现SENet,初学者一定不要错过(pytorch)

out += residual

return F.relu(out)

第二个残差模块


第二个残差模块用于实现ResNet50、ResNet101、ResNet152模型,SENet模块嵌入到第三个卷积后面。

class Bottleneck(nn.Module):

def init(self, in_places, places, stride=1, downsampling=False, expansion=4):

super(Bottleneck, self).init()

self.expansion = expansion

self.downsampling = downsampling

self.bottleneck = nn.Sequential(

nn.Conv2d(in_channels=in_places, out_channels=places, kernel_size=1, stride=1, bias=False),

nn.BatchNorm2d(places),

nn.ReLU(inplace=True),

nn.Conv2d(in_channels=places, out_channels=places, kernel_size=3, stride=stride, padding=1, bias=False),

nn.BatchNorm2d(places),

nn.ReLU(inplace=True),

nn.Conv2d(in_channels=places, out_channels=places * self.expansion, kernel_size=1, stride=1, bias=False),

nn.BatchNorm2d(places * self.expansion),

)

self.se = SELayer(places * self.expansion, 16)

if self.downsampling:

self.downsample = nn.Sequential(

nn.Conv2d(in_channels=in_places, out_channels=places * self.expansion, kernel_size=1, stride=stride,

bias=False),

nn.BatchNorm2d(places * self.expansion)

)

self.relu = nn.ReLU(inplace=True)

def forward(self, x):

residual = x

out = self.bottleneck(x)

out = self.se(out)

if self.downsampling:

residual = self.downsample(x)

out += residual

out = self.relu(out)

return out

SEResNet18、SEResNet34模型的完整代码


import torch

import torchvision

from torch import nn

from torch.nn import functional as F

from torchsummary import summary

class SELayer(nn.Module):

def init(self, channel, reduction=16):

super(SELayer, self).init()

self.avg_pool = nn.AdaptiveAvgPool2d(1)

self.fc = nn.Sequential(

nn.Linear(channel, channel // reduction, bias=False),

nn.ReLU(inplace=True),

nn.Linear(channel // reduction, channel, bias=False),

nn.Sigmoid()

)

def forward(self, x):

b, c, _, _ = x.size()

y = self.avg_pool(x).view(b, c)

y = self.fc(y).view(b, c, 1, 1)

return x * y.expand_as(x)

class ResidualBlock(nn.Module):

“”"

实现子module: Residual Block

“”"

def init(self, inchannel, outchannel, stride=1, shortcut=None):

super(ResidualBlock, self).init()

self.left = nn.Sequential(

nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),

nn.BatchNorm2d(outchannel),

nn.ReLU(inplace=True),

nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),

nn.BatchNorm2d(outchannel)

)

self.se = SELayer(outchannel, 16)

self.right = shortcut

def forward(self, x):

out = self.left(x)

out= self.se(out)

residual = x if self.right is None else self.right(x)

out += residual

return F.relu(out)

class ResNet(nn.Module):

“”"

实现主module:ResNet34

ResNet34包含多个layer,每个layer又包含多个Residual block

用子module来实现Residual block,用_make_layer函数来实现layer

“”"

def init(self, blocks, num_classes=1000):

super(ResNet, self).init()

self.model_name = ‘resnet34’

前几层: 图像转换

self.pre = nn.Sequential(

nn.Conv2d(3, 64, 7, 2, 3, bias=False),

nn.BatchNorm2d(64),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2, 1))

重复的layer,分别有3,4,6,3个residual block

self.layer1 = self._make_layer(64, 64, blocks[0])

self.layer2 = self._make_layer(64, 128, blocks[1], stride=2)

self.layer3 = self._make_layer(128, 256, blocks[2], stride=2)

self.layer4 = self._make_layer(256, 512, blocks[3], stride=2)

分类用的全连接

self.fc = nn.Linear(512, num_classes)

def _make_layer(self, inchannel, outchannel, block_num, stride=1):

“”"

构建layer,包含多个residual block

“”"

shortcut = nn.Sequential(

nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),

nn.BatchNorm2d(outchannel),

nn.ReLU()

)

layers = []

layers.append(ResidualBlock(inchannel, outchannel, stride, shortcut))

for i in range(1, block_num):

layers.append(ResidualBlock(outchannel, outchannel))

return nn.Sequential(*layers)

def forward(self, x):

x = self.pre(x)

x = self.layer1(x)

x = self.layer2(x)

x = self.layer3(x)

x = self.layer4(x)

x = F.avg_pool2d(x, 7)

x = x.view(x.size(0), -1)

return self.fc(x)

def Se_ResNet18():

return ResNet([2, 2, 2, 2])

def Se_ResNet34():

return ResNet([3, 4, 6, 3])

if name == ‘main’:

device = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)

model = Se_ResNet34()

model.to(device)

summary(model, (3, 224, 224))

SEResNet50、SEResNet101、SEResNet152完整


import torch

import torch.nn as nn

import torchvision

import numpy as np

from torchsummary import summary

print("PyTorch Version: ", torch.version)

print("Torchvision Version: ", torchvision.version)

all = [‘SEResNet50’, ‘SEResNet101’, ‘SEResNet152’]

class SELayer(nn.Module):

def init(self, channel, reduction=16):

super(SELayer, self).init()

self.avg_pool = nn.AdaptiveAvgPool2d(1)

self.fc = nn.Sequential(

nn.Linear(channel, channel // reduction, bias=False),

nn.ReLU(inplace=True),

nn.Linear(channel // reduction, channel, bias=False),

nn.Sigmoid()

)

def forward(self, x):

b, c, _, _ = x.size()

y = self.avg_pool(x).view(b, c)

y = self.fc(y).view(b, c, 1, 1)

return x * y.expand_as(x)

def Conv1(in_planes, places, stride=2):

return nn.Sequential(

nn.Conv2d(in_channels=in_planes, out_channels=places, kernel_size=7, stride=stride, padding=3, bias=False),

nn.BatchNorm2d(places),

nn.ReLU(inplace=True),

nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

)

class Bottleneck(nn.Module):

def init(self, in_places, places, stride=1, downsampling=False, expansion=4):

super(Bottleneck, self).init()

self.expansion = expansion

self.downsampling = downsampling

self.bottleneck = nn.Sequential(

nn.Conv2d(in_channels=in_places, out_channels=places, kernel_size=1, stride=1, bias=False),

nn.BatchNorm2d(places),

nn.ReLU(inplace=True),

nn.Conv2d(in_channels=places, out_channels=places, kernel_size=3, stride=stride, padding=1, bias=False),

nn.BatchNorm2d(places),

nn.ReLU(inplace=True),

nn.Conv2d(in_channels=places, out_channels=places * self.expansion, kernel_size=1, stride=1, bias=False),

nn.BatchNorm2d(places * self.expansion),

)

self.se = SELayer(places * self.expansion, 16)

if self.downsampling:

self.downsample = nn.Sequential(

nn.Conv2d(in_channels=in_places, out_channels=places * self.expansion, kernel_size=1, stride=stride,

bias=False),

nn.BatchNorm2d(places * self.expansion)

)

self.relu = nn.ReLU(inplace=True)

def forward(self, x):

residual = x

out = self.bottleneck(x)

out = self.se(out)

if self.downsampling:

residual = self.downsample(x)

out += residual

out = self.relu(out)

return out

class ResNet(nn.Module):

def init(self, blocks, num_classes=1000, expansion=4):

super(ResNet, self).init()

self.expansion = expansion

self.conv1 = Conv1(in_planes=3, places=64)

self.layer1 = self.make_layer(in_places=64, places=64, block=blocks[0], stride=1)

self.layer2 = self.make_layer(in_places=256, places=128, block=blocks[1], stride=2)

self.layer3 = self.make_layer(in_places=512, places=256, block=blocks[2], stride=2)

self.layer4 = self.make_layer(in_places=1024, places=512, block=blocks[3], stride=2)

self.avgpool = nn.AvgPool2d(7, stride=1)

self.fc = nn.Linear(2048, num_classes)

for m in self.modules():

if isinstance(m, nn.Conv2d):

nn.init.kaiming_normal_(m.weight, mode=‘fan_out’, nonlinearity=‘relu’)

elif isinstance(m, nn.BatchNorm2d):

nn.init.constant_(m.weight, 1)

nn.init.constant_(m.bias, 0)

def make_layer(self, in_places, places, block, stride):

layers = []

layers.append(Bottleneck(in_places, places, stride, downsampling=True))

for i in range(1, block):

layers.append(Bottleneck(places * self.expansion, places))

return nn.Sequential(*layers)

def forward(self, x):

x = self.conv1(x)

x = self.layer1(x)

x = self.layer2(x)

x = self.layer3(x)

x = self.layer4(x)

x = self.avgpool(x)

x = x.view(x.size(0), -1)

x = self.fc(x)

return x

def SEResNet50():

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-mSfm4Q5a-1713723875560)]

[外链图片转存中…(img-d1gEGAyx-1713723875561)]

[外链图片转存中…(img-4hr3NugD-1713723875562)]

[外链图片转存中…(img-aYBfC59u-1713723875563)]

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值