yolo3 Keras中Lambda层的替代品

时间:2019-12-08 07:33:16

标签: python tensorflow keras tensorflow.js yolo

我的目标

我想在Tensorflow(python)中训练一个自定义对象检测模型,并在挖掘了大量我发现this的示例后使用它使用Tensorflow js

我做了什么

我已经写了Tensorflow JS部分(从在线示例获得帮助)来从本地加载模型并获得预测。我使用了COCO预训练模型,它工作正常(因此,这里不添加代码)。

我怎么了

我对python和Tensorflow非常陌生。 训练模型qqwweee/keras-yolo3的示例是python的,它是Keras的Lamda

from keras.layers import Input, Lambda这个地方

model.compile(optimizer=Adam(lr=1e-3), loss={
# use custom yolo_loss Lambda layer.
'yolo_loss': lambda y_true, y_pred: y_pred})

model.compile(optimizer=Adam(lr=1e-4), loss={'yolo_loss': lambda y_true, y_pred: y_pred}) # recompile to apply the change

model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
    arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
    [*model_body.output, *y_true])
model = Model([model_body.input, *y_true], model_loss)

因此,到目前为止,我了解到,Lambda主要用于计算损失函数,这在TFJS中引起了主要问题,因为到目前为止尚未实现Lambda层,我想使用一些替代方法来代替lambda层。 这是我在TFJS中使用经过训练的模型时遇到的错误

Error loading layer ValueError: Unknown layer: Lambda. This may be due to one of the following reasons:
1. The layer is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.
2. The custom layer is defined in JavaScript, but is not registered properly with tf.serialization.registerClass().

这里"Unknown layer: Lambda" in tensorflowjs on browser也提出了类似的问题,它涉及编写自定义层,示例不足以做到这一点,最终导致死胡同。

我想要的

  1. 是否有任何方法可以使用lambda指导的其他损失函数?怎么样?
  2. 有没有为lambda编写自定义层的示例
  3. 我的理解在哪里错了?

p.s:我花了很多时间来找到解决方案,任何帮助将不胜感激,谢谢


在添加@edkeveked(感谢!)给出的空lambda层之后,错误Error loading layer ValueError: Unknown layer: Lambda消失了,但又遇到了其他问题。

检查模型摘要here

现在,在模型预热中,它会抛出该错误 热身代码

let zero = tfNode.zeros([1, 416, 416, 3]);
const result = await this.model.predict(zero)
result.map(async (t) => await t.data());
result.map(async (t) => t.dispose());

图像预测代码

batched = tfNode.tidy(() => {
    if (!(img instanceof tfNode.Tensor)) {
        img = tfNode.browser.fromPixels(img);
    }
    return img.expandDims(0);
});
result = await this.model.predict(batched);

我收到错误

"Error: Error when checking model : the Array of Tensors that you are passing to your model is not the size the the model expected. Expected to see 4 Tensor(s), but instead got 1 Tensors(s).
    at new ValueError (XXX\node_modules\@tensorflow\tfjs-layers\dist\errors.js:68:28)
    at checkInputData (XXX\node_modules\@tensorflow\tfjs-layers\dist\engine\training.js:316:19)
    at LayersModel.predict (XXX\node_modules\@tensorflow\tfjs-layers\dist\engine\training.js:981:9)
    at ObjectDetection.warmUp (XXX\tensorflow_predownloaded_model.js:47:45)
    at XXX\tensorflow_predownloaded_model.js:38:18"

1 个答案:

答案 0 :(得分:1)

由于尚不支持Lambda层,因此需要提供该层以使转换正常进行。 此外,加载的层不用于训练,因此lambda层可以为空。 (代码未尝试)

class Lambda extends tf.layers.Layer {
  constructor() {
    super({})
  }

  static get className() {
    return 'Lambda';
  }

}

tf.serialization.SerializationMap.register(Lambda);

;