使用Pytorch实现,步骤框架如下:
1.准备数据集prepare dataset
目的:提供训练或检测所需要的数据集
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
2.用类设计模型(即神经网络模型)design model using Class
目的: 构造出了神经网络,封装后,方便后面直接调用,输入x_data,实现前向传播forward,得到y_pred(预测值),且自动保存梯度
class LinearModel(torch.nn.Module):
def __init__(self):
super(LinearModel, self).__init__()
self.linear = torch.nn.Linear(1, 1)
def forward(self, x):
y_pred = self.linear(x)
return y_pred
model = LinearModel()
重点
self.linear = torch.nn.Linear(1, 1) 前向传播的过程中构建了线性层,self.linear会在forward中调用,利用该线性层进行计算
格式:torch.nn.Linear(in_feature,out_feature,bias)
1.in_feature:指x的特征维度(上一层神经元的个数)
2.out_feature:指y的特征维度(这一层神经元的个数)
3.bias: Linear线性变换中是否添加bias偏置,默认是Ture
由于数据集中的x和y的特征都是1维的,故这里为(1,1)
如若linear_layer =torch.nn.Linear(in_features=5, out_features=3)
这将创建一个从5维输入到3维输出的线性层
总的分三步走
1.类里面的第一个函数,构造线性层,组成神经网络
2.类里面的第二个函数,实现前向传播forwoard,得到y_pred(预测值)
3.LinearModel()类的实例化,即创建对象model
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear1 = torch.nn.Linear(8, 6) #创建第一层,输入8维,输出6维
self.linear2 = torch.nn.Linear(6, 4)#创建第二层,输入6维,输出4维
self.linear3 = torch.nn.Linear(4, 1)#创建第三层,输入4维,输出1维
self.sigmoid = torch.nn.Sigmoid() # 将其看作是网络的一层,而不是简单的函数使用,运算层
#在此处可以改变激活函数,如self.activate = torch.nn.ReLU(),对应forward的函数也要改
def forward(self, x):
x = self.sigmoid(self.linear1(x)) #前一个输出作为后一个输入,为防止出错故都用x,x不断更新
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x)) # y_pred ,最后一步为了保证输出为[0,1]最好还是用sigmoid,其他可以用别的
return x
model = Model()
3.构造损失函数和优化器(使用API)Construct loss and optimizer
目的 :
(1)利用y_pred计算loss是为了loss求导,进行反向传播,但此步骤没有反向传播,要到训练周期手动写
(2)optimizer是为了自动更新梯度 ,自动更新权重
criterion = torch.nn.MSELoss(reduction = 'sum')
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
重点
criterion = torch.nn.MSELoss(reduction = 'sum')
构造损失函数可以选取不同的函数,不一定要MSELoss
loss.backward()实现反向传播
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
构造优化器也可以选择不同的优化器,不一定要SGD
optimizer.zero_grad() 实现梯度清零
optimizer.step() 实现参数更新,即更新w和b的值
注意,梯度清零要在反向传播之前!
损失函数是关于参数(权重,偏置)的函数,故损失函数对参数求导,即横坐标是参数,不断更新梯度(导数)与参数,直到梯度(导数)为零时,对应的参数可使损失函数最小,即最准确!
criterion = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
4.写训练周期Training cycle (forward,backward,update)
for epoch in range(100):
y_pred = model(x_data) # 前向传播,求出预测值
loss = criterion(y_pred, y_data) # 计算损失函数
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向传播 backward ,自动计算梯度
optimizer.step() # update 参数,即更新w和b的值
每一次epoch的训练过程,总结就是
1.输入x_data,前向传播,求y_pred即y_pred = model(x_data)
2.根据y_pred和y_data计算损失函数loss = criterion(y_pred, y_data)
3.optimizer.zero_grad() 梯度清零梯度需要手动清零,反向传播 loss.backward()(计算梯度)
4.根据梯度,利用优化器更新参数 optimizer.step()