Tensorflow 来自具有自定义丢失功能的keras的TypeError
我曾尝试使用为回归算法概述的符合jit的Tensorflow 来自具有自定义丢失功能的keras的TypeError,tensorflow,keras,numba,Tensorflow,Keras,Numba,我曾尝试使用为回归算法概述的符合jit的numba函数创建自定义损失函数。它似乎可以作为一个度量,但当用作损失时,我有一个奇怪的错误。我有一个玩具函数,在这里复制了这个问题: @njit def test_del(y_true, y_pred): cols = y_true.shape[1] out = 0 for i in range(y_true.shape[1]): true_dam = np.abs(y_true[:, i]).max() #to
numba
函数创建自定义损失函数。它似乎可以作为一个度量,但当用作损失时,我有一个奇怪的错误。我有一个玩具函数,在这里复制了这个问题:
@njit
def test_del(y_true, y_pred):
cols = y_true.shape[1]
out = 0
for i in range(y_true.shape[1]):
true_dam = np.abs(y_true[:, i]).max() #toy
pred_dam = np.abs(y_pred[:, i]).max() #toy
out += np.mean(np.abs(np.log(pred_dam / true_dam))**2)
return out/cols
(是的,我知道这个玩具问题可以优化到更矢量化,但它遵循的是我实际函数的结构,这是不可能的,所以我就不谈了)
然后我有一个损失/度量函数:
def del_loss(y_true, y_pred):
return tf.numpy_function(test_del, [y_true, y_pred], tf.float64) +\
K.cast(tf.keras.losses.mean_squared_error(y_true, y_pred), tf.float64)
现在,如果我用delu loss
作为度量编译一个模型(只要我将它转换为float64
,这很奇怪,但不管怎样),它就可以正常工作。但如果我把它当作一种损失,我会得到一系列奇怪的错误:
Traceback (most recent call last):
#removed my chain of objects resulting in a `model.compile(loss = del_loss)` call
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\backend\tensorflow_backend.py", line 75, in symbolic_fn_wrapper
return func(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\engine\training.py", line 229, in compile
self.total_loss = self._prepare_total_loss(masks)
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\engine\training.py", line 692, in _prepare_total_loss
y_true, y_pred, sample_weight=sample_weight)
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\losses.py", line 73, in __call__
losses, sample_weight, reduction=self.reduction)
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\utils\losses_utils.py", line 166, in compute_weighted_loss
losses, None, sample_weight)
File "C:\ProgramData\Anaconda3\envs\MLEnv\lib\site-packages\keras\utils\losses_utils.py", line 76, in squeeze_or_expand_dimensions
elif weights_rank - y_pred_rank == 1:
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
现在,如果我试图追溯到最后一步,我得到了压缩或扩展维度
,并意识到我处于如果
块中,只有当我有样本重量
时才会触发-我没有。在任何情况下,之前的代码都是:
y_pred_rank = K.ndim(y_pred)
weights_rank = K.ndim(sample_weight)
if weights_rank != 0:
if y_pred_rank == 0 and weights_rank == 1:
y_pred = K.expand_dims(y_pred, -1)
elif weights_rank - y_pred_rank == 1:
sample_weight = K.squeeze(sample_weight, -1)
elif y_pred_rank - weights_rank == 1:
sample_weight = K.expand_dims(sample_weight, -1)
不应该有任何方法让
y\u pred\u rank
或weights\u rank
最终成为None
(即使weights
早些时候设置为1
(就像在compute\u weighted\u loss
中出现的那样),weights\u rank
最终应该为0),但显然是这样。我无法理解这与我的新损失函数之间的关系在我的机器上,这个没有numba的虚拟示例可以工作:
def test_del(y_true, y_pred):
cols = y_true.shape[1]
out = 0
for i in range(y_true.shape[1]):
true_dam = np.abs(y_true[:, i]).max() #toy
pred_dam = np.abs(y_pred[:, i]).max() #toy
out += np.mean(np.abs(np.log(pred_dam / true_dam))**2)
return out/cols
def del_loss(y_true, y_pred):
return tf.numpy_function(test_del, [y_true, y_pred], tf.float64) +\
K.cast(tf.keras.losses.mean_squared_error(y_true, y_pred), tf.float64)
inp = Input((10,))
x = Dense(30)(inp)
out = Dense(10)(x)
model = Model(inp, out)
model.compile('adam', del_loss)
model.fit(np.random.uniform(0,1, (3,10)), np.random.uniform(0,1, (3,10)), epochs=3)
嗯,也许只是我的环境可能会一团糟。谢谢