MNIST中所有样本都会将原本28*28的灰度图转换为长度为784的一维向量作为输入,其中每个元素分别对应了灰度图中的灰度值。MNIST使用一个长度为10的one-hot向量作为该样本所对应的标签,其中向量索引值对应了该样本以该索引为结果的预测概率。
from mindvision.dataset import Mnist
# 下载并处理MNIST数据集
download_train = Mnist(path="./mnist", split="train", batch_size=32, repeat_num=1, shuffle=True, resize=32, download=True)
##原本的数据集只有28*28,resize改成32*32,使图片满足网络模型输入的需求
download_eval = Mnist(path="./mnist", split="test", batch_size=32, resize=32, download=True)
dataset_train = download_train.run()
dataset_eval = download_eval.run()
import mindspore.nn as nn
##创建LeNet的网络结构,有三个卷积层,2个子采样层,3个全连接层
class LeNet5(nn.Cell):
"""
LeNet-5网络结构
"""
def __init__(self, num_class=10, num_channel=1):
super(LeNet5, self).__init__()
# 卷积层,输入的通道数为num_channel,输出的通道数为6,卷积核大小为5*5
self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')
# 卷积层,输入的通道数为6,输出的通道数为16,卷积核大小为5*5
self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')
# 全连接层,输入个数为16*5*5,输出个数为120
self.fc1 = nn.Dense(16 * 5 * 5, 120)
# 全连接层,输入个数为120,输出个数为84
self.fc2 = nn.Dense(120, 84)
# 全连接层,输入个数为84,分类的个数为num_class
self.fc3 = nn.Dense(84, num_class)
# ReLU激活函数
self.relu = nn.ReLU()
# 池化层
self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)
# 多维数组展平为一维数组
self.flatten = nn.Flatten()
def construct(self, x):
# 使用定义好的运算构建前向网络
x = self.conv1(x)
x = self.relu(x)
x = self.max_pool2d(x)
x = self.conv2(x)
x = self.relu(x)
x = self.max_pool2d(x)
x = self.flatten(x)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
return x
network = LeNet5(num_class=10)
from mindvision.classification.models import lenet
network = lenet(num_classes=10, pretrained=False)##10个分类
import mindspore.nn as nn
# 定义损失函数,这里使用交叉熵损失函数
net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
# 定义优化器函数
net_opt = nn.Momentum(network.trainable_params(), learning_rate=0.01, momentum=0.9)#学习率不会设置太大
import mindspore as ms
# 设置模型保存参数,模型训练保存参数的step为1875。
config_ck = ms.CheckpointConfig(save_checkpoint_steps=1875, keep_checkpoint_max=10)
# 应用模型保存参数
ckpoint = ms.ModelCheckpoint(prefix="lenet", directory="./lenet", config=config_ck)
from mindvision.engine.callback import LossMonitor
import mindspore as ms
# 初始化模型参数
model = ms.Model(network, loss_fn=net_loss, optimizer=net_opt, metrics={'accuracy'})
# 训练网络模型,并保存为lenet-1_1875.ckpt文件
model.train(10, dataset_train, callbacks=[ckpoint, LossMonitor(0.01, 1875)])
acc = model.eval(dataset_eval)
print("{}".format(acc))#输出:{'accuracy': 0.9897836538461539}
import mindspore as ms
# 加载已经保存的用于测试的模型
param_dict = ms.load_checkpoint("./lenet/lenet-1_1875.ckpt")
# 加载参数到网络中
ms.load_param_into_net(network, param_dict)
#验证模型
import numpy as np
import mindspore as ms
import matplotlib.pyplot as plt
mnist = Mnist("./mnist", split="train", batch_size=6, resize=32)#取六张图片验证
dataset_infer = mnist.run()
ds_test = dataset_infer.create_dict_iterator()
data = next(ds_test)
images = data["image"].asnumpy()
labels = data["label"].asnumpy()
plt.figure()
for i in range(1, 7):
plt.subplot(2, 3, i)
plt.imshow(images[i-1][0], interpolation="None", cmap="gray")
plt.show()
# 使用函数model.predict预测image对应分类
output = model.predict(ms.Tensor(data['image']))
predicted = np.argmax(output.asnumpy(), axis=1)
# 输出预测分类与实际分类
print(f'Predicted: "{predicted}", Actual: "{labels}"')