使用 Theano 函数在 Keras 中自定义损失函数
customised loss function in keras using theano function
我想使用自己的 binary_crossentropy 而不是使用 Keras 库附带的库。这是我的自定义函数:
import theano
from keras import backend as K
def elementwise_multiply(a, b): # a and b are tensors
c = a * b
return theano.function([a, b], c)
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = elementwise_multiply(first_log, y_true)
second_log = K.log(1 - y_pred)
second_log = elementwise_multiply(second_log, (1 - y_true))
result = second_log + first_log
return K.mean(result, axis=-1)
note: This is for practice. I'm aware of
T.nnet.binary_crossentropy(y_pred, y_true)
但是,当我编译模型时:
sgd = SGD(lr=0.001)
model.compile(loss = custom_objective, optimizer = sgd)
我收到这个错误:
--------------------------------------------------------------------------- TypeError Traceback (most recent call
last) in ()
36
37 sgd = SGD(lr=0.001)
---> 38 model.compile(loss = custom_objective, optimizer = sgd)
39 # ==============================================
C:\Program Files (x86)\Anaconda3\lib\site-packages\keras\models.py in
compile(self, optimizer, loss, class_mode)
418 else:
419 mask = None
--> 420 train_loss = weighted_loss(self.y, self.y_train, self.weights, mask)
421 test_loss = weighted_loss(self.y, self.y_test, self.weights, mask)
422
C:\Program Files (x86)\Anaconda3\lib\site-packages\keras\models.py in
weighted(y_true, y_pred, weights, mask)
80 '''
81 # score_array has ndim >= 2
---> 82 score_array = fn(y_true, y_pred)
83 if mask is not None:
84 # mask should have the same shape as score_array
in custom_objective(y_true, y_pred)
11 second_log = K.log(1 - K.clip(y_true, K.epsilon(), np.inf))
12 second_log = elementwise_multiply(second_log, (1-y_true))
---> 13 result = second_log + first_log
14 #result = np.multiply(result, y_pred)
15 return K.mean(result, axis=-1)
TypeError: unsupported operand type(s) for +: 'Function' and
'Function'
当我用内联函数替换 elementwise_multiply 时:
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = first_log * y_true
second_log = K.log(1 - y_pred)
second_log = second_log * (1-y_true)
result = second_log + first_log
return K.mean(result, axis=-1)
模型编译通过但损失值为nan:
Epoch 1/1 945/945 [==============================] - 62s - loss: nan -
acc: 0.0011 - val_loss: nan - val_acc: 0.0000e+00
有人可以帮我解决这个问题吗?!
谢谢
我发现了问题。我必须将 return 值乘以“-1”,因为我使用随机梯度下降 (sgd) 作为优化器而不是随机梯度上升!
这是代码,它非常有用:
import theano
from keras import backend as K
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = first_log * y_true
second_log = K.log(1 - y_pred)
second_log = second_log * (1 - y_true)
result = second_log + first_log
return (-1 * K.mean(result))
我想使用自己的 binary_crossentropy 而不是使用 Keras 库附带的库。这是我的自定义函数:
import theano
from keras import backend as K
def elementwise_multiply(a, b): # a and b are tensors
c = a * b
return theano.function([a, b], c)
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = elementwise_multiply(first_log, y_true)
second_log = K.log(1 - y_pred)
second_log = elementwise_multiply(second_log, (1 - y_true))
result = second_log + first_log
return K.mean(result, axis=-1)
note: This is for practice. I'm aware of T.nnet.binary_crossentropy(y_pred, y_true)
但是,当我编译模型时:
sgd = SGD(lr=0.001)
model.compile(loss = custom_objective, optimizer = sgd)
我收到这个错误:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () 36 37 sgd = SGD(lr=0.001) ---> 38 model.compile(loss = custom_objective, optimizer = sgd) 39 # ==============================================
C:\Program Files (x86)\Anaconda3\lib\site-packages\keras\models.py in compile(self, optimizer, loss, class_mode) 418 else: 419 mask = None --> 420 train_loss = weighted_loss(self.y, self.y_train, self.weights, mask) 421 test_loss = weighted_loss(self.y, self.y_test, self.weights, mask) 422
C:\Program Files (x86)\Anaconda3\lib\site-packages\keras\models.py in weighted(y_true, y_pred, weights, mask) 80 ''' 81 # score_array has ndim >= 2 ---> 82 score_array = fn(y_true, y_pred) 83 if mask is not None: 84 # mask should have the same shape as score_array
in custom_objective(y_true, y_pred) 11 second_log = K.log(1 - K.clip(y_true, K.epsilon(), np.inf)) 12 second_log = elementwise_multiply(second_log, (1-y_true)) ---> 13 result = second_log + first_log 14 #result = np.multiply(result, y_pred) 15 return K.mean(result, axis=-1)
TypeError: unsupported operand type(s) for +: 'Function' and 'Function'
当我用内联函数替换 elementwise_multiply 时:
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = first_log * y_true
second_log = K.log(1 - y_pred)
second_log = second_log * (1-y_true)
result = second_log + first_log
return K.mean(result, axis=-1)
模型编译通过但损失值为nan:
Epoch 1/1 945/945 [==============================] - 62s - loss: nan - acc: 0.0011 - val_loss: nan - val_acc: 0.0000e+00
有人可以帮我解决这个问题吗?!
谢谢
我发现了问题。我必须将 return 值乘以“-1”,因为我使用随机梯度下降 (sgd) 作为优化器而不是随机梯度上升!
这是代码,它非常有用:
import theano
from keras import backend as K
def custom_objective(y_true, y_pred):
first_log = K.log(y_pred)
first_log = first_log * y_true
second_log = K.log(1 - y_pred)
second_log = second_log * (1 - y_true)
result = second_log + first_log
return (-1 * K.mean(result))