You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何训练神经网络将单个自然数转换为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:27:52