swin transformer训练出错

1、在训练是swin transformer的训练过程中出现以下提醒

img


2、训练到第10个epoch出现以下情况函数不能实现,并保存了训练的权重

img


3、在换了一个数据集后(截取了部分coco公开数据集)该数据集的size不是一样大,不知道是什么原因出现以下问题

img

该回答引用ChatGPT

如有疑问,可以回复我!

1、这些提醒是关于Swin Transformer的训练过程中的一些信息和错误提示。具体来说:
"loss_rpn_cls", "loss_rpn_bbox", "loss_cls", "acc", "loss_bbox", "loss_mask", "loss"都是训练过程中的指标,用于衡量模型的性能。
"Saving checkpoint"表示正在保存训练的权重,"OSError"则提示保存失败,可能是由于权限或路径问题导致无法创建软链接。

2、训练到第10个epoch时,出现了保存checkpoint失败的情况,可能是由于无法创建软链接导致的。不过权重已经保存了,只是没有软链接到目标路径而已。

3、在更换数据集后,出现了数据处理的错误。具体来说,是在读取图片时返回了空值,导致无法计算img_shape。这可能是因为新数据集的大小不同,需要更改相关的数据处理流程来适应新数据集。

参考GPT和自己的思路:
1 您的第一个问题看起来像是一个警告而不是一个错误。警告中提到的“fused weight gradient mlp cuda’ module not found gradient accumulation fusion with weight gradient computation disabled”表明某些模块未被找到。它似乎与pytorch相关,这可能是因为您的pytorch版本不兼容所导致的。您可以尝试更新您的pytorch版本,或者查看模型代码以了解这些模块是如何使用的,然后尝试手动添加它们。如果您的模型在训练过程中仍然收敛,则可以忽略此警告。

2 您的第二个问题看起来像是由于某些权限限制导致的。请确保您有足够的权限来在文件系统中保存文件。您可以尝试将保存的路径更改为您具有写入权限的目录,并确保您的代码以管理员身份运行。此外,您还可以尝试使用其他文件格式(例如.h5或.pkl)来保存您的模型。

3 您的第三个问题可能是因为您使用的数据集大小不同导致的。请确保您的代码可以处理不同大小的数据集。您可以尝试使用缩放或填充来使所有图像大小相同,或者在读取图像时调整输入大小。另外,请确保您的数据集已正确加载并分配给正确的变量。如果问题仍然存在,请查看相关代码以获取更多信息。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:

  1. 提示提醒说明
    提示中出现了cuda runtime error,通常情况下这种问题都是因为显存不足导致的。因为训练的过程中需要同时保存一些中间变量和参数,所以显存的使用量应该是很大的,而且训练的epoch数越多,中间结果也就越多,显存的占用也会越来越大。解决这个问题可以尝试以下几种方法:
  • 缩小batch size,这样可以减少显存的使用量。
  • 如果你有多个显卡,可以尝试使用多显卡并行。
  • 修改模型架构,减小模型的大小和参数数量。
  • 升级显卡和显存到更大的容量。
  1. 函数不能实现情况
    如果函数不能实现的情况只会发生在某一个epoch的训练中,可以考虑将该epoch的训练权重保存下来,然后在重新开始训练的时候加载上一个可以继续训练的权重,接着训练。如果是多个epoch都出现了这个问题,需要进一步分析是哪些层或者哪些操作导致的异常,然后针对性地修改模型或者训练参数。

  2. 数据集大小变化的原因
    如果你截取了部分coco公开数据集,那么数据集的大小当然会变化。如果你使用的是图像数据,那么可以通过修改resize的大小来解决。如果你使用的是文本数据,那么需要重新对数据集进行处理,例如重新计算序列长度等。如果你使用的是其他类型数据,需要根据实际情况进行处理。

代码演示:

缩小batch size

import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import transforms, datasets

# 定义模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        ...

    def forward(self, x):
        ...

model = MyModel()

# 定义数据集
transform = transforms.Compose([
    transforms.RandomCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
train_dataset = datasets.ImageFolder('path/to/train/dataset', transform=transform)
val_dataset = datasets.ImageFolder('path/to/val/dataset', transform=transform)

# 定义优化器和损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=1e-4)
criterion = nn.CrossEntropyLoss()

# 定义训练和验证dataloader
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=4)

# 开始训练
for e in range(10):
    model.train()
    for i, batch_data in enumerate(train_loader):
        optimizer.zero_grad()
        x, y = batch_data
        x, y = x.cuda(), y.cuda()
        logits = model(x)
        loss = criterion(logits, y)
        loss.backward()
        optimizer.step()
        
    # 在每个epoch结束后进行验证
    model.eval()
    with torch.no_grad():
        total_correct = 0
        total_samples = 0
        for j, val_batch_data in enumerate(val_loader):
            x_val, y_val = val_batch_data
            x_val, y_val = x_val.cuda(), y_val.cuda()
            logits_val = model(x_val)
            _, pred = logits_val.max(dim=1)
            total_correct += (pred == y_val).sum().item()
            total_samples += pred.size(0)
        val_acc = total_correct / total_samples
    print('epoch=%d, val_acc=%.4f' % (e, val_acc))

多显卡并行

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
from torch.nn.parallel import DistributedDataParallel as DDP

# 以下代码是在分布式环境下使用多GPU的情况下进行并行训练的示例

# 初始化分布式训练环境
torch.distributed.init_process_group('gloo', rank=rank, world_size=world_size)

# 定义模型和数据集
model = MyModel().to(rank)
model = DDP(model, device_ids=[rank])
train_dataset = ...
val_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset, num_replicas=world_size, rank=rank)
train_loader = DataLoader(train_dataset, batch_size=32, sampler=train_sampler, num_workers=4)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=4)

# 定义优化器和损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=1e-4)
criterion = nn.CrossEntropyLoss()

# 开始训练
for e in range(10):
    train_sampler.set_epoch(e)
    model.train()
    for i, batch_data in enumerate(train_loader):
        optimizer.zero_grad()
        x, y = batch_data
        x, y = x.to(rank), y.to(rank)
        logits = model(x)
        loss = criterion(logits, y)
        loss.backward()
        optimizer.step()
        
    # 在每个epoch结束后进行验证
    model.eval()
    with torch.no_grad():
        total_correct = 0
        total_samples = 0
        for j, val_batch_data in enumerate(val_loader):
            x_val, y_val = val_batch_data
            x_val, y_val = x_val.to(rank), y_val.to(rank)
            logits_val = model(x_val)
            _, pred = logits_val.max(dim=1)
            total_correct += (pred == y_val).sum().item()
            total_samples += pred.size(0)
        val_acc = total_correct / total_samples
    print('rank=%d, epoch=%d, val_acc=%.4f' % (rank, e, val_acc))
    torch.save(model.module.state_dict(), 'path/to/model-%d.pkl' % rank)

修改模型架构

可以通过修改模型的层数、降低卷积核的数量、使用其他的网络结构等方式来降低模型的大小和参数数量,从而减小显存的使用量。

import torch
import torch.nn as nn

# 缩小卷积核数量
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.fc1 = nn.Linear(64 * 8 * 8, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)

        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)

        x = self.conv3(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)

        x = x.view(-1, 64 * 8 * 8)
        x = self.fc1(x)
        return x

升级显卡和显存容量

升级显卡和显存的容量是比较昂贵的操作,不过如果你需要训练的模型比较大或者数据量比较大,那么升级显卡和显存容量是必须的。
如果我的回答解决了您的问题,请采纳!