我在尝试训练我的LSTM网络语言模型,并使用困惑度函数作为我的损失函数,但得到了以下错误:
ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
我的损失函数如下所示:
from keras import backend as Kdef perplexity_raw(y_true, y_pred): """ 困惑度指标。为什么这还没有成为Keras的一部分?! https://stackoverflow.com/questions/41881308/how-to-calculate-perplexity-of-rnn-in-tensorflow https://github.com/keras-team/keras/issues/8267 """# cross_entropy = K.sparse_categorical_crossentropy(y_true, y_pred) cross_entropy = K.cast(K.equal(K.max(y_true, axis=-1), K.cast(K.argmax(y_pred, axis=-1), K.floatx())), K.floatx()) perplexity = K.exp(cross_entropy) return perplexity
我创建模型的方式如下:
# 定义模型model = Sequential()model.add(Embedding(vocab_size, 500, input_length=max_length-1))model.add(LSTM(750))model.add(Dense(vocab_size, activation='softmax'))print(model.summary())# 编译网络model.compile(loss=perplexity_raw, optimizer='adam', metrics=['accuracy'])# 训练网络model.fit(X, y, epochs=150, verbose=2)
当我尝试拟合模型时会出现错误。有人知道错误的原因和解决方法吗?
回答:
这些是罪魁祸首:K.argmax
和 K.max
。它们没有梯度。我还认为你在损失度量中根本不需要它们!这是因为max
和argmax
操作会去掉关于预测错误程度的信息。
我不知道你想测量哪种损失,但我认为你可能在寻找像tf.exp(tf.nn.sigmoid_cross_entropy_with_logits(y_true, y_pred))
或 tf.exp(tf.softmax_cross_entopy_with_logits(y_true, y_pred))
这样的东西。你可能需要使用tf.one_hot
将你的logits转换为独热编码。