首页 > 编程问答 >Pytorch从基础数据中学习时出现巨大损失

Pytorch从基础数据中学习时出现巨大损失

时间:2024-07-23 10:49:27浏览次数:12  
标签:python pytorch

我正在尝试制作一个非常基本的机器学习应用程序,基本上我希望模型能够根据我提供的虚拟数据尝试预测明年的每个月,但我遭受了巨大的损失 Loss: 5206342.5000 并且预测值与我的预期相差如此之远 Predicted values for each month of next year: [-0.043424129486083984, 0.041442010551691055, -0.16847632825374603, -0.18227830529212952, 0.4619046151638031, 1.128817081451416, 0.05658513307571411, 0.1113058477640152, 0.2900705337524414, 0.21394489705562592, 0.2618725001811981, 0.3829265236854553] 我对机器学习非常陌生,为什么我会看到如此巨大的损失和如此错误的预测值?

import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import numpy as np

# Example historical data (replace with your actual data loading)
data = {
    'ProjectId': ['666d60f2604698f1383d94e4', '666d60e2604698f1383d9495', '666d5fb1604698f1383d8e8f'],
    'Year': ['2023/2024', '2023/2024', '2023/2024'],
    'July': [0, 0, 0],
    'August': [0, 0, 0],
    'September': [0, 0, 0],
    'October': [0, 0, 0],
    'November': [0, 0, 0],
    'December': [10000, 5000, 100000],
    'January': [0, 0, 120000],
    'February': [0, 0, 0],
    'March': [0, 0, 0],
    'April': [0, 0, 0],
    'May': [0, 0, 0],
    'June': [0, 0, 0]
}

df = pd.DataFrame(data)

# Example: Extract X (input features) and y (target values)
X = df.drop(['ProjectId', 'Year'], axis=1).values.astype(np.float32)  # Convert to float32
y = df.drop(['ProjectId', 'Year'], axis=1).values.astype(np.float32)  # Assuming y includes next year's forecast

# Example: Splitting into training and validation sets
# Assume last row for validation, rest for training
X_train = torch.tensor(X[:-1], dtype=torch.float32).unsqueeze(0)  # Add batch dimension (1 sample)
y_train = torch.tensor(y[:-1], dtype=torch.float32).unsqueeze(0)  # Add batch dimension (1 sample)
X_val = torch.tensor(X[-1:], dtype=torch.float32).unsqueeze(0)  # Example single project for validation

