PyTorch实现神经网络 房价预测模型

avatar 2024年04月20日22:50:45 0 214 views
博主分享免费Java教学视频,B站账号:Java刘哥

原理就是,已经有了506条样本数据,其中13列是房子的特征数据,1列是房价数据。

取496条作为训练数据,10条最后测试验证。

根据496条数据,训练一个模型,输入13个特征,能返回一个预测房价pred。

然后将pred和我们真实的价格比较,计算误差。不断更新权重,训练一万次,每次打印误差。

一、模型定义、训练、保存等功能

demo_reg.py

import torch

# 1、初始化数据 data
import numpy as np
import re

ff = open("housing.data").readlines()
data = []
print(ff)
for item in ff:
    out = re.sub(r"\s{2,}", " ", item).strip()  # 将多个空格替换为一个空格
    data.append(out.split(" "))

data = np.array(data).astype(np.float32)
print(data)
print(data.shape)  # (506, 14)

# 所有数据
Y = data[:, -1]  # 取最后一列,为标签(房价)
X = data[:, 0:-1]  # 取前面所有列,为特征
# 训练数据
X_train = X[0: 496, ...]  # 取前496个样本, ... 表示取所有维度
Y_train = Y[0: 496, ...]
# 测试数据
X_test = X[496:, ...]  # 取后10个样本
Y_test = Y[496:, ...]


# print(X_train.shape)  # (496, 13) 表示 496行13列的 2维矩阵
# print(Y_train.shape)  # (496,) 表示 496行1列的 1维向量
# print(Y_test.shape)  # (10,) 表示 10行1列的 1维向量
# print(Y_test.shape)  # (10,) 表示 10行1列的 1维向量
# 注意:
# (1,1) 表示 1行1列的 2维矩阵
# (1,) 表示 1行1列的 1维向量

# 2、定义一个神经网络 net
class Net(torch.nn.Module):
    def __init__(self, n_feature, n_output):
        # 构造方法有2个参数,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


net = Net(13, 1)  # 输入特征数是13,输出特征数是1

# 3、定义损失函数 loss
loss_func = torch.nn.MSELoss()  # 均方误差

# 4、定义优化器 optimizer
# optimizer = torch.optim.SGD(net.parameters(), lr=0.01)  # 随机梯度下降
# optimizer = torch.optim.SGD(net.parameters(), lr=0.0001)  # 随机梯度下降
optimizer = torch.optim.Adam(net.parameters(), lr=0.01)  # 随机梯度下降

# 4、训练数据 training
for i in range(10000):
    # train
    x_data = torch.tensor(X_train, dtype=torch.float32)  # 将numpy数组转换为tensor, x_data是二维矩阵,496行13列
    y_data = torch.tensor(Y_train, dtype=torch.float32)  # y_data是一维向量,496行1列
    pred = net.forward(x_data)  # 前向传播,计算预测值
    pred = torch.squeeze(pred)  # 二维降为一维,去掉维度为1的维度,[496,1] 变成 [496,] 之所以要维度压缩,是因为计算损失时,要求两个维度一致
    loss_train = loss_func(pred, y_data) * 0.001  # 计算损失
    # print(pred.shape)
    # print(y_data.shape)
    optimizer.zero_grad()  # 梯度清零
    loss_train.backward()  # 反向传播
    optimizer.step()  # 更新参数
    print("ite:{}, loss_train:{}".format(i, loss_train.item()))

    # # 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_test.item()))

# 5、保存模型
torch.save(net, "model/model.pkl")  # 保存整个模型
# torch.save(net.state_dict(), "model/model_params.pkl")  # 只保存模型参数

 

二、模型加载、测试

demo_reg_inference.py

import torch

# 1、初始化数据 data
import numpy as np
import re

ff = open("housing.data").readlines()
data = []
print(ff)
for item in ff:
    out = re.sub(r"\s{2,}", " ", item).strip()  # 将多个空格替换为一个空格
    data.append(out.split(" "))

data = np.array(data).astype(np.float32)
# print(data)
# print(data.shape)  # (506, 14)

# 所有数据
Y = data[:, -1]  # 取最后一列,为标签(房价)
X = data[:, 0:-1]  # 取前面所有列,为特征
# 训练数据
X_train = X[0: 496, ...]  # 取前496个样本, ... 表示取所有维度
Y_train = Y[0: 496, ...]
# 测试数据
X_test = X[496:, ...]  # 取后10个样本
Y_test = Y[496:, ...]


# 2、定义一个神经网络 net
class Net(torch.nn.Module):
    def __init__(self, n_feature, n_output):
        # 构造方法有2个参数,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

# 3、加载已经训练好的模型
net = torch.load("model/model.pkl")

# 4、定义损失函数 loss
loss_func = torch.nn.MSELoss()

# 5、进行测试
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 # 求误差,乘以0.001是为了将loss放大,方便查看
print("loss_test:{}".format(loss_test.item()))

 

参考资料:https://coding.imooc.com/class/chapter/440.html

数据文件:链接:https://pan.baidu.com/s/1kZ36rkhfeTXqf9lGB-3cuw?pwd=4rt0 

提取码:4rt0 

 

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:0   待审核评论数:0