PyTorch Lightning搭建MLP模拟正弦波报缺少training_step方法如何解决
问题排查与修复方案
核心报错原因
你遇到的报错本质是类方法缩进错误,所有Lightning要求实现的方法都没有定义在MLP类的内部,导致实例化的模型对象缺失必要的成员方法。
MisconfigurationException: No
training_step()method defined. LightningTrainerexpects as minimum atraining_step(),train_dataloader()andconfigure_optimizers()to be defined.
所有需要修正的问题点
- 缩进错误:
forward、train_dataloader、training_step等方法全部写在了MLP类的外部,不属于类成员,Lightning无法从模型实例中读取到这些方法。 - 缺失导入:代码中使用了
TensorDataset,但没有从torch.utils.data导入该类,运行会触发NameError。 - 错误列名引用:你的数据集标签列名为
y,但代码中写的是train_targets[['cnt']],不存在的cnt列会触发KeyError。 - 激活函数拼写错误:PyTorch的ReLU激活函数为小写的
torch.relu(),你写的torch.Relu首字母大写错误,会触发属性查找失败。 - 浮点数相等判断逻辑错误:
test_step中用logits == y.data判断相等不符合浮点数计算逻辑,存在精度误差时永远返回False,需要用torch.isclose设置容差判断。 - 未定义全局变量:
test_step中用到的predictions_pred、predictions_actual没有提前初始化,运行会触发NameError。
修正后的核心代码
import numpy as np import torch import matplotlib.pyplot as plt import pytorch_lightning as pl import torch.optim as optim from torch import nn from pytorch_lightning import Trainer from sklearn.model_selection import train_test_split import pandas as pd from torch.utils.data import DataLoader, TensorDataset # 补导入TensorDataset # 数据生成部分保持不变 N=1000 x = np.random.randn(1000) y = np.sin(x) df = pd.DataFrame({'x':x, 'y':y}) train, test = train_test_split(df, test_size=0.2, random_state=42, shuffle=True) target_fields=['y'] train_features, train_targets = train.drop(target_fields, axis=1), train[target_fields] test_features, test_targets = test.drop(target_fields, axis=1), test[target_fields] # 修正类结构与缩进 class MLP(pl.LightningModule): def __init__(self): super(MLP,self).__init__() self.fc1 = nn.Linear(1, 10) self.fc2 = nn.Linear(10, 1) self.l_rate = 0.2 self.mse_loss = nn.MSELoss(reduction = 'mean') # 初始化预测存储列表 self.predictions_pred = [] self.predictions_actual = [] def forward(self, x): x = torch.relu(self.fc1(x)) # 修正ReLU拼写 x = self.fc2(x) return x def train_dataloader(self): # 修正标签列名 train_dataset = TensorDataset(torch.tensor(train_features.values).float(), torch.tensor(train_targets[['y']].values).float()) train_loader = DataLoader(dataset = train_dataset, batch_size = 128, shuffle=True) return train_loader def test_dataloader(self): test_dataset = TensorDataset(torch.tensor(test_features.values).float(), torch.tensor(test_targets[['y']].values).float()) test_loader = DataLoader(dataset = test_dataset, batch_size = 128) return test_loader def configure_optimizers(self): return optim.SGD(self.parameters(), lr=self.l_rate) def training_step(self, batch, batch_idx): x, y = batch logits = self.forward(x) loss = self.mse_loss(logits, y) self.log('train_loss', loss, prog_bar=True) # Lightning官方推荐的日志写法 return loss def test_step(self, batch, batch_idx): x, y = batch logits = self.forward(x) loss = self.mse_loss(logits, y) # 修正浮点数相等判断逻辑 correct = torch.sum(torch.isclose(logits, y.data, atol=1e-3)) self.predictions_pred.append(logits) self.predictions_actual.append(y.data) self.log('test_loss', loss) return {'test_loss': loss, 'test_correct': correct} def test_epoch_end(self, outputs): avg_loss = torch.stack([x['test_loss'] for x in outputs]).mean() self.log('avg_test_loss', avg_loss, prog_bar=True) # 运行训练 model = MLP() trainer = Trainer(max_epochs = 50) trainer.fit(model)
内容的提问来源于stack exchange,提问作者Anilaaryan
相关产品推荐
相关产品推荐

