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

How to use saved model in tensorflow.js

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

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

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

但是当我尝试使用该模型时,我遇到了一些逻辑问题。我使用 pandas dataframe 来训练模型,并使用 pandas 进行了一些测试和预测,但是如何在 js 中进行呢?我自己做的,但有一些错误。

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

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

    result = model.predict([1,2,3,4,5,6,7,8,9]);
    
  2. .bin文件在这里做什么?删除这个可以吗?

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

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

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

经过几个小时的联网,发现就是这两个原因。

const a = tf.tensor2d([1, 3, 0, 3, 3, 1, 2, 3, 2],[1,9],'int32');

const tensor = await getData();

前者重塑输入数据。后者很重要,等待数据读取。

为了完成@Nikita 的回答:

  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
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。所以,修改代码可能是这样的:
<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 文件存储模型的训练权重。你不能删除它。

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