案例之 PyTorch模拟线性回归
1. 案例需求1️⃣ 设置损失函数和优化器损失函数指MSE、MAE等优化器 是用来结合反向传播更新参数的之前在自动微分中更新参数的代码是通过公式w新 w旧 - 学习率 * 梯度或w.data w.data -0.01 * w.grad手动更新但优化器中有一个名为step的函数通过优化器.step()可在底层自动帮忙更新参数。2️⃣ MSE代替平方损失函数、DataLoader代替数据加载器、SGD随机梯度下降代替优化器即梯度下降、Linear代替假设函数即 ywxb。2. 需求1️⃣ 导包对于TensorDataset包python进阶中自己手动做过一个数据加载器(结论歌词)每批8条5000多条歌词生成 np来做训练之前是自己做的分批训练是后面会做的多的2️⃣ 数据加载器(DataLoader)可分批获取数据假设一个10000条数据每批100条可分成100批每100条进行训练即分批次训练。但张量无法直接转数据加载器可通过 张量 转 张量数据集对象TensorDataSet 转 数据加载器 DataLoader但当数据不是张量时要先将数据转成张量 如numpy对象即numpy对象 - - 张量Tensor - - 张量数据集对象TensorDataSet - - 数据加载器DataLoadernn神经网络包里面有大量的损失函数optim优化器包如 SGD随机梯度下降包make_regression创建线性回归模型数据集包后面不会用因为后面的数据集都已有了这次是自己造的所以需要用一次matplotlib.pyplot可视化包做绘图、可视化的3. 代码1. 定义函数创建线性回归样本数据def create_dataset():1️⃣ 创建数据集对象x, y, coef make_regression(...)n_samples100100条样本n_features11个特征noise10噪声噪声越大样本点越散coefTrue是否返回系数 默认为Falserandom_state3随机种子print(type(x))打印 x是一个ndarray类型即class ‘numpy.ndarray’想将 x封装成数据加载及先从numpy 转成张量在到数据集对象再到数据加载器2️⃣ 把上述的数据 numpy转成张量对象x torch.tensor(x,...)y torch.tensor(y,...)coef 权重不需要转后面用到 x特征y目标值标签打印结果y w( coef )x b( bias )2. 定义函数表示模型训练def train(x, y, coef):数据集、数据加载器、模型、损失、优化器1️⃣ 创建数据集对象将tensor–》数据集对象–》数据加载器datasetTensorDataset(x,y)2️⃣ 创建数据加载器对象参1数据集对象参2批量大小参数3是否打乱数据(训练集打乱测试集不打乱)dataloaderDataLoader(dataset,batch_size16,shuffleTrue)3️⃣ 创建模型对象参1输入特征维度参2输出特征维度modelnn.Linear(in_features1, out_features1)4️⃣ 创建损失函数对象criterion nn.MSELoss()5️⃣ 创建优化器对象参1模型参数参2学习率optimizeroptim.SGD(model.parameters(),lr0.01)# 导入相关模块importtorchfromtorch.utils.dataimportTensorDataset# 构造数据集对象fromtorch.utils.dataimportDataLoader# 数据加载器fromtorchimportnn# nn模块中有平方损失函数和假设函数fromtorchimportoptim# optim模块中有优化器函数fromsklearn.datasetsimportmake_regression# 创建线性回归模型数据集importmatplotlib.pyplotasplt# 可视化plt.rcParams[font.sans-serif][SimHei]# 用来正常显示中文标签plt.rcParams[axes.unicode_minus]False# 用来正常显示负号# 1.定义函数创建线性回归样本数据defcreate_dataset():# 1.创建数据集对象x,y,coefmake_regression(n_samples100,# 100条样本100个样本点n_features1,# 1个特征1个特征点noise10,# 噪声噪声越大样本点越散噪声越小样本点越集中coefTrue,# 是否返回系数默认为False返回值为Nonebias14.5,# 偏置random_state3# 随机种子随机种子相同输出数据相同)print(type(x))# class numpy.ndarray# 2.把上述的数据封装成 张量对象xtorch.tensor(x,dtypetorch.float32)ytorch.tensor(y,dtypetorch.float32)# 3.返回结果returnx,y,coef# 2.定义函数表示模型训练deftrain(x,y,coef):# 1.创建数据集对象将tensor--》数据集对象--》数据加载器datasetTensorDataset(x,y)# 2.创建数据加载器对象# 参1数据集对象参2批量大小参数3是否打乱数据(训练集打乱测试集不打乱)dataloaderDataLoader(dataset,batch_size16,shuffleTrue)# 3.创建模型对象# 参1输入特征维度参2输出特征维度modelnn.Linear(in_features1,out_features1)# 4.创建损失函数对象criterionnn.MSELoss()# 5.创建优化器对象# 参1模型参数参2学习率optimizeroptim.SGD(model.parameters(),lr0.01)# 6.具体的训练过程# 6.1 定义变量分别表示训练轮数每轮的(平均)损失值训练总损失值训练的样本数epochs,loss_list,total_loss,total_sample100,[],0.0,0# 6.2 开始训练按轮训练forepochinrange(epochs):# epochs的值0, 1, 2,...,99# 6.3 每轮是分批次训练的所以从数据加载器中获取 批次数据fortrain_x,train_yindataloader:# 7批(16, 16, 16, 16, 16, 16, 4)# 6.4 模型预测y_predmodel(train_x)# 6.5 计算(每轮的平均)损失值losscriterion(y_pred,train_y.reshape(-1,1))# -1自动计算# 6.6 计算总损失 和样本(批次)数total_lossloss.item()total_sample1# 6.7 梯度清零 反向传播 梯度更新optimizer.zero_grad()# 梯度清零loss.backward()# 反向传播计算梯度optimizer.step()# 梯度更新# 6.8 把本轮的平均损失值添加到列表中loss_list.append(total_loss/total_sample)print(f第{epoch1}轮平均损失值{total_loss/total_sample})# 7.打印最终的训练结果print(f{epochs}轮的平均损失分别是{loss_list})print(f模型参数权重{model.weight}, 偏置{model.bias})# 8.绘制损失曲线# 参1100轮参2每轮的平均损失值plt.plot(range(epochs),loss_list)plt.title(损失曲线变化图)plt.grid()# 绘制网格图plt.show()# 9.绘制预测值和真实值之间的关系# 9.1 绘制样本点分布情况plt.scatter(x,y)# 9.2 绘制训练模型的预测值# x:100个样本点的特征y_predtorch.tensor(data[v*model.weightmodel.biasforvinx])# 9.3 计算真实值y_truetorch.tensor(data[v*coef14.5forvinx])# 9.4 绘制预测值和真实值的折线图plt.plot(x,y_pred,colorred,label预测值)plt.plot(x,y_true,colorgreen,label真实值)# 9.5 绘制图例网格plt.legend()plt.grid()# 9.6 显示图像plt.show()# 3.测试if__name____main__:# 3.1 创建数据集x,y,coefcreate_dataset()print(fx:{x}, y:{y}, coef:{coef})# 3.2 模型训练train(x,y,coef)