(解决问题有酬谢)自己复现的resnet的deelabpv3效果差很多(与torch官方的比),不收敛,一直没找到原因,使用的数据集,train脚本都一样。
import torch.nn as nn
import torch
from torchinfo import summary
import netron
import onnx
from onnx import shape_inference
from torch.nn import functional as F
class BottleNeck(nn.Module):
"""搭建BottleNeck模块"""
expansion = 4
def __init__(self, in_channel, out_channel, stride, padding, dilation):
super(BottleNeck, self).__init__()
self.stride = stride
self.res = nn.Sequential(
nn.Conv2d(in_channel, out_channel * self.expansion, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_channel * self.expansion)
)
self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size=1, stride=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channel) # BN层, BN层放在conv层和relu层中间使用
self.conv2 = nn.Conv2d(out_channel, out_channel, kernel_size=3, stride=stride, padding=padding, bias=False,
dilation=dilation)
self.bn2 = nn.BatchNorm2d(out_channel)
self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion, kernel_size=1, stride=1, bias=False)
self.bn3 = nn.BatchNorm2d(out_channel * self.expansion) # Residual中第三层out_channel扩张到in_channel的4倍
self.relu = nn.ReLU(inplace=True)
# 前向传播
def forward(self, x):
identity = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
# out = self.relu(self.bn1(self.conv1(x)))
# out = self.relu(self.bn2(self.conv2(out)))
# out = self.bn3(self.conv3(out))
identity = self.res(identity)
out = self.relu(identity + out)
return out
class BottleNeck1(nn.Module): # 无残差结构的,因为发现torch的deeplabv3_resnet50结构只有layer中第一层bottleneck需要卷积残差,其他层直接加就可以
"""搭建BottleNeck模块"""
expansion = 4
def __init__(self, in_channel, out_channel, stride, padding, dilation):
super(BottleNeck1, self).__init__()
self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size=1, stride=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channel) # BN层, BN层放在conv层和relu层中间使用
self.conv2 = nn.Conv2d(out_channel, out_channel, kernel_size=3, stride=stride, padding=padding, bias=False,
dilation=dilation)
self.bn2 = nn.BatchNorm2d(out_channel)
self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion, kernel_size=1, stride=1, bias=False)
self.bn3 = nn.BatchNorm2d(out_channel * self.expansion) # Residual中第三层out_channel扩张到in_channel的4倍
self.relu = nn.ReLU(inplace=True)
# 前向传播
def forward(self, x):
identity = x.clone()
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
# out = self.relu(self.bn1(self.conv1(x)))
# out = self.relu(self.bn2(self.conv2(out)))
# out = self.bn3(self.conv3(out))
out = self.relu(identity + out)
return out
class Branch(nn.Module):
def __init__(self, in_channel, out_channel, kernel_size, dilation, padding):
super(Branch, self).__init__()
self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=padding, dilation=dilation, stride=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channel) # BN层, BN层放在conv层和relu层中间使用
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
out = self.relu(self.bn1(self.conv1(x)))
return out
class ASPPPooling(nn.Module):
def __init__(self, in_channels, out_channels):
super(ASPPPooling, self).__init__()
self.conv1 = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Conv2d(in_channels, out_channels, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU()
)
def forward(self, x):
size = x.shape[-2:]
out = self.conv1(x)
out = F.interpolate(out, size=size, mode='bilinear', align_corners=False)
return out
class Deeplab(nn.Module):
def __init__(self, numberclass): # in_channel=out_channel=64
super(Deeplab, self).__init__()
self.conv1 = nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False),
nn.BatchNorm2d(64),
nn.ReLU()
)
self.polling = torch.nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
self.laye1backbone1 = BottleNeck(64, 64, stride=1, dilation=1, padding=1)
self.laye1backbone2 = BottleNeck1(256, 64, stride=1, dilation=1, padding=1)
self.laye1backbone3 = BottleNeck1(256, 64, stride=1, dilation=1, padding=1)
self.laye2backbone1 = BottleNeck(256, 128, stride=2, dilation=1, padding=1)
self.laye2backbone2 = BottleNeck1(512, 128, stride=1, dilation=1, padding=1)
self.laye2backbone3 = BottleNeck1(512, 128, stride=1, dilation=1, padding=1)
self.laye2backbone4 = BottleNeck1(512, 128, stride=1, dilation=1, padding=1)
self.laye3backbone1 = BottleNeck(512, 256, stride=1, dilation=1, padding=1)
self.laye3backbone2 = BottleNeck1(1024, 256, stride=1, dilation=2, padding=2)
self.laye3backbone3 = BottleNeck1(1024, 256, stride=1, dilation=2, padding=2)
self.laye3backbone4 = BottleNeck1(1024, 256, stride=1, dilation=2, padding=2)
self.laye3backbone5 = BottleNeck1(1024, 256, stride=1, dilation=2, padding=2)
self.laye3backbone6 = BottleNeck1(1024, 256, stride=1, dilation=2, padding=2)
self.laye4backbone1 = BottleNeck(1024, 512, stride=1, dilation=2, padding=2)
self.laye4backbone2 = BottleNeck1(2048, 512, stride=1, dilation=4, padding=4)
self.laye4backbone3 = BottleNeck1(2048, 512, stride=1, dilation=4, padding=4)
self.branch1 = Branch(2048, 256, kernel_size=1, padding=0, dilation=1)
self.branch2 = Branch(2048, 256, kernel_size=3, padding=12, dilation=12)
self.branch3 = Branch(2048, 256, kernel_size=3, padding=24, dilation=24)
self.branch4 = Branch(2048, 256, kernel_size=3, padding=36, dilation=36)
self.branch5 = ASPPPooling(2048, 256)
self.result = nn.Sequential(nn.Conv2d(256 * 5, 256, 1, bias=False),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Dropout(0.5)
)
self.result1 = nn.Sequential(nn.Conv2d(256, 256, 3, padding=1, bias=False),
nn.BatchNorm2d(256),
nn.ReLU()
)
self.final = nn.Conv2d(256, numberclass, 1, padding=0, bias=False)
def forward(self, x):
out = self.conv1(x)
out = self.polling(out)
out = self.laye1backbone1(out)
out = self.laye1backbone2(out)
out = self.laye1backbone3(out)
out = self.laye2backbone1(out)
out = self.laye2backbone2(out)
out = self.laye2backbone3(out)
out = self.laye2backbone4(out)
out = self.laye3backbone1(out)
out = self.laye3backbone2(out)
out = self.laye3backbone3(out)
out = self.laye3backbone4(out)
out = self.laye3backbone5(out)
out = self.laye3backbone6(out)
out = self.laye4backbone1(out)
out = self.laye4backbone2(out)
out = self.laye4backbone3(out)
out1 = self.branch1(out)
out2 = self.branch2(out)
out3 = self.branch3(out)
out4 = self.branch4(out)
out5 = self.branch5(out)
out = self.result(torch.cat((out1, out2, out3, out4, out5), 1))
out = self.result1(out)
out = self.final(out)
out = F.interpolate(out, size=x.shape[-2:], mode='bilinear', align_corners=False)
return out