《动手学深度学习(PyTorch版)》笔记3.6

注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过。

Chapter3 Linear Neural Networks

3.6 Implementations of Softmax Regression from Scratch

import torch
import torchvision
import time
import matplotlib.pyplot as plt
import numpy as np 
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l
from IPython import display#初始化参数
batch_size=256
train_iter,test_iter=d2l.load_data_fashion_mnist(batch_size)
num_inputs=784
#图像有28*28像素,本节将其看作长度为784的向量
num_outputs=10
#softmax回归中输出与类别一样多,数据集有10个类别
W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)#定义softmax操作
def softmax(X):X_exp=torch.exp(X)partition=X_exp.sum(1,keepdim=True)return X_exp/partition#结果每行和为1#定义softmax回归模型
#在将数据传递到模型之前,使用reshape将每个原始图像展开为向量
def net(X):return softmax(torch.matmul(X.reshape((-1,W.shape[0])),W)+b)y = torch.tensor([0, 2])
#有了y,我们知道在第一个样本中第一类是正确的预测;在第二个样本中第三类是正确的预测
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
#2个样本在3个类别上的预测概率
#print(y_hat[[0, 1], y])
#使用y作为y_hat中概率的索引
#我们选择第一个样本中第一个类的概率和第二个样本中第三个类的概率,即输出[y[0],y[1]]#定义交叉熵损失函数
def cross_entropy(y_hat,y):return -torch.log(y_hat[range(len(y_hat)),y])#定义一个用于对多个变量累加的的类
class Accumulator:#@savedef __init__(self,n):self.data=[0.0]*ndef 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):#@save"""计算预测正确的数量"""if len(y_hat.shape)>1 and y_hat.shape[1]>1:#如果`y_hat`是矩阵,那么假定第二个维度存储每个类的预测分数y_hat=y_hat.argmax(axis=1)#使用`argmax`获得每行中最大元素的索引来获得预测类别cmp=y_hat.type(y.dtype)==y#由于等式运算符“`==`”对数据类型很敏感,因此我们将`y_hat`的数据类型转换为与`y`的数据类型一致。return float(cmp.type(y.dtype).sum())def evaluate_accuracy(net,data_iter):#@save"""计算在指定数据集上模型的精度"""if isinstance(net,torch.nn.Module):net.eval()#将模型设为评估模式metric=Accumulator(2)#Initializes an Accumulator with two variables: the number of correct predictions and the total number of predictions.with torch.no_grad():#disables gradient computationfor X,y in data_iter:metric.add(accuracy(net(X),y),y.numel())#y.numel() returns the total number of elements in y.return metric[0]/metric[1]#if __name__ == '__main__':#print(evaluate_accuracy(net,test_iter))#由于使用随机权重初始化net模型,因此该模型的精度接近于随机猜测,如在有10个类别情况下的精度接近0.1 #定义一个在动画中绘制数据的类
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:#lengend:图例legend = []d2l.use_svg_display()self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)#"plt.subplots()" is called to create a figure (self.fig) and one or more subplots (self.axes).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)#A lambda function is used to create an anonymous function that is then assigned to the "self.config_axes" attribute. #This is a common pattern in Python, especially when a short, simple function is needed, and there's no intention to reuse it elsewhere in the code.# It provides a more compact and inline way to express the behavior.self.X, self.Y, self.fmts = None, None, fmtsdef add(self, x, y):#Adds data points to the plot.if not hasattr(y, "__len__"):#If y is not iterable (doesn't have a length), it is converted to a list to ensure it can be processed as a collection of values.y = [y]n = len(y)if not hasattr(x, "__len__"):#If x is not iterable, it is repeated n times to match the length of y.x = [x] * nif not self.X:#If "self.X" is not initialized, it is initialized as a list of empty lists, with one list for each element in y.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()# clears the current axis to prepare for the new datafor x, y, fmt in zip(self.X, self.Y, self.fmts):self.axes[0].plot(x, y, fmt)self.config_axes()#configures the axis using specified parameters.display.display(self.fig)display.clear_output(wait=True)#训练
def train_epoch_ch3(net, train_iter, loss, updater):  #@save#updater是更新模型参数的常用函数,在后文定义"""训练模型一个迭代周期"""# 将模型设置为训练模式if isinstance(net, torch.nn.Module):#checks if the object referred to by the variable net is an instance of the "torch.nn.Module" classnet.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()# Clear previously calculated gradientsl.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#If the condition is False, it raises an AssertionError exception.assert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_accdef updater(batch_size):return d2l.sgd([W, b], lr, batch_size)if __name__ == '__main__':lr = 0.1num_epochs = 10train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)#预测
#给定一系列图像,我们将比较它们的实际标签(文本输出的第一行)和模型预测(文本输出的第二行)
def predict_ch3(net, test_iter, n=6):"""预测标签"""# Iterate over the test dataset to get a batch of images and their true labelsfor X, y in test_iter:break# Get the true labels in text formattrues = d2l.get_fashion_mnist_labels(y)# Use the trained model to make predictions on the test batch and convert predictions to text labelspreds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1)) # Create titles for the images by combining true labels and predicted labelstitles = [true + '\n' + pred for true, pred in zip(trues, preds)]# Display a subset (n) of the images along with their true and predicted labelsd2l.show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])if __name__ == '__main__':predict_ch3(net, test_iter)plt.show()#将折线图和预测结果的图像统一显示## 3.6 Implementations of Softmax Regression from Scratchimport torch
import torchvision
import time
import matplotlib.pyplot as plt
import numpy as np 
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l
from IPython import display#初始化参数
batch_size=256
train_iter,test_iter=d2l.load_data_fashion_mnist(batch_size)
num_inputs=784
#图像有28*28像素,本节将其看作长度为784的向量
num_outputs=10
#softmax回归中输出与类别一样多,数据集有10个类别
W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)#定义softmax操作
def softmax(X):X_exp=torch.exp(X)partition=X_exp.sum(1,keepdim=True)return X_exp/partition#结果每行和为1#定义softmax回归模型
#在将数据传递到模型之前,使用reshape将每个原始图像展开为向量
def net(X):return softmax(torch.matmul(X.reshape((-1,W.shape[0])),W)+b)y = torch.tensor([0, 2])
#有了y,我们知道在第一个样本中第一类是正确的预测;在第二个样本中第三类是正确的预测
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
#2个样本在3个类别上的预测概率
#print(y_hat[[0, 1], y])
#使用y作为y_hat中概率的索引
#我们选择第一个样本中第一个类的概率和第二个样本中第三个类的概率,即输出[y[0],y[1]]#定义交叉熵损失函数
def cross_entropy(y_hat,y):return -torch.log(y_hat[range(len(y_hat)),y])#定义一个用于对多个变量累加的的类
class Accumulator:#@savedef __init__(self,n):self.data=[0.0]*ndef 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):#@save"""计算预测正确的数量"""if len(y_hat.shape)>1 and y_hat.shape[1]>1:#如果`y_hat`是矩阵,那么假定第二个维度存储每个类的预测分数y_hat=y_hat.argmax(axis=1)#使用`argmax`获得每行中最大元素的索引来获得预测类别cmp=y_hat.type(y.dtype)==y#由于等式运算符“`==`”对数据类型很敏感,因此我们将`y_hat`的数据类型转换为与`y`的数据类型一致。return float(cmp.type(y.dtype).sum())def evaluate_accuracy(net,data_iter):#@save"""计算在指定数据集上模型的精度"""if isinstance(net,torch.nn.Module):net.eval()#将模型设为评估模式metric=Accumulator(2)#Initializes an Accumulator with two variables: the number of correct predictions and the total number of predictions.with torch.no_grad():#disables gradient computationfor X,y in data_iter:metric.add(accuracy(net(X),y),y.numel())#y.numel() returns the total number of elements in y.return metric[0]/metric[1]#if __name__ == '__main__':#print(evaluate_accuracy(net,test_iter))#由于使用随机权重初始化net模型,因此该模型的精度接近于随机猜测,如在有10个类别情况下的精度接近0.1 #定义一个在动画中绘制数据的类
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:#lengend:图例legend = []d2l.use_svg_display()self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)#"plt.subplots()" is called to create a figure (self.fig) and one or more subplots (self.axes).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)#A lambda function is used to create an anonymous function that is then assigned to the "self.config_axes" attribute. #This is a common pattern in Python, especially when a short, simple function is needed, and there's no intention to reuse it elsewhere in the code.# It provides a more compact and inline way to express the behavior.self.X, self.Y, self.fmts = None, None, fmtsdef add(self, x, y):#Adds data points to the plot.if not hasattr(y, "__len__"):#If y is not iterable (doesn't have a length), it is converted to a list to ensure it can be processed as a collection of values.y = [y]n = len(y)if not hasattr(x, "__len__"):#If x is not iterable, it is repeated n times to match the length of y.x = [x] * nif not self.X:#If "self.X" is not initialized, it is initialized as a list of empty lists, with one list for each element in y.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()# clears the current axis to prepare for the new datafor x, y, fmt in zip(self.X, self.Y, self.fmts):self.axes[0].plot(x, y, fmt)self.config_axes()#configures the axis using specified parameters.display.display(self.fig)display.clear_output(wait=True)#训练
def train_epoch_ch3(net, train_iter, loss, updater):  #@save#updater是更新模型参数的常用函数,在后文定义"""训练模型一个迭代周期"""# 将模型设置为训练模式if isinstance(net, torch.nn.Module):#checks if the object referred to by the variable net is an instance of the "torch.nn.Module" classnet.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()# Clear previously calculated gradientsl.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#If the condition is False, it raises an AssertionError exception.assert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_accdef updater(batch_size):return d2l.sgd([W, b], lr, batch_size)if __name__ == '__main__':lr = 0.1num_epochs = 10train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)#预测
#给定一系列图像,我们将比较它们的实际标签(文本输出的第一行)和模型预测(文本输出的第二行)
def predict_ch3(net, test_iter, n=6):"""预测标签"""# Iterate over the test dataset to get a batch of images and their true labelsfor X, y in test_iter:break# Get the true labels in text formattrues = d2l.get_fashion_mnist_labels(y)# Use the trained model to make predictions on the test batch and convert predictions to text labelspreds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1)) # Create titles for the images by combining true labels and predicted labelstitles = [true + '\n' + pred for true, pred in zip(trues, preds)]# Display a subset (n) of the images along with their true and predicted labelsd2l.show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])if __name__ == '__main__':predict_ch3(net, test_iter)plt.show()#将折线图和预测结果的图像统一显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32 裸机点亮led

