本次实践课我们学习了MindSpore的基本使用方法和深度学习中常用的一些技术,包括卷积神经网络(CNN)、批量归一化(Batch Normalization,BN)、Dropout等。

首先,我们使用MindSpore搭建了一个简单的CNN模型,用于对MNIST手写数字数据集进行分类。代码如下:

import mindspore.nn as nn
import mindspore.ops as ops
import mindspore.dataset as ds
import mindspore.dataset.transforms.c_transforms as C
import mindspore.dataset.vision.c_transforms as CV
from mindspore import context
from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits
from mindspore.nn.metrics import Accuracy
from mindspore.nn.optim import Momentum

context.set_context(mode=context.GRAPH_MODE, device_target="CPU")

class LeNet5(nn.Cell):
    def __init__(self, num_class=10):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5, pad_mode='valid')
        self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')
        self.fc1 = nn.Dense(16 * 5 * 5, 120)
        self.fc2 = nn.Dense(120, 84)
        self.fc3 = nn.Dense(84, num_class)

        self.relu = nn.ReLU()
        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)

    def construct(self, x):
        x = self.max_pool2d(self.relu(self.conv1(x)))
        x = self.max_pool2d(self.relu(self.conv2(x)))
        x = ops.reshape(x, (-1, 16 * 5 * 5))
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

def create_dataset(data_path, batch_size=32, repeat_size=1,
                   num_parallel_workers=1):
    # 定义数据集
    ds1 = ds.MnistDataset(data_path)

    # 定义数据增强
    trans = []
    trans.append(CV.Resize((32, 32)))
    trans.append(CV.Rescale(1 / 0.3081, -1))
    trans.append(C.ToTensor())
    trans = C.Compose(trans)

    # 应用数据增强并生成批量数据
    ds1 = ds1.map(input_columns="image", operations=trans)
    ds1 = ds1.batch(batch_size=batch_size, num_parallel_workers=num_parallel_workers, drop_remainder=True)
    ds1 = ds1.repeat(repeat_size)
    return ds1

# 加载数据集
data_path = "./mnist"
ds_train = create_dataset(data_path, batch_size=32, repeat_size=1)

# 定义模型、损失函数、优化器和评价指标
network = LeNet5()
criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
optimizer = Momentum(network.trainable_params(), learning_rate=0.01, momentum=0.9)
metric = Accuracy()

# 训练模型
for epoch in range(10):
    for i, (data, label) in enumerate(ds_train.create_dict_iterator()):
        output = network(data)
        loss = criterion(output, label)
        optimizer.clear_grad()
        loss.backward()
        optimizer.step()
        metric.update(output, label)
        if i % 100 == 0:
            print("Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}"
                  .format(epoch + 1, 10, i + 1, 1875, loss.asnumpy(), metric.eval()))

    metric.clear()

在上面的代码中,我们定义了一个LeNet5模型,它包括两个卷积层和三个全连接层,其中每个卷积层后面都跟着一个ReLU激活函数和一个2x2的最大池化层。我们还定义了一个数据集,并对数据进行了一些增强操作,包括将图像缩放到32x32、归一化到[-1,1]和将图像转换为张量。我们使用SoftmaxCrossEntropyWithLogits作为损失函数,使用Momentum优化器来更新模型参数,使用Accuracy作为评价指标。最后,我们训练模型并输出每个epoch的损失和精度。

在实验中,我们还学习了BN和Dropout两种常用的技术,它们可以帮助我们更好地训练深度神经网络。BN可以将每个特征通道的输出归一化到均值为0、方差为1,从而加速收敛并提高精度。Dropout可以在训练时随机将一些神经元的输出置为0,从而减少过拟合。

我们可以在LeNet5模型中加入BN和Dropout来进一步提高它的性能。代码如下:

class LeNet5(nn.Cell):
    def __init__(self, num_class=10):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5, pad_mode='valid')
        self.bn1 = nn.BatchNorm2d(6)
        self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')
        self.bn2 = nn.BatchNorm2d(16)
        self.fc1 = nn.Dense(16 * 5 * 5, 120)
        self.fc2 = nn.Dense(120, 84)
        self.fc3 = nn.Dense(84, num_class)

        self.relu = nn.ReLU()
        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)
        self.dropout = nn.Dropout(0.5)

    def construct(self, x):
        x = self.max_pool2d(self.relu(self.bn1(self.conv1(x))))
        x = self.max_pool2d(self.relu(self.bn2(self.conv2(x))))
        x = ops.reshape(x, (-1, 16 * 5 * 5))
        x = self.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.relu(self.fc2(x))
        x = self.dropout(x)
        x = self.fc3(x)
        return x

在上面的代码中,我们在每个卷积层后面加入了一个BN层,并在每个全连接层后面加入了一个Dropout层。这些层的作用是在训练时对数据进行归一化和随机置零,从而提高模型的泛化能力。

通过实验,我们进一步了解了MindSpore的基本使用方法和深度学习中常用的技术,包括卷积神经网络、批量归一化和Dropout等。我们还可以通过对模型的改进来提高它的性能


原文地址: https://www.cveoy.top/t/topic/fqv6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录