簡體   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