【问题标题】:logits and labels must be broadcastable: logits_size=[100,4] labels_size=[400,4]logits 和标签必须是可广播的:logits_size=[100,4] labels_size=[400,4]
【发布时间】:2025-11-28 21:10:01
【问题描述】:

我的 conda 环境

Python: 3.6.10
NumPy: 1.18.1
Pandas: 0.23.4
TensorFlow: 2.2.0

我正在使用自定义生成器并训练 CNN 1D。

生成器将文件名列表和批量大小作为输入,并从文件名中输出数据和 one-hot 编码标签。

数据

数据位于多个文件中。每个文件在 10 列中有 10 个长度为 8001 的单独信号。

自定义生成器以批量加载文件

def tf_data_generator(file_list, batch_size = 10):
    i = 0
    while True:
        if i*batch_size >= len(file_list):  
            i = 0
            np.random.shuffle(file_list)
        else:
            file_chunk = file_list[i*batch_size:(i+1)*batch_size] 
            data = []
            labels = []
            label_classes = tf.constant(["RS0", "Td2", "Jum","Td3"]) 
            for file in file_chunk:
                temp = pd.read_csv(open(file,'r'),header=None,index_col=False,squeeze=True)#
                sigdf=temp.str.split(expand=True,)
                sigdf=sigdf.replace('NaN',np.nan)
                sigdf=sigdf.dropna(axis=1)

                data.append(sigdf.values.reshape(10,8001,1)) 
                pattern = tf.constant(eval("file[79:-4]")) #extracting data from file name
                for j in range(len(label_classes)):
                    if re.match(pattern.numpy(), label_classes[j].numpy()): # matching pattern
                        l=[j]*len(sigdf.columns) #repeating label outputs according to the number of cols 
                        labels.extend(l)
            data = np.asarray(data).reshape(-1,8001,1)
            #one hot encoding the data
            labels = np.asarray(utils.to_categorical(labels))
            yield data, labels
            i = i + 1

检查生成器输出的代码

num = 0
for data, labels in check_data:
    print(data.shape, labels.shape)
    #print(labels, "<--Labels")
    print()
    num = num + 1
    if num > 5: break

输出

(100, 8001, 1) (100, 4)

(100, 8001, 1) (100, 4)

(100, 8001, 1) (100, 4)

(100, 8001, 1) (100, 4)

(100, 8001, 1) (100, 4)

(100, 8001, 1) (100, 4)

这里显示标签输出为100,4,用于 100 个信号,4 个输出的 one-hot 编码。

CNN 模型

model = tf.keras.Sequential([
    layers.Conv1D(16, 3, activation = "relu", input_shape = (8001,1)),
    layers.MaxPool1D(2),
    layers.Dropout(0.5),
    layers.Conv1D(32, 7, activation = "relu"),
    layers.MaxPool1D(2),
    layers.Dropout(0.5),
    layers.Conv1D(64, 7,activation="relu"),
    layers.MaxPool1D(2),
    layers.Dropout(0.5),
    layers.Flatten(),
    layers.Dense(16, activation = "relu"),
    layers.Dense(4, activation = "softmax")
])

model.compile(loss = "categorical_crossentropy", optimizer = "adam", metrics = ["accuracy"])

但是,当我尝试拟合模型时,我得到了错误

InvalidArgumentError:  logits and labels must be broadcastable: logits_size=[100,4] labels_size=[400,4]
     [[node categorical_crossentropy/softmax_cross_entropy_with_logits (defined at <ipython-input-105-142deaf73db1>:2) ]] [Op:__inference_train_function_26061]

在错误中,它显示[400,4] 作为标签大小。而生成器输出显示[100,4]。我不确定我哪里出错了!

【问题讨论】:

    标签: python-3.x tensorflow2.0


    【解决方案1】:

    这可能是因为标签的维度与输出的维度不同。 (见categorical_crossentropy)。
    要找出答案,您可以显示模型摘要以检查输出形状,使用:model.summary()。 或者您可以调用模型model(np.zeros((1, 8001, 1))) 并检查张量的形状。

    【讨论】:

    • 我检查了model(np.zeros((1,8001,1))。输出为&lt;tf.Tensor: shape=(1, 4), dtype=float32, numpy=array([[0.25, 0.25, 0.25, 0.25]], dtype=float32)&gt;。因此,正如预期的那样,输出为(1,4)。另外,我检查了model.summary( )。最后一层的输出是(None, 4)。而且,我确信来自 traindataset 的自定义生成器 &lt;FlatMapDataset shapes: ((None, 8001, 1), (None, 4)), types: (tf.float32, tf.float32)&gt; 的输出也是 (None,4)。所以,我不明白它在哪里调试失败!
    • 你能把所有相关的代码都加进去吗?以及 model.fit_generator 的完整打印输出
    • 这是编译 model.compile(loss = "categorical_crossentropy", optimizer = "adam", metrics = ["accuracy"]) 和适合 model.fit(train_dataset, validation_data = validation_dataset, steps_per_epoch = steps_per_epoch, validation_steps = validation_steps, epochs = 10) 的代码。我无法在 cmets 中发布整个错误日志,但我可以发布它here
    • 你能用正确的形状和类型尝试model.fit_generator(tf_data_generator )
    • 我收到与model.fit 相同的错误消息,并警告model.fit_generator 已被弃用