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

高光谱图像分类DNN代码报错:TypeError: forward()缺失参数'negative'

解决DNN高光谱图像分类中的TypeError问题

嘿,我来帮你排查这个错误!你遇到的TypeError: forward() missing 1 required positional argument: 'negative'是因为选错了损失函数,咱们一步步来解决:

错误根源

你用了nn.TripletMarginLoss(),这个损失函数是用来做三元组学习的(比如人脸识别里的锚点、正样本、负样本对比),它的forward方法必须接收三个参数:anchor、positive、negative。但你的分类任务只传了模型输出和标签两个参数,自然就会报错缺少negative参数啦。

另外你的代码还有几个小问题,我一起帮你修正。

完整修复方案

1. 替换为分类任务的专用损失函数

把三元组损失换成分类任务常用的CrossEntropyLoss,它只需要模型输出和标签两个参数,完美匹配你的需求。

2. 修正标签的数据类型

CrossEntropyLoss要求标签是整数类型的张量(LongTensor),而你当前的train_y和test_y是FloatTensor,需要转换一下,同时去掉多余的维度(比如从[batch_size,1]改成[batch_size])。

3. 修复测试函数的输入形状错误

测试函数里的test_X[i].view(-1, 1, 50, 50)完全不对——你的输入是103维的光谱向量,不是50x50的图像,应该改成test_X[i].view(-1, 103)。同时,获取真实标签的方式也错了,直接取test_y[i]就行,不用torch.argmax。

修改后的完整代码

下面是修复后的关键部分代码,我标了修改的核心点:

# 训练和测试函数
def train(dnn):
    BATCH_SIZE = 100
    EPOCHS = 3
    for epoch in range(EPOCHS):
        for i in tqdm(range(0, len(train_X), BATCH_SIZE)):
            batch_X = train_X[i:i+BATCH_SIZE]
            # 修正标签形状和类型:去掉多余维度并转为LongTensor
            batch_y = train_y[i:i+BATCH_SIZE].squeeze().long()
            dnn.zero_grad()
            outputs = dnn(batch_X)
            loss = loss_function(outputs, batch_y)
            loss.backward()
            optimizer.step()
            print(f"Epoch {epoch+1}, Batch {i//BATCH_SIZE}, Loss: {loss.item()}")

def test(net):
    correct = 0
    total = 0
    with torch.no_grad():
        for i in tqdm(range(len(test_X))):
            # 修正真实标签获取方式和类型
            real_class = test_y[i].long().to(device)
            # 修正输入形状:匹配103维的光谱向量
            net_out = net(test_X[i].view(-1, 103).to(device))[0]
            predicted_class = torch.argmax(net_out)
            if predicted_class == real_class:
                correct += 1
            total += 1  # 修正计数逻辑:无论对错都统计总数
    print("Accuracy:", round(correct/total,3))

if REBUILD_DATA:
    Data = DATA()
    datay = Data.integrated_data()
    Trainindex, Testindex, TrainSet, TestSet = Data.make_trainset_and_testset(rebuilddata=datay,ratio=0.1)
    train_X = torch.Tensor([i[0] for i in TrainSet])
    train_y = torch.Tensor([i[1] for i in TrainSet])
    train_X = train_X/3000
    test_X = torch.Tensor([i[0] for i in TestSet])
    test_y = torch.Tensor([i[1] for i in TestSet])
    print(train_X[0])
    # 加入设备配置:自动使用GPU加速(如果可用)
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    dnn = DNN().to(device)
    optimizer = optim.SGD(dnn.parameters(), lr = 0.001)
    # 替换为分类任务专用损失函数
    loss_function = nn.CrossEntropyLoss()
    train(dnn)
    # 别忘了调用测试函数评估效果
    test(dnn)

额外提几个小优化点:

  • 加入了设备自动配置,优先用GPU加速训练
  • 训练时的loss打印更清晰,方便监控训练状态
  • 修正了测试函数的计数逻辑,避免准确率计算错误

这样修改后,你的代码应该就能正常运行啦!

内容的提问来源于stack exchange,提问作者Yang Cong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:07:43