设计类专业好找工作吗,班级优化大师官方免费下载,旅游网站反链怎么做,建立自己公司网站的方法文章目录 1.线性回归1#xff09;介绍2#xff09;加载自由泳冠军数据集3#xff09;从0开始实现线性回归模型4#xff09;使用自动求导训练线性回归模型5#xff09;使用优化器训练线性回归模型 2.使用torch.nn模块构建线性回归模型1#xff09;使用torch.nn.Linear训练… 文章目录 1.线性回归1介绍2加载自由泳冠军数据集3从0开始实现线性回归模型4使用自动求导训练线性回归模型5使用优化器训练线性回归模型 2.使用torch.nn模块构建线性回归模型1使用torch.nn.Linear训练线性回归模型2使用torch.nn.Sequential类训练线性回归模型3使用torch.nn.Module训练线性回归模型 3.逻辑回归1介绍2从0开始实现逻辑回归模型3使用Pytorch实现逻辑回归模型 4.softmax回归1介绍2从头开始实现softmax回归3使用Pytorch实现softmax回归 5.神经网络1神经元2激活函数1.绘制Sigmoid激活函数2.绘制双曲正切Tanh激活函数3.绘制ReLU激活函数4.绘制LeakyReLU激活函数5.softmax函数6.选择正确的激活函数 3神经网络原理4Pytorch实现神经网络5神经网络应用示例一6神经网络应用示例二7两层神经网络解决异或问题8Fizz Buzz神经网络实现 1.线性回归
1介绍
模型构建步骤
1.定义找到目标函数将输入属性映射为输出属性。
2.模型假设用一条直线拟合数据
3.模型评估采用损失函数来评价预测值和真实值的接近程度。argmin是机器学习常用的函数用来寻找使损失函数最小时的参数取值。
4.梯度下降算法也叫最速下降法。用来求代价函数损失函数或者叫目标函数的最小值。基本思想随机选择一组参数初始值计算损失或者代价然后寻找能让代价下降最多的另一组参数反复迭代直至达到一个局部最优。
2加载自由泳冠军数据集
数据集为奥运会自由泳冠军数据
创建文件display_olympics_freestyle100m.py 添加代码如下
import torch
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef main():# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorx dataset_tensor[:, :-1]y dataset_tensor[:, -1]# 绘图plt.plot(x.numpy(), y.numpy(), o)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.show()if __name__ __main__:main()
运行结果
横坐标为奥运举办年份纵坐标为取胜时间
3从0开始实现线性回归模型
思路
1.建立线性回归模型
2.损失函数及损失函数求导
3.利用损失函数求导实现梯度函数
梯度下降的收敛可以通过设置最大迭代次数或者判断参数不再改变来确定已经收敛。更新参数使用全部样本成为批量梯度下降法BGD使用一个样本成为随机梯度下降法SGD使用部分样本叫小批量梯度下降法兼顾前两种优缺点。
4.重复计算预测值(前向传播然后计算损失和梯度更新参数
创建文件linear_regression_from_scratch.py 实现代码如下
# -*- coding: utf-8 -*-从头开始实现线性回归模型import torch
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef model(x, w, b): 回归模型 return w * x bdef loss_fn(y_pred, y): 损失函数 loss (y_pred - y) ** 2return loss.mean()def grad_loss_fn(y_pred, y): 损失函数求导 return 2 * (y_pred - y)def grad_fn(x, y, y_pred): 梯度函数 grad_w grad_loss_fn(y_pred, y) * xgrad_b grad_loss_fn(y_pred, y)return torch.stack([grad_w.mean(), grad_b.mean()])def model_training(x, y, n_epochs, learning_rate, params, print_paramsTrue): 训练 for epoch in range(1, n_epochs 1):w, b params# 前向传播y_pred model(x, w, b)# 计算损失loss loss_fn(y_pred, y)# 梯度grad grad_fn(x, y, y_pred)# 更新参数params params - learning_rate * gradif epoch 1 or epoch % 500 1:print(轮次%d\t损失%f % (epoch, float(loss)))if print_params:print(f参数{params.detach().numpy()})print(f梯度{grad.detach().numpy()})return paramsdef main():# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 模型参数初始化w torch.zeros(1)b torch.zeros(1)# 直接用未优化的模型来预测y_pred model(x, w, b)print(未优化的模型的预测结果, y_pred.detach().numpy())loss loss_fn(y_pred, y)print(未优化的模型的损失, loss.detach().numpy())params model_training(xx,yy,n_epochs50000,learning_rate0.00017,paramstorch.tensor([0.0, 0.0]))print(梯度下降找到的w和b%f %f \n % (params[0], params[1]))y_pred model(x, *params)print(f优化后的模型的预测结果{y_pred.detach().numpy()}\n)# 绘图plt.plot(xx.numpy(), y_pred.detach().numpy(), labelu模型)plt.plot(xx.numpy(), y.numpy(), o, labelu数据)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
运行结果 4使用自动求导训练线性回归模型
pytorch提供自动求导功能计算梯度。只要提供前向表达式就可以计算任意节点梯度。
只需要在张量的构造中添加requires_gradTrue参数即可。
detach().requires_grad_()表示将张量分离同时设置requires_gradTrue。
创建文件linear_regression_autograd.py 完整实现代码如下
# -*- coding: utf-8 -*-使用自动求导训练线性回归模型
import torch
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef model(x, w, b): 回归模型 return w * x bdef loss_fn(y_pred, y): 损失函数 loss (y_pred - y) ** 2return loss.mean()def model_training(x, y, params, n_epochs, learning_rate): 训练 for epoch in range(1, n_epochs 1):# 梯度清零if params.grad is not None:params.grad.zero_()# 前向传播y_pred model(x, *params)# 计算损失loss loss_fn(y_pred, y)# 反向传播loss.backward()# 更新参数params (params - learning_rate * params.grad).detach().requires_grad_()if epoch 1 or epoch % 500 0:print(轮次%d\t损失%f % (epoch, float(loss)))return paramsdef main():# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 初始化模型参数params torch.tensor([0.0, 0.0], requires_gradTrue)print(params.grad is None: , params.grad is None)loss loss_fn(model(x, *params), y)loss.backward()print(params.grad)if params.grad is not None:params.grad.zero_()params model_training(xx,yy,paramstorch.tensor([0.0, 0.0], requires_gradTrue),n_epochs50000,learning_rate0.00017)print(梯度下降找到的w和b%f %f \n % (params[0], params[1]))y_pred model(x, *params)print(f优化后的模型的预测结果{y_pred.detach().numpy()}\n)# 绘图plt.plot(xx.numpy(), y_pred.detach().numpy(), labelu模型)plt.plot(xx.numpy(), y.numpy(), o, labelu数据)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
5使用优化器训练线性回归模型
优化器optimizer用来优化梯度计算。包括SGD 优化Adam。
创建文件linear_regression_optimizers.py 完整实现代码如下
# -*- coding: utf-8 -*-使用优化器训练线性回归模型
import torch
import torch.optim as optim
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef model(x, w, b): 回归模型 return w * x bdef loss_fn(y_pred, y): 损失函数 loss (y_pred - y) ** 2return loss.mean()def model_training(x, y, params, n_epochs, optimizer): 训练 for epoch in range(1, n_epochs 1):# 前向传播p_pred model(x, *params)# 计算损失loss loss_fn(p_pred, y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()if epoch 1 or epoch % 500 0:print(轮次%d\t损失%f % (epoch, float(loss)))return paramsdef main():# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 参数params torch.tensor([0.0, 0.0], requires_gradTrue)learning_rate 0.00017# 使用optim模块中的现成优化器optimizer optim.SGD([params], lrlearning_rate)# 手工做一次优化y_pred model(x, *params)loss loss_fn(y_pred, y)# 梯度清零optimizer.zero_grad()# 优化loss.backward()optimizer.step()# 打印一次优化后的参数print(一次优化后的参数, params)# 手工再做一次优化params torch.tensor([0.0, 0.0], requires_gradTrue)optimizer optim.SGD([params], lrlearning_rate)y_pred model(x, *params)loss loss_fn(y_pred, y)# 梯度清零optimizer.zero_grad()# 优化loss.backward()optimizer.step()# 打印再一次优化后的参数print(再一次优化后的参数, params)print(\n使用SGD训练模型)params torch.tensor([0.0, 0.0], requires_gradTrue)optimizer optim.SGD([params], lrlearning_rate)params model_training(xx,yy,paramsparams,n_epochs50000,optimizeroptimizer)print(SGD优化器找到的w和b%f %f \n % (params[0], params[1]))print(\n使用Adam再训练一次模型)# 注意学习率和训练轮次都不同于SGD说明Adam是高级优化函数params torch.tensor([0.0, 0.0], requires_gradTrue)learning_rate 1e-1optimizer optim.Adam([params], lrlearning_rate)params model_training(xx,yy,paramsparams,n_epochs2000,optimizeroptimizer)print(Adam优化器找到的w和b%f %f \n % (params[0], params[1]))# 再做一次预测y_pred model(x, *params)# 绘图plt.plot(xx.numpy(), y_pred.detach().numpy(), labelu模型)plt.plot(xx.numpy(), y.numpy(), o, labelu数据)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
2.使用torch.nn模块构建线性回归模型
pytorch提供nn模块包含有Lineaar、Sequential、Model和各种损失函数。
1使用torch.nn.Linear训练线性回归模型
步骤
1.加载数据集划分划分训练集验证集
2.定义线性模型
3.设置优化器
4.分别使用自定义的损失函数和nn模块使用开箱即用的损失函数
# -*- coding: utf-8 -*-使用torch.nn.Linear训练线性回归模型
import torch
import torch.optim as optim
import torch.nn as nn
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef loss_fn(y_pred, y): 损失函数 loss (y_pred - y) ** 2return loss.mean()def model_training(x_train, y_train, x_val, y_val, n_epochs, optimizer, model, loss_fn): 训练 for epoch in range(1, n_epochs 1):# 前向传播y_pred_train model(x_train)loss_train loss_fn(y_pred_train, y_train)with torch.no_grad():y_pred_val model(x_val)loss_val loss_fn(y_pred_val, y_val)# 梯度清零optimizer.zero_grad()# 反向传播loss_train.backward()# 更新参数optimizer.step()if epoch 1 or epoch % 100 0:print(f轮次{epoch}\t训练损失{float(loss_train)}\t验证损失{float(loss_val)})def main():# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 扩充一维变为nn可以接受的shape和数据类型x x.unsqueeze(1).float()y y.unsqueeze(1).float()# 划分训练集验证集n_samples x.shape[0]n_train int(0.7 * n_samples)# 随机置乱shuffled_idx torch.randperm(n_samples)train_idx shuffled_idx[:n_train]val_idx shuffled_idx[n_train:]x_train x[train_idx]y_train y[train_idx]x_val x[val_idx]y_val y[val_idx]# 定义模型linear_model nn.Linear(1, 1)# 使用optim模块中的现成优化器learning_rate 1e-1epochs 3000optimizer optim.Adam(linear_model.parameters(), lrlearning_rate)# 使用自定义的损失函数model_training(x_trainx_train,y_trainy_train,x_valx_val,y_valy_val,n_epochsepochs,optimizeroptimizer,modellinear_model,loss_fnloss_fn)print()print(linear_model.weight)print(linear_model.bias)linear_model nn.Linear(1, 1)optimizer optim.Adam(linear_model.parameters(), lrlearning_rate)# 使用开箱即用的损失函数model_training(x_trainx_train,y_trainy_train,x_valx_val,y_valy_val,n_epochsepochs,optimizeroptimizer,modellinear_model,loss_fnnn.MSELoss())print(优化后的模型参数)print(linear_model.weight)print(linear_model.bias)# 绘图plt.plot(xx.numpy(), y.numpy(), go, labelu数据)x_range torch.arange(min(xx), max(xx)).unsqueeze(1)plt.plot(x_range.numpy(), linear_model(x_range - xx[0]).detach().numpy(), r-, labelu模型)plt.plot(xx.numpy(), linear_model(x).detach().numpy(), bx, labelu预测)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
2使用torch.nn.Sequential类训练线性回归模型
Sequential是一种容器添加并连接模块最终形成一个网络模型。
创建文件linear_regression_nn_sequential.py 添加代码如下
# -*- coding: utf-8 -*-使用torch.nn.Sequential类训练线性回归模型import torch
import torch.optim as optim
import torch.nn as nn
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef model_training(x_train, y_train, x_val, y_val, n_epochs, optimizer, model, loss_fn): 训练 for epoch in range(1, n_epochs 1):# 前向传播y_pred_train model(x_train)loss_train loss_fn(y_pred_train, y_train)y_pred_val model(x_val)loss_val loss_fn(y_pred_val, y_val)# 梯度清零optimizer.zero_grad()# 反向传播loss_train.backward()# 更新参数optimizer.step()if epoch 1 or epoch % 100 0:print(f轮次{epoch}\t训练损失{float(loss_train)}\t验证损失{float(loss_val)})def main():learning_rate 1e-1# 设置随机数种子seed 1torch.manual_seed(seed)torch.cuda.manual_seed_all(seed)# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 扩充一维变为nn可以接受的shape和数据类型x x.unsqueeze(1).float()y y.unsqueeze(1).float()# 划分训练集验证集n_samples x.shape[0]n_trin int(0.7 * n_samples)# 随机置乱shuffled_idx torch.randperm(n_samples)train_idx shuffled_idx[:n_trin]val_idx shuffled_idx[n_trin:]x_train x[train_idx]y_train y[train_idx]x_val x[val_idx]y_val y[val_idx]# 定义模型# 读者可尝试使用两种模型定义中的一种看看有什么区别# 第一种定义# seq_model nn.Sequential(# nn.Linear(1, 10),# nn.LogSigmoid(),# nn.Linear(10, 1)# )# 第二种定义from collections import OrderedDictseq_model nn.Sequential(OrderedDict([(hidden_linear, nn.Linear(1, 10)),(hidden_activation, nn.LogSigmoid()),(output_linear, nn.Linear(10, 1))]))# 打印模型信息print(seq_model)for name, param in seq_model.named_parameters():print({:21} {:19} {}.format(name, str(param.shape), param.numel()))optimizer optim.Adam(seq_model.parameters(), lrlearning_rate)# 使用开箱即用的损失函数model_training(x_trainx_train,y_trainy_train,x_valx_val,y_valy_val,n_epochs3000,optimizeroptimizer,modelseq_model,loss_fnnn.MSELoss())print(优化后的模型参数)for name, param in seq_model.named_parameters():print(name, param)# 绘图plt.plot(xx.numpy(), y.numpy(), go, labelu数据)x_range torch.arange(min(xx), max(xx)).unsqueeze(1)plt.plot(x_range.numpy(), seq_model(x_range - xx[0]).detach().numpy(), r-, labelu模型)plt.plot(xx.numpy(), seq_model(x).detach().numpy(), bx, labelu预测)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
3使用torch.nn.Module训练线性回归模型
使用nn.Module实现自定义线性模型。
创建文件linear_regression_nn_module.py 添加代码如下
# -*- coding: utf-8 -*-使用torch.nn.Module训练线性回归模型
import torch
import torch.optim as optim
import torch.nn as nn
from matplotlib import pyplot as plt
import pandas as pd
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falseclass LinearModel(nn.Module): 自定义模型 def __init__(self):super().__init__()self.hidden_linear nn.Linear(1, 10)self.activation nn.LogSigmoid()self.output_linear nn.Linear(10, 1)def forward(self, input):output self.hidden_linear(input)output self.activation(output)output self.output_linear(output)return outputdef model_training(x_train, y_train, x_val, y_val, n_epochs, optimizer, model, loss_fn): 训练 for epoch in range(1, n_epochs 1):# 前向传播y_pred_train model(x_train)loss_train loss_fn(y_pred_train, y_train)y_pred_val model(x_val)loss_val loss_fn(y_pred_val, y_val)# 梯度清零optimizer.zero_grad()# 反向传播loss_train.backward()# 更新参数optimizer.step()if epoch 1 or epoch % 100 0:print(f轮次{epoch}\t训练损失{float(loss_train)}\t验证损失{float(loss_val)})def main():learning_rate 1e-1# 设置随机数种子seed 1torch.manual_seed(seed)torch.cuda.manual_seed_all(seed)# 加载奥运会数据file_path ../datasets/Freestyle100m.csvdataset pd.read_csv(file_path)dataset_tensor torch.tensor(dataset.values) # 转换为tensorxx dataset_tensor[:, 0]y dataset_tensor[:, -1]# 为方便数值运算将原来的举办年减去第一届奥运会年x xx - xx[0]# 扩充一维变为nn可以接受的shape和数据类型x x.unsqueeze(1).float()y y.unsqueeze(1).float()# 划分训练集验证集n_samples x.shape[0]n_trin int(0.7 * n_samples)# 随机置乱shuffled_idx torch.randperm(n_samples)train_idx shuffled_idx[:n_trin]val_idx shuffled_idx[n_trin:]x_train x[train_idx]y_train y[train_idx]x_val x[val_idx]y_val y[val_idx]# 定义模型linear_model LinearModel()# 打印模型信息print(linear_model)for name, param in linear_model.named_parameters():print({:21} {:19} {}.format(name, str(param.shape), param.numel()))optimizer optim.Adam(linear_model.parameters(), lrlearning_rate)# 使用开箱即用的损失函数model_training(x_trainx_train,y_trainy_train,x_valx_val,y_valy_val,n_epochs3000,optimizeroptimizer,modellinear_model,loss_fnnn.MSELoss())print(优化后的模型参数)for name, param in linear_model.named_parameters():print(name, param)# 绘图plt.plot(xx.numpy(), y.numpy(), go, labelu数据)x_range torch.arange(min(xx), max(xx)).unsqueeze(1)plt.plot(x_range.numpy(), linear_model(x_range - xx[0]).detach().numpy(), r-, labelu模型)plt.plot(xx.numpy(), linear_model(x).detach().numpy(), bx, labelu预测)plt.xlabel(u奥运会年)plt.ylabel(u取胜时间秒)plt.legend()plt.show()if __name__ __main__:main()
3.逻辑回归
线性回归解决回归问题逻辑回归主要解决分类问题。区别在于前者目标值连续后者是离散的。
可以将逻辑回归视为神经网络的一个神经元
1介绍
思路
1.假设函数使用激活函数求输出。Sigmoid函数很好模拟了阶跃函数
2.代价函数求代价使用负对数似然代价函数表示。
3.逻辑回归梯度下降算法
2从0开始实现逻辑回归模型
创建文件logistic_regression_from_scratch.py 添加代码如下
# -*- coding: utf-8 -*-从头开始实现逻辑回归模型
import torch
import numpy as np
from matplotlib import pyplot as plt
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] Falsedef sigmoid(z): S型激活函数 g 1 / (1 torch.exp(-z))return gdef model(x, w, b): 逻辑回归模型 return sigmoid(x.mv(w) b)def loss_fn(y_pred, y): 损失函数 loss - y.mul(y_pred.view_as(y)) - (1 - y).mul(1 - y_pred.view_as(y))return loss.mean()def grad_loss_fn(y_pred, y): 损失函数求导 return y_pred.view_as(y) - ydef grad_fn(x, y, y_pred): 梯度函数 grad_w grad_loss_fn(y_pred, y) * xgrad_b grad_loss_fn(y_pred, y)return torch.cat((grad_w.mean(dim0), grad_b.mean().unsqueeze(0)), 0)def model_training(x, y, n_epochs, learning_rate, params, print_paramsTrue): 训练 for epoch in range(1, n_epochs 1):w, b params[: -1], params[-1]# 前向传播y_pred model(x, w, b)# 计算损失loss loss_fn(y_pred, y)# 梯度grad grad_fn(x, y, y_pred)# 更新参数params - learning_rate * gradif epoch 1 or epoch % 10 1:print(轮次%d\t损失%f % (epoch, float(loss)))if print_params:print(f参数{params.detach().numpy()})print(f梯度{grad.detach().numpy()})return paramsdef generate_data(): 随机生成数据 np.random.seed(0)# 使用二个高斯分布来生成随机数据phi 0.6means [[0.0, -3.2], [1.0, 3.5]]covs np.zeros((2, 2, 2))covs[0] [[0.58, -0.05], [-0.05, 1.55]]covs[1] [[0.65, -0.15], [-0.15, 1.12]]priors [1 - phi, phi]n 100x np.zeros((n, 2))y np.zeros((n, 1))# 选择一个高斯并随机抽样数据for i in range(n):comp np.random.choice(2, ppriors)x[i] np.random.multivariate_normal(means[comp], covs[comp], 1)y[i] compreturn torch.from_numpy(x).float(), torch.from_numpy(y).float()def plot_decision_boundary(x, y, theta):绘制二元分类问题的决策边界输入参数x输入y输出theta参数输出参数无plt.figure()neg_x x[np.where(y[:, 0] 0)]pos_x x[np.where(y[:, 0] 1)]neg plt.scatter(neg_x[:, 0], neg_x[:, 1], cb, markero)pos plt.scatter(pos_x[:, 0], pos_x[:, 1], cr, marker)# 绘制决策边界# 只需要两点便可以定义一条直线选择两个端点plot_x np.array([min(x[:, 0]), max(x[:, 0])])# 计算决策边界线theta0 theta1*x theta2*y 0# 已知x可计算yplot_y np.dot(np.divide(-1, theta[1]), (theta[2] np.dot(theta[0], plot_x)))lr, plt.plot(plot_x, plot_y, g) # 绘制拟合直线# 坐标plt.xlabel(x1)plt.ylabel(x2)# 图例plt.legend([neg, pos, lr], [负例, 正例, u决策边界], loclower right)plt.show()def main():# 随机生成数据x, y generate_data()# 模型参数初始化w torch.zeros(2)b torch.zeros(1)# 直接用未优化的模型来预测y_pred model(x, w, b)print(未优化的模型的预测结果, y_pred.detach().numpy())loss loss_fn(y_pred, y)print(未优化的模型的损失, loss.detach().numpy())params model_training(xx,yy,n_epochs500,learning_rate0.1,paramstorch.tensor([0.0, 0.0, 0.0]))print(f梯度下降找到的w和b{params.numpy()} \n)y_pred model(x, params[: -1], params[-1])print(f优化后的模型的预测结果{y_pred.detach().numpy()}\n)# 绘制决策边界plot_decision_boundary(x, y, params)if __name__ __main__:main()
运行结果
3使用Pytorch实现逻辑回归模型
使用nn.Sequential定义模型nn.Sigmoid定义激活函数。
创建文件logistic_regression_concise.py 添加代码如下
# -*- coding: utf-8 -*-简洁实现逻辑回归模型import torch
import torch.optim as optim
import torch.nn as nn
import numpy as np
from matplotlib import pyplot as plt
import matplotlib as mpl# 防止plt汉字乱码
mpl.rcParams[ufont.sans-serif] [SimHei]
mpl.rcParams[axes.unicode_minus] False
def model_training(x, y, n_epochs, optimizer, model, loss_fn): 训练 for epoch in range(1, n_epochs 1):# 前向传播y_pred model(x)# 计算损失loss loss_fn(y_pred, y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()if epoch 1 or epoch % 10 1:print(轮次%d\t损失%f % (epoch, float(loss)))def generate_data(): 随机生成数据 np.random.seed(0)# 使用二个高斯分布来生成随机数据phi 0.6means [[0.0, -3.2], [1.0, 3.5]]covs np.zeros((2, 2, 2))covs[0] [[0.58, -0.05], [-0.05, 1.55]]covs[1] [[0.65, -0.15], [-0.15, 1.12]]priors [1 - phi, phi]n 100x np.zeros((n, 2))y np.zeros((n, 1))# 选择一个高斯并随机抽样数据for i in range(n):comp np.random.choice(2, ppriors)x[i] np.random.multivariate_normal(means[comp], covs[comp], 1)y[i] compreturn torch.from_numpy(x).float(), torch.from_numpy(y).float()def plot_decision_boundary(x, y, model):绘制二元分类问题的决策边界输入参数x输入y输出model模型输出参数无plt.figure()neg_x x[np.where(y[:, 0] 0)]pos_x x[np.where(y[:, 0] 1)]neg plt.scatter(neg_x[:, 0], neg_x[:, 1], cb, markero)pos plt.scatter(pos_x[:, 0], pos_x[:, 1], cr, marker)# 绘制决策边界# 网格范围u np.linspace(min(x[:, 0]), max(x[:, 0]), 150)v np.linspace(min(x[:, 1]), max(x[:, 1]), 150)uu, vv np.meshgrid(u, v) # 生成网格数据z model(torch.cat((torch.from_numpy(uu.ravel()).float().unsqueeze(1),torch.from_numpy(vv.ravel()).float().unsqueeze(1)), 1))# 保持维度一致z z.detach().numpy().reshape(uu.shape)# 画图plt.contour(uu, vv, z, 0)# 坐标plt.xlabel(x1)plt.ylabel(x2)# 图例plt.legend([neg, pos], [负例, 正例], loclower right)plt.show()def main():# 随机生成数据x, y generate_data()# 定义模型seq_model nn.Sequential(nn.Linear(2, 1),nn.Sigmoid())# 打印模型信息print(seq_model)# 模型参数初始化print(\n使用SGD训练模型)learning_rate 0.1# 使用optim模块中的现成优化器optimizer optim.SGD(seq_model.parameters(), lrlearning_rate)model_training(xx,yy,n_epochs500,optimizeroptimizer,modelseq_model,loss_fnnn.BCELoss())print(优化后的模型参数)for name, param in seq_model.named_parameters():print(name, param)y_pred seq_model(x)print(f优化后的模型的预测结果{y_pred.detach().numpy()}\n)# 绘制决策边界plot_decision_boundary(x, y, seq_model)if __name__ __main__:main()
4.softmax回归
解决多元分类问题可以使用softmax回归。softmax回归的输出单元数k2,对应k个类别的预测概率分布。训练好模型后选择概率最大的类别作为预测类别。
1介绍
思想
1.假设函数概率分布归一化
2.代价函数使用交叉熵
2从头开始实现softmax回归
创建文件softmax_regression_from_scratch.py 添加代码如下
# -*- coding: utf-8 -*-从头开始实现softmax回归
import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils import data
import numpy as np# 超参数
num_inputs 784
num_outputs 10def softmax(z):实现Softmax激活函数。每一个Z减去一个max值是为了避免数值溢出输入参数z二维Tensor数组返回asoftmax(z)输出与z的shape一致z_rescale z - torch.max(z, dim1, keepdimTrue)[0]a torch.exp(z_rescale) / torch.sum(torch.exp(z_rescale), dim1, keepdimTrue)assert (a.shape z.shape)return adef model(x, w, b): 定义Softmax模型 return softmax(torch.mm(x.view((-1, num_inputs)), w) b)def cross_entropy(y_hat, y): 计算交叉熵 return - torch.log(y_hat.gather(1, y.view(-1, 1)))def grad_loss_fn(y_pred, y): 损失函数求导 return y_pred - torch.nn.functional.one_hot(y, num_classes10)def grad_fn(x, y, y_pred): 梯度函数 grad_w torch.mm(x.view((-1, num_inputs)).T, grad_loss_fn(y_pred, y))grad_b grad_loss_fn(y_pred, y)return [grad_w, grad_b.mean(dim0)]def accuracy(y_hat, y): 计算分类准确率 _, pred_y torch.max(y_hat, 1)return (pred_y y).mean().item()def evaluate_accuracy(data_iter, net, w, b): 计算准确率 correct_acc, n 0.0, 0for x, y in data_iter:_, pred_y torch.max(net(x, w, b).data, 1)correct_acc (pred_y y).sum().item()n y.shape[0]return correct_acc / ndef train(net, train_iter, test_iter, loss, num_epochs, params, lr): 模型训练 w, b paramsfor epoch in range(num_epochs):train_loss_sum, train_acc_sum, n 0.0, 0.0, 0for x, y in train_iter:# 前向传播y_pred net(x, w, b)# 计算损失loss_mini_batch loss(y_pred, y).sum()# 梯度grad grad_fn(x, y, y_pred)# 更新参数for i in range(len(params)):params[i] - lr * grad[i]# 统计train_loss_sum loss_mini_batch.item()train_acc_sum (y_pred.argmax(dim1) y).sum().item()n y.shape[0]# 测试准确率test_acc evaluate_accuracy(test_iter, net, w, b)print(轮次%d损失%.4f训练准确率%.3f测试准确率%.3f% (epoch 1, train_loss_sum / n, train_acc_sum / n, test_acc))def get_labels_by_indices(labels): 返回目标索引对应的标签字符串 text_labels [t-shirt, trouser, pullover, dress, coat, sandal, shirt, sneaker, bag, ankle boot]return [text_labels[int(i)] for i in labels]def main():# 超参数num_epochs, learning_rate, batch_size 5, 0.001, 32# 加载数据集mnist_train torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainTrue, downloadFalse,transformtransforms.ToTensor())train_iter data.DataLoader(mnist_train, batch_sizebatch_size, shuffleTrue)mnist_test torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainFalse, downloadFalse,transformtransforms.ToTensor())test_iter data.DataLoader(mnist_test, batch_sizebatch_size, shuffleFalse)# 参数w torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtypetorch.float, requires_gradFalse)b torch.zeros(num_outputs, dtypetorch.float, requires_gradFalse)# 训练模型train(model, train_iter, test_iter, cross_entropy, num_epochs, [w, b], learning_rate)# 显示部分测试数据的真实标签和预测标签x, y next(iter(test_iter))true_labels get_labels_by_indices(y.numpy())pred_labels get_labels_by_indices(model(x, w, b).argmax(dim1).numpy())for true_label, pred_label in zip(true_labels, pred_labels):print(f真实标签{true_label}\t预测标签{pred_label})if __name__ __main__:main()
3使用Pytorch实现softmax回归
使用Pytorch的自动求导功能。
创建文件softmax_regression.py 添加代码如下
# -*- coding: utf-8 -*-softmax回归实现
import torch
import torchvision
import torchvision.transforms as transforms
from torch import nn
from torch.utils import data
import torch.nn.functional as Fclass Net(nn.Module): 定义Softmax模型 def __init__(self):super(Net, self).__init__()self.fc1 nn.Linear(784, 10)def forward(self, x):# 展平数据 (n, 1, 28, 28) -- (n, 784)x x.view(-1, 784)return F.softmax(self.fc1(x), dim1)def train(epochs, train_loader, model, optimizer, loss_fn, print_every): 迭代训练模型 for epoch in range(epochs):# 每次输入batch_idx个数据loss_acc 0.0 # 累计损失for batch_idx, (data, target) in enumerate(train_loader):# 梯度清零optimizer.zero_grad()# 前向传播output model(data)# 损失loss loss_fn(output, target)# 反向传播loss.backward()# 更新参数optimizer.step()loss_acc loss.item()if batch_idx % print_every print_every - 1:print([%d, %5d] 损失 %.3f % (epoch 1, batch_idx 1, loss_acc / print_every))loss_acc 0.0print(完成训练)def test(model, test_loader): 测试 correct 0total 0# 预测不需要梯度来修改参数with torch.no_grad():for data in test_loader:images, labels dataoutputs model(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()print(在测试集中的预测准确率 {:.2%}.format(correct / total))def main():# 超参数num_epochs 5batch_size 16print_every 200learning_rate 0.001# 加载数据集mnist_train torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainTrue, downloadFalse,transformtransforms.ToTensor())train_loader data.DataLoader(mnist_train, batch_sizebatch_size, shuffleTrue)mnist_test torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainFalse, downloadFalse,transformtransforms.ToTensor())test_loader data.DataLoader(mnist_test, batch_sizebatch_size, shuffleFalse)model Net()# 交叉熵损失函数loss_fn nn.CrossEntropyLoss()# 优化算法optimizer torch.optim.Adam(model.parameters(), lrlearning_rate)train(num_epochs, train_loader, model, optimizer, loss_fn, print_every)test(model, test_loader)if __name__ __main__:main()
运行结果
轮次1损失0.6634训练准确率0.782测试准确率0.805 轮次2损失0.5175训练准确率0.826测试准确率0.817 轮次3损失0.4881训练准确率0.835测试准确率0.827 轮次4损失0.4720训练准确率0.840测试准确率0.830 轮次5损失0.4616训练准确率0.844测试准确率0.830 真实标签ankle boot 预测标签ankle boot 真实标签pullover 预测标签pullover 真实标签trouser 预测标签trouser 真实标签trouser 预测标签trouser 真实标签shirt 预测标签shirt 真实标签trouser 预测标签trouser 真实标签coat 预测标签coat 真实标签shirt 预测标签shirt 真实标签sandal 预测标签sandal 真实标签sneaker 预测标签sneaker 真实标签coat 预测标签coat 真实标签sandal 预测标签sandal 真实标签sneaker 预测标签sandal 真实标签dress 预测标签dress 真实标签coat 预测标签coat 真实标签trouser 预测标签trouser 真实标签pullover 预测标签pullover 真实标签coat 预测标签pullover 真实标签bag 预测标签bag 真实标签t-shirt 预测标签t-shirt 真实标签pullover 预测标签pullover 真实标签sandal 预测标签sneaker 真实标签sneaker 预测标签sneaker 真实标签ankle boot 预测标签sneaker 真实标签trouser 预测标签trouser 真实标签coat 预测标签pullover 真实标签shirt 预测标签shirt 真实标签t-shirt 预测标签t-shirt 真实标签ankle boot 预测标签ankle boot 真实标签dress 预测标签dress 真实标签bag 预测标签bag 真实标签bag 预测标签bag
5.神经网络
1神经元
线性回归实际上就是一个线性神经元。多变量线性回归实现了加权求和计算。增加了激活函数的神经元直接称为神经元。
2激活函数
1.绘制Sigmoid激活函数
创建文件plot_sigmoid.py 添加代码如下
# -*- coding: utf-8 -*-绘制Sigmoid激活函数import matplotlib.pyplot as plt
import numpy as np
import torch# x取值start到stop范围内间隔均匀的100个数
x_vals np.linspace(start-10., stop10., num100)activation torch.nn.Sigmoid()# Sigmoid激活函数
print(activation(torch.Tensor([-1., 0., 1.])))
y_vals activation(torch.Tensor(x_vals))# 绘制Sigmoid激活函数图像
plt.plot(x_vals, y_vals, r--, labelSigmoid, linewidth1.5)
plt.ylim([-0.5, 1.5])
plt.legend(locupper left)
plt.grid(axisy)
plt.show()
运行结果
2.绘制双曲正切Tanh激活函数
它是Sigmoid函数的变体放大并平移
# -*- coding: utf-8 -*-绘制双曲正切Tanh激活函数
import matplotlib.pyplot as plt
import numpy as np
import torch# x取值start到stop范围内间隔均匀的100个数
x_vals np.linspace(start-10., stop10., num100)activation torch.nn.Tanh()# 双曲正切激活函数
print(activation(torch.Tensor([-1., 0., 1.])))
y_vals activation(torch.Tensor(x_vals))# 绘制Tanh激活函数图像
plt.plot(x_vals, y_vals, r--, labelTanh, linewidth1.5)
plt.ylim([-1.5, 1.5])
plt.legend(locupper left)
plt.grid(axisy)
plt.show()
运行结果
3.绘制ReLU激活函数
创建文件display_olympics_freestyle100m.py 添加代码如下
# -*- coding: utf-8 -*-绘制ReLU激活函数
import matplotlib.pyplot as plt
import numpy as np
import torch# x取值start到stop范围内间隔均匀的100个数
x_vals np.linspace(start-10., stop10., num100)relu torch.nn.ReLU()
relu6 torch.nn.ReLU6()# ReLU激活函数
print(ReLU: , relu(torch.Tensor([-5., 5., 10.])))
y_relu relu(torch.Tensor(x_vals))# ReLU-6激活函数
print(ReLU-6: , relu6(torch.Tensor([-5., 5., 10.])))
y_relu6 relu6(torch.Tensor(x_vals))# 绘制ReLU激活函数图像
plt.plot(x_vals, y_relu, r:, labelReLU, linewidth1.5)
plt.plot(x_vals, y_relu6, b-., labelReLU6, linewidth1.5)
plt.ylim([-1, 8])
plt.legend(locupper left)
plt.grid(axisy)
plt.show()
运行结果 4.绘制LeakyReLU激活函数
创建文件display_olympics_freestyle100m.py 添加代码如下
# -*- coding: utf-8 -*-绘制LeakyReLU激活函数
import matplotlib.pyplot as plt
import numpy as np
import torch# x取值start到stop范围内间隔均匀的100个数
x_vals np.linspace(start-10., stop10., num100)leaky_relu torch.nn.LeakyReLU()
elu torch.nn.ELU()# ReLU激活函数
print(Leaky ReLU: , leaky_relu(torch.Tensor([-5., 5., 10.])))
y_leaky_relu leaky_relu(torch.Tensor(x_vals))# ELU激活函数
print(ELU: , elu(torch.Tensor([-5., 5., 10.])))
y_elu elu(torch.Tensor(x_vals))# 绘制ReLU激活函数图像
plt.plot(x_vals, y_leaky_relu, r:, labelLeaky ReLU, linewidth1.5)
plt.plot(x_vals, y_elu, b-., labelELU, linewidth1.5)
plt.ylim([-1, 8])
plt.legend(locupper left)
plt.grid(axisy)
plt.show()
运行结果 5.softmax函数
主要用于神经网络最后一层解决多元分类问题
6.选择正确的激活函数
中间层选ReLU二元分类选Sigmoid多元分类选Softmax函数深层网络一般避免Tanh函数和Sigmoid函数如果出现较多死亡神经元用Leaky ReLU和ELU函数代替
3神经网络原理
主要思想
1.神经网络表示和结构
2.前向传播
3.代价函数训练权重和偏置。一般采用交叉熵代价函数
4.BP算法即反向传播算法。用于优化神经网络参数算法推荐使用Pytorch的自动求导解决方案。
4Pytorch实现神经网络
nn.Sequential定义一个简单的神经网络模型
另一种方式是使用nn.Module定义神经网络。
两种方式实现如下
创建文件neural_networks_initialization.py 添加代码如下
# -*- coding: utf-8 -*-PyTorch定义神经网络及参数初始化
import torch
from torch import nn
from torch.nn import initnum_inputs, num_hiddens, num_outputs 4, 5, 3# nn.Sequential定义一个简单的神经网络模型
seq_model nn.Sequential(nn.Linear(num_inputs, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_outputs),nn.Softmax(dim1),
)class Net(nn.Module): 定义一个简单的神经网络模型 def __init__(self):super().__init__()self.fc1 nn.Linear(num_inputs, num_hiddens)self.act1 nn.ReLU()self.fc2 nn.Linear(num_hiddens, num_hiddens)self.act2 nn.ReLU()self.fc3 nn.Linear(num_hiddens, num_outputs)self.act3 nn.Softmax(dim1)def forward(self, x):x self.act1(self.fc1(x))x self.act2(self.fc2(x))return self.act3(self.fc3(x))def weights_init(m): 初始化网络权重 if isinstance(m, nn.Conv2d):init.normal_(m.weight.data)# init.xavier_normal_(m.weight.data)# init.kaiming_normal_(m.weight.data) # 卷积层参数初始化m.bias.data.fill_(0)elif isinstance(m, nn.Linear):m.weight.data.normal_() # 全连接层参数初始化def main():# 初始化for params in seq_model.parameters():init.normal_(params, mean0, std0.01)print(nn.Sequential定义的网络)print(seq_model)for name, param in seq_model.named_parameters():print(name, param.shape)# 随机初始化输入xx torch.randn(10, 4)y_hat seq_model(x)print(y_hat)model Net()# 网络参数初始化model.apply(weights_init) # apply函数会递归搜索网络中的子模块并应用初始化print(nnn.Module定义的网络)print(model)y_hat model(x)print(y_hat)if __name__ __main__:main()
5神经网络应用示例一
需求FashionMNIST分类问题。
创建文件neural_networks_demo1.py 添加代码如下
# -*- coding: utf-8 -*-PyTorch实现神经网络示例一
import torch
import torchvision
import torchvision.transforms as transforms
from torch import nn
from torch.utils import data
from torch.nn import initnum_inputs, num_hiddens, num_outputs 784, 256, 10# nn.Sequential模型
net nn.Sequential(nn.Linear(num_inputs, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_outputs),
)for params in net.parameters():init.normal_(params, mean0, std0.01)def train(epochs, train_loader, model, optimizer, loss_fn, print_every): 迭代训练模型 for epoch in range(epochs):loss_acc 0.0 # 累计损失# 每次输入第batch_idx批数据for batch_idx, (data, target) in enumerate(train_loader):# 梯度清零optimizer.zero_grad()# 前向传播output model(data.view(data.shape[0], -1))# 损失loss loss_fn(output, target)# 反向传播loss.backward()# 更新参数optimizer.step()loss_acc loss.item()if batch_idx % print_every print_every - 1:print([%d, %5d] 损失 %.3f % (epoch 1, batch_idx 1, loss_acc / print_every))loss_acc 0.0print(完成训练)def test(model, test_loader): 模型测试 correct 0total 0# 预测不需要梯度来修改参数with torch.no_grad():for data in test_loader:images, labels dataoutputs model(images.view(images.shape[0], -1))_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()print(在测试集中的预测准确率 {:.2%}.format(correct / total))def main():# 超参数num_epochs 5batch_size 16print_every 200learning_rate 0.001# 加载数据集mnist_train torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainTrue, downloadFalse,transformtransforms.ToTensor())train_loader data.DataLoader(mnist_train, batch_sizebatch_size, shuffleTrue)mnist_test torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainFalse, downloadFalse,transformtransforms.ToTensor())test_loader data.DataLoader(mnist_test, batch_sizebatch_size, shuffleFalse)# 交叉熵损失函数loss_fn nn.CrossEntropyLoss()# 优化算法optimizer torch.optim.Adam(net.parameters(), lrlearning_rate)# 训练与评估train(num_epochs, train_loader, net, optimizer, loss_fn, print_every)test(net, test_loader)if __name__ __main__:main()
6神经网络应用示例二
示例二使用nn.Module定义网络模型
创建文件neural_networks_demo2.py 添加代码如下
# -*- coding: utf-8 -*-PyTorch实现神经网络示例二
import torch
import torchvision
import torchvision.transforms as transforms
from torch import nn
from torch.utils import data
import torch.nn.functional as Fnum_inputs, num_hiddens, num_outputs 784, 256, 10class Net(nn.Module): nn.Module定义网络模型 def __init__(self):super(Net, self).__init__()self.fc1 nn.Linear(num_inputs, num_hiddens)self.fc2 nn.Linear(num_hiddens, num_outputs)def forward(self, x):# 展平数据 (n, 1, 28, 28) -- (n, 784)x x.view(x.shape[0], -1)x F.relu(self.fc1(x))return F.log_softmax(self.fc2(x), dim1)def train(epochs, train_loader, model, optimizer, loss_fn, print_every): 迭代训练模型 for epoch in range(epochs):loss_acc 0.0 # 累计损失# 每次输入第batch_idx批数据for batch_idx, (data, target) in enumerate(train_loader):# 梯度清零optimizer.zero_grad()# 前向传播output model(data)# 损失loss loss_fn(output, target)# 反向传播loss.backward()# 更新参数optimizer.step()loss_acc loss.item()if batch_idx % print_every print_every - 1:print([%d, %5d] 损失 %.3f % (epoch 1, batch_idx 1, loss_acc / print_every))loss_acc 0.0print(完成训练)def test(model, test_loader): 模型测试 correct 0total 0# 预测不需要梯度来修改参数with torch.no_grad():for data in test_loader:images, labels dataoutputs model(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()print(在测试集中的预测准确率 {:.2%}.format(correct / total))def main():# 超参数num_epochs 5batch_size 16print_every 200learning_rate 0.001# 加载数据集mnist_train torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainTrue, downloadFalse,transformtransforms.ToTensor())train_loader data.DataLoader(mnist_train, batch_sizebatch_size, shuffleTrue)mnist_test torchvision.datasets.FashionMNIST(root../datasets/FashionMNIST, trainFalse, downloadFalse,transformtransforms.ToTensor())test_loader data.DataLoader(mnist_test, batch_sizebatch_size, shuffleFalse)model Net()# 负对数似然损失函数loss_fn nn.NLLLoss()# 优化算法optimizer torch.optim.Adam(model.parameters(), lrlearning_rate)# 训练与评估train(num_epochs, train_loader, model, optimizer, loss_fn, print_every)test(model, test_loader)if __name__ __main__:main()
7两层神经网络解决异或问题
# -*- coding: utf-8 -*-两层神经网络解决异或问题
import torch
from torch import nndef main():# 设置随机数种子seed 1torch.manual_seed(seed)torch.cuda.manual_seed_all(seed)# 定义输入单元数、隐藏层单元数、输出层单元数n_in, n_h, n_out 2, 2, 1# 创建XOR数据集x torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])y torch.tensor([[0.0], [1.0], [1.0], [0.0]])# 创建模型model nn.Sequential(nn.Linear(n_in, n_h),nn.Sigmoid(),nn.Linear(n_h, n_out),nn.Sigmoid())# 损失函数criterion nn.MSELoss()# 优化器optimizer torch.optim.Adam(model.parameters(), lr0.01)# 梯度下降for epoch in range(1, 1001):# 前向传播y_pred model(x)# 计算损失loss criterion(y_pred, y)if epoch 1 or epoch % 100 0:print(f轮次{epoch}\t损失{loss.item()})# 梯度置零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 预测y_pred model(x)print(输入为\n{}.format(x))print(输出为\n{}.format(y_pred))if __name__ __main__:main()
8Fizz Buzz神经网络实现
# -*- coding: utf-8 -*-Fizz Buzz神经网络实现
import numpy as np
import torchdef binary_encode(i, num_digits): 将输入的十进制i转换为位数是num_digits的二进制 return np.array([i d 1 for d in range(num_digits)])def fizz_buzz_encode(i): 将输入数字编码为标签 if i % 3 0 and i % 5 0:return 3elif i % 5 0:return 2elif i % 3 0:return 1else:return 0def fizz_buzz_decode(i, encode): 解码为人类可读的输出 return [str(i), Fizz, Buzz, FizzBuzz][encode]# 超参数
learning_rate 0.05
epochs 3000
batch_size 128
num_digits 10
num_hidden 100# 构建训练集。使用101~1024作为训练数据
train_x torch.tensor([binary_encode(i, num_digits) for i in range(101, 2 ** num_digits)]).float()
train_y torch.tensor([fizz_buzz_encode(i) for i in range(101, 2 ** num_digits)]).long()
# 随机置乱
torch.manual_seed(123)
rand_idx torch.randperm(len(train_y))
train_x train_x[rand_idx, :]
train_y train_y[rand_idx]# 定义网络模型
model torch.nn.Sequential(torch.nn.Linear(num_digits, num_hidden),torch.nn.ReLU(),torch.nn.Linear(num_hidden, 4)
)# 定义损失函数和优化器
criterion torch.nn.CrossEntropyLoss()
optimizer torch.optim.Adam(model.parameters(), lrlearning_rate)# 模型训练
model.train()
for epoch in range(epochs):for start in range(0, len(train_x), batch_size):end start batch_sizebatch_x train_x[start:end]batch_y train_y[start:end]y_hat model(batch_x)loss criterion(y_hat, batch_y)optimizer.zero_grad()loss.backward()optimizer.step()# 计算训练损失loss criterion(model(train_x), train_y).item()print(fEpoch:{epoch}\tLoss:{loss})# 预测1~100
model.eval()
test_x torch.tensor([binary_encode(i, num_digits) for i in range(1, 101)]).float()
test_y torch.tensor([fizz_buzz_encode(i) for i in range(1, 101)]).long()
with torch.no_grad():pred_y model(test_x)
predictions zip(range(1, 101), list(pred_y.max(1)[1].data.tolist()))print(预测, [fizz_buzz_decode(i, x) for (i, x) in predictions])
acc np.sum(pred_y.max(1)[1].numpy() np.array(test_y)) / len(test_y)
print(准确率{:.2%}.format(acc))