(解决问题有酬谢)自己复现的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
你用的自己训练数据和训练脚本,这是问题所在,你的超参数,数据增强不足等都是原因
我这有完整写好的ResNet50,包括完整网络和优化器,损失函数等,你可以看看,不会的话我给你讲解:
https://github.com/Junzhou-Chen/classification
如果您使用的是自己的训练数据和训练脚本,并且调用的是torchvision中的deeplabv3_resnet50
模型,那么确保以下几个方面的一致性可能有助于解决问题:
数据预处理:检查您在训练过程中使用的数据预处理步骤是否与官方实现一致。确保输入数据的预处理方式(如缩放、裁剪、归一化等)与官方实现相同。
数据集的多样性和质量:确保使用的训练数据集与官方实现中使用的数据集在多样性和质量上相似。如果训练数据集与测试数据集有明显的分布差异,可能会导致模型在测试集上表现不佳。
学习率和优化器:检查您在训练脚本中设置的学习率和优化器是否与官方实现一致。学习率和优化器的选择对模型的收敛性能至关重要。
训练时间和迭代次数:确保您的训练时间和迭代次数与官方实现相似。如果您的训练时间或迭代次数不足,模型可能没有足够的时间来学习有意义的特征。
损失函数:检查您在训练过程中使用的损失函数是否与官方实现相同。使用与官方实现一致的损失函数可以确保训练过程的一致性。
如果您仔细检查了上述因素,并且仍然存在问题,可能需要进一步排查其他因素,例如网络结构的定义、权重初始化、模型评估指标等。
此外,您还可以尝试使用其他的超分辨率算法作为对比,看看是否能够改善效果。有时候,不同的算法在不同的数据集或场景下表现更好。
回答部分参考、引用ChatGpt以便为您提供更准确的答案:
根据提供的代码和描述,复现的resnet的deeplabv3效果与torch官方的结果相比差距较大且不收敛。有几个可能的原因和解决方法如下:
综上所述,通过调整学习率、正则化和归一化、选择适当的损失函数、检查数据集质量、检查网络结构以及增加训练时长和迭代次数等方法,可能有助于解决复现的resnet的deeplabv3效果差且不收敛的问题。
注意:由于无法查看完整的训练脚本和数据集,以上只是一些常见的问题和解决方法的示例,具体问题的解决可能需要进一步的调试和分析。
调用的函数是这个 self.model1 = torchvision.models.segmentation.deeplabv3_resnet50(pretrained= False,num_classes=1,pretrained_backbone=False),没有使用加载权重,损失函数是torch.nn.functional.binary_cross_entropy_with_logits,所以我自己写的代码里最后面也不需要加sigmod激活
引用gpt回答 有帮助的话 采纳一下
根据你提供的代码和信息,你自己实现的Deeplabv3模型与PyTorch官方版本相比效果差的原因可能有: