pytorh学习笔记——波士顿房价预测

 机器学习的“hello world”:波士顿房价预测

        波士顿房价预测的背景不用提了,简单了解一下数据集的结构。 
        波士顿房价的数据集,共有506组数据,每组数据共14项,前13项是影响房价的各种因素,比如:城镇人均犯罪率、一氧化氮浓度之类的,最后一项是基于前面的因素的房价。

一、逻辑框架 

 二、程序框架

import torch  # 导入pytorch

# data   解析数据


# net   # 搭建网络


# loss   # 计算损失


# optimizer   # 优化器



# train   # 训练



# test   # 测试

1、训练的初步的脚本

新建demo_net.py,输入代码:

import torch

# data   解析数据
import numpy as np
import re

ff = open('housing.data', 'r').readlines()  # 读取数据
data = []    # 存储数据
for item in ff:
    out = re.sub(r'\s{2,}', ' ', item).strip()   # 去除多余空格(将多个空格替换为一个空格)
    data.append(out.split(' '))    # 按照空格分割数据并添加到data中

data = np.array(data, dtype=np.float32)  # 转换为numpy数组
# print(data.shape)  # 打印数据形状  (506, 14)
Y = data[:, -1]  # 获取标签(所有行的最后一列)
X = data[:, :-1]  # 获取特征(所有行的除最后一列的所有列)

Y_train = Y[0:496, ...]  # 训练集标签
X_train = X[0:496, ...]  # 训练集特征
Y_test = Y[496:, ...]  # 测试集标签
X_test = X[496:, ...]  # 测试集特征

# print(Y_train.shape)  # 打印训练集标签形状  (496,)
# print(X_train.shape)  # 打印训练集特征形状  (496, 13)
# print(Y_test.shape)  # 打印测试集标签形状   (10,)
# print(X_test.shape)  # 打印测试集特征形状   (10, 13)


# net   # 搭建网络
class Net(torch.nn.Module):   # 定义网络
    def __init__(self, n_feature, n_output):   # n_feature:输入特征数,n_output:输出特征数
        super(Net, self).__init__()

        self.predict = torch.nn.Linear(n_feature, n_output)   # 定义网络结构(线性回归)

    def forward(self, x):   # 前向传播
        y = self.predict(x)
        return y


net = Net(13, 1)   # 实例化网络

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

# optimizer   # 优化器
optimizer = torch.optim.Adam(net.parameters(), lr=0.0001)   # 定义优化器

# train   # 训练
x_data = torch.tensor(X_train, dtype=torch.float32)   # 将训练集特征转换为tensor
y_data = torch.tensor(Y_train, dtype=torch.float32)   # 将训练集标签转换为tensor
for i in range(10000):   # 训练10000次
    pred = net.forward(x_data)   # 前向传播,返回的是一个二维tensor
    # print(pred.shape)   # 打印预测结果形状  (496, 1)
    pred = torch.squeeze(pred)   # 由于返回的是二维的tensor,所以需要去掉维度为1的维度
    loss = loss_func(pred, y_data)  # 计算损失
    optimizer.zero_grad()   # 清空上一次的梯度
    loss.backward()   # 反向传播
    optimizer.step()   # 优化器更新参数
    if (i+1) % 1000 == 0:   # 每1000次打印一次损失
        print('第{}次训练,损失为{}'.format(i+1, loss))
        print('预测结果为{}'.format(pred[:10]))
        print('真实结果为{}'.format(y_data[:10]))

# test   # 测试



 运行结果:

