终于进入正题了,用PyTorch进行构建简单的模型,构建思路如下:
1.Prepare dataset
2.Design model using Class
inherit from nn.Module
3.Construct loss and optimizer
using PyTorch API
4.Training cycle
forward, backward, update
下面代码块会有逐步的解释
# 1.准备数据集非正式任务,简单的数据集#In PyTorch, the computational graph is in mini-batch fashion, so X and Y are 3 × 1 Tensors. # 1.准备数据集 import torch x_data = torch.Tensor([[1.0], [2.0], [3.0]]) y_data = torch.Tensor([[2.0], [4.0], [6.0]])
# 2.Design Model
# 2. Design Model # 一个线性单元:y=xw+b # 我们需要知道输入量和输出量,即y和x的形状来确定w和b的形状 # 我们输出的loss需要转化成一个标量,可以求和 class LinearModel(torch.nn.Module): # 继承自torch.nn.Module def __init__(self): # 这是一个约定俗成的构造函数 初始化对象时要调用的函数,self 指代当前对象实例,当只有一个self的时候,在构造对象的时候不需要传入任何值。在 Python 中,可以使用双下划线开头的方法来控制属性的访问。不能从类的外部直接访问 super(LinearModel,self).__init__() # 这是调用父类(即torch.nn.Module)的构造函数。在Python中,super()函数用于调用父类的方法。 self.linear = torch.nn.Linear(1,1) # 构造继承自torch.nn.Linear的对象linear,torch.nn.Linear(1,1)是一个类,这句话构建了y=xw+b # 我们构造的对象linear是继承自Linear的,这个对象中有两个参数w和b # class torch.nn.Linear(in_features,out_features,bias+True) # in_features 是指输入的样本x是几维的 # bias是在运算中要不要加上偏置量,即b,默认值为True def forward(self,x): # 前馈的过程中所要进行的计算 y_pred = self.linear(x) # 调用刚刚的对象,直接在对象后面加括号,我们实现了一个可调用的对象 return y_pred # 这里就是创建了一个可以被直接调用的对象 model = LinearModel() # __call__方法是Python中唯一的一种方式,允许一个类的实例像函数一样被调用。 # 在Python中,任何一个实现了__call__方法的对象都可以像函数一样被调用。这意味着我们可以将一个类的实例当作函数来使用,使用对象的名称后加括号的方式进行调用。 # 当你对model实例进行调用时,实际上是调用了torch.nn.Linear的model.__call__()方法,而这个方法内部又调用了model.forward()方法进行前向传播计算。
# 补充知识1 *args和**kwargs
# 补充知识:*args和**kwargs # *args:你并不知道你要传入多少个数,于是创建一个元组 # **kwargs:你并不知道你要传入多少个数,于是创建一个字典 def func(*args,**kwargs): print(args) print(kwargs) print("Hello "+str(args[0])) func(1,2,3,4,x=7,y=8)
# 魔法函数__call__
# 补充知识:__call__方法是Python中唯一的一种方式,允许一个类的实例像函数一样被调用。 class Foobar: def __init__(self): pass def __call__(self,*args,**kwargs): print("Hello "+str(args[0])) # 定义一个对象 foobar = Foobar() foobar(1,2,3)
# 3.Construct loss and optimizer
# 3.Construct loss and optimizer criterion = torch.nn.MSELoss(size_average=False) optimizer = torch.optim.SGD(model.parameters(),lr=0.01) # criterion 依旧会构造计算图 # class torch.nn.MSELoss(size_average=True,reduce=True) # 这个类是计算loss=(y_hat-y)**2 # size_average是问要不要求均值,reduce是问是不是要降维,一般要降维,所以不写 # 所以criterion最后需要两个参数 y和y_hat,就可以求loss了 # optimizer 优化器 不会构造计算图 # class torch.optim.SGD(params,Is=<object object>,momentum=0,dampeming=0,weight_decay=0,nesterov=Fale) # parameters找出需要训练的权重,这里我model.parameters(),所以找出的是w # Ir是leaning rate 学习率,就是α # 最后得到的optimizer优化器知道对哪些权重(w)做优化,也知道学习率是多少
# 4.Training cycle
# 4.Training cycle for epoch in range(100): y_pred = model(x_data) # 算y_hat loss = criterion(y_pred,y_data) # 算loss print(epoch,loss.item()) # 打印日志 optimizer.zero_grad() # 梯度归零!!!!! loss.backward() # 反向传播 optimizer.step() # 更新 # Output weight and bias print('w=',model.linear.weight.item()) print('b=',model.linear.bias.item()) # Test Model x_test = torch.Tensor([[4.0]]) y_test = model(x_test) print('y_pred=',y_test.data.item())
好的我们已经可以基于pytorch构建简单模型了,以后一直是这四步,务必牢记于心。