一、自动微分模块是Pytorch内部的自动求导模块 自动微分自动求导作用自动精确求导无需手动计算自动微分模型在神经网络训练中的作用计算损失梯度1.定义模型权重参数. (输入特征)2.前向传播3.定义一个损失函数4.把前向传播的函数 或者是说 神经网络层和 预测值 带入损失函数计算损失值5.梯度清零 Pytorch 默认梯度累加6.backward(). 反向传播计算导数/梯度7.w.grad 获取导数值/梯度8.更新参数 W新 W旧 - 学习率 * 梯度9.多次训练- 把W新和B新 重复带入 步骤2例子自动微分的真实应用场景 (代码)# 1.准备数据集 # 随机种子 torch.manual_seed(5) # 创建样本 2行 5列 x torch.ones(2,5) # 创建真实预测值 2行 1列 y torch.zeros(2,1) # 2.定义模型权重参数 # 构建初始化模型 权重w 偏置b 开启梯度计算 w torch.rand(5,1, requires_gradTrue) b torch.rand(1, requires_gradTrue) # 3.前向传播 z x w b # z [w1w2w3w4w5b,w1w2w3w4w5b] [z1,z2] # 4.计算损失函数 MSE 默认 (default mean) loss_fn torch.nn.MSELoss() loss loss_fn(z, y) # 5.梯度清零 if w.grad is not None: w.grad.zero_() if b.grad is not None: b.grad.zero_() # 6.反向传播 loss.backward() # 7.梯度值 print(fw.grad:{w.grad} \n fb.grad:{b.grad} \n) # 8.更新权重 - 打印前后 W值 print(f旧 w:{w.data} \n f旧 b:{b.data} \n) w.data - 0.01 * w.grad.data b.data - 0.01 * b.grad.data print(f新 w:{w.data} \n f新 b:{b.data} \n) # 9.单次训练。。。多次循环 print(结束)二、梯度下降法针对损失函数沿着损失函数导数的反方向更新模型参数使得损失函数降低目标获取 损失函数的最小值对应的模型参数也就是最优模型梯度下降法 求损失函数的最小值如求 loss w**2 20 的极小值点 并打印loss是最小值时 w的值(梯度)计算过程1 定义点 w10, requires_gradTrue, dtypetorch.float322 定义函数 loss w**2 203 利用梯度下降法 循环迭代 求最优解/最小值3.1 前向传播,计算损失3.2 梯度清零 w.grad.zero_()3.3 反向传播 loss.backward()3.4 更新参数 w.data w.data - 0.01 * w.grad1-3# 1 定义点 w10, requires_gradTrue, dtypetorch.float32 w torch.tensor([10.0,20.0],requires_gradTrue,dtypetorch.float32) # 2 定义函数 loss w**2 20 loss w**2 20 # 120.0 # 3 利用梯度下降法 循环迭代 求最优解/最小值 print(f初始值w:{w.data}, w.grad: {w.grad}, loss.mean():{loss.mean()})3.1-3.4# 记录损失均值 loss_list [] for i in range(500): # 3.1 前向传播, 计算损失 loss w**2 20 # 3.2 梯度清零 w.grad.zero_() if w.grad is not None: w.grad.zero_() # 3.3 反向传播 loss.backward() loss.mean().backward() # loss_mean 2*w # 3.4 更新参数 w.data w.data - 0.01 * w.grad w.data w.data - 0.01 * w.grad # loss_mean 1/2* 2*w w [w1,w2] print(f第{i1}次迭代w:{w.data}, w.grad:{w.grad.data}, loss.mean():{loss.mean()}) # 添加到loss_list loss_list.append(loss.mean().item())绘制损失曲线iterations range(500) plt.figure(figsize(12,8)) plt.plot(iterations,loss_list) plt.xlabel(迭代次数) plt.ylabel(损失均值loss.mean) plt.grid() plt.show()三、detch() 函数detach() 函数的功能解决 开启梯度计算 requires_gradTrue 的张量无法转为numpy对象的问题1.定义张量开启梯度计算requires_grad Truew torch.tensor([1.0,2.0,3.0], requires_gradTrue, dtypetorch.float32) print(fw:{w}, shape: {w.shape}, requires_grad: {w.requires_grad})2.直接转为numpy数组 无法转# 2.直接转为numpy数组 # n1 w.numpy() # print(fn1:{n1}, shape: {n1.shape})3.使用detach().numpy()来转数组t1 w.detach() print(ft1:{t1}, shape: {t1.shape}, type: {type(t1)}, requires_grad: {t1.requires_grad}) n2 w.detach().numpy() print(fn2:{n2}, shape: {n2.shape})4.查看是否共享内存/浅拷贝 浅拷贝n2[0]28.0 print(fw:{w}, shape: {w.shape}) print(fn2:{n2}, shape: {n2.shape})四、Pytorch框架_模型线性回归1.准备数据集2.构建模型3.设置损失函数和优化器4.模型训练1 张量 - 数据集2 数据加载器3 构建模型 - 这里是模拟线性回归4 损失函数 - MSE损失函数5 优化器 - 随机梯度 SGD6 模型开始循环训练# 定义梯度训练的轮次# 记录 每个轮次的平均损失# 开始遍历轮次 训练6.1 初始化 当前轮次的训练总损失6.2 初始化 当前轮次的总样本数. 总共是100个样本6.3 根据批次 遍历数据 加载器分批训练向前传播-计算预测值-计算损失-梯度清零-反向传播-更新参数w新w旧-学习率*梯度记录 -批次的损失值 * 样本数 可视化绘图用6.4 计算当前批次的平均损失6.5 将每一批次的损失值 存到数组7 可视化训练过程 Pytorch 框架 模型线性回归 1.准备数据集 numpy数组 - 张量 - 数据集对象Dataset - 数据加载器DataLoader分批次加载 2.构建神经网络模型 nn.Linear() 3.设置损失函数和优化器 nn.MESLoss, optiom.SGD 4.模型训练 1.前向传播 2.计算损失 3.梯度清零 4.反向传播 5.更新参数 W新 W旧 - 学习率*梯度 5.模型测试 import torch #构造数据集对象 from torch.utils.data import TensorDataset #数据加载器按批次加载数据 from torch.utils.data import DataLoader #提供 MSE 损失函数 和 线性层线性用来模拟线性回归模型 from torch import nn #提供各种优化器用于更新模型参数公司为 W新 W旧 - 学习率lr * 梯度 grad from torch import optim #创建线性回归的示例数据集 from sklearn.datasets import make_regression import matplotlib.pyplot as plt # 1.准备数据集 def create_dataset(): x, y, coef make_regression( n_samples100, #样本数 n_features1, #特征数 n_targets1, #目标数 noise 10, #噪声 bias 13.9, #偏移 coefTrue, #是否返回系数 真实的权重 w斜率 random_state5 #随机种子 ) # 转化为 张量 x torch.tensor(x,dtypetorch.float) y torch.tensor(y,dtypetorch.float) return x, y, coef # 2.模型训练 def train_model(x,y,coef): # 1 张量 - 数据集 dataset TensorDataset(x,y) # 2 数据加载器 dataloader DataLoader( dataset, #数据集 batch_size16, #一次加载数量 批次大小 一般 64、32 shuffleTrue, #是否打乱数据训练时打乱测试时不打乱 drop_lastFalse #是否删除最后一个数量不够的批次一般是False ) # 3 构建模型 - 这里是模拟线性回归 model nn.Linear(1, 1) # 4 损失函数 - MSE损失函数 loss_fn nn.MSELoss() # 5 优化器 - 随机梯度 SGD optimizer optim.SGD(model.parameters(), lr0.01) # 6 模型训练 # 定义梯度训练的轮次 count 100 # 记录 每个轮次的平均损失 total_losses [] # 开始遍历轮次 训练 for epoch in range(count): # 1.初始化 当前轮次的训练总损失 total_loss 0.0 # 2.初始化 当前轮次的总样本数. 总共是100个样本 total_samples 0 # 3.根据批次 遍历数据 加载器分批训练 for x_train, y_train in dataloader: # 3.1 前向传播计算预测值 y_pred model(x_train) # 3.2 计算损失 # reshped(-1,1) 因为标签 y 只有1个是标量 要升维度 (1,1) loss loss_fn(y_pred, y_train.reshape(-1,1)) # 3.3 梯度清零 - 因为在pytorch 中梯度会自动累加 optimizer.zero_grad() # 3.4 反向传播 loss.backward() # 3.5 更新参数 W新 W旧 - 学习率 lr * 梯度 grad optimizer.step() # 3.6 统计 训练损失 和 样本数. # 这批次的损失值 * 样本数 total_loss loss.item() * x_train.shape[0] total_samples x_train.shape[0] # 4.计算当前批次的平均损失 train_loss total_loss / total_samples # 5.将每一批次的损失值 存到数组 total_losses.append(train_loss) # 6.打印本轮训练的平均损失 print(f{epoch 1}/{count}: | f{train_loss:.4f}) # 7 可视化训练过程 # 图 1 plt.rcParams[font.family] Arial Unicode MS print(f损失列表{total_losses}) plt.figure(figsize(15,8)) # 绘制第一个子图训练损失曲线图 plt.subplot(1,2,1) plt.title(训练损失曲线) x_epoch range(count) plt.plot(x_epoch, total_losses, label训练损失) plt.xlabel(epoch) plt.ylabel(loss) plt.grid() plt.legend() # 图 2 ------- # 真实值和预测值的对比 plt.subplot(1, 2, 2) plt.title(真实值和预测值的对比) plt.scatter(x, y, label真实散点) # 计算理论的真实线性回归直线 codf.item() 是真实斜率 13.9 是截距 B y_true [v*coef.item()13.9 for v in x] plt.plot(x, y_true, label真实线性回归) # 计算模型预测值 with torch.no_grad(): # 关闭梯度计算 model(x) 得到的预测张量原本连着梯度计算图和模型权重、输入 x 绑定 .detach()强制断开和梯度图的所有联系得到一个纯数值、无梯度、叶子张量 .numpy()把断开后的张量转成 numpy 数组 y_pred model(x).detach().numpy() # 绘制模型预测的线性回归直线 plt.plot(x, y_pred, label预测值) plt.xlabel(x) plt.ylabel(y) plt.grid() plt.legend() plt.show() if __name__ __main__: x, y, coef create_dataset() train_model(x,y,coef)
深度学习 —— Pytorch实践
一、自动微分模块是Pytorch内部的自动求导模块 自动微分自动求导作用自动精确求导无需手动计算自动微分模型在神经网络训练中的作用计算损失梯度1.定义模型权重参数. (输入特征)2.前向传播3.定义一个损失函数4.把前向传播的函数 或者是说 神经网络层和 预测值 带入损失函数计算损失值5.梯度清零 Pytorch 默认梯度累加6.backward(). 反向传播计算导数/梯度7.w.grad 获取导数值/梯度8.更新参数 W新 W旧 - 学习率 * 梯度9.多次训练- 把W新和B新 重复带入 步骤2例子自动微分的真实应用场景 (代码)# 1.准备数据集 # 随机种子 torch.manual_seed(5) # 创建样本 2行 5列 x torch.ones(2,5) # 创建真实预测值 2行 1列 y torch.zeros(2,1) # 2.定义模型权重参数 # 构建初始化模型 权重w 偏置b 开启梯度计算 w torch.rand(5,1, requires_gradTrue) b torch.rand(1, requires_gradTrue) # 3.前向传播 z x w b # z [w1w2w3w4w5b,w1w2w3w4w5b] [z1,z2] # 4.计算损失函数 MSE 默认 (default mean) loss_fn torch.nn.MSELoss() loss loss_fn(z, y) # 5.梯度清零 if w.grad is not None: w.grad.zero_() if b.grad is not None: b.grad.zero_() # 6.反向传播 loss.backward() # 7.梯度值 print(fw.grad:{w.grad} \n fb.grad:{b.grad} \n) # 8.更新权重 - 打印前后 W值 print(f旧 w:{w.data} \n f旧 b:{b.data} \n) w.data - 0.01 * w.grad.data b.data - 0.01 * b.grad.data print(f新 w:{w.data} \n f新 b:{b.data} \n) # 9.单次训练。。。多次循环 print(结束)二、梯度下降法针对损失函数沿着损失函数导数的反方向更新模型参数使得损失函数降低目标获取 损失函数的最小值对应的模型参数也就是最优模型梯度下降法 求损失函数的最小值如求 loss w**2 20 的极小值点 并打印loss是最小值时 w的值(梯度)计算过程1 定义点 w10, requires_gradTrue, dtypetorch.float322 定义函数 loss w**2 203 利用梯度下降法 循环迭代 求最优解/最小值3.1 前向传播,计算损失3.2 梯度清零 w.grad.zero_()3.3 反向传播 loss.backward()3.4 更新参数 w.data w.data - 0.01 * w.grad1-3# 1 定义点 w10, requires_gradTrue, dtypetorch.float32 w torch.tensor([10.0,20.0],requires_gradTrue,dtypetorch.float32) # 2 定义函数 loss w**2 20 loss w**2 20 # 120.0 # 3 利用梯度下降法 循环迭代 求最优解/最小值 print(f初始值w:{w.data}, w.grad: {w.grad}, loss.mean():{loss.mean()})3.1-3.4# 记录损失均值 loss_list [] for i in range(500): # 3.1 前向传播, 计算损失 loss w**2 20 # 3.2 梯度清零 w.grad.zero_() if w.grad is not None: w.grad.zero_() # 3.3 反向传播 loss.backward() loss.mean().backward() # loss_mean 2*w # 3.4 更新参数 w.data w.data - 0.01 * w.grad w.data w.data - 0.01 * w.grad # loss_mean 1/2* 2*w w [w1,w2] print(f第{i1}次迭代w:{w.data}, w.grad:{w.grad.data}, loss.mean():{loss.mean()}) # 添加到loss_list loss_list.append(loss.mean().item())绘制损失曲线iterations range(500) plt.figure(figsize(12,8)) plt.plot(iterations,loss_list) plt.xlabel(迭代次数) plt.ylabel(损失均值loss.mean) plt.grid() plt.show()三、detch() 函数detach() 函数的功能解决 开启梯度计算 requires_gradTrue 的张量无法转为numpy对象的问题1.定义张量开启梯度计算requires_grad Truew torch.tensor([1.0,2.0,3.0], requires_gradTrue, dtypetorch.float32) print(fw:{w}, shape: {w.shape}, requires_grad: {w.requires_grad})2.直接转为numpy数组 无法转# 2.直接转为numpy数组 # n1 w.numpy() # print(fn1:{n1}, shape: {n1.shape})3.使用detach().numpy()来转数组t1 w.detach() print(ft1:{t1}, shape: {t1.shape}, type: {type(t1)}, requires_grad: {t1.requires_grad}) n2 w.detach().numpy() print(fn2:{n2}, shape: {n2.shape})4.查看是否共享内存/浅拷贝 浅拷贝n2[0]28.0 print(fw:{w}, shape: {w.shape}) print(fn2:{n2}, shape: {n2.shape})四、Pytorch框架_模型线性回归1.准备数据集2.构建模型3.设置损失函数和优化器4.模型训练1 张量 - 数据集2 数据加载器3 构建模型 - 这里是模拟线性回归4 损失函数 - MSE损失函数5 优化器 - 随机梯度 SGD6 模型开始循环训练# 定义梯度训练的轮次# 记录 每个轮次的平均损失# 开始遍历轮次 训练6.1 初始化 当前轮次的训练总损失6.2 初始化 当前轮次的总样本数. 总共是100个样本6.3 根据批次 遍历数据 加载器分批训练向前传播-计算预测值-计算损失-梯度清零-反向传播-更新参数w新w旧-学习率*梯度记录 -批次的损失值 * 样本数 可视化绘图用6.4 计算当前批次的平均损失6.5 将每一批次的损失值 存到数组7 可视化训练过程 Pytorch 框架 模型线性回归 1.准备数据集 numpy数组 - 张量 - 数据集对象Dataset - 数据加载器DataLoader分批次加载 2.构建神经网络模型 nn.Linear() 3.设置损失函数和优化器 nn.MESLoss, optiom.SGD 4.模型训练 1.前向传播 2.计算损失 3.梯度清零 4.反向传播 5.更新参数 W新 W旧 - 学习率*梯度 5.模型测试 import torch #构造数据集对象 from torch.utils.data import TensorDataset #数据加载器按批次加载数据 from torch.utils.data import DataLoader #提供 MSE 损失函数 和 线性层线性用来模拟线性回归模型 from torch import nn #提供各种优化器用于更新模型参数公司为 W新 W旧 - 学习率lr * 梯度 grad from torch import optim #创建线性回归的示例数据集 from sklearn.datasets import make_regression import matplotlib.pyplot as plt # 1.准备数据集 def create_dataset(): x, y, coef make_regression( n_samples100, #样本数 n_features1, #特征数 n_targets1, #目标数 noise 10, #噪声 bias 13.9, #偏移 coefTrue, #是否返回系数 真实的权重 w斜率 random_state5 #随机种子 ) # 转化为 张量 x torch.tensor(x,dtypetorch.float) y torch.tensor(y,dtypetorch.float) return x, y, coef # 2.模型训练 def train_model(x,y,coef): # 1 张量 - 数据集 dataset TensorDataset(x,y) # 2 数据加载器 dataloader DataLoader( dataset, #数据集 batch_size16, #一次加载数量 批次大小 一般 64、32 shuffleTrue, #是否打乱数据训练时打乱测试时不打乱 drop_lastFalse #是否删除最后一个数量不够的批次一般是False ) # 3 构建模型 - 这里是模拟线性回归 model nn.Linear(1, 1) # 4 损失函数 - MSE损失函数 loss_fn nn.MSELoss() # 5 优化器 - 随机梯度 SGD optimizer optim.SGD(model.parameters(), lr0.01) # 6 模型训练 # 定义梯度训练的轮次 count 100 # 记录 每个轮次的平均损失 total_losses [] # 开始遍历轮次 训练 for epoch in range(count): # 1.初始化 当前轮次的训练总损失 total_loss 0.0 # 2.初始化 当前轮次的总样本数. 总共是100个样本 total_samples 0 # 3.根据批次 遍历数据 加载器分批训练 for x_train, y_train in dataloader: # 3.1 前向传播计算预测值 y_pred model(x_train) # 3.2 计算损失 # reshped(-1,1) 因为标签 y 只有1个是标量 要升维度 (1,1) loss loss_fn(y_pred, y_train.reshape(-1,1)) # 3.3 梯度清零 - 因为在pytorch 中梯度会自动累加 optimizer.zero_grad() # 3.4 反向传播 loss.backward() # 3.5 更新参数 W新 W旧 - 学习率 lr * 梯度 grad optimizer.step() # 3.6 统计 训练损失 和 样本数. # 这批次的损失值 * 样本数 total_loss loss.item() * x_train.shape[0] total_samples x_train.shape[0] # 4.计算当前批次的平均损失 train_loss total_loss / total_samples # 5.将每一批次的损失值 存到数组 total_losses.append(train_loss) # 6.打印本轮训练的平均损失 print(f{epoch 1}/{count}: | f{train_loss:.4f}) # 7 可视化训练过程 # 图 1 plt.rcParams[font.family] Arial Unicode MS print(f损失列表{total_losses}) plt.figure(figsize(15,8)) # 绘制第一个子图训练损失曲线图 plt.subplot(1,2,1) plt.title(训练损失曲线) x_epoch range(count) plt.plot(x_epoch, total_losses, label训练损失) plt.xlabel(epoch) plt.ylabel(loss) plt.grid() plt.legend() # 图 2 ------- # 真实值和预测值的对比 plt.subplot(1, 2, 2) plt.title(真实值和预测值的对比) plt.scatter(x, y, label真实散点) # 计算理论的真实线性回归直线 codf.item() 是真实斜率 13.9 是截距 B y_true [v*coef.item()13.9 for v in x] plt.plot(x, y_true, label真实线性回归) # 计算模型预测值 with torch.no_grad(): # 关闭梯度计算 model(x) 得到的预测张量原本连着梯度计算图和模型权重、输入 x 绑定 .detach()强制断开和梯度图的所有联系得到一个纯数值、无梯度、叶子张量 .numpy()把断开后的张量转成 numpy 数组 y_pred model(x).detach().numpy() # 绘制模型预测的线性回归直线 plt.plot(x, y_pred, label预测值) plt.xlabel(x) plt.ylabel(y) plt.grid() plt.legend() plt.show() if __name__ __main__: x, y, coef create_dataset() train_model(x,y,coef)