stm32不用库 裸机点亮led startup.s 定义栈入口函数 进入main .syntax unified .cpu cortex-m3 .fpu softvfp .thumb.global vtable .global reset_handler.type vtable, %object vtable:.word _estack.word reset_handler .size vtable, .-vtable.section .data .word _sidat…

docker 网络及如何资源(CPU/内存/磁盘)控制

安装Docker时&#xff0c;它会自动创建三个网络&#xff0c;bridge&#xff08;创建容器默认连接到此网络&#xff09;、 none 、host docker网络模式 Host 容器与宿主机共享网络namespace&#xff0c;即容器和宿主机使用同一个IP、端口范围&#xff08;容器与宿主机或其他使…

第140期 为什么有人无脑吹分布式(20240126)

数据库管理140期 2024-01-26 第140期 为什么有人无脑吹分布式&#xff08;20240126&#xff09;1 环境2 场景3 首席补刀总结 第140期 为什么有人无脑吹分布式&#xff08;20240126&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle ACE Associa…

mac安装telnet命令

1、安装brew 在mac终端执行命令&#xff1a; /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 报错&#xff1a; curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to raw.githubusercon…

C++ 设计模式之解释器模式

【声明】本题目来源于卡码网&#xff08;卡码网KamaCoder&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【设计模式大纲】 【简介】 --什么是解释器模式&#xff08;第22种设计模式&#xff09; 解释器模式&#xff08;Interpreter…

