跟李沐学AI——动手学深度学习 PyTorch版——学习笔记pycharm版本(第三天——08-09)2023.2.28

前言

  我认为,沐神的第七节课和第八节课十分的重要,是后面的基础。一定要掌握牢固了。
先处理几个问题:
  1、图片不显示的问题
因为沐神使用的是jupyter,而我使用的是pycharm,所以在原本的d2l.plt…后面需要添加一行代码,比如

import matplotlib.pyplot as plt  # 新添加的import
d2l.set_figsize()
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1)  
plt.show()  # 新添加的代码

或者在 调用d2l的时候,后面添加d2l.plt.show()
  2、ModuleNotFoundError: No module named ‘d2l’
在这里插入图片描述
  解决办法是,下载d2l包
在这里插入图片描述
  d2l包里面包含这几个文件,沐神的GitHub里面 下载地址在这里插入图片描述
  3、多线程的问题
在这里插入图片描述
报错原因是因为李沐用的linex系统,直接这样写没有问题,但是在window系统下,就出问题了,解决办法是,把return的值由4改为0,后面他直接调用的d2l.torch里面也需要改,遇到这个错误的时候,直接改就可以了。

def get_dataloader_workers():  # @save
    """使用4个进程来读取数据"""
    return 0  #  linux系统中可以使用多个子进程加载数据,windows系统里是不可以的

代码详细解释

  沐神提供了两个版本,一个是从零开始实现,一个是简洁实现。所谓的简洁实现就是用一些torch自带的库和他自己的d2l封装在一起的,沐神很贴心的后面加上了 # @save。
1、

def synthetic_data(w, b, num_examples):  # @save
    """生成y=Xw+b+噪声"""
    X = torch.normal(0, 1, (num_examples, len(w)))  # (a,b,c)  a:均值,b方差,c:size
    y = torch.matmul(X, w) + b  # mul and * 是 点乘, matmul and mm 叉乘
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))  # -1的意思是,总元素除以其他的元素

  torch.normal(a,b,c) # a:均值、b方差、c是size
  len(w) # 方法返回对象(字符、列表、元组等)长度或项目个数。

x1=[1,2,3]  # 3  (长度)
x2=[[1,2,3],[2,3,4]]    # 2  (数量)
x3='yy'    # 2
x4=torch.tensor([1,2,3])  # 3  (数量)
x5=torch.tensor([[1,2,3]])  # 1  (数量)
x6=[[1,2,3],[2,3,4],[3,4,5],[5,6,7]]    # 4  (数量)
print(len(x1),len(x2),len(x3),len(x4),len(x5))

torch.matmul的维度问题 ([1,2,3]是一维的,而[[1,2,3]]是二维的只不过只有一行而已)
  一维乘以一维==》标量
  二维乘以二维==》矩阵
  一维乘以二维==》3×(3×2)》(1×3)×(3×2)》1×2==》2(例子)
  一维乘以二维==》(3×2)×2==》(3×2)×(2×1)》3×1》3(例子)
2、

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))  # 生成一个features长度的序列
    # 这些样本是随机读取的,没有特定的顺序
    random.shuffle(indices)  # 打乱列表
    for i in range(0, num_examples, batch_size):  # 小批量的关键,需要理解
        batch_indices = torch.tensor(
            indices[i: min(i + batch_size, num_examples)])  # min的作用是在不整除的时候,不至于报错
        yield features[batch_indices], labels[batch_indices]  # 新的东西

  yield:作用就是使用一个固定大小的内存来处理不断生成的数据,从未达到减少内存的消耗。
  yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 data_iter(1) 不会执行data_iter 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 data_iter函数内部的代码,执行到 yield 时,data_iter函数就返回一个迭代值,下次迭代时,代码从 yield 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。
  也可以手动调用 data_iter的 next() 方法(因为data_iter 是一个 generator 对象,该对象具有 next() 方法),这样我们就可以更清楚地看到 data_iter 的执行流程。
一言以蔽之:yield就像一个中断器,每次循环调用一次。
for X, y in data_iter(batch_size, features, labels):
在这个循环中,yield了一次,生成了一个batch_size的数据,进入循环体进行处理。处理完之后,执行for的时候又生成了一个batch_size的数据,再进行处理,直到所有的数据全部处理完成。

**3、**简洁实现
逐行解释

def load_array(data_arrays, batch_size, is_train=True):  #@save
    """构造一个PyTorch数据迭代器"""
    dataset = data.TensorDataset(*data_arrays)  # 将特征和标签放在一起,存在dataset中
    return data.DataLoader(dataset, batch_size, shuffle=is_train)  # 生成小批量的,无序的数据

batch_size = 10
data_iter = load_array((features, labels), batch_size)
# 可以看到三个next生成的数据都不一样,每次next都提出一组无序的数据,记得家print才能显示数据
print(next(iter(data_iter)))  
print(next(iter(data_iter)))
print(next(iter(data_iter)))
from torch import nn

net = nn.Sequential(nn.Linear(2, 1))  # 网络,Sequential是一个容器
net[0].weight.data.normal_(0, 0.01)  # 初始化
net[0].bias.data.fill_(0)  # 初始化
loss = nn.MSELoss()  # 损失函数
trainer = torch.optim.SGD(net.parameters(), lr=0.03)  # 优化方式

num_epochs = 3  # 训练三轮
for epoch in range(num_epochs):
    for X, y in data_iter:  # 又开始yeild
        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}')

**4、**回归问题

y = torch.tensor([0, 2])
y_hat = torch.tensor([[0.1, 0.3, 0.6], []])
print(y_hat[[0, 1], y])  #[第0行中的第0个,第1行中的第2个]也就是[0.1,0.5]

 理解:真实的值是0和2,第一次预测的0,1,2的概率分别为[0.1,0.3,0.6],第一次预测的0,1,2的概率分别为[0.3, 0.2, 0.5],那么两次预测都正确的概率为[0.1,0.5]

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yy_helloworld

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值