本站原创文章,转载请说明来自《老饼讲解-深度学习》www.bbbdata.com
pytorch构建模型是应用pytorch来建模的最基础、最需要掌握的内容
本文通过展示一个最原始的构建模型的方法,来学习与理解pytorch模型构建的方法
通过本文,可以了解pytorch到底是以什么方式来构建一个模型的
本节展示一个pytorch的模型构建例子,下节再以此例子讲解pytorch中如何构建一个模型
pytorch模型-一个最原始的例子
在一般的教程中,我们看到的pytorch实现的模型都是高度封装的,
虽然高度封装的代码在实现上更为方便,但对于学习和理解pytorch的模型会造成一定的困难
下面我们展示在pytorch中用最原始的方式实现一个三层BP神经网络模型及训练的例子,
在本例中我们不调用pytorch提供的任何模块,以此更本质地了解pytorch的模型是怎么一回事
具体示例如下:
import torch
from torch import nn
# -----------定义模型-----------
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.w1 = nn.Parameter(torch.randn(2,3)) # 定义模型参数w1
self.b1 = nn.Parameter(torch.randn(1,3)) # 定义模型参数b1
self.w2 = nn.Parameter(torch.randn(3,2)) # 定义模型参数w
self.b2 = nn.Parameter(torch.randn(1,2)) # 定义模型参数b
def forward(self, x):
# 定义模型的计算
y1 = nn.functional.tanh(x@self.w1+self.b1)
y = y1@self.w2+self.b2
return y
# ------训练数据---------------
X = torch.tensor([[2.5, 1.3, 6.2, 1.3, 5.4, 6 ,4.3, 8.2]
,[-1.2,2.5,3.6,4,3.4,2.3,7.2,3.9]]).T # 输入数据
y = torch.tensor([0,0,1,0,1,1,1,1]) # 样本的标签
# -----模型训练----------------
model = Model() # 初始化模型
lossFun = torch.nn.CrossEntropyLoss() # 损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.1) # 初始化优化器
for i in range(500):
py = model(X) # 计算模型的输出值
L = lossFun(py, y)
print('第',str(i),'轮的Loss:',L) # 打印当前损失函数值
optimizer.zero_grad() # 更新梯度之前先清空梯度
L.backward() # 用损失函数更新模型系数的梯度
optimizer.step()
# -------打印结果-------------------
param_dict = model.state_dict() # 从模型中提取出模型参数
w1 = param_dict['w1'].data # 从参数字典中提取出参数w1
b1 = param_dict['b1'].data # 从参数字典中提取出参数b1
w2 = param_dict['w2'].data # 从参数字典中提取出参数w2
b2 = param_dict['b2'].data # 从参数字典中提取出参数b2
print('--------最终结果-------')
print('w1:',w1) # 打印模型系数w1
print('b1:',b1) # 打印模型系数b1
print('w2:',w2) # 打印模型系数w2
print('b2:',b2) # 打印模型系数b2
运行结果如下:
本节讲解在pytorch中如何构建一个模型,以及如何定义模型的参数
pytorch如何构建一个模型
从上述例子中,我们可以看到,在pytorch中构建建一个三层BP神经网络的模型代码如下:
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.w1 = nn.Parameter(torch.randn(2,3)) # 定义模型参数w1
self.b1 = nn.Parameter(torch.randn(1,3)) # 定义模型参数b1
self.w2 = nn.Parameter(torch.randn(3,2)) # 定义模型参数w
self.b2 = nn.Parameter(torch.randn(1,2)) # 定义模型参数b
def forward(self, x):
# 定义模型的计算
y1 = nn.functional.tanh(x@self.w1+self.b1)
y = y1@self.w2+self.b2
return y
pytorch里通过继承Module类来定义一个模型,一般需要实现Init方法和forward方法
1. Init方法用于定义模型的变量,也就是初始化模型计算过程所要用到的相关变量
2. forward方法则是模型的输出计算过程,向模型传入x后,将按此流程得到模型的输出
如果不实现forward也是可以的,只是调用模型计算时就会报错
总的来说,pytorch的模型就是一个Module类,
其中forward方法写模型的计算逻辑,而init则初始化模型forward中需要用到的参数或其它变量
pytorch如何给模型定义参数
在模型的Init里可以定义模型的参数,模型的参数变量必须是Parameter类型,才会被模型认为是模型的参数
例如W是一个tansor,只有使用nn.Parameter(W)把W转为Parameter类型,才会被模型识别为模型参数
也就是说,必须是Parameter类型的变量,Module才会将它们作为模型参数收集与管理起来
如下所示,定义为Parameter的变量会被作为模型的参数,而不是Parameter的变量会被忽略
import torch
from torch import nn
# -----------定义模型-----------
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.w = nn.Parameter(torch.tensor([2.])) # 定义变量w,是Parameter类
self.b = torch.tensor([2.]) # 定义变量b,不是Parameter类
# -----模型训练----------------
print('\n模型的参数:',Model().state_dict()) # 打印模型参数
运行结果如下:
可以看到,模型里只有被定义为Parameter的变量w才会被模型识别为模型参数
End