模型在pytorch上收敛,迁移到mindspore上loss和acc不变。
收藏回复举报
模型在pytorch上收敛,迁移到mindspore上loss和acc不变。
发表于2023-11-24 15:59:34
0 查看

1 系统环境

硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU

MindSpore版本: mindspore=2.1.0

执行模式(PyNative/ Graph):不限

Python版本: Python=3.7.10

操作系统平台: 不限

2 报错信息

2.1问题描述

尝试在 cifar10 上训练 vgg16, batch_size = 256, Resize((64,64)), fc层做了相应的调整(pytorch, mindspore 都用了相同的调整), 同样的模型架构, 同样的数据集, 同样的超参, pytorch 上收敛, mindspore 不收敛。

2.2报错信息

best_acc = 0
epochs = 30
best_ckpt_path = "./ckpts/vgg16.ckpt"

dataset_dir = "./datasets/cifar-10-batches-bin"  # 数据集根目录
batch_size = 256  # 批量大小
workers = 4  # 并行线程个数
num_classes = 10  # 分类数量
height, width = 2, 2

def create_dataset_cifar10(dataset_dir, usage, batch_size, workers):
    data_set = ds.Cifar10Dataset(dataset_dir=dataset_dir,
                                 usage=usage,
                                 num_parallel_workers=workers,
                                 shuffle=True)

    trans = [
        vision.Resize((64,64)),
        vision.Rescale(1.0 / 255.0, 0.0),
        vision.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010]),
        vision.HWC2CHW()
    ]

    target_trans = transforms.TypeCast(mstype.int32)

    data_set = data_set.map(operations=trans,
                            input_columns='image',
                            num_parallel_workers=workers)

    data_set = data_set.map(operations=target_trans,
                            input_columns='label',
                            num_parallel_workers=workers)

    data_set = data_set.batch(batch_size)
    return data_set
    

train_dataset = create_dataset_cifar10(dataset_dir=dataset_dir,
                                       usage="train",
                                       batch_size=batch_size,
                                       workers=workers)
step_size_train = train_dataset.get_dataset_size()

test_dataset = create_dataset_cifar10(dataset_dir=dataset_dir,
                                     usage="test",
                                     batch_size=batch_size,
                                     workers=workers)
step_size_val = test_dataset.get_dataset_size()

from mindspore import nn

def _make_layer(channels):
    in_channels = channels[0]
    layers = []
    for out_channels in channels[1:]:
        layers.append(nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, pad_mode='pad', padding=1))
        layers.append(nn.ReLU())
        in_channels = out_channels
    return nn.SequentialCell(layers)

class Vgg16(nn.Cell):
    """VGG16 module."""

    def __init__(self):
        super(Vgg16, self).__init__()
        self.b1 = _make_layer([3, 64, 64])
        self.b2 = _make_layer([64, 128, 128])
        self.b3 = _make_layer([128, 256, 256, 256])
        self.b4 = _make_layer([256, 512, 512, 512])
        self.b5 = _make_layer([512, 512, 512, 512])

        self.m1 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode='SAME')
        self.m2 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode='SAME')
        self.m3 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode='SAME')
        self.m4 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode='SAME')
        self.m5 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode='SAME')
        
        self.fc14 = nn.Dense(512*height * width, 512)
        self.fc15 = nn.Dense(512, 512)
        self.fc16 = nn.Dense(512, num_classes)
        
        self.flatten = nn.Flatten()
        self.ReLU = nn.ReLU()

    def construct(self, x):
        # block1
        x = self.b1(x)
        x = self.m1(x)

        # block2
        x = self.b2(x)
        x = self.m2(x)

        # block3
        x = self.b3(x)
        x = self.m3(x)

        # block4
        x = self.b4(x)
        block4 = x
        x = self.m4(x)

        # block5
        x = self.b5(x)
        x = self.m5(x)
        
        x = self.flatten(x)
        x = self.ReLU(self.fc14(x))
        x = self.ReLU(self.fc15(x))
        x = self.fc16(x)
        
        return x


model = Vgg16()

loss_fn = nn.CrossEntropyLoss()
optimizer = nn.SGD(model.trainable_params(), 1e-2)

def forward_fn(data, label):
    logits = model(data)
    loss = loss_fn(logits, label)
    return loss, logits

# 2. Get gradient function
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)

# 3. Define function of one-step training
def train_step(data, label):
    (loss, _), grads = grad_fn(data, label)
    optimizer(grads)
    return loss

def train(model, dataset):
    size = dataset.get_dataset_size()
    model.set_train()
    for batch, (data, label) in enumerate(dataset.create_tuple_iterator()):
        loss = train_step(data, label)

        if batch % 100 == 0:
            loss, current = loss.asnumpy(), batch
            print(f"loss: {loss:>7f}  [{current:>3d}/{size:>3d}]")


def test(model, dataset, loss_fn):
    global bestacc
    num_batches = dataset.get_dataset_size()
    model.set_train(False)
    total, test_loss, correct = 0, 0, 0
    for data, label in dataset.create_tuple_iterator():
        pred = model(data)
        total += len(data)
        test_loss += loss_fn(pred, label).asnumpy()
        correct += (pred.argmax(1) == label).asnumpy().sum()
    test_loss /= num_batches
    correct /= total
    print(f"Test: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
    return correct
    

for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(model, train_dataset)
    curr_acc = test(model, test_dataset, loss_fn)
    # 保存当前预测准确率最高的模型
    if curr_acc > best_acc:
        best_acc = curr_acc
        mindspore.save_checkpoint(model, best_ckpt_path)
print("Done!")

3 根因分析

4 解决方案

cke_9288.png

我要发帖子