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

PyTorch多层神经网络分类7类花卉图像遇错误求助

问题解决方案

一、解决张量形状不匹配错误

错误原因

输入图像是3通道32×32的张量(形状[128, 3, 32, 32]),但你初始化模型时将input_dim设为image_size = 32,未对图像做展平处理,导致第一层Linear的输入维度与实际输入形状不匹配,最终输出outputs的形状变成[128,3,32,1],和labels的[128]无法匹配,触发loss计算错误。

修复步骤

  1. 修正输入维度计算:图像展平后的总维度为3 * image_size * image_size = 3*32*32=3072,将input_dim设为该值,而非image_size。
  2. 在forward中添加展平操作:把输入的4D张量(batch, channel, h, w)展平为2D张量(batch, total_features)。
  3. 调整网络结构参数:7分类任务的output_dim应等于类别数7;同时不要用batch_size作为隐藏层维度(batch_size变化会导致网络结构变更),改用固定值。

修正后的模型代码:

import torch
import torch.nn as nn

number_of_classes = 7
image_size = 32
input_dim = 3 * image_size * image_size  # 展平后的输入维度:3*32*32=3072
num_hidden = [1024, 256]  # 自定义固定隐藏层维度
output_dim = number_of_classes  # 7分类任务输出维度为7

class MultiLayerNeuralNetwork(nn.Module):
    def __init__(self, input_dim, num_hidden, output_dim):
        super().__init__()
        # 第一层
        self.first_layer = nn.Linear(input_dim, num_hidden[0])
        nn.init.kaiming_uniform_(self.first_layer.weight, nonlinearity="relu")
        nn.init.constant_(self.first_layer.bias.data, 0)
        
        # 隐藏层
        self.hidden = nn.ModuleList()
        for k in range(len(num_hidden)-1):
            self.hidden.append(nn.Linear(num_hidden[k], num_hidden[k+1]))
            nn.init.kaiming_uniform_(self.hidden[k].weight, nonlinearity="relu")
            nn.init.constant_(self.hidden[k].bias.data, 0)
        
        # 输出层:分类任务用xavier初始化更合适
        self.output_layer = nn.Linear(num_hidden[-1], output_dim)
        nn.init.xavier_uniform_(self.output_layer.weight)
        nn.init.constant_(self.output_layer.bias.data, 0)

    def forward(self, x):
        # 展平:[batch, 3, 32, 32] -> [batch, 3*32*32]
        x = x.flatten(start_dim=1)
        x = torch.nn.functional.relu(self.first_layer(x))
        for layer in self.hidden:
            x = torch.nn.functional.relu(layer(x))
        # 输出层直接输出logits,交给loss函数处理
        x = self.output_layer(x)
        return x

multi_layer_nn_model = MultiLayerNeuralNetwork(input_dim, num_hidden, output_dim)
  1. 匹配loss函数与标签:使用CrossEntropyLoss,它要求输入为[batch, num_classes]的logits,标签为[batch]的类别索引(0-6,对应1-7的类别),正好适配你的labels形状:
    loss_function = nn.CrossEntropyLoss()
    

二、解决输出对应1-7类别的问题

问题分析

之前用sigmoid导致输出区间异常,7分类任务需要输出每个类别的概率分布,应通过softmax将logits转换为[0,1]区间的概率(每个样本概率和为1),再映射到1-7的类别。

处理步骤

  1. 训练阶段:模型输出logits即可,CrossEntropyLoss内部会自动计算softmax,无需手动添加。
  2. 推理阶段:对输出logits做softmax,取概率最大的类别索引后加1,得到1-7的类别:
    outputs = multi_layer_nn_model(input_images)
    probabilities = torch.nn.functional.softmax(outputs, dim=1)
    predicted_classes = torch.argmax(probabilities, dim=1) + 1  # 从0-6转为1-7
    

额外注意事项

  • 避免用batch_size定义隐藏层维度:这会导致batch_size变化时网络结构变更,需改用固定数值(如1024、256)。
  • 输出层初始化:分类任务的输出层不要用针对relu的kaiming初始化,xavier初始化更适配logits输出。

内容的提问来源于stack exchange,提问作者Gökenaz Akyol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:10:21