赞
踩
Infer 推理;Prediction 预测
是否大于50个样本——是分类问题——有标签是分类器/没标签用聚类
是否大于50个样本——不是分类问题——查看预测量级——预测数值用回归/用降维
表征学习出现的原因:
Features 特征;Mapping from features 从特征映射;Additional layers of more abstract features 更多抽象特征的附加层
Perceptron 感知器 Artificial Neural Network 人工神经网络
Back Propagation 反向传播 (偏导数)
各个神经网络架构:
官网直接安装,并且配置下path
conda env list 查看虚拟环境 (*代表在哪个环境下)
conda create -n 环境名字 python=版本
(conda create -n 环境名字 python=版本 -c 镜像地址)
我查看了pytorch官网目前显示(Latest PyTorch requires Python 3.8 or later. For more details, see Python section below.)我们至少要装3.8以上的版本,我们装3.9
确认下载依赖功能包:
conda activate yixuepytorch 进入我们创建好的虚拟环境
conda list 查看当下环境下,有哪些功能包
conda remove -n 虚拟环境名字 --all 删除所选环境
命令总结:
conda env list # 查看虚拟环境
conda create -n 环境名字 python=版本 # 创建新环境
#(conda create -n 环境名字 python=版本 -c 镜像地址)
conda activate yixuepytorch # 进入我们创建好的虚拟环境
conda list # 查看当下环境下,有哪些功能包
conda remove -n 虚拟环境名字 --all # 删除所选环境
命令总结:
conda install xxx #(conda install xxx -c 通道地址)
conda create -n yyy #(conda create -n yyy -c 通道地址)
conda config --show # 查看conda配置文件
conda config --get # 得到有哪些通道
conda config --add channels 通道地址 # 持久化添加通道地址
conda config --remove channels 通道地址# 持久化删除通道地址
(channel 通道,就是下载地址;defaults指的是官方地址)
官网确定CUDA Runtime版本我确定了12.1
可以从官网确定命令安装
也可以通过添加镜像源
先进入我们的虚拟环境
然后复制命令安装,查看是否正确
conda list 查看下功能包里是否有了pytorch
对于历史版本的pytorch在这里:
在我们做科研的步骤当中,遵循:
那么线性模型的样子大概就为:
Prediction 预测
训练可以看到输入和输出;测试只能看到输入,根据训练出来的函数去匹配测试是否合适;
模型不要过拟合;要有好的泛化能力
训练再拆为两份,一份训练一份开发集做评估;然后再在测试集看是否好;
我们接下来的任务是w和b的值到底是多少;预测结果我们一般叫y_hat
机器是去随机猜测数值,并且查看与实际数值的误差求最小(也叫Compute Loss计算损失):
由于在点的下面,差值为负,我们作为求平方
我们在不断求w的时候,找到mean最小的时候的值
Loss function & Cost function 接着设计损失函数
即得出:
# 导入功能包 import numpy as np import matplotlib.pyplot as plt # 准备训练集 x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0] # 定义模型,也就是前面说的Linear Model,也就是前馈计算 def forward(x): return x * w # 定义损失函数,也就是前面说的Loss Function def loss(x, y): y_pred = forward(x) return (y_pred - y) * (y_pred - y) # 创建空列表来保存 权重和权重的损失值(mse指的是损失) w_list = [] mse_list = [] # 设置采样间隔 for w in np.arange(0.0, 4.1, 0.1): print('w=', w) l_sum = 0 # x和y的val值不断从数据中取 for x_val, y_val in zip(x_data, y_data): y_pred_val = forward(x_val) # 计算预测值 loss_val = loss(x_val, y_val) # 计算损失值 l_sum += loss_val # 计算损失求和 print('\t', x_val, y_val, y_pred_val, loss_val) print('MSE=', l_sum / 3) # 保存进空列表 w_list.append(w) mse_list.append(l_sum / 3) # 画图显示 plt.plot(w_list, mse_list) plt.ylabel('Loss') plt.xlabel('w') plt.show()
我们将来不会拿权重画图,但是看超参数时,我们可以用这种图进行判别。(一般横坐标为epoch)
利用visdom功能包可以做深度学习的可视化,长时间的深度学习要学会存盘。
对于画三维的图功能包使用说明文档:
The mplot3d toolkit和numpy.meshgrid
解决y=wx+b的线性模型
# 导入功能包 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 这里设函数为y=3x+2 x_data = [1.0,2.0,3.0] y_data = [5.0,8.0,11.0] # 定义模型,也就是前面说的Linear Model def forward(x): return x * w + b # 定义损失函数,也就是前面说的Loss Function def loss(x,y): y_pred = forward(x) return (y_pred-y)*(y_pred-y) # 创建空列表来保存 权重的损失值 mse_list = [] # 设置采样间隔 W = np.arange(0.0,4.1,0.1) B = np.arange(0.0,4.1,0.1) [w,b] = np.meshgrid(W,B) l_sum = 0 for x_val, y_val in zip(x_data, y_data): y_pred_val = forward(x_val) print(y_pred_val) loss_val = loss(x_val, y_val) l_sum += loss_val # 画图 fig = plt.figure() ax = Axes3D(fig) fig.add_axes(ax) # python3.8以上版本需要添加此项操作才能画出3D图 ax.plot_surface(w, b, l_sum/3) plt.show()
更多内容线性回归模型可以看我写的:Python大数据分析——一元与多元线性回归模型
但是搜索量,参数越多,穷举法是不可能的
所以我们要改良方法,可以用分治法,但是分治法有一点缺陷是进入局部最优解
什么是局部最优解:
那么我们需要解决的问题就是:Optimization Problem 最优化问题
这就我们介绍下梯度下降算法Gradient Descent Algorithm
Gradient 梯度;这里的x指的是权重w;导数为负,说明为递减方向,也就是我们找导数负的
所以我们在梯度下降算法中(类似于贪心),更新权重的方法(其中α是学习率,一般要取小一点):
梯度下降不一定能得到最优结果,但能得到局部最优结果,因为他可能是非凸函数:
还有一种可能是死于鞍点,没法继续迭代,什么是鞍点:
这个东西是我们之后设计要考虑的,我们这节主要搞清楚什么是梯度下降,利用我们第三节的线性模型来讲解
首先算清楚偏微分是怎样的:
然后套入我们的损失函数当中:
Epoch 叫迭代轮数
# 导入功能包 import matplotlib.pyplot as plt # 建立数据集 x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0] # 设定初始权重(猜测),和学习率 w = 1.0 alpha = 0.01 # 定义模型,也就是前馈计算 def forward(x): return x * w # 定义成本函数 def cost(xs, ys): cost = 0 # 定义初始值 for x, y in zip(xs, ys): # 循环;zip就是把列表对应第i个元素组成一个新的列表 y_pred = forward(x) # 函数 cost += (y_pred - y) ** 2 # 对损失值求和 return cost / len(xs) # 除以样本的数量,也就是1/N # 定义梯度函数 def gradient(xs, ys): grad = 0 # 定义初始值 for x, y in zip(xs, ys): # 循环;zip就是把列表对应第i个元素组成一个新的列表 grad += 2 * x * (x * w - y) # 求和 return grad / len(xs) # 打印下进行个分割 print('Predict (before training)', 4, forward(4)) # 定义空列表用来画图 epoch_lst = [] cost_lst = [] # 训练过程,每次拿权重-学习率*梯度 for epoch in range(100): # 设置了100次训练 cost_val = cost(x_data, y_data) grad_val = gradient(x_data, y_data) w -= alpha * grad_val cost_lst.append(cost_val) # 用来画图做记录 epoch_lst.append(epoch) # 用来画图做记录 print('Epoch:', epoch, 'w=', w, 'loss=', cost_val) # 打印查看信息,几轮,当前权重,损失函数多少 # 打印下训练之后 print('Predict (after training)', 4, forward(4)) # 画图 plt.plot(epoch_lst,cost_lst) plt.ylabel('cost') plt.xlabel('cost') plt.show()
注意训练的结果一定是收敛的,如果说发散了,说明学习率大了,降低一点学习率
随机梯度下降 Stochastic Gradient Descent;损失函数的导数 Derivative of Loss Function
cost是所有样本,随机是N个数据里选一个;我们的数据是有噪声的,可能会把我们做推动
# 建立数据集 x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0] # 设定初始权重(猜测),和学习率 w = 1.0 alpha = 0.01 # 定义模型,也就是前馈计算 def forward(x): return x * w # 定义损失函数 def loss(x, y): y_pred = forward(x) return (y_pred - y) ** 2 # 定义梯度函数 def gradient(x, y): return 2 * x * (x * w - y) # 打印下进行个分割 print('Predict (before training)', 4, forward(4)) # 按训练集样本的每个梯度更新权重 for epoch in range(100): for x, y in zip(x_data, y_data): grad = gradient(x, y) # 对每一个样本来求梯度 w = w - alpha * grad print("\tgrad: ", x, y, grad) l = loss(x, y) print("progress:", epoch, "w=", w, "loss=", l) # 打印下训练之后 print('Predict (after training)', 4, forward(4))
这就是表示,一起算和一个个去算(在性能与时间复杂度取一个折中,叫做batch/mini-batch,批量的随机梯度下降)
在上节中我们的模型,可以看作一个非常简单的神经网络
Neuron 神经元;Stochastic Gradient Descent 随机梯度下降;Derivative of Loss Function 损失函数的导数;
简单模型可以通过解析式做,但是复杂网络就不能了,复杂网络:
对于5个输入x,中间隐层H(1)对应的是6个元素,那w权重就有6*5=30个
那么我们的计算图Computational Graph:
MM 矩阵乘法(缩写);ADD 向量加法
对于矩阵的求导计算,可以看这本书(对不同的求导,对应的梯度怎么计算):matrix cookbook
我们展开来观察一下:
发现是无论是几层,形式是一样的;为了使其有意义,我们要加一个非线性的变化函数,这样就没法展开了
Nonlinear Function 非线性函数
The composition of functions and Chain Rule 函数的组合和链式法则;进行累计,整体导数就求出来了
举个例子,f=xw:
我们来看下完整的序列图,前馈加反馈(其中下面的导数是求局部梯度)
对于y=xw+b
在 PyTorch 中,Tensor 是构建动态计算图的重要组成部分。储存w和损失函数对权重的导数等
它包含 data 和 grad,分别存储节点值和梯度 w.r.t 损失。
接下来我们就要用gpu pytorch了,你可以在命令行直接进入环境,然后进入python编程,但是这样非常费劲,如果我们想要在jupyter notebook里进行调用pytorch就要进去对应的环境(当然如果pytorch装入了base环境中就可以直接调用了)
# 首先进入对应的环境
conda activate pytorch
# 安装一个配置功能包
conda install ipykernel
# 创建对应notebook环境调用名称
python -m ipykernel install --name yixuepytorch
然后我们创建新的notebook的时候就能选用其他环境了
# 导入功能包 import torch # 创建数据样本 x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0] # 选择权重(如果需要autograd机制,Tensor的元素变量requires_grad必须设置为True) w = torch.Tensor([1.0]) # 这里w只有一个初始值 w.requires_grad = True # 设置需要计算梯度 # 设置学习率 alpha = 0.01 # 定义模型,也就是前馈计算 def forward(x): return x * w # 这里面的w是一个Tensor # 定义损失函数 def loss(x, y): y_pred = forward(x) return (y_pred - y) ** 2 # 打印下进行个分割 print('Predict (before training)', 4, forward(4)) # 训练过程 for epoch in range(100): # 设置了100次训练 for x, y in zip(x_data, y_data): # # zip就是把列表对应第i个元素组成一个新的列表 l = loss(x, y) # 前馈过程,计算loss(为张量) l.backward() # 反馈过程(向后,计算 require_grad 设置为 True 的 Tensor 的 grad,求梯度)/ 其中计算图也被释放了 print('\tgrad:', x, y, w.grad.item()) w.data = w.data - alpha * w.grad.data # 利用梯度来更新权重,data指的是数值,权重更新的时候对的是值的操作而不是张量tensor w.grad.data.zero_() # .backward() 计算的梯度将被累加,所以更新后要记得把权重数据里的梯度清零 print("progress:", epoch, l.item()) # 输出训练论数、最后的loss # 其中.data是进tensor修改;。item是把其中的数取出来 # 打印下训练之后 print("predict (after training)", 4, forward(4).item())
梯度也是tensor
再来个例子:
# 导入功能包 import torch # 创建数据样本 x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0] # 选择权重(如果需要autograd机制,Tensor的元素变量requires_grad必须设置为True) w1 = torch.Tensor([1.0]) # 初始权值 w1.requires_grad = True # 计算梯度,默认是不计算的 w2 = torch.Tensor([1.0]) w2.requires_grad = True b = torch.Tensor([1.0]) b.requires_grad = True # 设置学习率 alpha = 0.01 # 定义模型,也就是前馈计算 def forward(x): return w1 * x**2 + w2 * x + b # 这里面的w是一个Tensor # 定义损失函数 def loss(x, y): y_pred = forward(x) return (y_pred - y) ** 2 # 打印下进行个分割 print('Predict (before training)', 4, forward(4)) # 训练过程 for epoch in range(100): # 设置了100次训练 l = loss(1, 2) #为了在for循环之前定义l,以便之后的输出,无实际意义 for x,y in zip(x_data,y_data): # zip就是把列表对应第i个元素组成一个新的列表 l = loss(x, y) # 前馈过程,计算loss(为张量) l.backward() # 反馈过程(向后,计算 require_grad 设置为 True 的 Tensor 的 grad,求梯度)/ 其中计算图也被释放了 print('\tgrad:',x,y,w1.grad.item(),w2.grad.item(),b.grad.item()) w1.data = w1.data - 0.01 * w1.grad.data # 利用梯度来更新权重,注意这里的grad是一个tensor,所以要取他的data w2.data = w2.data - 0.01 * w2.grad.data b.data = b.data - 0.01 * b.grad.data w1.grad.data.zero_() # 释放之前计算的梯度 w2.grad.data.zero_() b.grad.data.zero_() print('Epoch:',epoch,l.item()) # 输出训练论数、最后的loss # 打印下训练之后 print("predict (after training)", 4, forward(4).item())
在用y=w1x²+w2x+b的模型训练100次后可以看到当x=4时,y=8.5,与正确值8相差比较大。原因可能是数据集本身是一次函数的数据,模型是二次函数。所以模型本身就不适合这个数据集,所以才导致预测结果和正确值相差比较大的情况。
这节主要是如何用pytorch更方便的实现之前的模型、梯度下降反向传播这些。
步骤:
1、准备数据集
2、使用类设计模型
3、构造损失和优化器
4、训练周期(前馈、反馈和更新)
在 PyTorch 中,计算图采用小批量方式,因此 X 和 Y 是 3 × 1 张量。
# 创建模型类
class LinearModel(torch.nn.Module):
def __init__(self): # 构造函数,做初始化对象默认调用的函数
super(LinearModel, self).__init__() # 调用父类构造
self.linear = torch.nn.Linear(1, 1) # nn.Linear 类包含两个张量(对象):权重和偏差。
def forward(self, x): # 前馈计算
y_pred = self.linear(x) # 定义可调用(nn.Linear类实现了神奇的方法 __call__(),它使得类的实例可以像函数一样被调用。)
return y_pred
model = LinearModel() # 创建 LinearModel 类的实例。为callable,可以直接调用,比如model(x)
# 训练100次
for epoch in range(100):
y_pred = model(x_data) # 前馈过程算y预测
loss = criterion(y_pred, y_data) # 算损失函数
print(epoch, loss)
optimizer.zero_grad() # 梯度清理0
loss.backward() # 反向传播
optimizer.step() # 更新所有权重(参数)
# 输出权重和偏差
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
# 测试模型
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)
100次才7.4说明我们收敛的还不够好,训练1000次发现越来越好
注意除了观察训练集上的收敛,也要观察测试集上的好坏, 防止过拟合
# 导入功能包 import torch # 导入数据集 x_data = torch.Tensor([[1.0], [2.0], [3.0]]) y_data = torch.Tensor([[2.0], [4.0], [6.0]]) # 创建模型类 class LinearModel(torch.nn.Module): def __init__(self): # 构造函数,做初始化对象默认调用的函数 super(LinearModel, self).__init__() # 调用父类构造 self.linear = torch.nn.Linear(1, 1) # nn.Linear 类包含两个张量(对象):权重和偏差。 def forward(self, x): # 前馈计算 y_pred = self.linear(x) # 定义可调用(nn.Linear类实现了神奇的方法 __call__(),它使得类的实例可以像函数一样被调用。) return y_pred model = LinearModel() # 创建 LinearModel 类的实例。为callable,可以直接调用,比如model(x) criterion = torch.nn.MSELoss(size_average=False) # 构造损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 构造优化器,实现随机梯度下降(可选的动量) # 训练100次 for epoch in range(100): y_pred = model(x_data) # 前馈过程算y预测 loss = criterion(y_pred, y_data) # 算损失函数 print(epoch, loss) optimizer.zero_grad() # 梯度清理0 loss.backward() # 反向传播 optimizer.step() # 更新所有权重(参数) # 输出权重和偏差 print('w = ', model.linear.weight.item()) print('b = ', model.linear.bias.item()) # 测试模型 x_test = torch.Tensor([[4.0]]) y_test = model(x_test) print('y_pred = ', y_test.data)
class的使用
更多的优化器:
• torch.optim.Adagrad • torch.optim.Adam • torch.optim.Adamax • torch.optim.ASGD • torch.optim.LBFGS • torch.optim.RMSprop • torch.optim.Rprop • torch.optim.SGD
更多的pytorch可以看官方教程
虽然叫回归,但做的是分类问题;现实生活中也基本上很多问题需要解决的也是分类问题。回归是连续的,分类是离散的(分类问题算的是样本属于所有类别的概率值;在分类中,模型的输出是输入属于确切类别的概率。)
比较一下问题的解决:
logistic函数由实数空间映射到0-1之间
经典的两个练习有:
sigmoid函数
但在pytorch里他是如概念里的图
比较下我们之前的,他的设计图:
损失函数的改变(之前是mse,mse是计算两个实数之间的差值):
两个分布之间差异性的大小(交叉熵):
二元分类的小批量损失函数
因为在σ操作里他是没有参数的,所以不需要在构造函数中初始化它
# 导入功能包
import torch.nn.functional as F
# 创建模型类
class LogisticRegressionModel(torch.nn.Module):
def __init__(self): # 构造函数,做初始化对象默认调用的函数
super(LogisticRegressionModel, self).__init__() # 调用父类构造
self.linear = torch.nn.Linear(1, 1) # nn.Linear 类包含两个张量(对象):权重和偏差。
def forward(self, x): # 前馈计算
y_pred = F.sigmoid(self.linear(x)) # 可调用函数,求完前面线性的值再应用到sigmoid里当中
损失函数:
criterion = torch.nn.BCELoss(size_average=False) # BCELoss就是cross-entropy(交叉熵)
# 导入功能包 import torch import torch.nn.functional as F # 数据集 x_data = torch.Tensor([[1.0], [2.0], [3.0]]) y_data = torch.Tensor([[0], [0], [1]]) # 0和1类(二分类) # 创建模型类 class LogisticRegressionModel(torch.nn.Module): def __init__(self): # 构造函数,做初始化对象默认调用的函数 super(LogisticRegressionModel, self).__init__() # 调用父类构造 self.linear = torch.nn.Linear(1, 1) # nn.Linear 类包含两个张量(对象):权重和偏差。 def forward(self, x): # 前馈计算 y_pred = F.sigmoid(self.linear(x)) # 可调用函数,求完前面线性的值再应用到sigmoid里当中 return y_pred model = LogisticRegressionModel() criterion = torch.nn.BCELoss(size_average=False) # 构造损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 构造优化器,实现随机梯度下降(可选的动量) # 训练1000次 for epoch in range(1000): y_pred = model(x_data) # 前馈过程算y预测 loss = criterion(y_pred, y_data) # 算损失函数 print(epoch, loss.item()) optimizer.zero_grad() # 梯度清理0 loss.backward() # 反向传播 optimizer.step() # 更新所有权重(参数) # 我们来坐下测试 import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 10, 200) # 0-10采200个点 x_t = torch.Tensor(x).view((200, 1)) # 把他变成一个200行一列的矩阵 y_t = model(x_t) # 张量送到我们训练的模型 y = y_t.data.numpy() # 拿出y的数据 plt.plot(x, y) plt.plot([0, 10], [0.5, 0.5], c='r') plt.xlabel('Hours') plt.ylabel('Probability of Pass') plt.grid() plt.show()
先看数据集(糖尿病)
Simple 样本;Feature 特征
Sigmoid 函数采用元素方式。
把输入维度改成8;把输出维度改成1(8个维度,就是八个参数变量影响;N组数据)
这个矩阵是N维空间映射到M维空间的一种变换
我们的目标是找一个8维空间到1维空间的非线性的空间变化
其实对于神经网络来说就是这样,逐步降维从而减少神经元也就是高复杂度,并且学习能力不能太强(否则过拟合),要有好的泛化能力:
直接降维1维
逐步降维,那么我们构造神经网络:
第一步准备数据集:
第二步构造模型:
第三步构造损失和优化器:
第四步训练:
# 导入功能包 import torch import numpy as np # 1准备数据 xy = np.loadtxt('diabetes.csv.gz', delimiter=',', dtype=np.float32) # 逗号作为分隔符;指定数据类型 x_data = torch.from_numpy(xy[:,:-1]) # 选择所有行;选择除去最后一列的所有列 y_data = torch.from_numpy(xy[:, [-1]]) # 选择所有行;只选择最后一列(用中括号的意思是为矩阵) # from_numpy会根据里面的数据创造两个tensor出来 # 2.创建模型类 class Model(torch.nn.Module): def __init__(self): # 构造函数,做初始化对象默认调用的函数 super(Model, self).__init__() # 调用父类构造 self.linear1 = torch.nn.Linear(8, 6) # 八维降六维 self.linear2 = torch.nn.Linear(6, 4) # 六维降四维 self.linear3 = torch.nn.Linear(4, 1) # 四维降一维 self.sigmoid = torch.nn.Sigmoid() # 激活函数 def forward(self, x): # 前馈计算 x = self.sigmoid(self.linear1(x)) # 可调用函数,求完前面线性的值再应用到sigmoid里当中 x = self.sigmoid(self.linear2(x)) x = self.sigmoid(self.linear3(x)) return x model = Model() # 3. 构造损失和优化器 criterion = torch.nn.BCELoss(size_average=True) # 构造损失函数;求均值 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 构造优化器,实现随机梯度下降(可选的动量) # 4.训练100次 for epoch in range(100): # 前馈 y_pred = model(x_data) # 前馈过程算y预测 loss = criterion(y_pred, y_data) # 算损失函数 print(epoch, loss.item()) # 反馈 optimizer.zero_grad() # 梯度清理0 loss.backward() # 反向传播 # 更新 optimizer.step() # 更新所有权重(参数)
其他类型激活函数:
其图像可以通过这个链接看到:https://dashee87.github.io/data%20science/deep%20learning/visualising-activation-functions-in-neural-networks/
我们可以通过查看pytorch文档,查看pytorch里有哪些激活函数可以调用:https://pytorch.org/docs/stable/nn.html#non-linear-activations-weighted-sum-nonlinearity
对于改激活函数,只改这里点即可了:
Terminology: Epoch, Batch-Size, Iterations 术语:纪元、批量大小、迭代
epoch:所有训练示例的一次前向传递和一次反向传递。
batch-size:一次向前向后传递中的训练示例数。
iterations:传递次数,每次传递使用 [batch size] 的示例数。
内层循环每次迭代执行一次mini-batch
Shuffle是打乱顺序;Loader是分组
数据集是一个抽象类。 我们可以定义我们的类继承自这个类
DataLoader是一个帮助我们在PyTorch中加载数据的类
DiabetesDataset继承自抽象类Dataset
表达式 dataset[index] 将调用这个神奇函数。
这个神奇的函数返回数据集的长度。
使用批量大小、洗牌、进程号初始化加载程序。(数据集对象;小批量容量;是否打乱;多线程)
注意在windows下:
多处理的实现在Windows上是不同的,它使用spawn而不是fork。(RuntimeError:在当前进程完成其引导阶段之前,试图启动一个新进程。这可能意味着您没有使用fork来启动子进程,并且您忘记在主模块中使用适当的习惯用法:if_name_== ‘main’:freeze_support()如果程序不打算冻结以产生可执行文件,则可以省略"freeze_support()"行。)
因此,我们必须用if子句包装代码,以防止代码多次执行。
所以是:
# 导入功能包 import torch import numpy as np from torch.utils.data import Dataset, DataLoader # 1.准备数据集 class DiabetesDataset(Dataset): def __init__(self, filepath): # filepath是路径(构造函数,做初始化对象默认调用的函数) xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32) # 逗号作为分隔符;指定数据类型 self.len = xy.shape[0] # 将数据集的个数,也就是N拿出来 self.x_data = torch.from_numpy(xy[:, :-1]) # 选择所有行;选择除去最后一列的所有列 self.y_data = torch.from_numpy(xy[:, [-1]]) # 选择所有行;只选择最后一列(用中括号的意思是为矩阵) # from_numpy会根据里面的数据创造两个tensor出来 def __getitem__(self, index): # 根据索引返回数据样本 return self.x_data[index], self.y_data[index] # 返回的是矩阵 def __len__(self): # 将数据集的个数 return self.len dataset = DiabetesDataset('diabetes.csv.gz') # 构造数据对象,数据文件路径送过去 train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=0) # 数据集对象;小批量容量;是否打乱;多线程 # 2.创建模型类 class Model(torch.nn.Module): def __init__(self): # 构造函数,做初始化对象默认调用的函数 super(Model, self).__init__() # 调用父类构造 self.linear1 = torch.nn.Linear(8, 6) # 八维降六维 self.linear2 = torch.nn.Linear(6, 4) # 六维降四维 self.linear3 = torch.nn.Linear(4, 1) # 四维降一维 self.sigmoid = torch.nn.Sigmoid() # 激活函数 def forward(self, x): # 前馈计算 x = self.sigmoid(self.linear1(x)) # 可调用函数,求完前面线性的值再应用到sigmoid里当中 x = self.sigmoid(self.linear2(x)) x = self.sigmoid(self.linear3(x)) return x model = Model() # 3. 构造损失和优化器 criterion = torch.nn.BCELoss(size_average=True) # 构造损失函数;求均值 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 构造优化器,实现随机梯度下降(可选的动量) # 4.训练 if __name__ == '__main__': for epoch in range(100): for i, data in enumerate(train_loader, 0): # train_loader的x,y放入了data里,0是起始索引 # 1. 准备数据集 inputs, labels = data # 先把输入x和标签y拿出来 # 2. 前馈 y_pred = model(inputs) # 前馈过程算y预测 loss = criterion(y_pred, labels) # 算损失函数 print(epoch, i, loss.item()) # 3. 反馈 optimizer.zero_grad() # 优化器清零 loss.backward() # 梯度清理0 # 4. 优化 optimizer.step() # 优化
之前我们是这样的(二分类):
那么现在多分类(要求概率和为1,每个概率是≥0的)所以要用softmax:
Softmax层:
假设 声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。