《动手学深度学习 Pytorch版》 3.3 线性回归的简洁实现

2023-11-11

import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l

from torch import nn  # nn 是神经网络(Neural Networks)的缩写

3.3.1 生成数据集

true_w = torch.tensor([2, -3.4])  # 与上一节类似 生成数据集
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)

3.3.2 读取数据集

# 调用现有 API 读取数据,其中 is_train 表示是否打乱数据
def load_array(data_arrays, batch_size, is_train=True):  #@save
    """构造一个PyTorch数据迭代器"""
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train)
batch_size = 10
data_iter = load_array((features, labels), batch_size)  # 构造迭代器

next(iter(data_iter))  # 调用 next 函数从迭代器获取第一项
[tensor([[-0.5500,  0.3406],
         [-0.1213,  0.0385],
         [ 1.0384, -0.4336],
         [-0.6411, -0.5833],
         [ 0.9083, -0.2935],
         [-1.5141, -1.2149],
         [ 3.8181, -0.4858],
         [ 1.4873,  0.4429],
         [-0.9654, -1.1355],
         [ 1.2120, -0.8451]]),
 tensor([[ 1.9365],
         [ 3.8387],
         [ 7.7771],
         [ 4.8915],
         [ 7.0209],
         [ 5.2958],
         [13.4798],
         [ 5.6838],
         [ 6.1303],
         [ 9.5189]])]

3.3.3 定义模型

标准的深度学习模型可以试图框架预先定义好的层,我们可以只关注模型的构建而非层的实现细节。

我们定义的模型 net 是 Sequential 类的实例,Sequential 类可以将多个层串在一起,即将数据传入第一层,再将第一层的输出作为第二层输入,以此类推。本模型只用了一层,实际上使用不到 Sequential 类,在此只是熟悉以下标准流程。

net = nn.Sequential(nn.Linear(2, 1))

3.3.4 初始化模型参数

通过 net[0] 选择网络中的第一层,然后使用 weight.data 和 bias.data 访问参数,直接使用预定义的方法 normal_ 和 fill_ 重写参数。

net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
tensor([0.])

3.3.5 定义损失函数

均方误差使用的是 MSELoss 类,也称为平方 L 2 L_2 L2 范数。默认情况下,它返回所以样本损失的平均值。

loss = nn.MSELoss()

3.3.6 定义优化算法

PyTorch 在 optim 模块中实现了小批量随机梯度下降算法的许多变体。可通过 net.parameters() 从模型获得优化参数以实例化一个 SGD 实例。

trainer = torch.optim.SGD(net.parameters(), lr=0.03)

3.3.7 训练

num_epochs = 3

for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)
        trainer.zero_grad()  # 梯度归零
        l.backward()  # 反向传播
        trainer.step()  # 更新模型参数
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')
epoch 1, loss 0.000116
epoch 2, loss 0.000115
epoch 3, loss 0.000115
w = net[0].weight.data
print('w 的误差估计:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b 的估计误差:', true_b - b)
w 的误差估计: tensor([-5.7220e-06, -6.5851e-04])
b 的估计误差: tensor([-0.0003])

练习

(1)如果将小批量的总损失替换为小批量损失的平均值,需要如何更改学习率?

不是默认就是损失的均值吗?

如果是均值,则梯度会多一个系数 1 b a t c h _ s i z e \frac{1}{batch\_size} batch_size1,所以为了抵消该系数应该使 l r × b a t c h _ s i z e lr\times batch\_size lr×batch_size

ps:所以说上一节那个 sgd 除一个 batch_size 可能是因为最后传的是总损失,在优化器里除个 batch_size 模拟框架实现的 SGD 默认传均值的样子。感觉多此一举,怪怪的。


