赞
踩
!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
input:
fair_probs = torch.ones([6]) / 6#创建一个包含6个1的数组,同时都除以6
print(fair_probs)
multinomial.Multinomial(1, fair_probs).sample()#在fair_probs中再随机采样一个,因为传入的参数为1
output:
tensor([0.1667, 0.1667, 0.1667, 0.1667, 0.1667, 0.1667])
tensor([0., 1., 0., 0., 0., 0.])
在估计一个骰子的公平性时,我们希望从同一分布中生成多个样本。 如果用Python的for循环来完成这个任务,速度会慢得惊人。 因此我们使用深度学习框架的函数同时抽取多个样本,得到我们想要的任意形状的独立样本数组
multinomial.Multinomial(10, fair_probs).sample()
tensor([0., 4., 1., 4., 1., 0.])
让我们进行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();
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.生成数据集
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 随机的
其中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)
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)
这里我们使用iter构造python迭代器,并且使用next从迭代器中获取第一项
next(iter(data_iter))
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]])]
3.定义模型
对于标准深度学习模型,我们可以使用**框架的预定义好的层,**这里只需要关注使用那些层来构造模型,而不必关注实现细节。我们首先定义一个模型变量net,他是一个Sequential类的实例。Sequential类将多个层联系在一起。当给定输入数据时,Sequential实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。
回顾:全连接层,因为他的每一个输入都通过矩阵-向量乘法得到他的输出。
在PyTorch中,全连接层在Linear类中定义。 值得注意的是,我们将两个参数传递到nn.Linear中。 第一个指定输入特征形状,即2,第二个指定输出特征形状,输出特征形状为单个标量,因此为1。
# nn是神经网络的缩写
from torch import nn
net = nn.Sequential(nn.Linear(2, 1))
4.初始化模型参数
net[0].weight.data.normal_(0, 0.01)#下划线的意思是,使用正态分布替换掉权重data的值
net[0].bias.data.fill_(0)#使用填充0替换掉偏差data的值
5.定义损失函数
loss = nn.MSELoss()
[计算均方误差使用的是MSELoss类,也称为平方 L2 范数]。 默认情况下,它返回所有样本损失的平均值。
6.定义优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
小批量随机梯度下降算法是一种优化神经网络的标准工具, 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}')
output:
epoch 1, loss 0.000157
epoch 2, loss 0.000094
epoch 3, loss 0.000094
比较生成数据集的真实参数和通过有限数据训练获得的模型参数:
w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)
output:
w的估计误差: tensor([-0.0008, 0.0006])
b的估计误差: tensor([0.0013])
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 512
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size)
#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);
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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。