第1000次训练,损失为213.7091064453125
预测结果为tensor([30.3859, 35.9642, 30.5334, 27.4028, 29.8967, 30.7044, 31.1800, 38.9477,
        41.2886, 35.3080], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第2000次训练,损失为115.01570129394531
预测结果为tensor([25.6781, 28.8944, 24.1358, 20.5663, 22.7628, 23.5741, 26.7624, 33.8008,
        35.9616, 30.7862], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第3000次训练,损失为92.31402587890625
预测结果为tensor([24.9008, 25.9834, 22.5986, 19.7416, 21.3243, 21.9060, 25.3798, 30.4637,
        31.5297, 28.2170], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第4000次训练,损失为78.46049499511719
预测结果为tensor([24.7822, 24.7402, 22.6722, 20.6557, 21.6591, 21.9934, 24.7024, 27.8985,
        27.8058, 26.3184], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第5000次训练,损失为69.00062561035156
预测结果为tensor([24.8879, 24.1986, 23.2193, 21.9481, 22.4841, 22.6186, 24.2389, 25.9268,
        24.7516, 24.8738], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第6000次训练,损失为62.37424850463867
预测结果为tensor([25.2287, 24.1047, 23.8811, 23.1481, 23.3747, 23.3950, 23.9017, 24.6387,
        22.4893, 23.9274], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第7000次训练,损失为57.1735954284668
预测结果为tensor([25.7705, 24.3499, 24.5864, 24.1829, 24.2396, 24.2240, 23.6420, 23.9154,
        20.8723, 23.3721], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第8000次训练,损失为52.881893157958984
预测结果为tensor([26.3800, 24.6829, 25.2719, 25.0930, 25.0307, 25.0057, 23.3551, 23.3264,
        19.4090, 22.8640], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第9000次训练,损失为49.33217239379883
预测结果为tensor([26.9553, 24.9474, 25.9011, 25.8923, 25.7059, 25.6638, 22.9824, 22.6079,
        17.8117, 22.2006], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第10000次训练,损失为46.42286682128906
预测结果为tensor([27.4543, 25.1425, 26.4893, 26.5836, 26.2601, 26.1888, 22.5538, 21.7727,
        16.1070, 21.4219], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])

看得出,当前的预测结果还是有很大的偏差的。

2、改进后的训练脚本

        .提高学习率,将学习率设为0.01

第10000次训练,损失为22.985254287719727
预测结果为tensor([29.2464, 24.2876, 30.5644, 28.9724, 28.4927, 25.0255, 21.5255, 18.3571,
        10.0867, 17.6953], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])

提高学习率之后,收敛更快,所以损失从46.4降到了22.9。

        .增加训练次数,训练100000次

第100000次训练,损失为21.93065071105957
预测结果为tensor([30.0387, 25.0656, 30.6645, 28.7074, 28.0154, 25.3406, 22.7764, 19.2288,
        11.0369, 18.6134], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])

增加训练次数后,损失略有下降,但不明显。

        .加入隐藏层

将网络的定义更换为下面的代码:

# net   # 搭建网络
class Net(torch.nn.Module):   # 定义网络
    def __init__(self, n_feature, n_output):   # 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):   # 前向传播
        y = self.hidden(x)   # 隐藏层
        y = torch.relu(y)   # 激活函数
        y = self.predict(y)
        return y

 运行结果:

第1000次训练,损失为16.16332244873047
预测结果为tensor([31.5807, 24.7012, 31.1625, 33.0276, 29.9564, 28.7967, 21.1699, 17.8390,
        11.0052, 17.8434], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第2000次训练,损失为10.760713577270508
预测结果为tensor([31.2304, 21.0812, 30.4874, 34.0178, 30.2638, 26.8140, 21.4654, 19.2940,
        15.2969, 18.9148], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第3000次训练,损失为9.041060447692871
预测结果为tensor([30.0590, 22.6623, 31.4998, 34.3279, 34.0962, 28.8110, 22.4006, 20.0406,
        17.4557, 19.8644], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第4000次训练,损失为7.654926776885986
预测结果为tensor([28.6500, 22.9828, 31.4478, 34.5795, 35.0444, 28.6649, 22.2122, 20.1728,
        17.4889, 19.9103], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第5000次训练,损失为7.204400539398193
预测结果为tensor([25.6355, 21.1540, 29.2047, 32.6562, 33.3360, 26.2489, 20.5876, 18.6758,
        15.7114, 18.5272], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第6000次训练,损失为4.584250450134277
预测结果为tensor([25.8020, 21.5723, 30.2412, 33.8467, 34.3686, 27.0365, 21.3067, 19.1034,
        16.5482, 19.0247], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第7000次训练,损失为3.7115399837493896
预测结果为tensor([26.3502, 21.7220, 30.8541, 34.7135, 35.1162, 27.7273, 22.0456, 19.7786,
        17.4401, 19.6452], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第8000次训练,损失为4.195467472076416
预测结果为tensor([25.8955, 21.2075, 30.6258, 34.2735, 34.5896, 27.4262, 21.6917, 19.4653,
        17.4221, 19.2694], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第9000次训练,损失为3.0317327976226807
预测结果为tensor([26.5321, 21.7933, 32.1591, 34.9432, 34.8340, 28.1285, 22.0055, 20.0637,
        18.4400, 19.3234], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第10000次训练,损失为2.727705478668213
预测结果为tensor([26.0240, 21.3191, 32.9476, 35.2049, 34.8349, 27.9297, 22.2083, 20.0651,
        18.3588, 18.8366], grad_fn=<SliceBackward0>)
真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])

看得出,10000次训练后,损失已经降到了2.7,比起之前已经大有提高。

3、测试

加入测试代码后:

import torch

# data   解析数据
import numpy as np
import re

ff = open('housing.data', 'r').readlines()  # 读取数据
data = []    # 存储数据
for item in ff:
    out = re.sub(r'\s{2,}', ' ', item).strip()   # 去除多余空格(将多个空格替换为一个空格)
    data.append(out.split(' '))    # 按照空格分割数据并添加到data中

data = np.array(data, dtype=np.float32)  # 转换为numpy数组
# print(data.shape)  # 打印数据形状  (506, 14)
Y = data[:, -1]  # 获取标签(所有行的最后一列)
X = data[:, :-1]  # 获取特征(所有行的除最后一列的所有列)

Y_train = Y[0:496, ...]  # 训练集标签
X_train = X[0:496, ...]  # 训练集特征
Y_test = Y[496:, ...]  # 测试集标签
X_test = X[496:, ...]  # 测试集特征

# print(Y_train.shape)  # 打印训练集标签形状  (496,)
# print(X_train.shape)  # 打印训练集特征形状  (496, 13)
# print(Y_test.shape)  # 打印测试集标签形状   (10,)
# print(X_test.shape)  # 打印测试集特征形状   (10, 13)


# net   # 搭建网络
class Net(torch.nn.Module):   # 定义网络
    def __init__(self, n_feature, n_output):   # 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):   # 前向传播
        y = self.hidden(x)   # 隐藏层
        y = torch.relu(y)   # 激活函数
        y = self.predict(y)
        return y


net = Net(13, 1)   # 实例化网络

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

# optimizer   # 优化器
optimizer = torch.optim.Adam(net.parameters(), lr=0.01)   # 定义优化器

# train   # 训练
train_x_data = torch.tensor(X_train, dtype=torch.float32)   # 将训练集特征转换为tensor
train_y_data = torch.tensor(Y_train, dtype=torch.float32)   # 将训练集标签转换为tensor
test_x_data = torch.tensor(X_test, dtype=torch.float32)   # 将测试集特征转换为tensor
test_y_data = torch.tensor(Y_test, dtype=torch.float32)   # 将测试集标签转换为tensor
for i in range(10000):   # 训练10000次
    pred_train = net.forward(train_x_data)   # 前向传播,返回的是一个二维tensor
    # print(pred.shape)   # 打印预测结果形状  (496, 1)
    pred_train = torch.squeeze(pred_train)   # 由于返回的是二维的tensor,所以需要去掉维度为1的维度
    loss_train = loss_func(pred_train, train_y_data)  # 计算损失
    optimizer.zero_grad()   # 清空上一次的梯度
    loss_train.backward()   # 反向传播
    optimizer.step()   # 优化器更新参数
    # test   # 测试
    pred_test = net.forward(test_x_data)
    pred_test = torch.squeeze(pred_test)
    loss_test = loss_func(pred_test, test_y_data)  # 计算损失
    if (i+1) % 1000 == 0:   # 每1000次打印一次损失
        print('第{}次训练,训练损失为{}'.format(i + 1, loss_train))
        print('训练预测结果为{}'.format(pred_train[:10]))
        print('训练真实结果为{}'.format(train_y_data[:10]))
        print('第{}次训练,测试损失为{}'.format(i + 1, loss_test))
        print('测试预测结果为{}'.format(pred_test[:10]))
        print('测试真实结果为{}'.format(test_y_data[:10]))





 运行结果:

C:\Users\DY\.conda\envs\torch\python.exe E:\AI_tset\boston\main.py 
第1000次训练,训练损失为13.062897682189941
训练预测结果为tensor([32.4538, 22.4545, 31.6084, 34.6321, 30.7499, 28.7717, 21.2537, 18.4388,
        14.3816, 17.8076], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第1000次训练,测试损失为15.603384017944336
测试预测结果为tensor([17.2584, 20.4116, 21.6079, 19.7471, 20.3963, 21.4410, 21.3918, 28.3847,
        25.5809, 21.5427], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第2000次训练,训练损失为9.312514305114746
训练预测结果为tensor([28.3546, 20.2573, 28.6708, 33.5919, 31.0789, 25.5264, 20.3330, 18.5948,
        15.6572, 17.6856], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第2000次训练,测试损失为14.083860397338867
测试预测结果为tensor([18.4503, 20.9926, 22.3660, 20.1845, 21.4613, 22.1625, 20.6208, 28.3789,
        25.4795, 20.2372], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第3000次训练,训练损失为6.208388328552246
训练预测结果为tensor([28.0445, 21.0570, 29.5777, 34.5575, 34.3055, 28.3384, 20.9634, 19.6007,
        16.1345, 18.6369], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第3000次训练,测试损失为6.905886650085449
测试预测结果为tensor([16.9234, 19.6245, 21.3344, 18.5896, 20.3094, 21.4729, 19.0355, 24.3601,
        22.2127, 18.4200], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第4000次训练,训练损失为5.641458511352539
训练预测结果为tensor([25.9988, 21.0524, 29.1003, 33.8196, 34.5036, 27.8455, 20.7901, 19.6908,
        15.6711, 18.6173], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第4000次训练,测试损失为8.056257247924805
测试预测结果为tensor([17.5898, 20.1642, 21.8730, 19.0862, 21.0310, 22.3734, 19.6710, 24.7076,
        22.8086, 18.9423], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第5000次训练,训练损失为5.656107425689697
训练预测结果为tensor([25.2531, 20.6933, 28.9231, 32.7898, 34.1414, 27.3489, 20.4208, 19.7374,
        15.6711, 18.3137], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第5000次训练,测试损失为10.021121978759766
测试预测结果为tensor([19.1231, 20.8267, 22.5154, 19.6338, 21.5662, 23.3536, 20.3911, 25.4182,
        23.7853, 19.5190], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第6000次训练,训练损失为4.3244428634643555
训练预测结果为tensor([26.9243, 21.3463, 30.2934, 34.4237, 35.6593, 29.0201, 21.4505, 20.5173,
        17.6037, 18.9231], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第6000次训练,测试损失为6.1388702392578125
测试预测结果为tensor([19.1049, 20.0117, 21.6194, 18.9644, 20.5173, 22.2967, 19.1247, 23.9584,
        22.5197, 18.1853], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第7000次训练,训练损失为4.283013343811035
训练预测结果为tensor([27.0127, 22.1808, 30.9352, 35.3205, 36.2137, 29.5154, 21.7429, 20.6820,
        18.5019, 19.3641], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第7000次训练,测试损失为4.814659118652344
测试预测结果为tensor([18.5595, 19.3107, 21.0298, 18.4600, 19.9520, 21.3664, 17.8218, 23.2565,
        21.3452, 16.9308], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第8000次训练,训练损失为4.039644718170166
训练预测结果为tensor([26.9686, 22.5262, 31.3496, 35.2846, 36.3410, 29.3871, 21.7442, 20.7460,
        18.5969, 19.5158], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第8000次训练,测试损失为4.698439598083496
测试预测结果为tensor([18.2167, 19.3340, 21.3022, 18.2839, 20.1922, 21.6993, 17.1337, 23.3157,
        21.3075, 16.1727], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第9000次训练,训练损失为4.54683256149292
训练预测结果为tensor([23.9196, 20.3218, 29.5554, 32.8275, 34.2579, 27.2489, 20.4540, 18.9822,
        17.2778, 18.3638], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第9000次训练,测试损失为8.086548805236816
测试预测结果为tensor([19.2664, 20.9391, 22.9442, 19.6506, 21.8333, 23.6144, 18.8776, 24.7309,
        22.6941, 17.8243], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])
第10000次训练,训练损失为3.7810146808624268
训练预测结果为tensor([23.9642, 20.4657, 29.9442, 32.6707, 34.3400, 27.2285, 20.6211, 19.3677,
        17.7232, 18.5607], grad_fn=<SliceBackward0>)
训练真实结果为tensor([24.0000, 21.6000, 34.7000, 33.4000, 36.2000, 28.7000, 22.9000, 27.1000,
        16.5000, 18.9000])
第10000次训练,测试损失为7.744905948638916
测试预测结果为tensor([19.1582, 20.7719, 22.6360, 19.5414, 21.7677, 23.4768, 19.0810, 24.2579,
        22.2269, 17.9408], grad_fn=<SliceBackward0>)
测试真实结果为tensor([19.7000, 18.3000, 21.2000, 17.5000, 16.8000, 22.4000, 20.6000, 23.9000,
        22.0000, 11.9000])

进程已结束,退出代码0

4、保存和加载

#  第一种保存和加载方法
torch.save(net.state_dict(), 'net_dict.pkl')   # 保存模型参数
net.load_state_dict(torch.load('net_dict.pkl'))   # 加载模型参数

#  第二种保存和加载方法
torch.save(net, 'net.pkl')   # 保存模型
torch.load('net.pkl')   # 加载模型

 加入保存代码后的完整代码:

import torch

# data   解析数据
import numpy as np
import re

ff = open('housing.data', 'r').readlines()  # 读取数据
print(ff)
data = []    # 存储数据
for item in ff:
    out = re.sub(r'\s{2,}', ' ', item).strip()   # 去除多余空格(将多个空格替换为一个空格)
    data.append(out.split(' '))    # 按照空格分割数据并添加到data中

data = np.array(data, dtype=np.float32)  # 转换为numpy数组
# print(data.shape)  # 打印数据形状  (506, 14)
Y = data[:, -1]  # 获取标签(所有行的最后一列)
X = data[:, 0:-1]  # 获取特征(所有行的除最后一列的所有列)

Y_train = Y[0:496, ...]  # 训练集标签
X_train = X[0:496, ...]  # 训练集特征
Y_test = Y[496:, ...]  # 测试集标签
X_test = X[496:, ...]  # 测试集特征

# print(Y_train.shape)  # 打印训练集标签形状  (496,)
# print(X_train.shape)  # 打印训练集特征形状  (496, 13)
# print(Y_test.shape)  # 打印测试集标签形状   (10,)
# print(X_test.shape)  # 打印测试集特征形状   (10, 13)


# net   # 搭建网络
class Net(torch.nn.Module):   # 定义网络
    def __init__(self, n_feature, n_output):   # 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):   # 前向传播
        y = self.hidden(x)   # 隐藏层
        y = torch.relu(y)   # 激活函数
        y = self.predict(y)
        return y


net = Net(13, 1)   # 实例化网络

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

# optimizer   # 优化器
optimizer = torch.optim.Adam(net.parameters(), lr=0.01)   # 定义优化器

# train   # 训练
train_x_data = torch.tensor(X_train, dtype=torch.float32)  # 将训练集特征转换为tensor
train_y_data = torch.tensor(Y_train, dtype=torch.float32)  # 将训练集标签转换为tensor
test_x_data = torch.tensor(X_test, dtype=torch.float32)  # 将测试集特征转换为tensor
test_y_data = torch.tensor(Y_test, dtype=torch.float32)  # 将测试集标签转换为tensor
for i in range(10000):   # 训练10000次
    pred_train = net.forward(train_x_data)   # 前向传播,返回的是一个二维tensor
    # print(pred.shape)   # 打印预测结果形状  (496, 1)
    pred_train = torch.squeeze(pred_train)   # 由于返回的是二维的tensor,所以需要去掉维度为1的维度
    loss_train = loss_func(pred_train, train_y_data)  # 计算损失
    optimizer.zero_grad()   # 清空上一次的梯度
    loss_train.backward()   # 反向传播
    optimizer.step()   # 优化器更新参数
    # test   # 测试
    pred_test = net.forward(test_x_data)
    pred_test = torch.squeeze(pred_test)
    loss_test = loss_func(pred_test, test_y_data)  # 计算损失
    if (i+1) % 1000 == 0:   # 每1000次打印一次损失
        print('第{}次训练,训练损失为{}'.format(i + 1, loss_train))
        print('训练预测结果为{}'.format(pred_train[:10]))
        print('训练真实结果为{}'.format(train_y_data[:10]))
        print('第{}次测试,测试损失为{}'.format(i + 1, loss_test))
        print('测试预测结果为{}'.format(pred_test[:10]))
        print('测试真实结果为{}'.format(test_y_data[:10]))

# #  第一种保存和加载方法
# torch.save(net.state_dict(), 'net_dict.pkl')   # 保存模型参数
# net.load_state_dict(torch.load('net_dict.pkl'))   # 加载模型参数

#  第二种保存和加载方法
torch.save(net, 'net.pkl')   # 保存模型
# torch.load('net.pkl')   # 加载模型
print('已保存')

5、推理

新建inference.py,输入:

import torch
# from demo_net import Net   # 使用这种方法会重复训练
# data   解析数据
import numpy as np
import re


class Net(torch.nn.Module):   # 定义网络   # 将之前定义的网络复制过来
    def __init__(self, n_feature, n_output):   # 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):   # 前向传播
        y = self.hidden(x)   # 隐藏层
        y = torch.relu(y)   # 激活函数
        y = self.predict(y)
        return y


ff = open('housing.data', 'r').readlines()  # 读取数据
data = []    # 存储数据
for item in ff:
    out = re.sub(r'\s{2,}', ' ', item).strip()   # 去除多余空格(将多个空格替换为一个空格)
    data.append(out.split(' '))    # 按照空格分割数据并添加到data中

data = np.array(data).astype(np.float32)  # 转换为numpy数组
# print(data.shape)  # 打印数据形状  (506, 14)
Y = data[:, -1]  # 获取标签(所有行的最后一列)
X = data[:, :-1]  # 获取特征(所有行的除最后一列的所有列)

Y_train = Y[0:496, ...]  # 训练集标签
X_train = X[0:496, ...]  # 训练集特征
Y_test = Y[496:, ...]  # 测试集标签
X_test = X[496:, ...]  # 测试集特征

net = torch.load('net.pkl')
loss_func = torch.nn.MSELoss()   # 定义损失函数(均方误差)

test_x_data = torch.tensor(X_test, dtype=torch.float32)   # 将测试集特征转换为tensor
test_y_data = torch.tensor(Y_test, dtype=torch.float32)   # 将测试集标签转换为tensor
pred_test = net.forward(test_x_data)
pred_test = torch.squeeze(pred_test)
loss_test = loss_func(pred_test, test_y_data)  # 计算损失

print('测试集预测结果:', pred_test)
print('测试集实际结果:', Y_test)
print('测试集损失:', loss_test)   # 打印测试集损失

 运行后,直接得出了推理结果:

测试集预测结果: tensor([17.9976, 20.7273, 22.6870, 19.7387, 22.0204, 23.5350, 19.9008, 23.2567,
        22.4825, 18.6679], grad_fn=<SqueezeBackward0>)
测试集实际结果: [19.7 18.3 21.2 17.5 16.8 22.4 20.6 23.9 22.  11.9]
测试集损失: tensor(9.1494, grad_fn=<MseLossBackward0>)

存疑:在推理的脚本里使用torch.load()调用之前自定义并保存的网络,如使用from demo_net import Net的方法调用,运行推理脚本后,则会又执行一次训练过程。而将之前定义的网络直接复制到推理脚本则不会。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/889753.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nullinux:一款针对Linux操作系统的安全检测工具

关于Nullinux Nullinux是一款针对Linux操作系统的安全检测工具&#xff0c;广大研究人员可以利用该工具针对Linux目标设备执行网络侦查和安全检测。 该工具可以通过SMB枚举目标设备的安全状况信息&#xff0c;其中包括操作系统信息、域信息、共享信息、目录信息和用户信息。如…

第四次论文问题知识点及问题

1、NP-hard问题 NP-hard&#xff0c;指所有NP问题都能在多项式时间复杂度内归约到的问题。 2、启发式算法 ‌‌启发式算法&#xff08;heuristic algorithm&#xff09;是相对于最优化算法提出的。它是一种基于直观或经验构造的算法&#xff0c;旨在以可接受的花费给出待解决…

『网络游戏』进入游戏主城UI跳转主城【26】

首先在Unity客户端中创建一个空节点重命名为MainCityWnd 设置父物体为全局 创建空节点钉在左上角作为角色信息UI 在钉子下创建Image 创建脚本&#xff1a;MainCityWnd.cs 编写脚本&#xff1a;MainCityWnd.cs 挂载脚本 创建脚本&#xff1a;MainCitySys.cs 编写脚本&#xff1a…

Java中二维数组-杨辉三角

使用二维数组打印一个10行杨辉三角 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1&#xff09;第一行有1个元素&#xff0c;第n行有n个元素 2&#xff09;每一行的第一个元素和最后一个元素都是1 3&#xff09;从第三行开始&#xff0c;对于非第一个元素和最后一个元素的元素…

商贸物流痛点解析

商贸物流痛点解析 在当今全球化的商业环境中&#xff0c;商贸与物流之间的紧密协作已成为业务成功的关键因素。然而&#xff0c;许多组织面临着信息不对称、资源配套不足以及系统间隔离等痛点&#xff0c;这些问题严重阻碍了商贸体系与物流、仓储和园区的有效联动&#xff0c;…

[mysql]多表查询详解

我们如果要查询,我们就要用 SELECT .... FROM .... WHERE AND/OR/NOT #我们需要用过滤的条件来对数据进行筛选,不然会有很多多余数据 ORDER BY (ASC/DESC)#排序 LIMIT....,#是在几个有限的数据库管理系统里所以,PGsql,mysql,等 多表查询的意义 我们目前为止的查询语句…

linux 安装gitlab

安装环境 CentOS 7.7 (centos6.10会报错)2g内存防火墙关闭 安装步骤&#xff1a; 1 安装gitlab # yum install -y git curl policycoreutils-python openssh-server # 安装依赖 # wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.2.2-ce…

IPv 4

IP协议 网络层主要由IP&#xff08;网际协议&#xff09;和ICMP&#xff08;控制报文协议&#xff09;构成&#xff0c;对应OSI中的网络层&#xff0c;网络层以实现逻辑层面点对点通信为目的。目前应用最广泛的IP协议为IPv4 基本概念给出 主机&#xff1a;配有IP地址但不具有路…

【原创】java+springboot+mysql劳动教育网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【数据结构-栈】【贪心】力扣2434. 使用机器人打印字典序最小的字符串

给你一个字符串 s 和一个机器人&#xff0c;机器人当前有一个空字符串 t 。执行以下操作之一&#xff0c;直到 s 和 t 都变成空字符串&#xff1a; 删除字符串 s 的 第一个 字符&#xff0c;并将该字符给机器人。机器人把这个字符添加到 t 的尾部。 删除字符串 t 的 最后一个 …

让AI像人一样思考和使用工具,reAct机制详解

reAct机制详解 reAct是什么reAct的关键要素reAct的思维过程reAct的代码实现查看效果引入依赖&#xff0c;定义模型定义相关工具集合工具创建代理启动测试完整代码 思考 reAct是什么 reAct的核心思想是将**推理&#xff08;Reasoning&#xff09;和行动&#xff08;Acting&…

SDH8303直插DIP8,7W-12W非隔离升压降压转换器

SDH8303是用于开关电源的内置高压 MOSFET 的电流模式 PWM 控制器&#xff0c;采用DIP-8封装&#xff0c;全电压下典型功率7W-12W。 SDH8303芯片内置高压启动电路&#xff0c;在轻载下会进入打嗝模式&#xff0c;具有降频、抖频、软启动、VDD 打嗝功能&#xff0c;还集成了 VDD …

猿人学 — 第1届第17题(解题思路附源码)

猿人学 — 第1届第17题 根据题目“天杀的Http2.0”大概知道&#xff0c;请求的协议应该遵照的是Http2.0协议&#xff0c;并且目标网站专门对此进行了检测&#xff0c;在Network面板中右键表头&#xff0c;勾选Protocol 果不其然&#xff0c;一堆请求都是遵照Http2.0协议。而u…

论文阅读 BLIP-2

Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 使用冻结的图像编码器和大型语言模型进行语言-图像预训练的引导 BLIP-2 通过一个轻量级的查询变换器弥合了模态之间的差距。 Querying Transformer 第一阶段通过冻结的图像编…

Word排版 | 如何文字部分固定行距、图片(嵌入型)单倍行距

问题描述 在写一个要求比较高的项目报告&#xff0c;总共有109页 89张图片&#xff0c;而且必须用word写 因此&#xff1a; 文字部分需要固定行距23磅图片部分需要单倍行距&#xff08;不然无法使用嵌入式&#xff09; 难点 文字和图片难以有效分离&#xff0c;无法分别设…

3D渲图软件推荐:打造高质量渲染效果

在现代设计领域&#xff0c;3D渲图已经成为展示设计方案和产品外观的重要手段。无论是建筑设计、产品设计还是影视动画&#xff0c;都需要借助专业的3D渲染图软件来实现逼真的视觉效果。 本文将为您介绍几款备受好评的3D渲染图软件&#xff0c;帮助您在项目中选择合适的工具。…

筛选因数快速法+map

前言&#xff1a;老是忘记怎么快速筛选因数&#xff0c;我们只需要枚举小于sqrt&#xff08; num &#xff09; 的数&#xff0c;这样可以降低很多复杂度&#xff0c;而且我们的因数一定是成对出现的&#xff0c;所以我们遇到一个因数的时候x&#xff0c;判断 x 2 x^2 x2 是否…

【华为】配置RIP协议

RIP&#xff08;Routing Information Protocol&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;主要用于小型网络中的动态路由。RIP有两个主要版本&#xff1a;‌RIPv1和‌RIPv2&#xff0c;它们之间存在一些关键区别&#xff1a; ‌分类支持‌&#xf…

STM32之CAN外设

相信大家在学习STM32系列的单片机时&#xff0c;在翻阅芯片的数据手册时&#xff0c;都会看到这么一个寄存器外设——CAN外设寄存器。那么&#xff0c;大家知道这个外设的工作原理以及该如何使用吗&#xff1f;这节的内容将会详细介绍STM32上的CAN外设&#xff0c;文章结尾附有…

树的中心——dfs

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e510, M N*2; int h[N], e[M], ne[M], idx; int n; int ans 2e9; bool st[N]; void add(int a, int b) // 添加一条边a->b {e[idx] b, ne[idx] h[a], h[a] idx ; } int dfs(int u) {int…