温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - Keras backend function seems to be working incorrectly
keras loss-function python tensorflow

python - Keras后端功能似乎无法正常工作

发布于 2020-03-27 10:25:00

我正在尝试在Keras中实现自定义损失功能。

首先,我想确保可以从我的自定义函数中调用以前的损失函数。这是奇怪的东西开始的地方:

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

可以正常工作。

现在,在keras.losses中“ sparse_categorical_crossentropy”的实现如下:

def sparse_categorical_crossentropy(y_true, y_pred):
    return K.sparse_categorical_crossentropy(y_true, y_pred)

我得出的结论是K.sparse_categorical_crossentropy直接通过也应该起作用。但是,它抛出expected activation_6 to have shape (4,) but got array with shape (1,)

同样,定义一个自定义损失函数,如下所示:

def custom_loss(y_true, y_pred):
    return keras.losses.sparse_categorical_crossentropy(y_true, y_pred)

不起作用。在训练过程中,减少了损失(看起来是正确的),但是准确性却没有提高(但是使用非定制损失功能时,准确性确实提高了)

I am not sure what is happening, neither do I know how to debug it properly. Any help would be highly appreciated.

查看更多

查看更多

提问者
Johannes
被浏览
264
Anubhav Singh 2019-07-03 21:42

I tested what you are saying on my code and yes, you are right. I was initially getting the same error as you were getting, but once I changed the metrics parameter from accuracy to sparse_categorical_accuracy, I started getting higher accuracy.

Here, one important thing to note is when we tell keras to use accuracy as metrics, keras uses the default accuracy which is categorical_accuracy. So, if we want to implement our own custom loss function, then we have to set metrics parameter accordingly.

Read about available metrics function in keras from here.

Case 1:

def sparse_categorical_crossentropy(y_true, y_pred):
    return K.sparse_categorical_crossentropy(y_true, y_pred)

model.compile(optimizer='adam',
              loss=sparse_categorical_crossentropy,
              metrics=['accuracy'])

output:

ValueError:检查目标时出错:预期density_71的形状为(10,),但数组的形状为(1,)

情况2:

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

输出:

Epoch 1/2
60000/60000 [==============================] - 2s 38us/step - loss: 0.4714 - acc: 0.8668
Epoch 2/2
60000/60000 [==============================] - 1s 22us/step - loss: 0.2227 - acc: 0.9362
10000/10000 [==============================] - 1s 94us/step

情况3:

def custom_sparse_categorical_crossentropy(y_true, y_pred):
    return K.sparse_categorical_crossentropy(y_true, y_pred)

model.compile(optimizer='adam',             
              loss=custom_sparse_categorical_crossentropy, 
              metrics=['accuracy'])

输出:

Epoch 1/2
60000/60000 [==============================] - 2s 41us/step - loss: 0.4558 - acc: 0.1042
Epoch 2/2
60000/60000 [==============================] - 1s 22us/step - loss: 0.2164 - acc: 0.0997
10000/10000 [==============================] - 1s 89us/step

情况4:

def custom_sparse_categorical_crossentropy(y_true, y_pred):
    return K.sparse_categorical_crossentropy(y_true, y_pred)

model.compile(optimizer='adam',
              loss=custom_sparse_categorical_crossentropy,
              metrics=['sparse_categorical_accuracy'])

输出:

Epoch 1/2
60000/60000 [==============================] - 2s 40us/step - loss: 0.4736 - sparse_categorical_accuracy: 0.8673
Epoch 2/2
60000/60000 [==============================] - 1s 23us/step - loss: 0.2222 - sparse_categorical_accuracy: 0.9372
10000/10000 [==============================] - 1s 85us/step

完整代码:

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import keras.backend as K


mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = tf.keras.models.Sequential([

tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(100, activation=tf.nn.relu),
tf.keras.layers.Dropout(0.10),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

def custom_sparse_categorical_crossentropy(y_true, y_pred):
    return K.sparse_categorical_crossentropy(y_true, y_pred)

#def sparse_categorical_accuracy(y_true, y_pred):
#    # reshape in case it's in shape (num_samples, 1) instead of (num_samples,)
#    if K.ndim(y_true) == K.ndim(y_pred):
#        y_true = K.squeeze(y_true, -1)
#    # convert dense predictions to labels
#    y_pred_labels = K.argmax(y_pred, axis=-1)
#    y_pred_labels = K.cast(y_pred_labels, K.floatx())
#    return K.cast(K.equal(y_true, y_pred_labels), K.floatx())

model.compile(optimizer='adam',
          loss=custom_sparse_categorical_crossentropy,
         metrics=['sparse_categorical_accuracy'])

history = model.fit(x_train, y_train, epochs=2, batch_size=200)
model.evaluate(x_test, y_test)

sparse_categorical_accuracy此处sparse_categorical_crossentropy此处检查实施