繁体   English   中英

ValueError: `logits` 和 `labels` 必须具有相同的形状,收到 ((None, 16) vs (None, 1))

[英]ValueError: `logits` and `labels` must have the same shape, received ((None, 16) vs (None, 1))

我发现了类似的问题,但是少数接受了答案的问题对我不起作用。 以下是我的二进制分类器代码:

from google.colab import drive
drive.mount('/content/drive')

df = pd.read_csv('/content/drive/My Drive/dielectron.csv')
df = df.drop('Run', axis=1); df = df.drop('M', axis=1)
df.info()
df.head()

scaler = MinMaxScaler()

index = df.index.to_list() 
columns = df.columns.tolist()

scaler = MinMaxScaler()

df_scaled = scaler.fit_transform(df)
Df = pd.DataFrame(df_scaled , index=index , columns=columns)
Df.info()

Df= Df.drop('Event', axis=1)
x = Df.drop('Q2', axis=1).to_numpy()
y = Df['Q2']
y = np.asarray(y).astype('float32').reshape((-1,1))

model = tf.keras.Sequential([
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(16, activation='sigmoid')
])

epochs = 20


es = tf.keras.callbacks.EarlyStopping(monitor='val loss',
                                      patience = 3,
                                      mode = 'min',
                                      restore_best_weights=True)

model.compile(loss= tf.keras.losses.BinaryCrossentropy(),
              optimizer= tf.optimizers.Adam(),
              metrics= [tf.keras.metrics.BinaryAccuracy()]
)

history = model.fit(x, y, epochs=epochs, validation_split=0.3, callbacks=[es])

为输入mode.fit()的 x 和 y 运行x.shapey.shape会返回以下值:

x.shape:(100000, 15)
y.shape:(100000, 1)

如果有任何明显的错误,我很抱歉,我对 ML 和 DL 和 tf keras 相对缺乏经验。

运行此代码会返回以下错误:

ValueError: in user code:

    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1021, in train_function  *
        return step_function(self, iterator)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1010, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1000, in run_step  **
        outputs = model.train_step(data)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 860, in train_step
        loss = self.compute_loss(x, y, y_pred, sample_weight)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 919, in compute_loss
        y, y_pred, sample_weight, regularization_losses=self.losses)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/compile_utils.py", line 201, in __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    File "/usr/local/lib/python3.7/dist-packages/keras/losses.py", line 141, in __call__
        losses = call_fn(y_true, y_pred)
    File "/usr/local/lib/python3.7/dist-packages/keras/losses.py", line 245, in call  **
        return ag_fn(y_true, y_pred, **self._fn_kwargs)
    File "/usr/local/lib/python3.7/dist-packages/keras/losses.py", line 1932, in binary_crossentropy
        backend.binary_crossentropy(y_true, y_pred, from_logits=from_logits),
    File "/usr/local/lib/python3.7/dist-packages/keras/backend.py", line 5247, in binary_crossentropy
        return tf.nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)

    ValueError: `logits` and `labels` must have the same shape, received ((None, 16) vs (None, 1)).

我使用的数据集可以在这个网站上找到,也有人可以向我解释一下 logit 到底是什么? 我正在脱离上下文并猜测它与功能有关,但是查找它会产生相互矛盾的答案


逻辑和分类

对于分类,您通常需要将原始值的向量转换为概率分布,即转换为元素在 [0,1] 中且总和为 1 的向量。在这种情况下,“logits”指的是原始值在转换之前。

  • 对于两个类别之间的分类(二元分类),转换后的向量只需要一个元素来表示输入属于类别 0 的概率p 0 ,因为p 1隐含为 1 - p 0 在这种情况下,从 logits 到分布的转换是使用Sigmoid函数完成的,损失函数通常是二元交叉熵(BCE)。
  • 对于两个以上类别之间的分类,您需要对分布进行 one-hot 编码。 也就是说,您希望转换后的向量中的元素数与类数相同。 然后第n个元素表示p n ,即输入属于第n个类的概率。 在这种情况下,从 logits 到分布的转换将使用Softmax函数完成,损失函数通常是Categorical Cross Entropy (CCE)。

请注意,没有什么可以阻止您对二进制分布进行一次热编码,即具有一个转换后的向量,其中两个元素分别表示p 0p 1 然而,BCE 损失的 Tensorflow 实现假设二进制分布不是单热编码的。


回答

由于您的数据集具有y.shape:(100000, 1) ,因此它是一个二进制分类数据集。 这要求网络的输出是大小为 1 而不是 16 的向量。

此外,如果您使用 Tensorflow BCE 损失函数,您还可以选择(通过from_logits参数)指定给函数的 size-1 预测向量是否包含原始 logits 或分布。 from_logits=True时,该函数将首先对预测向量应用 sigmoid,然后计算通常的 BCE。

因此,只需将您的模型和损失函数指定为(忽略箭头标记)

model = tf.keras.Sequential([
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(1, activation='sigmoid') <---
])

model.compile(loss=tf.keras.losses.BinaryCrossentropy(),
              optimizer= tf.optimizers.Adam(),
              metrics=[tf.keras.metrics.BinaryAccuracy()]
)

或者

model = tf.keras.Sequential([
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(16, activation='relu'),
                                   tf.keras.layers.Dense(1) <---
])

model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True) <---,
              optimizer= tf.optimizers.Adam(),
              metrics=[tf.keras.metrics.BinaryAccuracy()]
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM