手写数字辨认(分类任务)
1. 导入必要的库from pathlib import Path
import requests
import pickle
import gzip
import numpy as np
import torch
from torch import nn
import torch.nn.functional as F
from torch.utils.data import TensorDataset, DataLoader
from torch import optim
[*]功能: 导入所需的库,以便进行文件操作、数据处置惩罚、构建神经网络、计算损失以及加载和处置惩罚数据。
2. 数据预备
a. 创建数据路径并下载数据集
DATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"
PATH.mkdir(parents=True, exist_ok=True)
URL = "http://deeplearning.net/data/mnist/"
FILENAME = "mnist.pkl.gz"
if not (PATH / FILENAME).exists():
content = requests.get(URL + FILENAME).content
(PATH / FILENAME).open("wb").write(content)
[*]功能:
[*]创建存储数据集的路径 data/mnist。
[*]从指定 URL 下载 MNIST 数据集,并保存为 mnist.pkl.gz 文件,如果文件已经存在则不重复下载。
b. 加载数据集
with gzip.open((PATH / FILENAME).as_posix(), "rb") as f:
((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")
[*]功能:
[*]使用 gzip 解压缩文件并使用 pickle 加载数据集,得到训练数据 x_train、训练标签 y_train、验证数据 x_valid 和验证标签 y_valid。
3. 数据转换为 PyTorch 张量
x_train_test, y_train_test, x_valid_test, y_valid_test = map(torch.tensor, (x_train, y_train, x_valid, y_valid))
[*]功能: 将 NumPy 数组转换为 PyTorch 张量,以便后续的模型训练和计算。
4. 模型构建
a. 界说神经网络结构
class Mnist_NN(nn.Module):
def __init__(self):
super().__init__()
self.hidden1 = nn.Linear(784, 128)# 第一隐藏层
self.hidden2 = nn.Linear(128, 256)# 第二隐藏层
self.out = nn.Linear(256, 10) # 输出层
self.dropout = nn.Dropout(0.5) # Dropout层
[*]功能:
[*]创建一个名为 Mnist_NN 的神经网络类,继承自 nn.Module。
[*]在初始化方法中界说网络的结构,包括两个隐蔽层和一个输出层,以及一个 Dropout 层以镌汰过拟合。
b. 界说前向流传方法
def forward(self, x):
x = F.relu(self.hidden1(x))# 第一层激活
x = self.dropout(x) # Dropout
x = F.relu(self.hidden2(x))# 第二层激活
x = self.dropout(x) # Dropout
x = self.out(x) # 输出层
return x
[*]功能:
[*]界说前向流传过程,输入数据通过各层进行计算,并应用 ReLU 激活函数和 Dropout。
5. 损失函数和优化器
a. 界说损失函数
loss_func = F.cross_entropy# 使用交叉熵损失函数
[*]功能: 选择交叉熵损失函数作为模型的损失计算标准。
b. 界说优化器
def get_model():
model = Mnist_NN()# 实例化模型
return model, optim.SGD(model.parameters(), lr=0.001)# 使用 SGD 优化器
[*]功能:
[*]创建模型实例,并界说 SGD 优化器,学习率设置为 0.001。
6. 数据加载
a. 创建数据集和数据加载器
train_ds = TensorDataset(x_train, y_train)# 创建训练数据集
train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True)# 创建训练数据加载器
valid_ds = TensorDataset(x_valid, y_valid)# 创建验证数据集
valid_dl = DataLoader(valid_ds, batch_size=bs * 2)# 创建验证数据加载器
[*]功能:
[*]将训练和验证数据转换为 TensorDataset 格式,以便于进行批量处置惩罚。
[*]创建数据加载器 DataLoader,在训练时打乱训练集的序次,方便分批次读取数据。
6.5 loss_batch
def loss_batch(model, loss_func, xb, yb, opt=None):
# 计算当前批次的损失
loss = loss_func(model(xb), yb)
# 如果提供了优化器 opt,则进行反向传播和优化
if opt is not None:
loss.backward()# 计算损失的梯度(反向传播)
opt.step() # 更新模型参数
opt.zero_grad()# 清空梯度,避免累积
# 返回当前批次的损失值和该批次数据的大小
return loss.item(), len(xb)
7. 训练过程
a. 界说训练函数
def fit(steps, model, loss_func, opt, train_dl, valid_dl):
for step in range(steps):
model.train()# 设置模型为训练模式
for xb, yb in train_dl:# 遍历训练数据
loss_batch(model, loss_func, xb, yb, opt)# 计算并优化损失
model.eval()# 设置模型为评估模式
with torch.no_grad():# 禁用梯度计算
losses, nums = zip(
*
)# 计算验证集损失
val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)# 计算加权平均损失
print('当前step:' + str(step), '验证集损失:' + str(val_loss))# 打印损失
[*]功能:
[*]界说 fit 函数,负责训练过程,包括:
[*]将模型设置为训练模式并进行训练。
[*]在验证模式下计算验证集损失并输出。
8. 运行训练
train_dl, valid_dl = get_data(train_ds, valid_ds, bs)# 获取数据加载器
model, opt = get_model()# 获取模型和优化器
fit(25, model, loss_func, opt, train_dl, valid_dl)# 开始训练
[*]功能:
[*]通过调用 get_data 和 get_model 函数获取数据加载器和模型,然后调用 fit 函数进行训练。
总结
以上步骤展示了从数据预备到模型训练的完备过程。每一步都围绕着构建一个用于手写数字辨认的神经网络进行,确保数据的加载、模型的构建和训练过程都能顺遂进行。通过这些步骤,终极可以得到一个能够对手写数字进行分类的模型。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]