пользовательская функция потерь с несколькими выходами и использованием add_loss - PullRequest
0 голосов
/ 13 марта 2019

У меня есть авто-кодер в керасе, и мне нужна функция потерь, которая является комбинацией mse, двоичного_кросентропии и третьей части, которая пытается сделать минимальное количество пикселей вывода, значение которых отличается от 0 или 1.потеря должна быть такой: a mse + b binary_crossentropy + c * L.Я использовал приведенный ниже код для этого, но он выдает эту ошибку:

Traceback (последний вызов был последним): файл "", строка 134, в if (pred_w (i, j)> = 0 &pred_w (i, j) <0,1) | (pred_w (i, j) <= 1 & pred_w (i, j)> = 0,9): Ошибка типа: объект 'Tensor' не может быть вызван

не могли бы вы сказать мне, что я должен сделать, чтобы решить эту проблему?Я ценю вашу помощь.

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)

1 Ответ

0 голосов
/ 14 марта 2019

Технически ошибка просто говорит вам, что pred_w (i, j) должно быть pred_w [i, j], если вы хотите сослаться на элемент матрицы.Однако, чтобы сделать этот код таким, каким вы его собираетесь запускать, требуется немного больше переписать.

Чтобы реально оптимизировать потери, главное, чтобы они были дифференцируемыми в отношении весов в сетях.Примеры, которые вы можете использовать в этом случае, могут быть:

  • (x-0,5) ^ N для относительно высокого значения N

  • или логарифмические барьеры, т. е. -log (x) -log (1-x)

фактического подсчета чисел (что не поможет при оптимизации) может быть достигнуто с помощью чего-то вроде

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

Может быть, это полезно для вывода количества чисел в этом диапазоне во время тренировки или что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...