我正在尝试实现一个加权的二进制交叉熵损失函数,我正在使用一个自定义的训练循环进行训练
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_gradsy_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渐变。我甚至尝试为输入和真正的标签y_true添加ds_tape.watch。但仍在接收None。
在我的网络中,我在某个层之后使用了tf.math.reduce_max。这会是问题的根源吗?
还是因为我在张量y_pred上使用了numpy函数
当目标和源为UNCONNECTED时,tf.GradientTape().gradient()返回None。我搞不懂它是怎么断线的。
注意:当我使用tf.keras.losses.binary_crossentropy(y_true,y_pred)时,没有出现上面提到的错误。只有当我使用自定义损失计算代码而不是keras函数时,才会发生此错误
有什么解决方案吗?我在网上看到的方法都不管用。
发布于 2020-06-12 22:32:32
通过使用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函数不能用于张量。如果使用,计算图将不会保持连接。
发布于 2020-06-12 21:59:43
我像这样运行你的代码:
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())除以0很可能是你的罪魁祸首。
通过更多的欺骗,我发现这一行导致了错误:
log_logits = np.append(np.log(y_pred),np.log(1-y_pred),axis=0).Thttps://stackoverflow.com/questions/62345351
复制相似问题