1. 构建数据集
构建数据集是模型训练的第一步。在本实验中,我们使用了MNIST手写数字数据集。具体步骤如下:
- 下载数据集:使用
download
函数从指定URL下载并解压MNIST数据集。 - 数据预处理:定义数据预处理管道,包括图像的缩放、归一化和维度转换。
- 加载数据集:使用
MnistDataset
函数加载训练和测试数据集,并应用预处理管道。最后将数据集按批次大小进行分组。
from download import download
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)
def datapipe(path, batch_size):
image_transforms = [
vision.Rescale(1.0 / 255.0, 0),
vision.Normalize(mean=(0.1307,), std=(0.3081,)),
vision.HWC2CHW()
]
label_transform = transforms.TypeCast(mindspore.int32)
dataset = MnistDataset(path)
dataset = dataset.map(image_transforms, 'image')
dataset = dataset.map(label_transform, 'label')
dataset = dataset.batch(batch_size)
return dataset
train_dataset = datapipe('MNIST_Data/train', batch_size=64)
test_dataset = datapipe('MNIST_Data/test', batch_size=64)
2. 定义神经网络模型
神经网络模型定义了模型的架构。在本实验中,我们定义了一个包含三层全连接层和ReLU激活函数的简单神经网络。
class Network(nn.Cell):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.dense_relu_sequential = nn.SequentialCell(
nn.Dense(28*28, 512),
nn.ReLU(),
nn.Dense(512, 512),
nn.ReLU(),
nn.Dense(512, 10)
)
def construct(self, x):
x = self.flatten(x)
logits = self.dense_relu_sequential(x)
return logits
model = Network()
3. 定义超参、损失函数及优化器
超参、损失函数和优化器是模型训练的关键参数。
- 超参:包括训练轮次(epochs)、批次大小(batch size)和学习率(learning rate)。
epochs = 3
batch_size = 64
learning_rate = 1e-2
- 损失函数:使用
nn.CrossEntropyLoss
计算预测值与目标值之间的误差。
loss_fn = nn.CrossEntropyLoss()
- 优化器:使用
nn.SGD
优化器来更新模型参数。
optimizer = nn.SGD(model.trainable_params(), learning_rate=learning_rate)
4. 输入数据集进行训练与评估
最后一步是输入数据集进行训练和评估。我们定义了 train_loop
和 test_loop
函数来分别执行训练和测试。
训练函数
训练函数 train_loop
包括以下步骤:
- 设置模型为训练模式。
- 循环遍历训练数据集,计算损失和梯度,更新模型参数。
def forward_fn(data, label):
logits = model(data)
loss = loss_fn(logits, label)
return loss, logits
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)
def train_step(data, label):
(loss, _), grads = grad_fn(data, label)
optimizer(grads)
return loss
def train_loop(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}]")
测试函数
测试函数 test_loop
包括以下步骤:
- 设置模型为评估模式。
- 循环遍历测试数据集,计算损失和准确率。
def test_loop(model, dataset, loss_fn):
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")
训练与评估
在每个训练轮次中,我们调用 train_loop
和 test_loop
函数进行训练和测试,并输出每轮的损失和准确率。
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(model, train_dataset)
test_loop(model, test_dataset, loss_fn)
print("Done!")
结果分析
在训练3轮后,模型的准确率逐渐提高,损失逐渐降低。具体结果如下:
- 第1轮:损失从2.327下降到0.298,准确率达到90.6%。
- 第2轮:损失从0.467下降到0.083,准确率达到92.7%。
- 第3轮:损失从0.364下降到0.126,准确率达到93.7%。
最终,经过3轮训练,模型在测试集上的准确率达到了93.7%,表明模型具有较好的分类性能。
总结
1. download
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
download | url: str, path: str, kind: str, replace: bool | 从指定URL下载文件并解压到目标路径 | download("https://example.com/data.zip", "./", "zip", True) |
2. 数据预处理相关函数
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
vision.Rescale | scale: float, shift: float | 按比例缩放图像 | vision.Rescale(1.0 / 255.0, 0) |
vision.Normalize | mean: tuple, std: tuple | 图像归一化处理 | vision.Normalize(mean=(0.1307,), std=(0.3081,)) |
vision.HWC2CHW | 无 | 将图像从HWC格式转换为CHW格式 | vision.HWC2CHW() |
transforms.TypeCast | dtype: type | 转换标签数据类型 | transforms.TypeCast(mindspore.int32) |
3. 数据集相关函数
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
MnistDataset | path: str | 加载MNIST数据集 | MnistDataset('MNIST_Data/train') |
map | operations: list, input_columns: str | 对数据集进行操作,如图像预处理 | dataset.map(image_transforms, 'image') |
batch | batch_size: int | 将数据集按批次大小进行分组 | dataset.batch(batch_size) |
4. 神经网络相关函数
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
nn.Cell | 无 | 定义神经网络的基类 | class Network(nn.Cell) |
nn.Flatten | 无 | 将输入展平 | self.flatten = nn.Flatten() |
nn.Dense | in_channels: int, out_channels: int | 全连接层 | nn.Dense(28*28, 512) |
nn.ReLU | 无 | ReLU激活函数 | nn.ReLU() |
nn.SequentialCell | cells: list | 顺序容器 | nn.SequentialCell([nn.Dense(28*28, 512), nn.ReLU()]) |
5. 超参、损失函数和优化器相关函数
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
nn.CrossEntropyLoss | 无 | 交叉熵损失函数 | loss_fn = nn.CrossEntropyLoss() |
nn.SGD | params: list, learning_rate: float | 随机梯度下降优化器 | optimizer = nn.SGD(model.trainable_params(), learning_rate=1e-2) |
6. 训练与评估相关函数
函数/关键词 | 参数 | 作用 | 例句 |
---|---|---|---|
mindspore.value_and_grad | fn: callable, params: list, has_aux: bool | 计算函数的值和梯度 | grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True) |
create_tuple_iterator | 无 | 创建数据集迭代器 | for data, label in dataset.create_tuple_iterator(): |
asnumpy | 无 | 将张量转换为NumPy数组 | loss.asnumpy() |
示例
以下是上述函数和关键词的使用示例:
# 下载数据集
from download import download
url = "https://example.com/data.zip"
path = download(url, "./", kind="zip", replace=True)
# 数据预处理
import mindspore
from mindspore.dataset import vision, transforms
from mindspore.dataset import MnistDataset
def datapipe(path, batch_size):
image_transforms = [
vision.Rescale(1.0 / 255.0, 0),
vision.Normalize(mean=(0.1307,), std=(0.3081,)),
vision.HWC2CHW()
]
label_transform = transforms.TypeCast(mindspore.int32)
dataset = MnistDataset(path)
dataset = dataset.map(image_transforms, 'image')
dataset = dataset.map(label_transform, 'label')
dataset = dataset.batch(batch_size)
return dataset
train_dataset = datapipe('MNIST_Data/train', batch_size=64)
test_dataset = datapipe('MNIST_Data/test', batch_size=64)
# 定义神经网络
import mindspore.nn as nn
class Network(nn.Cell):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.dense_relu_sequential = nn.SequentialCell(
nn.Dense(28*28, 512),
nn.ReLU(),
nn.Dense(512, 512),
nn.ReLU(),
nn.Dense(512, 10)
)
def construct(self, x):
x = self.flatten(x)
logits = self.dense_relu_sequential(x)
return logits
model = Network()
# 定义超参、损失函数和优化器
epochs = 3
batch_size = 64
learning_rate = 1e-2
loss_fn = nn.CrossEntropyLoss()
optimizer = nn.SGD(model.trainable_params(), learning_rate=learning_rate)
# 训练与评估
import mindspore
def forward_fn(data, label):
logits = model(data)
loss = loss_fn(logits, label)
return loss, logits
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)
def train_step(data, label):
(loss, _), grads = grad_fn(data, label)
optimizer(grads)
return loss
def train_loop(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_loop(model, dataset, loss_fn):
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")
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(model, train_dataset)
test_loop(model, test_dataset, loss_fn)
print("Done!")
通过表格和示例,可以更直观地理解每个函数和关键词的作用、参数及其使用方法。希望这些总结和示例对您有帮助。