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!")
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 解决方案