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

CNN气球检测模型调用fit()报错:输入形状不兼容求助

气球检测CNN模型训练时的输入形状不兼容问题

训练模型调用fit()时触发错误:

ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 224, 224, 3), found shape=(None, None, None, 224, 224, 3)

尝试过小修改但未解决,寻求问题原因及修复方案。

原代码

import numpy as np
import pandas as pd

import tensorflow as tf
import tensorflow_datasets as tfds
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
          optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
          metrics=['accuracy'])

annotations_file = '/content/balloon-data.csv'
annotations = pd.read_csv(annotations_file)

image_paths = []
labels = []
for i, row in annotations.iterrows():
    if row['num_balloons'] > 0:
        image_path = 'path/to/image/{}'.format(row['fname'])
        image_paths.append(image_path)
        labels.append(1)
    else:
        image_path = 'path/to/image/{}'.format(row['fname'])
        image_paths.append(image_path)
        labels.append(0)

dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))

def preprocess_image(image_path, label):
    image = tf.io.read_file(image_path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, (224, 224))
    image = image / 255.0
    return image, label

dataset = dataset.map(lambda x, y: preprocess_image(x, y)).batch(64)

train_size = int(0.8 * len(image_paths))
test_size = len(image_paths) - train_size
train_dataset = dataset.take(train_size)
test_dataset = dataset.skip(train_size)

train_dataset = train_dataset.shuffle(1024).batch(32)
test_dataset = test_dataset.batch(32)

train_dataset = train_dataset.shuffle(1024).batch(64)
test_dataset = test_dataset.batch(64)

model.fit(train_dataset, epochs=10, validation_data=test_dataset)

已尝试的修改

# 原代码中这一行
dataset = dataset.map(lambda x, y: preprocess_image(x, y)).batch(64) 
# 修改为
dataset = dataset.map(preprocess_image)

# 删除了以下重复batch的代码
train_dataset = train_dataset.shuffle(1024).batch(64)
test_dataset = test_dataset.batch(64)

问题原因及最终修复方案

错误核心是重复调用batch()导致数据集维度嵌套:

  • 原代码先对整个dataset执行.batch(64),此时每个元素是包含64个样本的batch
  • 后续又对train_dataset和test_dataset多次调用.batch(),相当于把已有的batch再次打包,形成嵌套的batch结构,输入形状变成(None, None, None, 224, 224, 3),和模型期望的(None, 224, 224, 3)不匹配

修正步骤:

  1. 预处理阶段只做映射,不提前batch,保持数据集每个元素是单样本
  2. 划分训练测试集后,仅执行一次shuffle和batch操作

修正后的完整代码:

import numpy as np
import pandas as pd

import tensorflow as tf
import tensorflow_datasets as tfds
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
          optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
          metrics=['accuracy'])

annotations_file = '/content/balloon-data.csv'
annotations = pd.read_csv(annotations_file)

image_paths = []
labels = []
for i, row in annotations.iterrows():
    if row['num_balloons'] > 0:
        image_path = 'path/to/image/{}'.format(row['fname'])
        image_paths.append(image_path)
        labels.append(1)
    else:
        image_path = 'path/to/image/{}'.format(row['fname'])
        image_paths.append(image_path)
        labels.append(0)

dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))

def preprocess_image(image_path, label):
    image = tf.io.read_file(image_path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, (224, 224))
    image = image / 255.0
    return image, label

# 仅做预处理映射,不提前batch
dataset = dataset.map(preprocess_image)

train_size = int(0.8 * len(image_paths))
test_size = len(image_paths) - train_size
train_dataset = dataset.take(train_size)
test_dataset = dataset.skip(train_size)

# 对划分后的数据集执行一次shuffle和batch
train_dataset = train_dataset.shuffle(1024).batch(64)
test_dataset = test_dataset.batch(64)

model.fit(train_dataset, epochs=10, validation_data=test_dataset)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:15:46