【问题标题】:custom loss function with multiple output and using add_loss具有多个输出并使用 add_loss 的自定义损失函数
【发布时间】:2019-08-04 15:45:54
【问题描述】:

我在 keras 中有一个自动编码器,我需要一个损失函数,它是 mse、binary_crossentropy 和第三部分的组合,它试图使输出的像素数最小,其值不同于 0 或 1。最终损失应该是这样的:amse+bbinary_crossentropy+c*L。我为此使用了以下代码,但它会产生此错误:

Traceback(最近一次调用最后一次):文件 “”,第 134 行,在 if (pred_w(i,j)>=0 & pred_w(i,j)=0.9): TypeError: 'Tensor' object is not callable

你能告诉我我应该怎么做才能解决这个问题吗?感谢您的帮助。

wtm=Input((4,4,1))
image = Input((28, 28, 1))
conv1 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl1e')(image)
conv2 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl2e')(conv1)
conv3 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl3e')(conv2)
#conv3 = Conv2D(8, (3, 3), activation='relu', padding='same', name='convl3e', kernel_initializer='Orthogonal',bias_initializer='glorot_uniform')(conv2)
BN=BatchNormalization()(conv3)
encoded =  Conv2D(1, (5, 5), activation='relu', padding='same',name='encoded_I')(BN)

#-----------------------adding w---------------------------------------   

wpad=Kr.layers.Lambda(lambda xy: xy[0] + Kr.backend.spatial_2d_padding(xy[1], padding=((0, 24), (0, 24))))
encoded_merged=wpad([encoded,wtm])

#-----------------------decoder------------------------------------------------
#------------------------------------------------------------------------------
deconv1 = Conv2D(64, (5, 5), activation='elu', padding='same', name='convl1d')(encoded_merged)
deconv2 = Conv2D(64, (5, 5), activation='elu', padding='same', name='convl2d')(deconv1)
deconv3 = Conv2D(64, (5, 5), activation='elu',padding='same', name='convl3d')(deconv2)
deconv4 = Conv2D(64, (5, 5), activation='elu',padding='same', name='convl4d')(deconv3)
BNd=BatchNormalization()(deconv4)

decoded = Conv2D(1, (5, 5), activation='sigmoid', padding='same', name='decoder_output')(BNd)    
model=Model(inputs=[image,wtm],outputs=decoded)

decoded_noise = GaussianNoise(0.5)(decoded)

#----------------------w extraction------------------------------------
convw1 = Conv2D(64, (5,5), activation='relu', name='conl1w')(decoded_noise)#24
convw2 = Conv2D(64, (5,5), activation='relu', name='convl2w')(convw1)#20
convw3 = Conv2D(64, (5,5), activation='relu' ,name='conl3w')(convw2)#16
convw4 = Conv2D(64, (5,5), activation='relu' ,name='conl4w')(convw3)#12
convw5 = Conv2D(64, (5,5), activation='relu', name='conl5w')(convw4)#8
convw6 = Conv2D(64, (5,5), activation='relu', name='conl6w')(convw5)#4
convw7 = Conv2D(64, (5,5), activation='relu',padding='same', name='conl7w',dilation_rate=(2,2))(convw6)#4
convw8 = Conv2D(64, (5,5), activation='relu', padding='same',name='conl8w',dilation_rate=(2,2))(convw7)#4
convw9 = Conv2D(64, (5,5), activation='relu',padding='same', name='conl9w',dilation_rate=(2,2))(convw8)#4
convw10 = Conv2D(64, (5,5), activation='relu',padding='same', name='conl10w',dilation_rate=(2,2))(convw9)#4
BNed=BatchNormalization()(convw10)
pred_w = Conv2D(1, (1, 1), activation='sigmoid', padding='same', name='reconstructed_W',dilation_rate=(2,2))(BNed)  

w_extraction=Model(inputs=[image,wtm],outputs=[decoded,pred_w])

count=0
for i in range(28):
    for j in range(28):
        if (pred_w(i,j)>=0 & pred_w(i,j)<0.1)|(pred_w(i,j)<=1 & pred_w(i,j)>=0.9):
            count+=1

loss = K.sum(0.7*mse(decoded, image),binary_crossentropy(pred_w,wtm))+count
w_extraction.add_loss(loss)

【问题讨论】:

  • 我认为您应该包含完整的错误跟踪,以便其他人查找导致问题的行号
  • Traceback(最近一次调用最后):文件“”,第 134 行,在 if (pred_w(i,j)>=0 & pred_w( i,j)=0.9): TypeError: 'Tensor' object is not callable
  • 这是它产生的错误。我不知道以这种方式使用计数是否正确。我想在训练期间减少这个计数,但我不确定这段代码能不能做到?

标签: python tensorflow keras loss-function


【解决方案1】:

从技术上讲,如果您想引用矩阵的条目,该错误只会告诉您 pred_w(i,j) 应该是 pred_w[i,j] 。但是,要使此代码按照您的预期运行,需要进行更多的重写。

要真正优化损失,主要是它需要在网络中的权重方面是可微的。在这种情况下您可以使用的示例可能是:

  • (x-0.5)^N 表示相对较高的 N

  • 或log-barriers,即-log(x)-log(1-x)

实际上计算数字(这对优化没有帮助)可以用类似的东西来实现

count = tf.sum(pred_w<=0.1) + tf.sum(predictions_w>=0.9)

也许这有助于在训练期间输出该范围内的数字数量或类似情况。

【讨论】:

  • 谢谢。我是一个初学者,也许我说的是错误的。我喜欢在我的损失函数中添加一个术语,强制输出中的值变为 0 或 1(或接近它们)我认为通过计算值不同于 0 和 1 的值将其放入损失函数中,我强制网络减少它们。你能告诉我这是真的吗?我该怎么办?
  • 您对这个问题有什么建议?我怎样才能将这样的东西添加到损失函数中?
  • 我不确定您要什么。我在回答中给出了两个目标相似的损失示例:如果您从损失中减去 (x-0.5)^N,您的损失会在接近 0 和 1 / 远离 0.5 时变小,您可以对此进行优化。正如我在回答中所说的那样:计数缺失的主要原因是它们不可微分,即它们对模型输出没有导数,典型的神经网络优化器无法对此进行优化。
  • 这意味着如果我使用计数,它会在反向传播中变为零,因为它是一个数字,或者你的意思是它不可微分?
  • 我想我应该多解释一下我需要的东西。我的网络有两个输入(图像和 w,其中 w 是 0 和 1 输入)和两个输出,其中一个是输入图像的重建图像,第二个输出是重建图像,但值为 0 或 1。
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 2019-01-11
  • 2020-04-12
  • 1970-01-01
相关资源
最近更新 更多