我正致力于使用张量流作为后端为keras创建自定义丢失函数。要做到这一点,我想尝试类似于此处显示的内容:Customize Keras' loss function in a way that the y_true will depend on y_pred
然而,在运行脚本(取自Van)时:
import theano
from keras import backend as K
from keras.layers import Dense
from keras.models import Sequential
def customized_loss(y_true, y_pred):
loss = K.switch(K.equal(y_true, -1), 0, K.square(y_true-y_pred))
return K.sum(loss)
if __name__ == '__main__':
model = Sequential([ Dense(3, input_shape=(4,)) ])
model.compile(loss=customized_loss, optimizer='sgd')
import numpy as np
x = np.random.random((1, 4))
y = np.array([[1,-1,0]])
output = model.predict(x)
print output
# [[ 0.47242549 -0.45106074 0.13912249]]
print model.evaluate(x, y) # keras's loss
# 0.297689884901
print (output[0, 0]-1)**2 + 0 +(output[0, 2]-0)**2 # double-check
# 0.297689929093
我收到以下错误: AttributeError:'int'对象没有属性'get_shape'
然后我尝试使用tf.where(如Van的评论中所见),但是我收到了这个错误: ValueError:形状必须相等,但对于'loss / dense_1_loss / Select'(op:'Select'),形状必须为0和2,输入形状为:[?,?],[],[?,3]。
任何帮助将不胜感激
编辑: 完整的堆栈跟踪是: 对于第一种情况(K.switch):
Using TensorFlow backend.
2018-02-21 14:47:22.907033: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
Traceback (most recent call last):
File "temp.py", line 19, in <module>
model.compile(loss=customized_loss, optimizer='sgd')
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\models.py", line 806, in compile
**kwargs)
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\engine\training.py", line 860, in compile
sample_weight, mask)
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\engine\training.py", line 460, in weighted
score_array = fn(y_true, y_pred)
File "temp.py", line 10, in customized_loss
loss = K.switch(K.equal(y_true, -1), 0, K.square(y_true-y_pred))
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py", line 2674, in switch
expr_ndim = ndim(then_expression)
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py", line 590, in ndim
dims = x.get_shape()._dims
AttributeError: 'int' object has no attribute 'get_shape'
第二个错误(使用tf.where而不是K.switch):
Using TensorFlow backend.
2018-02-21 14:49:31.651045: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
Traceback (most recent call last):
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py", line 686, in _call_cpp_shape_fn_impl
input_tensors_as_shapes, status)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 473, in __exit__
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: Shapes must be equal rank, but are 0 and 2 for 'loss/dense_1_loss/Select' (op: 'Select') with input shapes: [?,?], [], [?,3].
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "temp.py", line 19, in <module>
model.compile(loss=customized_loss, optimizer='sgd')
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\models.py", line 806, in compile
**kwargs)
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\engine\training.py", line 860, in compile
sample_weight, mask)
File "C:\Users\shai\Anaconda3\lib\site-packages\keras\engine\training.py", line 460, in weighted
score_array = fn(y_true, y_pred)
File "temp.py", line 12, in customized_loss
loss = tf.where(K.equal(y_true, -1), 0.0, K.square(y_true - y_pred))
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\ops\array_ops.py", line 2441, in where
return gen_math_ops._select(condition=condition, t=x, e=y, name=name)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_math_ops.py", line 3987, in _select
"Select", condition=condition, t=t, e=e, name=name)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 787, in _apply_op_helper
op_def=op_def)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2958, in create_op
set_shapes_for_outputs(ret)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2209, in set_shapes_for_outputs
shapes = shape_func(op)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2159, in call_with_requiring
return call_cpp_shape_fn(op, require_shape_fn=True)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py", line 627, in call_cpp_shape_fn
require_shape_fn)
File "C:\Users\shai\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py", line 691, in _call_cpp_shape_fn_impl
raise ValueError(err.message)
ValueError: Shapes must be equal rank, but are 0 and 2 for 'loss/dense_1_loss/Select' (op: 'Select') with input shapes: [?,?], [], [?,3].
答案 0 :(得分:2)
而不是使用普通整数作为switch
的参数传递兼容的张量,例如使用zeros_like
创建它:
loss = K.switch(K.equal(y_true, -1), K.zeros_like(y_true), K.square(y_true-y_pred))