任务背景
给定未来一段时间的温度,使用神经网络预测输出是天气炎热,温暖,凉爽,偏冷,寒冷
输入是未来 20天内的气温数据,输出标签是 0,1,2,3,4
代码
"""
@Author : 琛歌很无聊
@Description: 使用 Pytorch的简单demo:给定一段时间的温度,输出是天气炎热,温暖,凉爽,偏冷,寒冷
输入是未来 20天内的气温数据,输出标签是 0,1,2,3,4
"""
import numpy as np
import torch
import torch.utils.data as Data
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
def getlabel(X): # 获取样本对应的标签
Y = np.zeros(len(X))
for i in range(len(X)):
if np.mean(X[i]) > 30:
Y[i] = 0 # 平均温度大于30时,标签设置为炎热(0)
elif np.mean(X[i]) > 20:
Y[i] = 1
elif np.mean(X[i]) > 10:
Y[i] = 2
elif np.mean(X[i]) > 0:
Y[i] = 3
else:
Y[i] = 4
return Y
class MyDataset(Data.Dataset): # 继承父类
def __init__(self, train_x, train_y):
self.train_x = train_x
self.train_y = train_y
def __getitem__(self, item):
return self.train_x[item], self.train_y[item]
def __len__(self):
return len(self.train_y)
class MyNeuralNet(nn.Module): # 继承父类
def __init__(self, input_dim, output_dim):
super(MyNeuralNet, self).__init__()
self.activation = nn.ReLU() # 激活函数
# 定义网络
self.n1 = nn.Linear(input_dim, 16)
self.n2 = nn.Linear(16, 8)
self.n3 = nn.Linear(8, output_dim)
def forward(self, x):
'''
:param x: 输入矩阵
:return: 网络输出值
'''
y = self.n1(x)
y = self.activation(y)
y = self.n2(y)
y = self.n3(y)
return y
'''
1.获取训练集和测试集
'''
train_X = np.random.uniform(33, 42, (100, 20)) # 随机生成温度值域[33,42),大小为100*20的数组,100是样本数,20是维度数
train_X = np.append(train_X, np.random.uniform(19, 35, (100, 20)), axis=0) # np.append是数组拼接
train_X = np.append(train_X, np.random.uniform(5, 24, (100, 20)), axis=0) # np.append是数组拼接
train_X = np.append(train_X, np.random.uniform(-2, 11, (100, 20)), axis=0) # np.append是数组拼接
train_X = np.append(train_X, np.random.uniform(-15, 3, (100, 20)), axis=0) # np.append是数组拼接
train_Y = getlabel(train_X)
# print(train_Y)
print("训练集输入的大小为:", np.shape(train_X))
test_X = np.random.uniform(30, 40, (1, 20))
test_Y=getlabel(test_X)
'''
2.加载数据集和加载模型
'''
train_X = torch.Tensor(train_X) # 将array转成Tensor,float类型
train_Y = torch.LongTensor(train_Y) # LongTensor中数字是整数
test_X = torch.Tensor(test_X) # 将array转成Tensor,float类型
train_dataset = MyDataset(train_x=train_X, train_y=train_Y)
train_loader = Data.DataLoader(train_dataset, batch_size=16, shuffle=True) # batch_size控制一批样本的数量,shuffle控制是否打乱样本取样
model = MyNeuralNet(input_dim=20, output_dim=5) # 定义模型网络
loss_fun = nn.CrossEntropyLoss() # 定义损失函数
optimizer = optim.AdamW(model.parameters(), lr=1e-3) # lr是学习率
'''
3.在模型上训练
'''
max_epoch = 100
loss_list = []
for epoch in range(max_epoch):
for i, (x, y) in enumerate(train_loader):
predict_y = model(x) # 1.做向前计算
loss = loss_fun(predict_y, y) # 2.计算损失函数
optimizer.zero_grad() # 3.清除网络状态
loss.backward() # 4.loss反向传播
optimizer.step() # 5.更新网络参数
# 输出Loss,并存储
print(loss)
loss_list.append(loss.item())
'''
4.绘制损失函数曲线图
'''
print(loss_list)
plt.plot(loss_list)
plt.title("loss")
plt.show()
'''
5.使用训练好的模型进行泛化测试
'''
print("测试集是\n", test_X)
predict_Y = model(test_X)
predict_Y = torch.softmax(predict_Y, dim=1) # 将输出值映射到[0,1]概率分布区间
predict_Y = predict_Y[0].detach().numpy() # Tensor转数组array
predict_Y = np.round(predict_Y * 100, 3) # 乘以100为百分比,保留3位小数
print("预测标签概率分布")
print(predict_Y)
print("预测标签值")
print(np.argmax(predict_Y, 0)) # 取最大值的下标为预测值
print("实际标签值")
print(test_Y)
结果展示
测试集是
tensor([[38.7667, 37.0874, 30.7980, 34.7945, 37.9251, 39.0055, 37.2950, 38.5757,
30.0081, 36.3308, 38.7851, 39.2595, 35.2415, 38.8545, 35.7583, 32.1818,
35.3024, 32.5636, 32.8940, 34.4463]])
预测标签概率分布
[99.759 0.241 0. 0. 0. ]
预测标签值
0
实际标签值
[0.]
代码讲解地址
https://www.bilibili.com/video/BV1KX4y177x8/?spm_id_from=333.999.0.0&vd_source=de24eb60706a87145c55dda9edb79815