# Define LSTM model for forecasting
class LSTMForecast(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(LSTMForecast, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        lstm_out, _ = self.lstm(x)
        out = self.fc(lstm_out[:, -1, :])  # Predict based on the last LSTM output
        return out

# Initialize the model, loss function, and optimizer
input_size = X_train.shape[-1]
hidden_size = 64
output_size = y_train.shape[-1]

model = LSTMForecast(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
num_epochs = 100
for epoch in range(num_epochs):
    optimizer.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    loss.backward()
    optimizer.step()

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# Example: Making predictions for next year's forecast
model.eval()
with torch.no_grad():
    forecast = model(X_val)
    forecast_values = forecast.numpy().tolist()[0]  # Convert to numpy and list

print(f'Predicted values for each month of next year: {forecast_values}')

你代码中有一些问题导致损失很大,预测不准确:

  1. 输入和目标数据相同: 你正在使用 X 作为输入特征, y 作为目标值,但两者都是从 df.drop(['ProjectId', 'Year'], axis=1) 中获取的。这意味着你的模型试图根据自身来预测月份值,这没有意义,会导致模型过度拟合训练数据,并且不能很好地推广到未见过的数据。

  2. 训练数据不足: 你只有 3 个数据点用于训练,这对于 LSTM 来说太少了,不足以学习数据中的任何有意义的模式。

  3. 数据缩放: 你的数据范围很大(从 0 到 120000)。在将数据输入 LSTM 之前,对数据进行缩放(例如,使用 MinMaxScaler 或 StandardScaler)可能会有所帮助,以提高训练稳定性。

  4. 缺少验证: 你没有使用验证集来跟踪模型在训练过程中的性能。验证集有助于检测过度拟合,并可以提供对模型在未见过的数据上的性能的更好估计。

以下是如何解决这些问题以及如何改进代码的方法:

import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

# Example historical data (replace with your actual data loading)
data = {
    'ProjectId': ['666d60f2604698f1383d94e4', '666d60e2604698f1383d9495', '666d5fb1604698f1383d8e8f'],
    'Year': ['2023/2024', '2023/2024', '2023/2024'],
    'July': [0, 0, 0],
    'August': [0, 0, 0],
    'September': [0, 0, 0],
    'October': [0, 0, 500],
    'November': [1000, 2000, 1500],
    'December': [10000, 5000, 100000],
    'January': [12000, 6000, 120000],
    'February': [0, 0, 0],
    'March': [0, 0, 0],
    'April': [0, 0, 0],
    'May': [0, 0, 0],
    'June': [0, 0, 0]
}

df = pd.DataFrame(data)

# Data Preprocessing
# Assuming 'July' to 'June' are current year data, 
# and we want to predict 'July' to 'June' of next year
data = df.drop(['ProjectId', 'Year'], axis=1).values.astype(np.float32)

# Scale the data
scaler = MinMaxScaler()
data = scaler.fit_transform(data)

# Create input-output pairs with a sliding window
sequence_length = 6  # Use past 6 months to predict next 6 months
X, y = [], []
for i in range(len(data) - sequence_length):
    X.append(data[i:i+sequence_length])
    y.append(data[i+sequence_length:i+2*sequence_length])
X = np.array(X)
y = np.array(y)

# Split data into training and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# Convert to PyTorch tensors
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)
X_val = torch.tensor(X_val, dtype=torch.float32)
y_val = torch.tensor(y_val, dtype=torch.float32)

# Define LSTM model for forecasting
class LSTMForecast(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(LSTMForecast, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        lstm_out, _ = self.lstm(x)
        out = self.fc(lstm_out[:, -1, :])  # Predict based on the last LSTM output
        return out

# Initialize the model, loss function, and optimizer
input_size = X_train.shape[-1]
hidden_size = 64
output_size = y_train.shape[-1]

model = LSTMForecast(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
num_epochs = 100
for epoch in range(num_epochs):
    # Training
    model.train()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    # Validation
    model.eval()
    with torch.no_grad():
        val_outputs = model(X_val)
        val_loss = criterion(val_outputs, y_val)

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {loss.item():.4f}, Val Loss: {val_loss.item():.4f}')

# Example: Making predictions
model.eval()
with torch.no_grad():
    forecast = model(X_val)
    forecast = scaler.inverse_transform(forecast.numpy())  # Inverse transform to get original scale
    print(f'Predicted values: {forecast}')

改进之处:

  • 数据预处理:
    • 使用滑动窗口创建输入-输出对,其中过去 6 个月的值用于预测未来 6 个月的值。
    • 使用 MinMaxScaler 对数据进行缩放,使其范围在 0 到 1 之间,从而提高训练稳定性。
  • 训练数据: 通过使用滑动窗口,我们从现有数据中创建了更多数据点,从而为 LSTM 提供了更多学习内容。
  • 验证集: 我们将数据分成训练集和验证集,以跟踪训练过程中的性能,并更好地估计模型在未见过的数据上的性能。
  • 逆缩放: 在进行预测后,我们使用 inverse_transform 方法将预测值缩放回其原始比例。

这些更改应该会带来更低的损失和更准确的预测。但是,请记住,LSTM 在时间序列预测方面非常强大,但它们需要大量数据才能有效。考虑收集更多数据以进一步改进你的模型。

标签:python,pytorch
From: 78778376

相关文章

  • 使用递归函数计算阶乘时,我在 python 中遇到类型错误
    defcalc_fact(n):如果(n==1或n==0):返回1别的:n*calc_fact(n-1)print(calc_fact(5))试图创建函数来计算阶乘,不支持类型错误操作数*:对于int或Nonetype我不知道为什么谢谢Python代码中出现“类型错误:不支持的操作数类型为*:'int'和'NoneType'”表明你......
  • 如何调试 python Flask [84] [CRITICAL] WORKER TIMEOUT?
    调试:gtts.tts:保存到temp.mp37月22日09:10:56PM[2024-07-2215:40:56+0000][84][严重]工作超时(pid:87)|||7月22日09:10:56PM[2024-07-2215:40:56+0000][87][INFO]工人退出(pid:87)7月22日09:10:57PM[2024-07-2215:40:57+0000][95][INF......
  • 类型错误:无法将函数返回值转换为 Python 类型!签名是 () -> 处理 anaconda spider
    这是代码:importosimportrandomimportnumpyasnpimportpandasaspdimporttensorflowastffromtensorflow.kerasimportbackendasKfromtensorflow.keras.layersimportDense,Dropout,Flatten,Conv2D,MaxPool2D,Input......
  • python进阶---闭包与装饰器
    一、闭包        在Python中,闭包是指一个函数内部定义的函数,这个内部函数可以访问并修改其外部函数的局部变量,即使外部函数已经执行完毕。闭包可以通过多层函数嵌套来实现。    闭包的三要素:    1、外部函数嵌套内部函数    2、外部函数返......
  • PyTorch LSTM 模型上的 CrossEntropyLoss,每个时间步一分类
    我正在尝试创建一个LSTM模型来检测时间序列数据中的异常情况。它需要5个输入并产生1个布尔输出(如果检测到异常则为True/False)。异常模式通常连续3-4个时间步长。与大多数LSTM示例不同,它们预测未来数据或对整个数据序列进行分类,我尝试在每个时间步输出True/False检......
  • 我如何为 yolov5 制作 gui,从 pytorch 和 opencv 加载到 tkinker?
    请帮助我,我不明白如何使用yolo和tkinker作为gui来制作用于实时检测的gui。以及如何将边界框从pytorch渲染到tkinker?这里是代码:importtorchfrommatplotlibimportpyplotaspltimportnumpyasnpimportcv2model=torch.hub.load('ultralytics/yolov5......
  • 强制从当前包自动导入的 Python 以此包的名称为前缀
    我在VSCode中使用Python和Pylance扩展。在我正在编辑的自己的包中,自动添加的导入(设置“导入格式:绝对”)如下所示:frommydirectory.myfileimportmyclass但是,我的Python包正在被被一个(非常愚蠢且不可协商的)外部系统消耗,该系统拒绝正确解释它,除非导入的格式特别......
  • Python语言-面向对象
    知识代码classJobSalary(object):job=''def__init__(self,city):self.jobname="数据分析师"self.exp=''self.city=city#方法defdata_normalize(self,data):print(f'正在规范化......
  • 需要帮助使用 Selenium Python 单击 Microsoft Teams 按钮
    我将Python与Selenium结合使用,并自动登录MicrosoftTeams。进入后,弹出窗口显示我需要单击“立即切换”以切换到V2版本。我似乎无法使用SeleniumPython成功单击此按钮。谁能帮我自动点击这个按钮?这是我不成功的尝试:self.driver.find_element(By.CLASS_NAME,......
  • python接口自动化(四十)- logger 日志 - 下(超详解)
    宏哥微信粉丝群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介按照上一篇的计划,这一篇给小伙伴们讲解一下:(1)多模块使用logging,(2)通过文件配置logging模块,(3)自己封装一个日志(logging)类。可能有的小伙伴在这里会有个疑问一个logging为什么分两篇的篇幅......