如何在 tensorflow.js 中使用保存的模型

如何在 tensorflow.js 中使用保存的模型

问题描述:

我发现我可以在 tensorflow.js 中使用 Python 训练的 tensorflow 模型.

I have found that I could use python-trained tensorflow model in tensorflow.js.

我使用 tensorflowjs_wizard 转换了模型并按照他们的说明进行操作.

I converted the model with tensorflowjs_wizard and followed their instructions.

结果,我得到了json文件和bin文件(这是js使用的模型文件)

As a result, I got json file and bin file(this is the model file for js usage).

但是当我尝试使用该模型时,我遇到了一些合乎逻辑的问题.我使用 pandas 数据框训练模型并使用 pandas 进行了一些测试和预测,但是如何在 js 中进行呢?我自己做了,但出现了一些错误.

But when I tried to use the model, I got stuck with some logical hits. I used pandas dataframe to train model and made some tests and predictions with pandas, but how to do it in js? I did it myself but got some errors.

简而言之,我有这些问题.

To make it short, I have these questions.

  1. 如何在js中使用model.predict()?可以这样使用吗?

result = model.predict([1,2,3,4,5,6,7,8,9]);

  • .bin 文件在这里做什么?删除这个可以吗?

  • What is .bin file doing here? Will it be OK to delete this?

    我发现loadLayerModel()loadGraphModel() 用于从文件中加载模型,什么时候使用?

    I found that loadLayerModel() or loadGraphModel() is used to load model from file, what is used when?

    这里是 HTML 和 js 文件(如 tensorflow.js 教程).

    Here are the HTML and js files(as in tensorflow.js tutorials).

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>TensorFlow</title>
      <!-- Import TensorFlow.js -->
      <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>
      
      <!-- Import the main script file -->
      <script src="script.js" type="module"></script>
    </head>
    <body>
      
    </body>
    </html>
    

    script.js

    async function getData() {
      const a = tf.tensor2d([1, 3, 0, 3, 3, 1, 2, 3, 2]);
      return a;
    }
    
    async function run() {
      const model = await tf.loadGraphModel('/json/model.json');
      const tensor = getData();
      const result = model.predict(tensor);
      console.log(result);
    }
    
    document.addEventListener('DOMContentLoaded', run)
    

    这是控制台错误消息.

    tensor_ops.js:209 Uncaught (in promise) Error: tensor2d() requires shape to be provided when `values` are a flat/TypedArray
        at Object.uy [as tensor2d] (tensor_ops.js:209)
        at getData (script.js:3)
        at HTMLDocument.run (script.js:9)
    
    graph_executor.js:119 Uncaught (in promise) Error: Cannot compute the outputs [Identity] from the provided inputs []. Missing the following inputs: [dense_21_input]
        at t.e.compile (graph_executor.js:119)
        at t.e.execute (graph_executor.js:152)
        at t.e.execute (graph_model.js:288)
        at t.e.predict (graph_model.js:242)
        at HTMLDocument.run (script.js:10)
    

    文件夹树:

    index.html
    
    script.js
    
    json/model.json
    
    json/group1-shard1of1.bin
    

  • 为了完成@Nikita的回答:

    In order to complete @Nikita's answer:

    1. 由于您的训练数据都是整数,因此模型需要整数.最好在训练时将它们转换为浮动.例如像这样:

    train = np.array(train).astype('float32')
    train_labels = np.array(train_labels).astype('float32')
    model.fit(train ,train_labels , epochs=20)
    

    1. 另一件可能很重要的事情是,由于您尚未为最后一层定义激活函数,因此您可以在任何范围内进行预测,甚至是负数.最好从损失函数中去除 from_logits=True 并将 activation=softmax 添加到最后一层:
    1. One other thing may be important is that, since you have not defined activation function for your last layer, you get prediction in any range, even negative numbers. It's better to remove from_logits=True from loss function and add activation=softmax to last layer:

    model = tf.keras.Sequential([
        tf.keras.layers.Dense(1,activation="relu"),
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(4,activation="softmax")
    ])
    
    model.compile(optimizer='adam',
        loss=tf.keras.losses.SparseCategoricalCrossentropy(),
        metrics=['accuracy'])
    

    1. 你会得到4个数字作为输出,如果你想得到类别索引,你可以在预测后使用argmax.所以,修改代码可能是这样的:
    1. You will get 4 numbers as output, and if you want to get category index, you may use argmax after prediction. So, modification code maybe something like this:

    <html>
    <head>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>   
    <script>
        async function run(){
            const MODEL_URL = 'http://127.0.0.1:8887/model.json';
            const model = await tf.loadLayersModel(MODEL_URL);
            console.log(model.summary());
            const input = tf.tensor2d([1, 3, 0, 3, 3, 1, 2, 3, 2], [1,9]);
            const result = await model.predict(input);
            const res = await result.argMax(axis=1);
            alert(res)
        }
        run();
    </script>
    </head> 
    <body></body>   
    </html>
    

    1. .json 文件存储模型架构,.bin 文件存储模型的训练权重.您无法删除它.

    1. .json file stores your model architecture, and .bin file(s) stores trained weights of your model. You can not delete it.

    tf.loadLayersModel() 加载由层对象组成的模型,包括其拓扑结构和可选的权重.它的局限性在于,这不适用于 TensorFlow SavedModels 或其转换形式.对于这些模型,您应该使用 tf.loadGraphModel().

    tf.loadLayersModel() loads a model composed of layer objects, including its topology and optionally weights. It's limitations is ,this is not applicable to TensorFlow SavedModels or their converted forms. For those models, you should use tf.loadGraphModel().