PyTorch多层感知器(MLP)实现报错求助:TypeError问题排查
PyTorch MLP TypeError 解决方法
错误根源
报错TypeError: cross_entropy_loss(): argument 'input' (position 1) must be Tensor, not NeuralNet,核心原因是模型调用方式错误,导致传入损失函数的不是模型输出的张量,而是模型本身;同时代码里还有其他几处逻辑错误,共同引发了这个问题。
具体错误点及修正方案
Forward函数逻辑错误
原代码中forward函数最后一行out = self.l3(out),out未定义,应该用经过前两层处理后的x,并且要返回计算结果:def forward(self, x): x = torch.relu(self.l1(x)) x = torch.relu(self.l2(x)) out = self.l3(x) # 替换未定义的out为前一层输出x return out # 必须返回模型输出张量模型调用方式错误
model.to(features)是将模型移动到指定设备(CPU/GPU)的方法,不是执行前向传播的方式。正确的前向传播应该直接调用model(features),同时要先把输入张量调整为符合模型输入要求的形状,并移动到对应设备:# 先处理输入:调整形状并移到目标设备 features = features.reshape(-1, input_size*input_size).to(device) # 正确执行前向传播得到输出 outputs = model(features)损失计算重复且错误
原代码重复计算损失,还错误使用了不存在的torch.criterion属性。既然已经定义了criterion = nn.CrossEntropyLoss(),直接用它计算损失即可:# 删掉以下两行错误代码: # loss = torch.nn.CrossEntropyLoss()(outputs, labels) # loss = torch.criterion(outputs, labels) # 替换为: loss = criterion(outputs, labels)冗余的梯度清零操作
循环开头已经调用了optimizer.zero_grad(),后面反向传播前的重复调用可以删除,避免冗余操作。
完整修正后的代码
import torch import torch.nn as nn # Hyper-parameters input_size = 48 hidden_size = 16 num_classes = 4 num_epochs = 2 batch_size = 15 learning_rate = 0.001 # 定义计算设备 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') class NeuralNet(nn.Module): def __init__(self, input_size, hidden_size, num_classes): super(NeuralNet, self).__init__() self.l1 = nn.Linear(input_size*input_size, input_size) self.l2 = nn.Linear(input_size, hidden_size) self.l3 = nn.Linear(hidden_size, num_classes) def forward(self, x): x = torch.relu(self.l1(x)) x = torch.relu(self.l2(x)) out = self.l3(x) return out # 初始化模型并移到目标设备 model = NeuralNet(input_size, hidden_size, num_classes).to(device) print(model) # 训练配置 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) # 训练模型 n_total_steps = len(trainloader) for epoch in range(num_epochs): for i, (features, labels) in enumerate(trainloader): optimizer.zero_grad() # 预处理输入张量 features = features.reshape(-1, input_size*input_size).to(device) labels = labels.to(device) # 前向传播 outputs = model(features) # 计算损失 loss = criterion(outputs, labels) # 反向传播与优化 loss.backward() optimizer.step() if (i+1) % 100 == 0: print (f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{n_total_steps}], Loss: {loss.item():.4f}')
内容的提问来源于stack exchange,提问作者Mohammad Asim
相关产品推荐
相关产品推荐

