写在前面
1.深度学习往往需要自己定义网络框架,无论是复现还是找创新点。
2.网络结构的改进算不上创新,但也往往是基础中的基础。
3.这里写一下自己搭建的一些方式和习惯。
简单搭建
1.导入pytorch。
import torch
import torch.nn as nn
import torch.nn.functional as F
2.定义网络结构并引入测试。
class MyNetwork(nn.Module):
def __init__(self, in_channel=1, num_class=2):
super(MyNetwork, self).__init__()
self.num_classes = num_class
self.in_channel =in_channel
def forward(self, x):
return x
if __name__ == '__main__':
device = torch.device('cpu')
input=torch.randn(1, 1, 48, 48, 32).to(device)
net=MyNetwork().to(device)
out=net(input)
print(out.shape)
3.写入卷积层、池化层。
class MyNetwork(nn.Module):
def __init__(self, in_channel=1, num_class=2):
super(MyNetwork, self).__init__()
self.num_classes = num_class
self.in_channel =in_channel
self.conv = nn.Conv3d(1, 1, kernel_size=(3,3,3), padding=(1,1,1))
self.pool = nn.MaxPool3d(kernel_size=2,stride=2)
def forward(self, x):
x = self.conv(x)
x = self.pool(x)
return x
if __name__ == '__main__':
device = torch.device('cpu')
input=torch.randn(1, 1, 48, 48, 32).to(device)
net=MyNetwork().to(device)
out=net(input)
print(out.shape)
4.封装卷积。
class ContinusParalleConv(nn.Module):
def __init__(self, in_channels, out_channels):
super(ContinusParalleConv, self).__init__()
self.in_channels = in_channels
self.out_channels = out_channels
self.Conv_forward = nn.Sequential(
nn.Conv3d(self.in_channels, self.out_channels, kernel_size=(3,3,3), padding=(1,1,1)),
nn.BatchNorm3d(out_channels),
nn.ReLU(),
nn.Conv3d(self.out_channels, self.out_channels, kernel_size=(3,3,3), padding=(1,1,1)),
nn.BatchNorm3d(self.out_channels),
nn.ReLU()
)
def forward(self, x):
x = self.Conv_forward(x)
return x
class MyNetwork(nn.Module):
def __init__(self, in_channel=1, num_class=2):
super(MyNetwork, self).__init__()
self.num_classes = num_class
self.in_channel =in_channel
self.conv = ContinusParalleConv(1,1)
self.pool = nn.MaxPool3d(kernel_size=2,stride=2)
def forward(self, x):
x = self.conv(x)
x = self.pool(x)
return x
if __name__ == '__main__':
device = torch.device('cpu')
input=torch.randn(1, 1, 48, 48, 32).to(device)
net=MyNetwork().to(device)
out=net(input)
print(out.shape)
基本上就是一个基础的network搭建了。
补充
还有一些操作,比如
导入已有的预训练模型
from torchvision.models import resnet18
class Resnet18(nn.Module):
def __init__(self, num_classes=2, pretrained=False):
super(Resnet18, self).__init__()
model = resnet18(pretrained)
self.model = model
def forward(self, x):
x = self.model(x)
return x
if __name__ == '__main__':
device = torch.device('cpu')
input=torch.randn(1, 3, 48, 48).to(device)
net=Resnet18().to(device)
out=net(input)
print(out.shape)
查看网络参数量和Flops
if __name__ == '__main__':
device = torch.device('cpu')
input=torch.randn(1, 3, 48, 48).to(device)
net=Resnet18().to(device)
out=net(input)
print(out.shape)
from thop import profile
macs, params = profile(net, inputs=(input,))
print(macs / 1000000000)
print(params / 1000000)
通道叠加
y_1_0 = torch.cat([self.upsample_1_2(y_2_1), t_1_2], dim=1)
激活函数
final = F.softmax(self.final_super_x_x(x_x_x), dim=1)
有时候模型不拟合的原因就是忘记加归一化。
各种各样的注意力
无论通道还是空间注意力,transform还是混合注意力。先把注意力封装了,然后导入进来就行。
3D插入注意力可以看我之前写的这篇,通过reshape实现。
https://blog.csdn.net/weixin_45638136/article/details/126607637?spm=1001.2014.3001.5501
封装
很多东西可以封装起来,比如通道数
class UNet3Stage(nn.Module):
def __init__(self, in_channel=1, num_class=2, base_channels=32):
super(UNet3Stage, self).__init__()
self.num_classes = num_class
self.in_channel =in_channel
"""
encoding
"""
self.stage_0 = ContinusParalleConv_2d(self.in_channel, base_channels)
self.stage_1 = SingleConv_2d(base_channels, base_channels*2)
self.stage_2 = SingleConv(base_channels*2, base_channels*4)
self.stage_3 = SingleConv(base_channels*4, base_channels*8)
这样后期调参数量就很方便了,学会封装。