Keras 中的自定义损失函数
Custom loss function in Keras
我正在研究图像 class-增量 classifier 方法,使用 CNN 作为特征提取器和全连接块 classifying。
首先,我微调了一个 VGG per-trained network 来完成一个新任务。为新任务训练网络后,我会为每个 class 存储一些示例,以避免忘记何时有新的 classes 可用。
当某些 classes 可用时,我必须计算样本的每个输出,包括新 classes 的样本。现在在旧 classes 的输出中添加零,并在新 classes 输出中添加对应于每个新 class 的标签,我有了新标签,即:
如果 3 个新 classes 输入....
旧class类型输出:[0.1, 0.05, 0.79, ..., 0 0 0]
新的class类型输出:[0.1, 0.09, 0.3, 0.4, ..., 1 0 0]
**最后的输出对应于class。
我的问题是,如何更改自定义函数的损失函数以针对新的 classes 进行训练?
我要实现的损失函数定义为:
其中蒸馏损失对应于旧 classes 的输出以避免遗忘,class化损失对应于新的 classes。
如果你能给我一个代码示例来改变keras中的损失函数就太好了。
谢谢!!!!!
你所要做的就是为此定义一个函数,使用keras后端函数进行计算。该函数必须采用真实值和模型预测值。
现在,由于我不确定你的函数中的 g、q、x 和 y 是什么,我将在这里创建一个基本示例,而不关心它的含义或它是否是一个实际有用的函数:
import keras.backend as K
def customLoss(yTrue,yPred):
return K.sum(K.log(yTrue) - K.log(yPred))
所有后台功能都可以看到here。
之后,使用该函数而不是常规函数编译您的模型:
model.compile(loss=customLoss, optimizer = .....)
由于 Keras 不再 multi-backend (source),自定义损失的操作应该直接在 Tensorflow 中进行,而不是使用后端。
您可以使用 Tensorflow 进行自定义损失,方法是创建一个以 y_true
和 y_pred
作为参数的函数,如 documentation:
中所建议
import tensorflow as tf
x = tf.random.uniform(minval=0, maxval=1, shape=(10, 1), dtype=tf.float32)
y = tf.random.uniform(minval=0, maxval=1, shape=(10, 1), dtype=tf.float32)
def custom_mse(y_true, y_pred):
squared_difference = tf.square(y_true - y_pred)
return tf.reduce_mean(squared_difference, axis=-1)
custom_mse(x, y)
<tf.Tensor: shape=(10,), dtype=float32, numpy=
array([0.30084264, 0.03535452, 0.10345092, 0.28552982, 0.02426687,
0.04410492, 0.01701574, 0.55496216, 0.74927425, 0.05747304],
dtype=float32)>
然后您可以在model.compile()
中设置您的自定义损失。这是一个完整的例子:
x = tf.random.uniform(minval=0, maxval=1, shape=(1000, 4), dtype=tf.float32)
y = tf.multiply(tf.reduce_sum(x, axis=-1), 5) # y is a function of x
model = tf.keras.Sequential([
tf.keras.layers.Dense(16, input_shape=[4], activation='relu'),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(loss=custom_mse, optimizer='adam')
history = model.fit(x, y, epochs=10)
Train on 1000 samples
Epoch 1/5
32/1000 [..............................] - ETA: 10s - loss: 99.5402
1000/1000 [==============================] - 0s 371us/sample - loss: 105.6800
Epoch 2/5
32/1000 [..............................] - ETA: 0s - loss: 89.2909
1000/1000 [==============================] - 0s 35us/sample - loss: 98.8208
Epoch 3/5
32/1000 [..............................] - ETA: 0s - loss: 86.4339
1000/1000 [==============================] - 0s 34us/sample - loss: 82.7988
Epoch 4/5
32/1000 [..............................] - ETA: 0s - loss: 75.2580
1000/1000 [==============================] - 0s 33us/sample - loss: 52.4585
Epoch 5/5
32/1000 [..............................] - ETA: 0s - loss: 28.1625
1000/1000 [==============================] - 0s 34us/sample - loss: 17.8190
我正在研究图像 class-增量 classifier 方法,使用 CNN 作为特征提取器和全连接块 classifying。
首先,我微调了一个 VGG per-trained network 来完成一个新任务。为新任务训练网络后,我会为每个 class 存储一些示例,以避免忘记何时有新的 classes 可用。
当某些 classes 可用时,我必须计算样本的每个输出,包括新 classes 的样本。现在在旧 classes 的输出中添加零,并在新 classes 输出中添加对应于每个新 class 的标签,我有了新标签,即: 如果 3 个新 classes 输入....
旧class类型输出:[0.1, 0.05, 0.79, ..., 0 0 0]
新的class类型输出:[0.1, 0.09, 0.3, 0.4, ..., 1 0 0]
**最后的输出对应于class。
我的问题是,如何更改自定义函数的损失函数以针对新的 classes 进行训练? 我要实现的损失函数定义为:
其中蒸馏损失对应于旧 classes 的输出以避免遗忘,class化损失对应于新的 classes。
如果你能给我一个代码示例来改变keras中的损失函数就太好了。
谢谢!!!!!
你所要做的就是为此定义一个函数,使用keras后端函数进行计算。该函数必须采用真实值和模型预测值。
现在,由于我不确定你的函数中的 g、q、x 和 y 是什么,我将在这里创建一个基本示例,而不关心它的含义或它是否是一个实际有用的函数:
import keras.backend as K
def customLoss(yTrue,yPred):
return K.sum(K.log(yTrue) - K.log(yPred))
所有后台功能都可以看到here。
之后,使用该函数而不是常规函数编译您的模型:
model.compile(loss=customLoss, optimizer = .....)
由于 Keras 不再 multi-backend (source),自定义损失的操作应该直接在 Tensorflow 中进行,而不是使用后端。
您可以使用 Tensorflow 进行自定义损失,方法是创建一个以 y_true
和 y_pred
作为参数的函数,如 documentation:
import tensorflow as tf
x = tf.random.uniform(minval=0, maxval=1, shape=(10, 1), dtype=tf.float32)
y = tf.random.uniform(minval=0, maxval=1, shape=(10, 1), dtype=tf.float32)
def custom_mse(y_true, y_pred):
squared_difference = tf.square(y_true - y_pred)
return tf.reduce_mean(squared_difference, axis=-1)
custom_mse(x, y)
<tf.Tensor: shape=(10,), dtype=float32, numpy=
array([0.30084264, 0.03535452, 0.10345092, 0.28552982, 0.02426687,
0.04410492, 0.01701574, 0.55496216, 0.74927425, 0.05747304],
dtype=float32)>
然后您可以在model.compile()
中设置您的自定义损失。这是一个完整的例子:
x = tf.random.uniform(minval=0, maxval=1, shape=(1000, 4), dtype=tf.float32)
y = tf.multiply(tf.reduce_sum(x, axis=-1), 5) # y is a function of x
model = tf.keras.Sequential([
tf.keras.layers.Dense(16, input_shape=[4], activation='relu'),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(loss=custom_mse, optimizer='adam')
history = model.fit(x, y, epochs=10)
Train on 1000 samples
Epoch 1/5
32/1000 [..............................] - ETA: 10s - loss: 99.5402
1000/1000 [==============================] - 0s 371us/sample - loss: 105.6800
Epoch 2/5
32/1000 [..............................] - ETA: 0s - loss: 89.2909
1000/1000 [==============================] - 0s 35us/sample - loss: 98.8208
Epoch 3/5
32/1000 [..............................] - ETA: 0s - loss: 86.4339
1000/1000 [==============================] - 0s 34us/sample - loss: 82.7988
Epoch 4/5
32/1000 [..............................] - ETA: 0s - loss: 75.2580
1000/1000 [==============================] - 0s 33us/sample - loss: 52.4585
Epoch 5/5
32/1000 [..............................] - ETA: 0s - loss: 28.1625
1000/1000 [==============================] - 0s 34us/sample - loss: 17.8190