Keras 后端功能似乎无法正常工作
Keras backend function seems to be working incorrectly
我正在尝试在 Keras 中实现自定义损失函数。
首先,我想确保可以从我的自定义函数中调用之前的损失函数。这就是奇怪的事情开始的地方:
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
按预期工作。
现"sparse_categorical_crossentropy"在keras.losses中的实现如下:
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)
不起作用。在训练过程中减少了损失(这似乎是正确的)但准确性没有提高(但在使用非自定义损失函数时确实如此)
我不确定发生了什么,也不知道如何正确调试它。任何帮助将不胜感激。
我在我的代码上测试了你所说的,是的,你是对的。我最初遇到的错误与您遇到的错误相同,但是一旦我将指标参数从 accuracy
更改为 sparse_categorical_accuracy
,我就开始获得更高的准确性。
这里,需要注意的一件重要事情是当我们告诉keras使用accuracy
作为metrics
时,keras使用默认精度categorical_accuracy
。所以,如果我们想实现自己的自定义损失函数,那么我们必须相应地设置 metrics
参数。
从 here.
中了解 keras 中可用的指标函数
案例一:
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'])
输出:
ValueError: Error when checking target: expected dense_71 to have
shape (10,) but got array with shape (1,)
案例二:
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
案例三:
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
案例四:
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)
从 here and sparse_categorical_crossentropy
from here 查看 sparse_categorical_accuracy
的实现。
当您使用 accuracy
指标时,Kera 实际上会根据损失选择不同的精度实现,因为精度的计算方式取决于标签和模型的预测:
- 对于
categorical_crossentropy
,它使用 categorical_accuracy
作为准确度指标。
- 对于
binary_crossentropy
,它使用 binary_accuracy
作为准确度指标。
- 对于
sparse_categorical_crossentropy
,它使用 sparse_categorical_accuracy
作为准确度指标。
Keras 只能在您使用预定义损失时执行此操作,否则它无法猜测。对于您的自定义损失,您可以直接使用三种精度实现之一,例如 metrics=['sparse_categorical_accuracy']
.
我正在尝试在 Keras 中实现自定义损失函数。
首先,我想确保可以从我的自定义函数中调用之前的损失函数。这就是奇怪的事情开始的地方:
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
按预期工作。
现"sparse_categorical_crossentropy"在keras.losses中的实现如下:
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)
不起作用。在训练过程中减少了损失(这似乎是正确的)但准确性没有提高(但在使用非自定义损失函数时确实如此)
我不确定发生了什么,也不知道如何正确调试它。任何帮助将不胜感激。
我在我的代码上测试了你所说的,是的,你是对的。我最初遇到的错误与您遇到的错误相同,但是一旦我将指标参数从 accuracy
更改为 sparse_categorical_accuracy
,我就开始获得更高的准确性。
这里,需要注意的一件重要事情是当我们告诉keras使用accuracy
作为metrics
时,keras使用默认精度categorical_accuracy
。所以,如果我们想实现自己的自定义损失函数,那么我们必须相应地设置 metrics
参数。
从 here.
中了解 keras 中可用的指标函数案例一:
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'])
输出:
ValueError: Error when checking target: expected dense_71 to have shape (10,) but got array with shape (1,)
案例二:
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
案例三:
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
案例四:
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)
从 here and sparse_categorical_crossentropy
from here 查看 sparse_categorical_accuracy
的实现。
当您使用 accuracy
指标时,Kera 实际上会根据损失选择不同的精度实现,因为精度的计算方式取决于标签和模型的预测:
- 对于
categorical_crossentropy
,它使用categorical_accuracy
作为准确度指标。 - 对于
binary_crossentropy
,它使用binary_accuracy
作为准确度指标。 - 对于
sparse_categorical_crossentropy
,它使用sparse_categorical_accuracy
作为准确度指标。
Keras 只能在您使用预定义损失时执行此操作,否则它无法猜测。对于您的自定义损失,您可以直接使用三种精度实现之一,例如 metrics=['sparse_categorical_accuracy']
.