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

CNN模型拟合报错:ValueError: logits与labels形状不匹配求助

问题解决:CNN二分类中logits与labels形状不匹配错误

错误根源

报错ValueError: logits and labels must have the same shape, received ((None, 3) vs (None, 2))的核心原因有两点:

  • 模型最后输出层的单元数设置错误:你用了units=3,但你的标签是二分类的one-hot编码(维度[260,2]),输出维度和标签维度不匹配
  • 损失函数与输出层激活函数搭配错误:当前用了softmax激活+binary_crossentropy损失,这不符合二分类的标准配置

修正方案(两种可选)

方案1:保持one-hot标签,适配softmax激活

这种方案适合用one-hot编码的标签(也就是你当前的trainlabels):

  1. 将最后一层全连接层的单元数改为2,匹配二分类的类别数
  2. 损失函数替换为categorical_crossentropy,和softmax激活搭配

修改后的模型代码:

model <- keras_model_sequential()

model %>%
  layer_conv_2d(filters = 32,
                kernel_size = c(3,3),
                activation = 'relu',
                input_shape = c(250, 250, 3)) %>%
  layer_conv_2d(filters = 32,
                kernel_size = c(3,3),
                activation = 'relu') %>%
  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_dropout(rate = 0.25) %>%
  layer_conv_2d(filters = 64,
                kernel_size = c(3,3),
                activation = 'relu') %>%
  layer_conv_2d(filters = 64,
                kernel_size = c(3,3),
                activation = 'relu') %>%
  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_dropout(rate = 0.25) %>%
  layer_flatten()%>%
  layer_dense(units = 256, activation = 'relu',) %>%
  layer_dropout(rate = 0.25) %>%
  # 修正:输出单元数改为2
  layer_dense(units = 2, activation = 'softmax')%>%
  
  compile(loss = 'categorical_crossentropy',  # 修正:替换损失函数
        optimizer = optimizer_sgd(lr = 0.01,
                                  decay = 1e-6,
                                  momentum = 0.9,
                                  nesterov = TRUE),
        metrics = c('accuracy'))

方案2:用原始标签,适配sigmoid激活

这种方案不需要one-hot编码,直接用原始的trainy(0/1数组):

  1. 最后一层全连接层单元数设为1,用sigmoid激活
  2. 损失函数保持binary_crossentropy,标签直接传入trainy而非trainlabels

修改后的关键代码:

# 不需要to_categorical,直接用原始标签
trainlabels <- trainy
testlabels <- testy

model <- keras_model_sequential()

model %>%
  # 前面的卷积、池化层保持不变
  layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = 'relu', input_shape = c(250, 250, 3)) %>%
  layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = 'relu') %>%
  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_dropout(rate = 0.25) %>%
  layer_conv_2d(filters = 64, kernel_size = c(3,3), activation = 'relu') %>%
  layer_conv_2d(filters = 64, kernel_size = c(3,3), activation = 'relu') %>%
  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_dropout(rate = 0.25) %>%
  layer_flatten()%>%
  layer_dense(units = 256, activation = 'relu',) %>%
  layer_dropout(rate = 0.25) %>%
  # 修正:输出单元数1,sigmoid激活
  layer_dense(units = 1, activation = 'sigmoid')%>%
  
  compile(loss = 'binary_crossentropy',
        optimizer = optimizer_sgd(lr = 0.01,
                                  decay = 1e-6,
                                  momentum = 0.9,
                                  nesterov = TRUE),
        metrics = c('accuracy'))

# 拟合时传入原始标签trainy
history <- model %>%
  fit(train,
      trainy,
      epochs = 50, 
      batch_size = 32,
      validation_split = 0.2)

额外建议

  • 你之前尝试调整图片尺寸到100×100,这个操作本身没问题,但和当前错误无关,错误根源是输出层和损失函数的配置
  • 可以考虑在输入层前添加layer_resizing来统一图片尺寸,比如:
model %>%
  layer_resizing(height = 100, width = 100) %>%  # 新增这一行
  layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = 'relu', input_shape = c(100, 100, 3)) %>%
  # 后续层保持不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:27:35