携手创造,一起生长!这是我参与「日新计划 8 月更文应战」的第22天,点击查看活动概况
前语
在上一篇文章中,咱们介绍神经网络的根本概念,包括感知器的根本概念,前向计算,反向传播,分类与回归,过拟合和欠拟合,正则化问题。
今日,咱们来运用运用Pytorch进行波士顿房价猜测模型建立。
-
1.1 Pytorch建立神经网络根本组成模块
-
数据:对练习数据进行加载,而且用于对网络参数进行练习
-
网络结构:建立的神经网络最重要的一个模块
-
丢失:在进行问题建模的时分,针对分类问题和回归问题结构出来的优化方式,怎么去计算猜测值和实在值之间的误差,而且运用计算出来的误差完成对网络参数的优化
-
优化:选用的优化算法,如:梯度下降法
-
测验:对练习好的网络进行测验,测验是伴随在练习的进程中的操作
-
推理:对练习好的网络进行推理,推理是在练习好网络之后,运用网络来完成咱们想要解决的一些任务
-
1.2 Pytorch完成波士顿房价猜测模型建立
- 波士顿返奖这些数据于1978年开端计算,共506个数据点,涵盖了麻省波士顿不同郊区房屋14种特征信息
- 数据集下载地址:t.cn/RfHTAgY
- 丢失函数: MSE-LOSS
代码实现:
-
1.2.1 数据集加载
# data
import numpy as np
import re
data = []
ff = open("housing.data").readlines() # 将数据的每一列都读取出来
for item in ff:
out = re.sub(r"\s{2,}", " ", item).strip()
print(out)
data.append(out.split(" "))
data = np.array(data).astype(np.float64) # 将数据进行类型转换为float
print(data.shape)
运转成果:
(506, 14)
-
1.2.2 数据集的区分
# 这些数据前十三个是x,后一个是y
# 切分数据
Y = data[:, -1]
X = data[:, 0:-1]
# 区分测验集和练习集,界说前496个样本为练习集的样本
X_train = X[0:496, ...]
Y_train = Y[0:496, ...]
X_test = X[496:, ...]
Y_test = Y[496:, ...]
print(X_train.shape)
print(Y_train.shape)
print(X_test.shape)
print(Y_test.shape)
运转成果:
(496, 13)
(496,)
(10, 13)
(10,)
能够看到,练习集由496个样本,测验集有10个样本
-
1.2.3 界说网络结构
在这里,只界说一个简单的回归网络结构
# 界说一个简单的神经网络:只要一个躲藏层,也就是线性层
class Net(torch.nn.Module):
def __init__(self, n_feature, n_output):
super(Net, self).__init__()
self.predict = torch.nn.Linear(n_feature, n_output)
def forward(self, x):
out = self.predict(x)
return out
# 初始化网络
net = Net(13, 1)
-
1.2.4 界说loss和optimizer
选用MES-LOSS的办法
# loss
# 选用均方丢失
loss_func = torch.nn.MSELoss()
# optimizer
optimizer = torch.optim.SGD(net.parameters(), lr=0.01)
-
1.2.5 界说练习的进程
在经过线性函数拿到的pred是一个二维的,而y_data经过Y_train来进行初始化的时分,是一维的,这时,能够对pred做一个维度的删去,或者对y_data做维度的扩展
# training
for i in range(1000):
x_data = torch.tensor(X_train, dtype=torch.float32)
y_data = torch.tensor(Y_train, dtype=torch.float32)
pred = net.forward(x_data)
pred = torch.squeeze(pred)
loss = loss_func(pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 打印迭代次数和loss的变化
print("ite:{}, loss_train:{}".format(i, loss))
print(pred[0:10])
print(y_data[0:10])
履行当时的脚本之后会发现,咱们计算出来的丢失都是nan,那么loss为什么会产生nan的情况呢?
- 学习率可能太高了
- loss自身太大了
将loss降低1000倍,将lr降低100倍
# optimizer
optimizer = torch.optim.SGD(net.parameters(), lr=0.0001)
# training
for i in range(1000):
x_data = torch.tensor(X_train, dtype=torch.float32)
y_data = torch.tensor(Y_train, dtype=torch.float32)
pred = net.forward(x_data)
pred = torch.squeeze(pred)
loss = loss_func(pred, y_data) * 0.001
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 打印迭代次数和loss的变化
print("ite:{}, loss_train:{}".format(i, loss))
print(pred[0:10])
print(y_data[0:10])
这时能够发现loss不再为nan了
最终loss收敛在了97这个位置上,观察猜测成果和实在成果之间的误差还是比较大的,这说明咱们的模型处于欠拟合的状况,
关于模型处于欠拟合的状况能够做的:
- 加大练习的次数
- 在初始学习的时分运用大的学习率,在迭代过必定次数之后对学习率进行动态的调整
- 选用其他的优化函数,比方dam
- 将模型变得更杂乱,比方再加入一个躲藏层
打印测验集的loss
# test
x_data = torch.tensor(X_test, dtype=torch.float32)
y_data = torch.tensor(Y_test, dtype=torch.float32)
pred = net.forward(x_data)
pred = torch.squeeze(pred)
loss_test = loss_func(pred, y_data) * 0.001
print("ite:{}, loss_test:{}".format(i, loss))
能够发现,测验集的loss也是下降的,在多轮练习之后,练习集的loss在3.5,测验集的loss在6.0
-
1.2.6 保存模型
把模型悉数保存下来
torch.save(net, "model.pkl")
保存模型的参数:
torch.save(net.state_dict(), "params.pkl")
-
1.2.7 推理
加载模型
import torch
torch.load("model.kpl")
推理代码展现:
class Net(torch.nn.Module):
def __init__(self, n_feature, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, 100)
self.predict = torch.nn.Linear(100, n_output)
def forward(self, x):
out = self.hidden(x)
out = torch.relu(out)
out = self.predict(out)
return out
data = []
ff = open("housing.data").readlines() # 将数据的每一列都读取出来
for item in ff:
out = re.sub(r"\s{2,}", " ", item).strip()
data.append(out.split(" "))
data = np.array(data).astype(np.float64) # 将数据进行类型转换为float
print(data.shape)
# 这些数据前十三个是x,后一个是y
# 切分数据
Y = data[:, -1]
X = data[:, 0:-1]
# 区分测验集和练习集,界说前496个样本为练习集的样本
X_train = X[0:496, ...]
Y_train = Y[0:496, ...]
X_test = X[496:, ...]
Y_test = Y[496:, ...]
print(X_train.shape)
print(Y_train.shape)
print(X_test.shape)
print(Y_test.shape)
net = torch.load("model.pkl")
loss_func = torch.nn.MSELoss()
# test
x_data = torch.tensor(X_test, dtype=torch.float32)
y_data = torch.tensor(Y_test, dtype=torch.float32)
pred = net.forward(x_data)
pred = torch.squeeze(pred)
loss_test = loss_func(pred, y_data) * 0.001
print("loss_test:{}".format(loss_test))
运转成果:
loss_test:0.006096621975302696
经过save和load model就能够完成对模型的保存