本次实践课我们学习并使用用MindSpore请根据这次实践所学习到的内容并结合自己所查的资料适当进行补充比如BN、Dropout等描述你的实验过程、相关代码及其必要的注释、自己的改进策略、看法和理解等。
本次实践课我们学习了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 著作权归作者所有。请勿转载和采集!