torch.zeros , torch.empty , torch.randn,torch.add,x*weights=x.mm(weights)……
在定义数据时,加入requires_grad=True,表示自动求导。
x=torch.randn(3,4,requires_grad=True)
requires_grad中自动求导
z.backward(retain_graph=True)不清零时梯度自动叠加
.grad是梯度,梯度(gradient)是一个向量,它既有方向又有大小,它的方向是某一函数在某点处变化率最大的方向,此时它的大小就是变化率。
定义数据主要转换为tensor模式,根据方程构造是否自动求导
torch.save(model.state_dict(,‘model.pkl’))
model.load_state_dict(torch.load(‘model.pkl’))
将设备转为CUDA,即GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
将数据转化为GPU模式
inputs = torch.from_numpy(x_train).to(device)
labels = torch.from_numpy(y_train).to(device)
具体数据具体分析,将若有日期等格式将日期转换为数据格式
此处,输入数据大小为348*14。
x = torch.tensor(input_features, dtype = float)
y = torch.tensor(labels, dtype = float)
weights = torch.randn((14, 128), dtype = float, requires_grad = True)
biases = torch.randn(128, dtype = float, requires_grad = True)
weights2 = torch.randn((128, 1), dtype = float, requires_grad = True)
biases2 = torch.randn(1, dtype = float, requires_grad = True)
weights表示随机生成输入层至隐藏层权重,biases表示随机生成输入层至隐藏层偏移。
由于只有单隐藏层,故 weights2 表示隐藏层至输出层权重,biases2 表示隐藏层至输出层的偏移。
learning_rate = 0.001 #学习率
losses = []
定义每次学习0.001,学习1000次。
for i in range(1000):
# 计算隐层
hidden = x.mm(weights) + biases
# 加入激活函数
hidden = torch.relu(hidden)
# 预测结果
predictions = hidden.mm(weights2) + biases2
# 通计算损失
loss = torch.mean((predictions - y) ** 2)
losses.append(loss.data.numpy())
# 打印损失值
if i % 100 == 0:
print('loss:', loss)
#返向传播计算
loss.backward()
#更新参数
weights.data.add_(- learning_rate * weights.grad.data)
biases.data.add_(- learning_rate * biases.grad.data)
weights2.data.add_(- learning_rate * weights2.grad.data)
biases2.data.add_(- learning_rate * biases2.grad.data)
# 每次迭代都得记得清空
weights.grad.data.zero_()
biases.grad.data.zero_()
weights2.grad.data.zero_()
biases2.grad.data.zero_()
根据昨天的公式,隐藏层hidden=x.mm(weights) + biases,
激活函数 hidden = torch.relu(hidden)可更改
而预测结果 predictions = hidden.mm(weights2) + biases2
损失值在此定义了一个均方误差,并将损失值格式转为numpy
反向传播计算,反向传播是将当前求出的损失率进行由输出层至输入层的一个方向求偏导的过程,反向求导旨在优化参数w,使得误差更小。反向传播简单过程可浏览8分钟搞懂神经网络反向传播算法_哔哩哔哩_bilibili
在反向传播完成后,计算梯度,并进行w1,w2,b1,b2的更新。
更新操作为,沿着梯度的反方向进行学习率*梯度的更新。
在每次更新完毕后迭代清空。
最后predictions输出结果。
predictions
1.首先根据输入输出数据大小在权重初始化中改变x,y的维度
2.需要将梯度求导项打开
3.定义学习率以及学习损失
4.根据学习率n进行1/n次的迭代
5.更新迭代方式
在整个过程中,可以对训练过程进行优化的参数有:
1)损失率
2)激活函数(大多情况下用relu)
3)损失的计算,可将方差改为其他损失类型。
input_size = input_features.shape[1]#输入大小
hidden_size = 128#隐藏层
output_size = 1#输出大小
batch_size = 16#batch梯度下降
my_nn = torch.nn.Sequential(
torch.nn.Linear(input_size, hidden_size),
torch.nn.Sigmoid(),#激活函数
torch.nn.Linear(hidden_size, output_size),
)#两层全连接定义网络结构
cost = torch.nn.MSELoss(reduction='mean')#均方差的损失函数库
optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)#优化器动态调整学习率由大变小。
# 训练网络
losses = []#损失
for i in range(1000):
batch_loss = []
# MINI-Batch方法来进行训练
for start in range(0, len(input_features), batch_size):
end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)
yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)#用到batch分批取数据
prediction = my_nn(xx)#前向传播库,直接进行前向传播
loss = cost(prediction, yy)#损失求取
optimizer.zero_grad()#优化的梯度清零
loss.backward(retain_graph=True)#反向传播
optimizer.step()#更新操作
batch_loss.append(loss.data.numpy())#读取损失结果
# 打印损失
if i % 100==0:
losses.append(np.mean(batch_loss))
print(i, np.mean(batch_loss))
x = torch.tensor(input_features, dtype = torch.float)
predict = my_nn(x).data.numpy()
预测值转为numpy进行画图。
本篇内容是在数据预处理完毕后进行的初级神经网络构建与测试操作。
神经网络的大致思路为,由输入层前向传播至输出层,在前向传播过程中,若使用线性方式,每条传播路径对应一个w,每一组w对应一个可控参数b,定义一个学习率,通过每次学习计算出该次学习的输出结果以及经过定义的误差。得到误差后进行反向传播过程,修改传入的参数。
针对于单隐藏层神经网络,采用全链接的方式连接输入层至隐藏层,隐藏层至输出层。
通过torch.nn.Sequential可简化原来的w,b的定义方式,通过定义cost来使用库直接计算方差,通过torch.optim.Adam来动态优化学习率。