CodeGPT

GitCode - 开发者的代码家园 gitcode.com/ inscode.csdn.net/liujiaping/java_1706242128563/edit?openFileMain.java&editTypelite marketplace.visualstudio.com/items?itemNameCSDN.csdn-codegpt&spm1018.2226.3001.9836&extra%5Butm_source%5Dvip_chatgpt_c…

【算法】用JAVA代码实现LRU 【缓存】【LRU】

LRU(Least Recently Used)是一种常见的缓存淘汰策略,用于在缓存空间不足时确定哪些数据应该被淘汰。其基本原则是淘汰最近最少被访问的数据。 工作原理: 最近使用优先: LRU算法基于这样的思想:最近被使用的数据很可能在短时间内还会被使用,因此保留这些数据有助于提高缓…

linux bash shell的getopt以及函数用法小记

getopt 长选项 短选项 可选参数whilecaseifbasename函数变量shiftread 实现功能描述&#xff1a; 1. 实现可选参数传入 -c 或 --clearBuild。 2. 用shell脚本来实现选择&#xff0c;make时是否clean。 3. 可以打印用法帮助 和 作者信息。 #!/bin/bash# sh函数定义 *******…

vue3 实现上传图片裁剪

在线的例子以及代码&#xff0c;请点击访问链接

