当前位置:   article > 正文

动手学深度学习:代码笔记_动手学深度学习代码

动手学深度学习代码


前言
本文使用的是colab,采用pytorch框架,对应的视频教学是李沐的动手学深度学习,本文针对代码进行注释和整理笔记。

2.预备知识

2.6概率

!pip install git+https://github.com/d2l-ai/d2l-zh@release  # installing d2l
pip install matplotlib_inline
#导入对应的包
%matplotlib inline
import torch
from torch.distributions import multinomial
from d2l import torch as d2l

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

input:

fair_probs = torch.ones([6]) / 6#创建一个包含6个1的数组,同时都除以6
print(fair_probs)
multinomial.Multinomial(1, fair_probs).sample()#在fair_probs中再随机采样一个,因为传入的参数为1
  • 1
  • 2
  • 3

output:

tensor([0.1667, 0.1667, 0.1667, 0.1667, 0.1667, 0.1667])
tensor([0., 1., 0., 0., 0., 0.])
  • 1
  • 2

在估计一个骰子的公平性时,我们希望从同一分布中生成多个样本。 如果用Python的for循环来完成这个任务,速度会慢得惊人。 因此我们使用深度学习框架的函数同时抽取多个样本,得到我们想要的任意形状的独立样本数组

multinomial.Multinomial(10, fair_probs).sample()
  • 1
tensor([0., 4., 1., 4., 1., 0.])
  • 1

让我们进行500组实验,每组抽取10个样本
input:

counts = multinomial.Multinomial(10, fair_probs).sample((500,))
print(counts)
cum_counts = counts.cumsum(dim=0)#累加(dim=0:行累加,dim=1:列累加)
estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True)

d2l.set_figsize((6, 4.5))
for i in range(6):
    d2l.plt.plot(estimates[:, i].numpy(),
                 label=("P(die=" + str(i + 1) + ")"))
d2l.plt.axhline(y=0.167, color='black', linestyle='dashed')
d2l.plt.gca().set_xlabel('Groups of experiments')
d2l.plt.gca().set_ylabel('Estimated probability')
d2l.plt.legend();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

output:

tensor([[1., 2., 4., 2., 1., 0.],
        [3., 1., 2., 1., 2., 1.],
        [2., 0., 0., 4., 3., 1.],
        ...,
        [3., 2., 2., 2., 0., 1.],
        [1., 3., 1., 1., 2., 2.],
        [3., 3., 2., 1., 0., 1.]])
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

3.线性神经网络

3.3线性回归的简洁实现

1.生成数据集

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

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)#synthetic 随机的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其中synthetic_data函数是3.2定义过的函数,如下:

def synthetic_data(w, b, num_examples):  
    """生成y=Xw+b+噪声"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.读取数据集
我们可以调用框架中的API来读取数据,通过迭代器指定batch_size.

def load_array(data_arrays, batch_size, is_train=True): 
    """构造一个PyTorch数据迭代器"""
    dataset = data.TensorDataset(*data_arrays)# * 号表示对list解开入参,即把列表元素分别当作参数传入,TensorDataset():对数据进行包装
    return data.DataLoader(dataset, batch_size, shuffle=is_train)#shuffle表示是否需要对数据进行打乱

batch_size = 10
data_iter = load_array((features, labels), batch_size)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里我们使用iter构造python迭代器,并且使用next从迭代器中获取第一项

next(iter(data_iter))
  • 1

output:

[tensor([[ 0.7882, -0.7068],
         [ 0.5081,  0.2577],
         [-0.5769,  0.1545],
         [-0.3271, -0.6080],
         [-0.2716, -1.4628],
         [-1.1530, -1.4643],
         [ 0.1635, -0.2018],
         [-0.0753, -1.1161],
         [ 3.4251,  0.1953],
         [ 0.3589, -0.9478]]),
 tensor([[ 8.1742],
         [ 4.3357],
         [ 2.5157],
         [ 5.6106],
         [ 8.6395],
         [ 6.8726],
         [ 5.2155],
         [ 7.8377],
         [10.3918],
         [ 8.1590]])]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

3.定义模型
对于标准深度学习模型,我们可以使用**框架的预定义好的层,**这里只需要关注使用那些层来构造模型,而不必关注实现细节。我们首先定义一个模型变量net,他是一个Sequential类的实例。Sequential类将多个层联系在一起。当给定输入数据时,Sequential实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。
回顾:全连接层,因为他的每一个输入都通过矩阵-向量乘法得到他的输出。

在PyTorch中,全连接层在Linear类中定义。 值得注意的是,我们将两个参数传递到nn.Linear中。 第一个指定输入特征形状,即2,第二个指定输出特征形状,输出特征形状为单个标量,因此为1。

# nn是神经网络的缩写
from torch import nn

net = nn.Sequential(nn.Linear(2, 1))
  • 1
  • 2
  • 3
  • 4

4.初始化模型参数

net[0].weight.data.normal_(0, 0.01)#下划线的意思是,使用正态分布替换掉权重data的值
net[0].bias.data.fill_(0)#使用填充0替换掉偏差data的值

  • 1
  • 2
  • 3

5.定义损失函数

loss = nn.MSELoss()
  • 1

[计算均方误差使用的是MSELoss类,也称为平方 L2 范数]。 默认情况下,它返回所有样本损失的平均值。

6.定义优化算法

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

小批量随机梯度下降算法是一种优化神经网络的标准工具, PyTorch在optim模块中实现了该算法的许多变种。 当我们(实例化一个SGD实例)时,我们要指定优化的参数 (可通过net.parameters()从我们的模型中获得)以及优化算法所需的超参数字典。 小批量随机梯度下降只需要设置lr值,这里设置为0.03。

7.训练
回顾一下:在每个迭代周期里,我们将完整遍历一次数据集(train_data), 不停地从中获取一个小批量的输入和相应的标签。 对于每一个小批量,我们会进行以下步骤:

通过调用net(X)生成预测并计算损失l(前向传播)。
通过进行反向传播来计算梯度。
通过调用优化器来更新模型参数。
为了更好的衡量训练效果,我们计算每个迭代周期后的损失,并打印它来监控训练过程。

num_epochs = 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X) ,y)
        trainer.zero_grad()#优化前先把梯度清0
        l.backward()#这里不需要手动求sum因为pytorch已经把sum求好了
        trainer.step()#调用step函数进行模型的更新
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

output:

epoch 1, loss 0.000157
epoch 2, loss 0.000094
epoch 3, loss 0.000094
  • 1
  • 2
  • 3

比较生成数据集的真实参数和通过有限数据训练获得的模型参数:

w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)
  • 1
  • 2
  • 3
  • 4

output:

w的估计误差: tensor([-0.0008,  0.0006])
b的估计误差: tensor([0.0013])
  • 1
  • 2

3.7softmax简洁实现

import torch
from torch import nn
from d2l import torch as d2l
  • 1
  • 2
  • 3
batch_size = 512
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size)
  • 1
  • 2
#pytorch不会隐式的调整输入的形状,因此
#我们在线性层前定义了展平层(flatten),来调整网络输入的形状
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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
loss = nn.CrossEntropyLoss(reduction='none')
  • 1
trainer = torch.optim.SGD(net.parameters(),lr=0.1)
  • 1
num_epochs = 10
d2l.train_ch3(net,train_iter,test_iter,loss,num_epochs,trainer)
  • 1
  • 2

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/373321?site
推荐阅读
相关标签
  

闽ICP备14008679号