如何在 Keras 中创建这个自定义损失函数并确保它是可微的?
Posted
技术标签:
【中文标题】如何在 Keras 中创建这个自定义损失函数并确保它是可微的?【英文标题】:How to create this custom loss function in Keras and ensure it is differentiable? 【发布时间】:2018-03-23 21:59:10 【问题描述】:我正在使用功能模型 API,我想在 Keras 中创建以下自定义损失函数:
损失方程图像
我正在实现一个无监督的 CNN,值 Ix、Iy、It 和 epsilon 是常数,u 和 v 是我要学习的参数。
到目前为止,我的尝试都失败了,当我尝试训练它时,我的模型返回一个 ValueError 说“不支持任何值”。谷歌搜索后,我发现这是由于我的损失不可区分。
有人可以告诉我如何以 Keras 可区分的方式正确创建此损失函数。我的代码如下,任何帮助将不胜感激。
def charbonnier(I_x, I_y, I_t, U, V, e):
def charb(y_true, y_pred):
loss = K.sqrt(K.pow((multiply([U, I_x]) + multiply([V, I_y]) + I_t), 2) + e)
return K.mean(loss, axis=-1)
return charb
# Return the tf session used by the backend (optional)
tf_session = K.get_session()
def cnn(frame1, frame2):
# Concatenate the two images into one tensor.
input_ = np.dstack((frame1, frame2))
input_ = np.expand_dims(input_, axis=0)
print(input_.shape)
# Compute derivatives
I_x, I_y, I_t = compute_derivatives(input_)
#input_ = K.variable(input_)
inp_shape = (1, frame1.shape[0], frame1.shape[1], 2)
inp = Input(batch_shape=inp_shape)
conv1 = Conv2D(256, (7, 7), activation='relu', padding='same')(inp)
conv2 = Conv2D(256, (5, 5), activation='relu', padding='same')(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv2)
conv3 = Conv2D(512, (5, 5), activation='relu', padding='same')(pool1)
conv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv3)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv4)
conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool2)
conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv5)
pool3 = MaxPooling2D(pool_size=(2, 2))(conv6)
conv7 = Conv2D(1024, (3, 3), activation='relu', padding='same')(pool3)
conv8 = Conv2D(512, (1, 1), activation='relu', padding='same')(conv7)
pool4 = MaxPooling2D(pool_size=(2, 2))(conv8)
conv9 = Conv2D(256, (5, 5), activation='relu', padding='same')(pool4)
upsample1 = UpSampling2D(size=(2, 2))(conv9)
conv10 = Conv2D(128, (5, 5), activation='relu', padding='same')(upsample1)
upsample2 = UpSampling2D(size=(2, 2))(conv10)
conv11 = Conv2D(64, (5, 5), activation='relu', padding='same')(upsample2)
upsample3 = UpSampling2D(size=(2, 2))(conv11)
conv12 = Conv2D(2, (15, 13), padding='same')(upsample3)
leaky_relu = LeakyReLU(alpha=0.3)(conv12)
upsample4 = UpSampling2D(size=(2, 2), name='flow')(leaky_relu)
model = Model(inputs=inp, outputs=upsample4)
U = K.variable(model.output[0, :, :, 0])
V = K.variable(model.output[0, :, :, 1])
e = K.constant(0.1)
c_loss = charbonnier(I_x, I_y, I_t, U, V, e)
model.compile(loss=c_loss, optimizer='adam')
model.fit(input_, input_, batch_size=1, epochs=10)
model.evaluate()
【问题讨论】:
【参考方案1】:解决了。
变量 U 和 V 应按如下方式创建:
U = model.output[0, :, :, 0]
V = model.output[0, :, :, 1]
【讨论】:
以上是关于如何在 Keras 中创建这个自定义损失函数并确保它是可微的?的主要内容,如果未能解决你的问题,请参考以下文章
Keras 中的自定义损失函数 - 遍历 TensorFlow