实力上榜!安全狗入选《CCSIP 2023中国网络安全行业业全景册(第六版)》多个细项

1月24日&#xff0c;Freebuf发布了《CCSIP 2023中国网络安全行业业全景册&#xff08;第六版&#xff09;》。 作为国内云原生安全领导厂商&#xff0c;安全狗也入选多个细分领域。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a;安全狗&#xff09;创办于2013年&…

学习gin框架知识的小注意点

Gin框架的初始化 有些项目中 初始化gin框架写的是&#xff1a; r : gin.New() r.Use(logger.GinLogger(), logger.GinRecovery(true)) 而不是r : gin.Default() 为什么呢&#xff1f; 点击进入Default源码发现其实他也是new两个中间件&#xff0c;&#xff08;Logger&…

【并发编程】锁死的问题——如何解决?以及如何避免?

目录 1.如何解决 一、死锁的定义和原因 1.1 定义 1.2 原因 二、常见的死锁场景 2.1 线程间相互等待资源 2.2 嵌套锁的循环等待 2.3 对资源的有序请求 三、死锁排查的方法 3.1 使用jstack命令 3.2 使用jconsole 3.3 使用VisualVM 四、常见的解决方案 4.1 避免嵌套锁…

深入研究C语言数组:高级技巧和性能优化的探索

在前文中&#xff0c;我们介绍了C语言数组的基本概念、多维数组的使用以及作为函数参数的传递方式。本文将进一步探索C语言数组的高级用法和性能优化技巧&#xff0c;帮助读者更深入地理解和运用数组。 动态数组 C语言中&#xff0c;数组的大小在创建时就被确定了&#xff0c…

STK姿态分析(一)矢量组件

文章目录 内容简介一、卫星矢量二、卫星坐标平面三、卫星姿态球面 – 内容简介 接下来一系列文章将进行STK目标&#xff08;卫星、导弹、火箭、飞机、船舶&#xff09;姿态分析的仿真。本篇将使用矢量&#xff08;vector&#xff09;组件对卫星姿态、传感器指向等进行3D可视化…

注册表学习——注册表结构

简介&#xff1a;注册表是由很多项和值构成的。 HEKY_USERS&#xff08;HKU&#xff09; 主要保存默认用户及当前登录用户配置信息。 .DEFAULT 该项是针对未来创建的新用户所保存的默认配置项。 S-1-5-18等项 这些项叫作安全标识符&#xff08;SID&#xff09;用来表示Windows操…

Maven 跳过test 进行 package

在使用Maven构建项目时&#xff0c;如果你想要跳过测试阶段&#xff08;test phase&#xff09;并直接打包&#xff08;package&#xff09;&#xff0c;你可以在命令行中使用特定的Maven命令选项。以下是一些常用的命令和选项&#xff1a; 1. 使用-DskipTests选项&#xff1a…

Linux(linux版本 centos 7) 下安装 oracle 19c详细教程(新手小白易上手)

一、安装前准备 1、下载预安装包 wget http://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm预安装包下载成功 2、下载oracle安装包 下载地址如下 https://www.oracle.com/cn/database/technologies…

渲染与创造之美:互为表里的艺术

在五彩斑斓的艺术世界中&#xff0c;渲染与创造是两股不可或缺的力量。它们之间的关系&#xff0c;恰如弓与箭&#xff0c;互为表里&#xff0c;共同塑造出无数令人叹为观止的视觉景象。创造之美是指通过创新思维和创造力&#xff0c;将想象具象化为现实&#xff0c;创造出新的…

spring-aop的介绍和使用

目录 1&#xff1a;为什么我会使用这个框架 2&#xff1a;那怎么快速入手属于自己的spring-aop呢&#xff08;或者说怎么在自己项目调用spring-aop这个框架呢&#xff09; 1->环境&#xff08;自己去建一个maven项目&#xff09; 2->导入spring-aop框架包&#xff08…

Python全自动性能无人机

Python全自动性能无人机研发开发的重要性可以从以下几个方面进行阐述&#xff1a; 编程语言的灵活性&#xff1a;Python是一种高级编程语言&#xff0c;具有简单易学的特点&#xff0c;能够快速地实现想法并进行快速原型设计。这种灵活性使得Python成为开发无人机控制系统的理想…