隐藏页面特效
Fork me on GitHub

李沐《动手学深度学习》 Softmax回归实现

前言

本篇是在看完李沐老师的Softmax回归课程后,做的总结笔记,并且针对实现代码根据个人的习惯进行了一些调整,本篇博文仅作记录,完整的学习笔记可以留言分享。
李沐老师在课程中是使用的Jupyter运行的代码,然而我本人更加习惯在IDLE或者VScode中运行代码,所以就将整个实现拆成了两个文件,一个是用于获取数据集,绘制图像等操作的准备文件,命名为Prepare_for_Softmax.py,另一个就是用于实现Softmax回归的Softmax_Regression文件

一些注意点记录

  • 数据集建议手动下载,默认下载太卡

  • 前往数据集下载网址直接下载需要的四个数据集。

下载1: train-images-idx3-ubyte.gz
下载2: train-labels-idx1-ubyte.gz
下载3: t10k-images-idx3-ubyte.gz
下载4: t10k-labels-idx1-ubyte.gz

  • 数据集存储位置在脚本目录的上级目录中,默认文件名叫做data,直接将下载好的文件放到data\FashionMNIST\raw下即可,且不用解压,第一次运行时在加载本地数据集时会自动进行解压并读取

  • 前期的准备工作Prepare_for_Softmax.py

import torch from IPython import display from d2l import torch as d2l # 数据集获取 def get_dataloader_workers(): """使用4个进程来读取数据""" return 8 def load_data_fashion_mnist(batch_size, resize=None): """下载Fashion-MNIST数据集,然后将其加载到内存中""" trans = [transforms.ToTensor()] if resize: trans.insert(0, transforms.Resize(resize))# 这边是为后续如果要调整图片做的安排 trans = transforms.Compose(trans) mnist_train = torchvision.datasets.FashionMNIST( root="../data", train=True, transform=trans, download=False) mnist_test = torchvision.datasets.FashionMNIST( root="../data", train=False, transform=trans, download=False) return (data.DataLoader(mnist_train, batch_size, shuffle=True, num_workers=get_dataloader_workers()), data.DataLoader(mnist_test, batch_size, shuffle=False, num_workers=get_dataloader_workers())) # 图表绘制 class Animator: """在动画中绘制数据""" def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None, ylim=None, xscale='linear', yscale='linear', fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1, figsize=(3.5, 2.5)): # 增量地绘制多条线 if legend is None: legend = [] d2l.use_svg_display() self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize) if nrows * ncols == 1: self.axes = [self.axes, ] # 使用lambda函数捕获参数 self.config_axes = lambda: d2l.set_axes( self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend) self.X, self.Y, self.fmts = None, None, fmts def add(self, x, y): # 向图表中添加多个数据点 if not hasattr(y, "__len__"): y = [y] n = len(y) if not hasattr(x, "__len__"): x = [x] * n if not self.X: self.X = [[] for _ in range(n)] if not self.Y: self.Y = [[] for _ in range(n)] for i, (a, b) in enumerate(zip(x, y)): if a is not None and b is not None: self.X[i].append(a) self.Y[i].append(b) self.axes[0].cla() for x, y, fmt in zip(self.X, self.Y, self.fmts): self.axes[0].plot(x, y, fmt) self.config_axes() display.display(self.fig) plt.draw() plt.pause(0.001) display.clear_output(wait=True) # 训练部分 class Accumulator: """在n个变量上累加""" def __init__(self, n): self.data = [0.0] * n def add(self, *args): self.data = [a + float(b) for a, b in zip(self.data, args)] def reset(self): self.data = [0.0] * len(self.data) def __getitem__(self, idx): return self.data[idx] def accuracy(y_hat, y): """计算预测正确的数量""" if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: y_hat = y_hat.argmax(axis=1) cmp = y_hat.type(y.dtype) == y return float(cmp.type(y.dtype).sum()) def evaluate_accuracy(net, data_iter): """计算在指定数据集上模型的精度""" if isinstance(net, torch.nn.Module): net.eval() # 将模型设置为评估模式 metric = Accumulator(2) # 正确预测数、预测总数 with torch.no_grad(): for X, y in data_iter: metric.add(accuracy(net(X), y), y.numel()) return metric[0] / metric[1] def train_epoch_ch3(net, train_iter, loss, updater): """训练模型一个迭代周期""" # 将模型设置为训练模式 if isinstance(net, torch.nn.Module): net.train() # 训练损失总和、训练准确度总和、样本数 metric = Accumulator(3) for X, y in train_iter: # 计算梯度并更新参数 y_hat = net(X) l = loss(y_hat, y) if isinstance(updater, torch.optim.Optimizer): # 使用PyTorch内置的优化器和损失函数 updater.zero_grad() l.mean().backward() updater.step() else: # 使用定制的优化器和损失函数 l.sum().backward() updater(X.shape[0]) metric.add(float(l.sum()), accuracy(y_hat, y), y.numel()) # 返回训练损失和训练精度 return metric[0] / metric[2], metric[1] / metric[2] def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): """训练模型""" animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9], legend=['train loss', 'train acc', 'test acc']) for epoch in range(num_epochs): train_metrics = train_epoch_ch3(net, train_iter, loss, updater) test_acc = evaluate_accuracy(net, test_iter) animator.add(epoch + 1, train_metrics + (test_acc,)) train_loss, train_acc = train_metrics assert train_loss < 0.5, train_loss assert train_acc <= 1 and train_acc > 0.7, train_acc assert test_acc <= 1 and test_acc > 0.7, test_acc
  • 那么下面就是具体的回归函数的实现Softmax_Regression.py
import torch from torch import nn from d2l import torch as d2l from Prepare_for_Softmax import * # 引入数据集,fashion_mnist batch_size = 256 train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size) # 初始化模型参数 net = nn.Sequential(nn.Flatten(),nn.Linear(784,10)) def init_weights(m): if type(m) == nn.Linear: nn.init.normal_(m.weight,std=0.01) net.apply(init_weights) # Softmax实现 loss = nn.CrossEntropyLoss(reduction='none') # 算法优化,采用小批量梯度下降 trainer = torch.optim.SGD(net.parameters(),lr=0.1) # 训练模型 num_epochs = 10 d2l.train_ch3(net,train_iter,test_iter,loss,num_epochs,trainer) d2l.plt.show() def predict_ch3(net, test_iter, n=6): """预测标签""" for X, y in test_iter: break trues = d2l.get_fashion_mnist_labels(y) preds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1)) titles = [true +'\n' + pred for true, pred in zip(trues, preds)] #print(titles) d2l.show_images( X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n]) d2l.plt.show() predict_ch3(net,test_iter)
  • 绘制出来的动态曲线
  • 最终的分类情况

小结

  • 本次只是针对教程中的代码进行了一个复现,一轮顺下来感觉只能说是掌握了6,70%,中间还是有不少地方掌握不是很深刻,后续还是要反复多敲几次代码实现

__EOF__

本文作者Konmu
本文链接https://www.cnblogs.com/Konmu/p/16870075.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Konmu  阅读(345)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示