网站建设是半年的持久战,wordpress页面美化,主页制作语言缩写,有没有做ppt很厉害的网站目录
#x1f31e;一、实验目的
#x1f31e;二、实验准备
#x1f31e;三、实验内容
#x1f33c;1. 线性回归
#x1f33b;1.1 矢量化加速
#x1f33b;1.2 正态分布与平方损失
#x1f33c;2. 线性回归的从零开始实现
#x1f33b;2.1. 生成数据集
#x… 目录
一、实验目的
二、实验准备
三、实验内容
1. 线性回归
1.1 矢量化加速
1.2 正态分布与平方损失
2. 线性回归的从零开始实现
2.1. 生成数据集
2.2 读取数据集
2.3. 初始化模型参数
2.4. 定义模型
2.5. 定义损失函数
2.6. 定义优化算法
2.7. 训练
2.8 小结
2.9 练习
3. 线性回归的简洁实现
3.1. 生成数据集
3.2. 读取数据集
3.3 定义模型
3.4 初始化模型参数
3.5 定义损失函数
3.6 定义优化算法
3.7 训练
3.8 小结
3.9 练习
四、实验心得 一、实验目的
熟悉PyTorch框架了解PyTorch的基本概念、数据结构和核心函数创建线性回归模型使用PyTorch构建一个简单的线性回归模型该模型能够学习输入特征和目标变量之间的线性关系线性回归从零开始实现及其简洁实现并完成章节后习题。 二、实验准备
根据GPU安装pytorch版本实现GPU运行实验代码配置环境用来运行 Python、Jupyter Notebook和相关库等相关库。 三、实验内容
资源获取关注公众号【科创视野】回复 深度学习
1. 线性回归
1使用jupyter notebook新增的pytorch环境新建ipynb文件完成线性回归从零开始实现的实验代码与练习结果如下 1.1 矢量化加速
%matplotlib inline
import math
import time
import numpy as np
import torch
from d2l import torch as d2ln 10000
a torch.ones([n])
b torch.ones([n])class Timer: #save记录多次运行时间def __init__(self):self.times []self.start()def start(self):启动计时器self.tik time.time()def stop(self):停止计时器并将时间记录在列表中self.times.append(time.time() - self.tik)return self.times[-1]def avg(self):返回平均时间return sum(self.times) / len(self.times)def sum(self):返回时间总和return sum(self.times)def cumsum(self):返回累计时间return np.array(self.times).cumsum().tolist()c torch.zeros(n)
timer Timer()
for i in range(n):c[i] a[i] b[i]
f{timer.stop():.5f} sec
输出结果 1.2 正态分布与平方损失
def normal(x, mu, sigma):p 1 / math.sqrt(2 * math.pi * sigma**2)return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)# 再次使用numpy进行可视化
x np.arange(-7, 7, 0.01)# 均值和标准差对
params [(0, 1), (0, 2), (3, 1)]
d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabelx,ylabelp(x), figsize(4.5, 2.5),legend[fmean {mu}, std {sigma} for mu, sigma in params])
输出结果 2. 线性回归的从零开始实现
%matplotlib inline
import random
import torch
from d2l import torch as d2l 2.1. 生成数据集
def synthetic_data(w, b, num_examples): #save生成yXwb噪声X torch.normal(0, 1, (num_examples, len(w)))y torch.matmul(X, w) by 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)print(features:, features[0],\nlabel:, labels[0])
输出结果 d2l.set_figsize()
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1);
输出结果 2.2 读取数据集
def data_iter(batch_size, features, labels):num_examples len(features)indices list(range(num_examples))# 这些样本是随机读取的没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices torch.tensor(indices[i: min(i batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]batch_size 10for X, y in data_iter(batch_size, features, labels):print(X, \n, y)break
输出结果 2.3. 初始化模型参数
w torch.normal(0, 0.01, size(2,1), requires_gradTrue)
b torch.zeros(1, requires_gradTrue)
w,b
输出结果 2.4. 定义模型
def linreg(X, w, b): #save线性回归模型return torch.matmul(X, w) b 2.5. 定义损失函数
def squared_loss(y_hat, y): #save均方损失return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 2.6. 定义优化算法
def sgd(params, lr, batch_size): #save小批量随机梯度下降with torch.no_grad():for param in params:param - lr * param.grad / batch_sizeparam.grad.zero_() 2.7. 训练
lr 0.03
num_epochs 3
net linreg
loss squared_lossfor epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l loss(net(X, w, b), y) # X和y的小批量损失# 因为l形状是(batch_size,1)而不是一个标量。l中的所有元素被加到一起# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size) # 使用参数的梯度更新参数with torch.no_grad():train_l loss(net(features, w, b), labels)print(fepoch {epoch 1}, loss {float(train_l.mean()):f})
输出结果 print(fw的估计误差: {true_w - w.reshape(true_w.shape)})
print(fb的估计误差: {true_b - b})
输出结果 2.8 小结 我们学习了深度网络是如何实现和优化的。在这一过程中只使用张量和自动微分不需要定义层或复杂的优化器。这一节只触及到了表面知识。在下面的部分中我们将基于刚刚介绍的概念描述其他模型并学习如何更简洁地实现其他模型。 2.9 练习
1.如果我们将权重初始化为零会发生什么。算法仍然有效吗
# 在单层网络中(一层线性回归层)将权重初始化为零时可以的但是网络层数加深后在全连接的情况下
# 在反向传播的时候由于权重的对称性会导致出现隐藏神经元的对称性使得多个隐藏神经元的作用就如同
# 1个神经元算法还是有效的但是效果不大好。参考https://zhuanlan.zhihu.com/p/75879624。
2.假设试图为电压和电流的关系建立一个模型。自动微分可以用来学习模型的参数吗
# 可以的建立模型UIWb然后采集(UI)的数据集通过自动微分即可学习W和b的参数。
import torch
import random
from d2l import torch as d2l
#生成数据集
def synthetic_data(r, b, num_examples):I torch.normal(0, 1, (num_examples, len(r)))u torch.matmul(I, r) bu torch.normal(0, 0.01, u.shape) # 噪声return I, u.reshape((-1, 1)) # 标量转换为向量true_r torch.tensor([20.0])
true_b 0.01
features, labels synthetic_data(true_r, true_b, 1000)#读取数据集
def data_iter(batch_size, features, labels):num_examples len(features)indices list(range(num_examples))random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices torch.tensor(indices[i: min(i batch_size, num_examples)])yield features[batch_indices],labels[batch_indices]batch_size 10
# 初始化权重
r torch.normal(0,0.01,size ((1,1)), requires_grad True)
b torch.zeros(1, requires_grad True)# 定义模型
def linreg(I, r, b):return torch.matmul(I, r) b
# 损失函数
def square_loss(u_hat, u):return (u_hat - u.reshape(u_hat.shape)) ** 2/2
# 优化算法
def sgd(params, lr, batch_size):with torch.no_grad():for param in params:param - lr * param.grad/batch_sizeparam.grad.zero_()lr 0.03
num_epochs 10
net linreg
loss square_lossfor epoch in range(num_epochs):for I, u in data_iter(batch_size, features, labels):l loss(net(I, r, b), u)l.sum().backward()sgd([r, b], lr, batch_size)with torch.no_grad():train_l loss(net(features, r, b), labels)print(fepoch {epoch 1}, loss {float(train_l.mean()):f})
print(r)
print(b)
print(fr的估计误差: {true_r - r.reshape(true_r.shape)})
print(fb的估计误差: {true_b - b})输出结果 3.能基于普朗克定律使用光谱能量密度来确定物体的温度吗 # 3
# 普朗克公式
# x:波长
# T:温度
import torch
import random
from d2l import torch as d2l#生成数据集
def synthetic_data(x, num_examples):T torch.normal(0, 1, (num_examples, len(x)))u c1 / ((x ** 5) * ((torch.exp(c2 / (x * T))) - 1));u torch.normal(0, 0.01, u.shape) # 噪声return T, u.reshape((-1, 1)) # 标量转换为向量c1 3.7414*10**8 # c1常量
c2 1.43879*10**4 # c2常量
true_x torch.tensor([500.0])features, labels synthetic_data(true_x, 1000)#读取数据集
def data_iter(batch_size, features, labels):num_examples len(features)indices list(range(num_examples))random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices torch.tensor(indices[i: min(i batch_size, num_examples)])yield features[batch_indices],labels[batch_indices]batch_size 10
# 初始化权重
x torch.normal(0,0.01,size ((1,1)), requires_grad True)# 定义模型
def planck_formula(T, x):return c1 / ((x ** 5) * ((torch.exp(c2 / (x * T))) - 1))
# 损失函数
def square_loss(u_hat, u):return (u_hat - u.reshape(u_hat.shape)) ** 2/2
# 优化算法
def sgd(params, lr, batch_size):with torch.no_grad():for param in params:param - lr * param.grad/batch_sizeparam.grad.zero_()lr 0.001
num_epochs 10
net planck_formula
loss square_lossfor epoch in range(num_epochs):for T, u in data_iter(batch_size, features, labels):l loss(net(T, x), u)l.sum().backward()sgd([x], lr, batch_size)with torch.no_grad():train_l loss(net(features, x), labels)print(fepoch {epoch 1}, loss {float(train_l.mean()):f})print(fr的估计误差: {true_x - x.reshape(true_x.shape)})输出结果 4.计算二阶导数时可能会遇到什么问题这些问题可以如何解决
# 一阶导数的正向计算图无法直接获得可以通过保存一阶导数的计算图使得可以求二阶导数(create_graph和retain_graph都置为True
# 保存原函数和一阶导数的正向计算图)。实验如下
import torchx torch.randn((2), requires_gradTrue)
y x**3dy torch.autograd.grad(y, x, grad_outputstorch.ones(x.shape),retain_graphTrue, create_graphTrue)
dy2 torch.autograd.grad(dy, x, grad_outputstorch.ones(x.shape))dy_ 3*x**2
dy2_ 6*xprint()
print(dy, dy_)
print()
print(dy2, dy2_)输出结果 5.为什么在squared_loss函数中需要使用reshape函数
# 以防y^和y一个是行向量、一个是列向量使用reshape可以确保shape一样。
6.尝试使用不同的学习率观察损失函数值下降的快慢。
# ①学习率过大前期下降很快但是后面不容易收敛
# ②学习率过小损失函数下降会很慢。
7.如果样本个数不能被批量大小整除data_iter函数的行为会有什么变化
# 报错。 3. 线性回归的简洁实现
1使用jupyter notebook新增的pytorch环境新建ipynb文件完成线性回归的简洁实现的实验代码与练习结果如下 3.1. 生成数据集
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2ltrue_w torch.tensor([2, -3.4])
true_b 4.2
features, labels d2l.synthetic_data(true_w, true_b, 1000) 3.2. 读取数据集
def load_array(data_arrays, batch_size, is_trainTrue): #save构造一个PyTorch数据迭代器dataset data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffleis_train)batch_size 10
data_iter load_array((features, labels), batch_size)next(iter(data_iter))
输出结果 3.3 定义模型
# nn是神经网络的缩写
from torch import nnnet nn.Sequential(nn.Linear(2, 1)) 3.4 初始化模型参数
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
输出结果 3.5 定义损失函数
loss nn.MSELoss() 3.6 定义优化算法
trainer torch.optim.SGD(net.parameters(), lr0.03) 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(fepoch {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)
输出结果 3.8 小结
我们可以使用PyTorch的高级API更简洁地实现模型。在PyTorch中data模块提供了数据处理工具nn模块定义了大量的神经网络层和常见损失函数。我们可以通过_结尾的方法将参数替换从而初始化参数。 3.9 练习
1.如果将小批量的总损失替换为小批量损失的平均值需要如何更改学习率
# 将学习率除以batchsize。
2.查看深度学习框架文档它们提供了哪些损失函数和初始化方法
用Huber损失代替原损失即 # Huber损失可以用torch自带的函数解决
torch.nn.SmoothL1Loss()
# 也可以自己写
import torch.nn as nn
import torch.nn.functional as Fclass HuberLoss(nn.Module):def __init__(self, sigma):super(HuberLoss, self).__init__()self.sigma sigmadef forward(self, y, y_hat):if F.l1_loss(y, y_hat) self.sigma:loss F.l1_loss(y, y_hat) - self.sigma/2else:loss (1/(2*self.sigma))*F.mse_loss(y, y_hat)return loss#%%
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)def load_array(data_arrays, batch_size, is_train True): #savepytorch数据迭代器dataset data.TensorDataset(*data_arrays) # 把输入的两类数据一一对应*表示对list解开入参return data.DataLoader(dataset, batch_size, shuffle is_train) # 重新排序batch_size 10
data_iter load_array((features, labels), batch_size) # 和手动实现中data_iter使用方法相同#%%
# 构造迭代器并验证data_iter的效果
next(iter(data_iter)) # 获得第一个batch的数据#%% 定义模型
from torch import nn
net nn.Sequential(nn.Linear(2, 1)) # Linear中两个参数一个表示输入形状一个表示输出形状
# sequential相当于一个存放各层数据的list单层时也可以只用Linear#%% 初始化模型参数
# 使用net[0]选择神经网络中的第一层
net[0].weight.data.normal_(0, 0.01) # 正态分布
net[0].bias.data.fill_(0)#%% 定义损失函数
loss torch.nn.HuberLoss()
#%% 定义优化算法
trainer torch.optim.SGD(net.parameters(), lr0.03) # optim module中的SGD
#%% 训练
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(fepoch {epoch1}, 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)输出结果 3.如何访问线性回归的梯度
#假如是多层网络可以用一个self.xxx某层然后在外面通过net.xxx.weight.grad和net.xxx.bias.grad把梯度给拿出来。
net[0].weight.grad
net[0].bias.grad输出结果 四、实验心得
通过此次实验我熟悉了PyTorch框架以及PyTorch的基本概念、数据结构和核心函数创建了线性回归模型使用PyTorch构建一个简单的线性回归模型完成了线性回归从零开始实现及其简洁实现以及章节后习题。明白了以下几点 1.深度学习的关键要素包括训练数据、损失函数、优化算法以及模型本身。这些要素相互作用共同决定了模型的性能和表现。 2.矢量化是一种重要的数学表达方式它能使数学计算更加简洁高效。通过使用向量和矩阵运算可以将复杂的计算过程转化为简单的线性代数运算从而提高计算效率。 3.最小化目标函数和执行极大似然估计是等价的。在机器学习中通常通过最小化损失函数来优化模型。而在概率统计中可以通过最大化似然函数来估计模型参数。这两种方法在数学上是等价的都可以用于优化模型。 4.线性回归模型可以被看作是一个简单的神经网络模型。它只包含一个输入层和一个输出层其中输入层的神经元数量与输入特征的维度相同输出层的神经元数量为1。线性回归模型可以用于解决回归问题通过学习输入特征与输出之间的线性关系来进行预测。 5.在深度学习中学习了如何实现和优化深度神经网络。在这个过程中只使用张量Tensor和自动微分Automatic Differentiation而不需要手动定义神经网络层或复杂的优化器。张量是深度学习中的基本数据结构它可以表示多维数组并支持各种数学运算。自动微分是一种计算梯度的技术它能够自动计算函数相对于输入的导数从而实现了反向传播算法。 6.为了更加简洁地实现模型可以利用PyTorch的高级API。在PyTorch中data模块提供了数据处理工具包括数据加载、预处理和批处理等功能使得数据的处理变得更加方便和高效。nn模块则提供了大量的神经网络层和常见损失函数的定义可以直接使用这些层和函数来构建和训练模型无需手动实现。此外还可以通过使用_结尾的方法来进行参数的替换和初始化从而更加灵活地管理模型的参数。