【问题标题】:Error in Keras custom loss function - tensotflowKeras 自定义损失函数中的错误 - tensorflow
【发布时间】:2019-05-03 21:15:40
【问题描述】:

我是 tensorflow 的新手,我一直在关注以下问题的答案,以便在 Keras 中构建一个仅考虑前 20 个预测的自定义损失函数。

How can I sort the values in a custom Keras / Tensorflow Loss Function?

但是,当我尝试使用此代码编译模型时,我收到以下关于尺寸的错误

InvalidArgumentError: input must have last dimension >= k = 20 but is 1 for 'loss_21/dense_65_loss/TopKV2' (op: 'TopKV2') with input shapes: [?,1], [] and with computed input tensors: input[1] = <20>.

重新产生错误的代码的简化版本如下。

import tensorflow as tf    
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.optimizers import SGD

top = 20

def top_loss(y_true, y_pred):
    y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred, top)
    loss_per_sample = tf.reduce_mean(tf.reduce_sum(y_pred_top_k,
            axis=-1))

    return loss_per_sample

model = Sequential()
model.add(Dense(50, input_dim=201))
model.add(Dense(1))
sgd = SGD(lr=0.01, decay=0, momentum=0.9)
model.compile(loss=top_loss, optimizer=sgd)

在编译模型时,top_loss函数的下面一行会抛出错误。

y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred, top)

似乎y_pred 在编译时的形状默认为[?,1],而tf.nn.top_k 函数期望维度至少高于“k”(即20)。

我是否必须将y_pred 转换为某个东西,以便tf.nn.top_k 知道它的尺寸正确?

【问题讨论】:

  • 你也可以发布你的模型代码吗?
  • 我用一个重现错误的简单示例编辑了我的问题。似乎在编译时输入顶部 top_loss 具有未定义的尺寸,而 tf.nn.top_k 期望不同。

标签: python tensorflow keras


【解决方案1】:

用途:

y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred[:,0], top)

y_pred[:,0] 获取全批次的预测值作为 rank 1 张量。

另一个问题:

但是,最后一批仍然会出现问题。假设您的批量大小为 32,您的训练数据大小为 100,那么最后一批的大小将小于 20,因此 tf.nn.top_k 将导致最后一批的运行时错误。只需确保您的最后一批大小 >= 20 即可避免此问题。然而,更好的方法是检查当前批次是否小于 20,如果是,请调整您的 k 值以在 top_k 中使用

代码

import tensorflow as tf    
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.optimizers import SGD

top = tf.constant(20)

def top_loss(y_true, y_pred):
    result = tf.cond(tf.math.greater(top_, tf.shape(y_true)[0]), 
                     lambda: tf.shape(y_true)[0], lambda: top)

    y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred[:,0], result)
    loss_per_sample = tf.reduce_mean(tf.reduce_sum(y_pred_top_k,
            axis=-1))

    return loss_per_sample

model = Sequential()
model.add(Dense(50, input_dim=201))
model.add(Dense(1))
sgd = SGD(lr=0.01, decay=0, momentum=0.9)
model.compile(loss=top_loss, optimizer=sgd)

【讨论】:

    猜你喜欢
    • 2018-10-28
    • 2017-12-29
    • 2019-03-10
    • 2017-12-20
    • 2020-10-21
    • 1970-01-01
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    相关资源
    最近更新 更多