如何训练神经网络将单个自然数转换为one-hot编码向量
解决自然数转One-Hot编码的神经网络训练问题
核心问题分析
你的代码存在几个关键错误,导致网络无法学到正确的映射关系:
- 输入与标签完全颠倒:数据集里
input列是待转换的自然数,但训练时你误把label列当输入、input列当标签,网络完全学错了映射目标。 - Softmax使用错误:
CrossEntropyLoss已经内置了LogSoftmax的计算逻辑,手动添加Softmax会导致损失计算偏差;且dim=0的维度设置不符合单样本/批量输入的要求。 - 不必要的Dropout干扰:这个任务是简单的一对一映射,Dropout会降低训练效率,完全没必要使用。
- 训练轮数不足:仅5轮训练远不足以让网络收敛到最优状态。
- 单样本训练效率低下:循环逐个处理样本的方式慢且没必要,批量处理才是PyTorch的标准用法。
修正后的完整代码
import pandas as pd import torch import torch.nn as nn import torch.optim as optim from sklearn.model_selection import train_test_split import random random.seed(0) torch.manual_seed(0) class Net(nn.Module): def __init__(self, num_classes=25): super(Net, self).__init__() # 简化网络结构,该任务无需复杂层级 self.fc1 = nn.Linear(1, 64) self.fc2 = nn.Linear(64, num_classes) self.relu = nn.ReLU() def forward(self, x): # 确保输入形状匹配Linear层要求:(batch_size, 1) x = x.unsqueeze(1) x = self.fc1(x) x = self.relu(x) x = self.fc2(x) # CrossEntropyLoss会自动处理Softmax,无需手动添加 return x # 0-24共25个类别 net = Net(num_classes=25) # 生成数据集:input是自然数,label与input一致 dataset = pd.DataFrame([random.randint(0, 24) for _ in range(10000)], columns=['input']) dataset['label'] = dataset['input'] train, test = train_test_split(dataset, test_size=0.2) # 转换为张量,批量处理提升效率 train_inputs = torch.tensor(train['input'].values, dtype=torch.float) train_labels = torch.tensor(train['label'].values, dtype=torch.long) test_inputs = torch.tensor(test['input'].values, dtype=torch.float) test_labels = torch.tensor(test['label'].values, dtype=torch.long) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.001) # 增加训练轮数确保收敛 epochs = 50 for epoch in range(epochs): net.train() optimizer.zero_grad() outputs = net(train_inputs) loss = criterion(outputs, train_labels) loss.backward() optimizer.step() # 每5轮评估一次效果 if (epoch + 1) % 5 == 0: net.eval() with torch.no_grad(): test_outputs = net(test_inputs) _, predicted = torch.max(test_outputs, 1) total = test_labels.size(0) correct = (predicted == test_labels).sum().item() print(f'Epoch [{epoch+1}/{epochs}], Test Accuracy: {100 * correct / total:.2f}%')
效果说明
修正后网络会快速收敛,最终测试准确率可以达到100%,完美实现自然数到对应One-Hot编码(通过torch.max取argmax即可得到对应位置的1)的映射。
内容的提问来源于stack exchange,提问作者Aldan Creo
相关产品推荐
相关产品推荐