(2)查看深度学习框架文档,它们提供了哪些损失函数和初始化方法?用胡伯尔损失代替原损失,即
l ( y , y ′ ) = { ∣ y − y ′ ∣ − σ 2 , 若 ∣ y − y ′ ∣ > σ 1 2 σ ( y − y ′ ) 2 , 其他情况 \begin{equation} l(y,y')=\left\{ \begin{aligned} & |y-y'|-\frac{\sigma}{2} &&, 若|y-y'|>\sigma\\ & \frac{1}{2\sigma}(y-y')^2 &&, 其他情况 \end{aligned} \right. \end{equation} l(y,y)= yy2σ2σ1(yy)2,yy>σ,其他情况

dir(nn)
['AdaptiveAvgPool1d',
 'AdaptiveAvgPool2d',
 'AdaptiveAvgPool3d',
 'AdaptiveLogSoftmaxWithLoss',
 'AdaptiveMaxPool1d',
 'AdaptiveMaxPool2d',
 'AdaptiveMaxPool3d',
 'AlphaDropout',
 'AvgPool1d',
 'AvgPool2d',
 'AvgPool3d',
 'BCELoss',
 'BCEWithLogitsLoss',
 'BatchNorm1d',
 'BatchNorm2d',
 'BatchNorm3d',
 'Bilinear',
 'CELU',
 'CTCLoss',
 'ChannelShuffle',
 'ConstantPad1d',
 'ConstantPad2d',
 'ConstantPad3d',
 'Container',
 'Conv1d',
 'Conv2d',
 'Conv3d',
 'ConvTranspose1d',
 'ConvTranspose2d',
 'ConvTranspose3d',
 'CosineEmbeddingLoss',
 'CosineSimilarity',
 'CrossEntropyLoss',
 'CrossMapLRN2d',
 'DataParallel',
 'Dropout',
 'Dropout1d',
 'Dropout2d',
 'Dropout3d',
 'ELU',
 'Embedding',
 'EmbeddingBag',
 'FeatureAlphaDropout',
 'Flatten',
 'Fold',
 'FractionalMaxPool2d',
 'FractionalMaxPool3d',
 'GELU',
 'GLU',
 'GRU',
 'GRUCell',
 'GaussianNLLLoss',
 'GroupNorm',
 'Hardshrink',
 'Hardsigmoid',
 'Hardswish',
 'Hardtanh',
 'HingeEmbeddingLoss',
 'HuberLoss',
 'Identity',
 'InstanceNorm1d',
 'InstanceNorm2d',
 'InstanceNorm3d',
 'KLDivLoss',
 'L1Loss',
 'LPPool1d',
 'LPPool2d',
 'LSTM',
 'LSTMCell',
 'LayerNorm',
 'LazyBatchNorm1d',
 'LazyBatchNorm2d',
 'LazyBatchNorm3d',
 'LazyConv1d',
 'LazyConv2d',
 'LazyConv3d',
 'LazyConvTranspose1d',
 'LazyConvTranspose2d',
 'LazyConvTranspose3d',
 'LazyInstanceNorm1d',
 'LazyInstanceNorm2d',
 'LazyInstanceNorm3d',
 'LazyLinear',
 'LeakyReLU',
 'Linear',
 'LocalResponseNorm',
 'LogSigmoid',
 'LogSoftmax',
 'MSELoss',
 'MarginRankingLoss',
 'MaxPool1d',
 'MaxPool2d',
 'MaxPool3d',
 'MaxUnpool1d',
 'MaxUnpool2d',
 'MaxUnpool3d',
 'Mish',
 'Module',
 'ModuleDict',
 'ModuleList',
 'MultiLabelMarginLoss',
 'MultiLabelSoftMarginLoss',
 'MultiMarginLoss',
 'MultiheadAttention',
 'NLLLoss',
 'NLLLoss2d',
 'PReLU',
 'PairwiseDistance',
 'Parameter',
 'ParameterDict',
 'ParameterList',
 'PixelShuffle',
 'PixelUnshuffle',
 'PoissonNLLLoss',
 'RNN',
 'RNNBase',
 'RNNCell',
 'RNNCellBase',
 'RReLU',
 'ReLU',
 'ReLU6',
 'ReflectionPad1d',
 'ReflectionPad2d',
 'ReflectionPad3d',
 'ReplicationPad1d',
 'ReplicationPad2d',
 'ReplicationPad3d',
 'SELU',
 'Sequential',
 'SiLU',
 'Sigmoid',
 'SmoothL1Loss',
 'SoftMarginLoss',
 'Softmax',
 'Softmax2d',
 'Softmin',
 'Softplus',
 'Softshrink',
 'Softsign',
 'SyncBatchNorm',
 'Tanh',
 'Tanhshrink',
 'Threshold',
 'Transformer',
 'TransformerDecoder',
 'TransformerDecoderLayer',
 'TransformerEncoder',
 'TransformerEncoderLayer',
 'TripletMarginLoss',
 'TripletMarginWithDistanceLoss',
 'Unflatten',
 'Unfold',
 'UninitializedBuffer',
 'UninitializedParameter',
 'Upsample',
 'UpsamplingBilinear2d',
 'UpsamplingNearest2d',
 'ZeroPad2d',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 '_reduction',
 'common_types',
 'factory_kwargs',
 'functional',
 'grad',
 'init',
 'intrinsic',
 'modules',
 'parallel',
 'parameter',
 'qat',
 'quantizable',
 'quantized',
 'utils']
loss = nn.SmoothL1Loss()

num_epochs = 3

for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)
        trainer.zero_grad()  # 梯度归零
        l.backward()  # 反向传播
        trainer.step()  # 更新模型参数
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')

