我正在尝试实现加权二进制交叉熵损失函数 另外,我在训练中使用了自定义训练循环
def grads_ds(model_ds, ds_inputs,y_true,cw):
with tf.GradientTape() as ds_tape:
#ds_tape.watch(tf.convert_to_tensor(y_true.astype('float')))
#ds_tape.watch(tf.convert_to_tensor(ds_inputs))
y_pred = model_ds(ds_inputs)
#print(y_true,y_pred)
log_logits = np.append(np.log(y_pred),np.log(1-y_pred),axis=0).T
org_labs = np.append(y_true,1-y_true,axis=0).T
loss = K.sum(-1*org_labs*cw*log_logits,axis=1)
loss_value_ds = K.sum(loss)
ds_grads = ds_tape.gradient(loss_value_ds,model_ds.trainable_variables)
return loss_value_ds, ds_grads
y_true
和y_pred
的形状均为(1,3),而cw
的形状为(3,2)
cw
是
[[0.5145 3.6036]
[1.7163 0.7127]
[2.4231 0.6708]]
ds_tape.gradient
返回None
渐变。
我什至尝试为输入添加ds_tape.watch
和真实标签y_true
。但仍然收到None
。
在我的网络中,经过一定层后,我使用了tf.math.reduce_max
。这可能是问题的根源吗?
还是因为我在张量y_pred
上使用了numpy函数?
tf.GradientTape().gradient()
时, None
返回UNCONNECTED
。我不知道它是如何断开的。
注意:当我使用tf.keras.losses.binary_crossentropy(y_true,y_pred)
时,没有发生如上所述的错误。仅当我使用自定义损失计算代码而不是keras函数时,才会发生此错误
有解决方案吗? 我在网络上看不到任何方法。
答案 0 :(得分:0)
我这样运行您的代码:
import statistics
statistics.median(data)
最终,您的函数返回了一堆import tensorflow as tf
import numpy as np
K = tf.keras.backend
(x_trn,y_trn),(x_val,y_val) = tf.keras.datasets.mnist.load_data()
model = get_simple_1conv_1dense_model(x_trn,y_trn)
g = grads_ds(model, x_tst, y_tst, cw=1) # hopefully cw=1 makes sense
渐变:
None
但是,原因似乎很简单。在运行时,它产生了一个错误:
(<tf.Tensor: shape=(), dtype=float32, numpy=nan>, [None, None, None, None])
除以零很可能是您的罪魁祸首。
多花点时间,我发现这条线会导致错误:
/path/to/anaconda3/bin/ipython:9: RuntimeWarning: divide by zero encountered in log
if __name__ == '__main__':
/path/to/anaconda3/bin/ipython:11: RuntimeWarning: invalid value encountered in multiply
sys.exit(start_ipython())
答案 1 :(得分:0)
我通过使用tf.keras.backend
中的函数重写代码来解决了这个问题
def grads_ds(model_ds, ds_inputs,y_true,cw):
with tf.GradientTape() as ds_tape:
y_pred = model_ds(ds_inputs)
logits_1 = -1*y_true*K.log(y_pred)*cw[:,0]
loss = logits_1 + logits_0
loss_value_ds = K.sum(loss)
ds_grads = ds_tape.gradient(loss_value_ds,model_ds.trainable_variables,unconnected_gradients=tf.UnconnectedGradients.NONE)
return loss_value_ds, ds_grads
故事的寓意:numpy
函数不能在张量上使用。如果使用,则计算图不会保持连接状态。