Tensorflow.js:运算最大值的梯度错误。输入'$ a'的渐变形状为'32,200',与输入'32,1'的形状不匹配

时间:2019-03-14 10:15:33

标签: tensorflow tensorflow.js

我构建了一个非常简单的Tensorflow操作,一切似乎都有意义,但是当我调用fit函数时,该模型无法通过上述错误消息向后传播梯度:

Error in gradient for op maximum. 

The gradient of input '$a' has shape '32,200', 
which does not match the shape of the input '32,1'

以下是xTrainyTrain的类型

xTrain
  Array(3) [2000, 20, 73]
  float32
yTrain
  Array(2) [2000, 200]
  float32

以下是模型的预期输入和输出:

model.input
  Array(3) [null, 20, 73]
  float32
model.outputs[0]
  Array(2) [null, 200]
  float32

[EDIT]我应该注意,我的问题仅在尝试使用

时发生
loss: 'cosineProximity'

这是我的代码:

console.log("starting compute_and_save_model");

const model = tf.sequential();
model.add(tf.layers.simpleRNN({
    units: length_of_embedding,//amount_of_rnn_units,
    recurrentInitializer: 'glorotNormal',
    inputShape: [max_len, recogized_letters.length],
    return_sequences: false,
}));

console.log(model.input.shape);
console.log(model.input.dtype);
console.log(model.outputs[0].shape);
console.log(model.outputs[0].dtype);
console.log(model.batchInputShape);

model.compile({
    loss: 'cosineProximity',
    optimizer: 'adam',
    metrics: ['acc']
});

console.log("starting compute_and_save_model (fit)")

await model.fit(xTrain, yTrain, {
    epochs: 2,
    batchSize: 32,
    validationSplit: 0.2,
    callbacks: {
        onBatchBegin(b) {
            console.log("starting compute_and_save_model (fit:"+b+")");
        }
    }
});
  

可从https://stackblitz.com/edit/js-ddlwge运行

有人知道这里有什么问题吗?

  

编辑:我试图创建自己的cosineProximity实现并得到相同的错误。供参考的是我对cosineProximity的实现:

     
const cosine = tf.layers.dot({axes: -1,normalize:true})
     
loss: function(a,b) {
    return tf.neg(tf.mean(cosine.apply([a,b])));
},

1 个答案:

答案 0 :(得分:1)

好吧,我花了一些时间,看来这是Tensforflow.js实现中的错误。

如果您遇到相同的问题,则可以自己应用以下补丁来解决此问题(我相信tfjs-layers维护者最终会合并此请求请求,因此希望以后不会再出现此问题)。

  

https://github.com/tensorflow/tfjs-layers/pull/499

| export function l2Normalize(x: Tensor, axis?: number): Tensor {
|   return tidy(() => {
|     const squareSum = tfc.sum(K.square(x), axis, true);
-     const epsilonTensor = tfc.mul(scalar(epsilon()), tfc.onesLike(x));
+     const epsilonTensor = tfc.mul(scalar(epsilon()), tfc.onesLike(squareSum));
|     const norm = tfc.sqrt(tfc.maximum(squareSum, epsilonTensor));
|     return tfc.div(x, norm);
|   });
| }