w = net[0].weight.data
print('w 的误差估计:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b 的估计误差:', true_b - b)
epoch 1, loss 0.000057
epoch 2, loss 0.000057
epoch 3, loss 0.000057
w 的误差估计: tensor([0.0005, 0.0001])
b 的估计误差: tensor([-0.0001])

(3)如何访问线性回归的梯度?

net[0].weight.grad, net[0].bias.grad
(tensor([[0.0064, 0.0048]]), tensor([-0.0056]))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《动手学深度学习 Pytorch版》 3.3 线性回归的简洁实现 的相关文章

随机推荐

  • 送书

    六月 初夏 高考结束 毕业季到来 准大学生纠结选什么专业 毕业生迈进就业大军 不论什么身份 大家都在思考着同一件事情 当下什么能力最热门 想要得到答案很简单 打开任意一款求职软件 热门岗位的职位简介中都少不了这一项 数据分析能力 4月20日
  • 笔记&代码

    1 1数据与统计学 统计学的含义 数据及其分类和来源 1 1 1 什么是统计学 收集数据 数据分析 描述统计 利用图表 计算简单统计量 推断统计 根据样本判断总体 参数估计和假设检验 1 1 2 变量与数据 变量 数据 变量的观测结果就是数
  • TCP详解之重传机制

    TCP详解之重传机制 TCP 实现可靠传输的方式之一 是通过序列号与确认应答 在 TCP 中 当发送端的数据到达接收主机时 接收端主机会返回一个确认应答消息 表示已收到消息 但在错综复杂的网络 并不一定能如上图那么顺利能正常的数据传输 万一
  • OpenGL ES 着色器(shader)介绍

    1 Shader Shader其实就是一段执行在GPU上的程序 此程序使用OpenGL ES SL语言来编写 它是一个描述顶点或像素特性的简单程序 在opengles中常用的shader有两种 vertex shader和fragment
  • 在styled-components的样式声明中做px到rem的自动转换

    原文地址 最近在尝试使用styled components来做React下的样式开发 这样可以利用js语言的灵活来增强css的能力 在用styled components处理px到rem的转换时 有点问题了 styled component
  • 嵌入式学习(四)——串口

    目录 一 通信的基本概念 1 1 同步通信和异步通信 1 2 电平信号和差分信号 1 3 并行接口和串行接口 1 4 单工通信和双工通信 二 串口通信 2 1 基本概念 2 2 起始位 数据位 奇偶校验位 停止位 2 3 RS232电平和T
  • 如何将二维数组作为函数的参数传递

    如何将二维数组作为函数的参数传递 今天写程序的时候要用到二维数组作参数传给一个函数 我发现将二维数组作参数进行传递还不是想象得那么简单里 但是最后我也解决了遇到的问题 所以这篇文章主要介绍如何处理二维数组当作参数传递的情况 希望大家不至于再
  • 如何加速实现数据透明度 驱动企业释放数据价值

    本文根据王锦超先生在 DQMIS 2020第四届数据质量管理国际峰会 现场演讲内容整理而成 图1 1 思迪博软件 Stibo Systems 中国区总经理 王锦超 演讲嘉宾介绍 王锦超 专注于服务企业信息化建设十余年 在主数据管理 数据治理
  • 贪心法田忌赛马问题Java代码,hdoj 1052 Tian Ji - The Horse Racing【田忌赛马】 【贪心】...

    hdoj 1052 Tian Ji The Horse Racing 田忌赛马 贪心 思路 先按从小到大排序 然后从最快的开始比 假设i j 是最慢的一端 flag1 flag2是最快的一端 田的最快的大于king的 则比较 如果等于然后判
  • linux 系统安装vscode 图文学习记录

    目录 1 下载 2 解压 3 移动到 usr local 目录 4 复制一个VScode图标文件到 usr share icons 目录 后面会有用 5 创建启动器 1 下载 到地址下载安装包 https code visualstudio
  • OpenGL programming with GLSL: Part I

    The standards of OpenGL GLSL are evolving constantly we enter to the era of programmable graphic pipeline at the same ti
  • 关于对象的引用作为参数,可以直接访问私有成员的问题

    include using namespace std class CPoint public CPoint int xx int yy x xx y yy CPoint const CPoint p x p x y p y private
  • 详解掩膜mask及不规则mask应用

    部分引用自 https www cnblogs com skyfsm p 6894685 html 在OpenCV中我们经常会遇到一个名字 Mask 掩膜 很多函数都使用到它 那么这个Mask到底什么呢 mask经常应用于 原图 src 与
  • [OpenCV实战]41 嵌入式计算机视觉设备选择

    文章目录 1 简介 1 1 深度学习与传统计算机视觉 1 2 性能考量 1 3 社区支持 2 结论 3 参考 在计算机视觉领域中 不同的场景不同的应用程序需要不同的解决方案 在本文中 我们将快速回顾可用于在单板计算机 指所有的逻辑线路 定时
  • Element UI的数据表格数据检索方法

    Element UI的数据表格数据检索方法 vue兼容性很好的前端组件 刚开始上手 感觉这一些方法功能蛮强大的 跟大家分享一下吧 一 表体数据检索 1 1 样式检索 如图 我们想根据数据表格中出现的特定文本 优 良 中 进行样式的检索 这种
  • Win10 bat 调用管理员运行打开/杀死进程

    原因 后台有个插件服务与其他进程存在端口 串口冲突 需要使用管理员身份杀死进程 注意 以下代码为bat脚本 保存时另存为 gt 编码格式选择 ANSI 在运行时则不会出现中文乱码 Q 如何调起管理员身份的cmd A 使用vbs脚本 代码如下
  • 应急响应思路

    一 挖矿病毒应急响应 1 判断遭遇的挖矿木马 a 挖矿木马挖矿现象 1 cpu占用过高2 网络连接外部网络3 配置文件特征pools b 排查网络链接及进程定位挖矿木马 1 排查定时任务2 排查守护连接 c 判断挖矿木马时间 d 判断挖矿木
  • ES 22 - Elasticsearch中如何进行日期(数值)范围查询

    目录 1 范围查询的符号 2 数值范围查询 3 时间范围查询 3 1 简单查询示例 3 2 关于时间的数学表达式 date math 3 3 关于时间的四舍五入 4 日期格式化范围查询 format 5 时区范围查询 time zone 1
  • nginx-ingress配置跨域

    nginx ingress controller 配置跨域 直接在ingress 的annation里面加 kubernetes io ingress class nginx nginx ingress kubernetes io cors
  • 《动手学深度学习 Pytorch版》 3.3 线性回归的简洁实现

    import numpy as np import torch from torch utils import data from d2l import torch as d2l from torch import nn nn 是神经网络