MNIST全连接神经网络准确率无变化问题排查求助
排查MNIST全连接网络准确率无变化的问题
以下是代码中导致准确率无变化的核心问题及修正方案:
核心错误点
- 输入特征维度完全错误:MNIST的图片是28×28的灰度图,经过
nn.Flatten()后每个样本的特征维度应为28*28=784,但你代码中所有nn.Linear的in_features=2,相当于只使用了输入数据的前2个特征,完全丢弃了图像的绝大多数信息,模型根本无法学习数字特征。 - 最后一层错误添加激活函数:
CrossEntropyLoss内部已包含Softmax操作,要求输入是未经过激活的logits。你在最后一层输出后添加nn.ELU(),会破坏输出分布,导致损失计算异常,模型无法正确优化。 - 冗余重复定义:代码重复定义了
model、criterion、optimizer等变量,虽不影响运行,但会造成代码混乱,需删除重复部分。 - 未将模型和数据移至指定设备:定义了
device但未将模型、输入数据移至对应设备,既不规范也会影响运行效率。 - 不必要的切片操作:
outp = outp[:y_batch.shape[0]]完全多余,DataLoader返回的x_batch和y_batch数量天然匹配,该操作可能引发潜在错误。
修正后的完整代码
import torch import torch.nn as nn from torchvision.datasets import MNIST from torchvision import transforms as tfs # 数据预处理 data_tfs = tfs.Compose([ tfs.ToTensor(), tfs.Normalize((0.5,), (0.5,)) # 修正:添加逗号确保元组格式正确 ]) root = './' train_dataset = MNIST(root, train=True, transform=data_tfs, download=True) val_dataset = MNIST(root, train=False, transform=data_tfs, download=True) train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True) valid_dataloader = torch.utils.data.DataLoader(val_dataset, batch_size=128, shuffle=False) # 定义模型 model = nn.Sequential( nn.Flatten(), nn.Linear(in_features=784, out_features=128), # 修正:输入维度改为784 nn.ELU(), nn.Linear(in_features=128, out_features=10) # 修正:移除最后一层的ELU激活 ) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters()) loaders = {"train": train_dataloader, "valid": valid_dataloader} device = "cuda" if torch.cuda.is_available() else "cpu" model.to(device) # 将模型移至指定设备 max_epochs = 10 accuracy = {"train": [], "valid": []} for epoch in range(max_epochs): for k, dataloader in loaders.items(): epoch_correct = 0 epoch_all = 0 for x_batch, y_batch in dataloader: # 将数据移至指定设备 x_batch = x_batch.to(device) y_batch = y_batch.to(device) if k == "train": model.train() optimizer.zero_grad() outp = model(x_batch) else: model.eval() with torch.no_grad(): outp = model(x_batch) preds = outp.argmax(-1) correct = (preds == y_batch).sum() all = preds.shape[0] epoch_correct += correct.item() epoch_all += all if k == "train": loss = criterion(outp, y_batch) loss.backward() optimizer.step() if k == "train": print(f"Epoch: {epoch+1}") epoch_acc = epoch_correct / epoch_all print(f"Loader: {k}. Accuracy: {epoch_acc:.4f}") accuracy[k].append(epoch_acc)
内容的提问来源于stack exchange,提问作者tehnofury
相关产品推荐
相关产品推荐

