前端搞AI:在浏览器中训练模型

2022-07-29 08:42:28 浏览数 (1)

⭐️ 本文首发自 [前端修罗场],是一个由资深开发者独立运行的专业技术社区,我专注 Web 技术、答疑解惑、面试辅导以及职业发展。帮你评估知识点的掌握程度,获得更全面的学习指导意见,交个朋友,不走弯路,少吃亏!

识别鸢尾花

本文将在浏览器中定义、训练和运行模型。为了实现这一功能,我将构建一个识别鸢尾花的案例。

接下来,我们将创建一个神经网络。同时,根据开源数据集我们将鸢尾花分为三类:Setosa、Virginica 和 Versicolor。

每个机器学习项目的核心都是数据集。我们需要采取的第一步是将这个数据集拆分为训练集和测试集

这样做的原因是我们将使用我们的训练集来训练我们的算法和我们的测试集来检查我们的预测的准确性,以验证我们的模型是否可以使用或需要调整。

为了方便起见,我已经将训练集和测试集拆分为两个 JSON 文件:

  • 测试集: testing.json
代码语言:javascript复制
[{"sepal_length":,"sepal_width":2.9,"petal_length":4.5,"petal_width":1.5,"species":"versicolor"},{"sepal_length":5.2,"sepal_width":3.4,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":6.5,"sepal_width":,"petal_length":5.8,"petal_width":2.2,"species":"virginica"},{"sepal_length":5.9,"sepal_width":3.2,"petal_length":4.8,"petal_width":1.8,"species":"versicolor"},{"sepal_length":5.1,"sepal_width":3.8,"petal_length":1.9,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.4,"sepal_width":,"petal_length":4.5,"petal_width":1.5,"species":"versicolor"},{"sepal_length":,"sepal_width":3.2,"petal_length":4.7,"petal_width":1.4,"species":"versicolor"},{"sepal_length":5.7,"sepal_width":2.8,"petal_length":4.5,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.1,"sepal_width":2.5,"petal_length":,"petal_width":1.1,"species":"versicolor"},{"sepal_length":4.9,"sepal_width":2.4,"petal_length":3.3,"petal_width":,"species":"versicolor"},{"sepal_length":5.1,"sepal_width":3.7,"petal_length":1.5,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.7,"sepal_width":2.8,"petal_length":4.1,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.6,"sepal_width":,"petal_length":4.5,"petal_width":1.5,"species":"versicolor"},{"sepal_length":6.1,"sepal_width":,"petal_length":4.6,"petal_width":1.4,"species":"versicolor"}]
  • 训练集: training.json
代码语言:javascript复制
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释 
* [{"sepal_length":5.1,"sepal_width":3.5,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.9,"sepal_width":,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.7,"sepal_width":3.2,"petal_length":1.3,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.6,"sepal_width":3.1,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":3.6,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.6,"sepal_width":3.4,"petal_length":1.4,"petal_width":0.3,"species":"setosa"},{"sepal_length":,"sepal_width":3.4,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.4,"sepal_width":2.9,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.9,"sepal_width":3.1,"petal_length":1.5,"petal_width":0.1,"species":"setosa"},{"sepal_length":5.4,"sepal_width":3.7,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.8,"sepal_width":3.4,"petal_length":1.6,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.8,"sepal_width":,"petal_length":1.4,"petal_width":0.1,"species":"setosa"},{"sepal_length":4.3,"sepal_width":,"petal_length":1.1,"petal_width":0.1,"species":"setosa"},{"sepal_length":5.8,"sepal_width":,"petal_length":1.2,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.7,"sepal_width":4.4,"petal_length":1.5,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.4,"sepal_width":3.9,"petal_length":1.3,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.1,"sepal_width":3.5,"petal_length":1.4,"petal_width":0.3,"species":"setosa"},{"sepal_length":5.7,"sepal_width":3.8,"petal_length":1.7,"petal_width":0.3,"species":"setosa"},{"sepal_length":5.1,"sepal_width":3.8,"petal_length":1.5,"petal_width":0.3,"species":"setosa"},{"sepal_length":5.4,"sepal_width":3.4,"petal_length":1.7,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.6,"sepal_width":3.6,"petal_length":,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.1,"sepal_width":3.3,"petal_length":1.7,"petal_width":0.5,"species":"setosa"},{"sepal_length":4.8,"sepal_width":3.4,"petal_length":1.9,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":,"petal_length":1.6,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":3.4,"petal_length":1.6,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.2,"sepal_width":3.5,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.7,"sepal_width":3.2,"petal_length":1.6,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.8,"sepal_width":3.1,"petal_length":1.6,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.4,"sepal_width":3.4,"petal_length":1.5,"petal_width":0.4,"species":"setosa"},{"sepal_length":5.2,"sepal_width":4.1,"petal_length":1.5,"petal_width":0.1,"species":"setosa"},{"sepal_length":5.5,"sepal_width":4.2,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.9,"sepal_width":3.1,"petal_length":1.5,"petal_width":0.1,"species":"setosa"},{"sepal_length":,"sepal_width":3.2,"petal_length":1.2,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.5,"sepal_width":3.5,"petal_length":1.3,"petal_width":0.2,"species":"setosa"},{"sepal_length":4.9,"sepal_width":3.1,"petal_length":1.5,"petal_width":0.1,"species":"setosa"},{"sepal_length":4.4,"sepal_width":,"petal_length":1.3,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.1,"sepal_width":3.4,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":3.5,"petal_length":1.3,"petal_width":0.3,"species":"setosa"},{"sepal_length":4.5,"sepal_width":2.3,"petal_length":1.3,"petal_width":0.3,"species":"setosa"},{"sepal_length":4.4,"sepal_width":3.2,"petal_length":1.3,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":3.5,"petal_length":1.6,"petal_width":0.6,"species":"setosa"},{"sepal_length":4.8,"sepal_width":,"petal_length":1.4,"petal_width":0.3,"species":"setosa"},{"sepal_length":5.1,"sepal_width":3.8,"petal_length":1.6,"petal_width":0.2,"species":"setosa"},{"sepal_length":5.3,"sepal_width":3.7,"petal_length":1.5,"petal_width":0.2,"species":"setosa"},{"sepal_length":,"sepal_width":3.3,"petal_length":1.4,"petal_width":0.2,"species":"setosa"},{"sepal_length":6.4,"sepal_width":3.2,"petal_length":4.5,"petal_width":1.5,"species":"versicolor"},{"sepal_length":5.5,"sepal_width":2.3,"petal_length":,"petal_width":1.3,"species":"versicolor"},{"sepal_length":6.5,"sepal_width":2.8,"petal_length":4.6,"petal_width":1.5,"species":"versicolor"},{"sepal_length":6.3,"sepal_width":3.3,"petal_length":4.7,"petal_width":1.6,"species":"versicolor"},{"sepal_length":6.6,"sepal_width":2.9,"petal_length":4.6,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.2,"sepal_width":2.7,"petal_length":3.9,"petal_width":1.4,"species":"versicolor"},{"sepal_length":,"sepal_width":,"petal_length":3.5,"petal_width":,"species":"versicolor"},{"sepal_length":5.9,"sepal_width":,"petal_length":4.2,"petal_width":1.5,"species":"versicolor"},{"sepal_length":,"sepal_width":2.2,"petal_length":,"petal_width":,"species":"versicolor"},{"sepal_length":6.1,"sepal_width":2.9,"petal_length":4.7,"petal_width":1.4,"species":"versicolor"},{"sepal_length":5.6,"sepal_width":2.9,"petal_length":3.6,"petal_width":1.3,"species":"versicolor"},{"sepal_length":6.7,"sepal_width":3.1,"petal_length":4.4,"petal_width":1.4,"species":"versicolor"},{"sepal_length":5.8,"sepal_width":2.7,"petal_length":4.1,"petal_width":,"species":"versicolor"},{"sepal_length":6.2,"sepal_width":2.2,"petal_length":4.5,"petal_width":1.5,"species":"versicolor"},{"sepal_length":5.6,"sepal_width":2.5,"petal_length":3.9,"petal_width":1.1,"species":"versicolor"},{"sepal_length":6.1,"sepal_width":2.8,"petal_length":,"petal_width":1.3,"species":"versicolor"},{"sepal_length":6.3,"sepal_width":2.5,"petal_length":4.9,"petal_width":1.5,"species":"versicolor"},{"sepal_length":6.1,"sepal_width":2.8,"petal_length":4.7,"petal_width":1.2,"species":"versicolor"},{"sepal_length":6.4,"sepal_width":2.9,"petal_length":4.3,"petal_width":1.3,"species":"versicolor"},{"sepal_length":6.6,"sepal_width":,"petal_length":4.4,"petal_width":1.4,"species":"versicolor"},{"sepal_length":6.8,"sepal_width":2.8,"petal_length":4.8,"petal_width":1.4,"species":"versicolor"},{"sepal_length":6.7,"sepal_width":,"petal_length":,"petal_width":1.7,"species":"versicolor"},{"sepal_length":5.7,"sepal_width":2.6,"petal_length":3.5,"petal_width":,"species":"versicolor"},{"sepal_length":5.5,"sepal_width":2.4,"petal_length":3.8,"petal_width":1.1,"species":"versicolor"},{"sepal_length":5.5,"sepal_width":2.4,"petal_length":3.7,"petal_width":,"species":"versicolor"},{"sepal_length":5.8,"sepal_width":2.7,"petal_length":3.9,"petal_width":1.2,"species":"versicolor"},{"sepal_length":,"sepal_width":2.7,"petal_length":5.1,"petal_width":1.6,"species":"versicolor"},{"sepal_length":,"sepal_width":3.4,"petal_length":4.5,"petal_width":1.6,"species":"versicolor"},{"sepal_length":6.7,"sepal_width":3.1,"petal_length":4.7,"petal_width":1.5,"species":"versicolor"},{"sepal_length":6.3,"sepal_width":2.3,"petal_length":4.4,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.6,"sepal_width":,"petal_length":4.1,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.5,"sepal_width":2.5,"petal_length":,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.5,"sepal_width":2.6,"petal_length":4.4,"petal_width":1.2,"species":"versicolor"},{"sepal_length":5.8,"sepal_width":2.6,"petal_length":,"petal_width":1.2,"species":"versicolor"},{"sepal_length":,"sepal_width":2.3,"petal_length":3.3,"petal_width":,"species":"versicolor"},{"sepal_length":5.6,"sepal_width":2.7,"petal_length":4.2,"petal_width":1.3,"species":"versicolor"},{"sepal_length":5.7,"sepal_width":,"petal_length":4.2,"petal_width":1.2,"species":"versicolor"},{"sepal_length":6.2,"sepal_width":2.9,"petal_length":4.3,"petal_width":1.3,"species":"versicolor"},{"sepal_length":6.3,"sepal_width":3.3,"petal_length":,"petal_width":2.5,"species":"virginica"},{"sepal_length":5.8,"sepal_width":2.7,"petal_length":5.1,"petal_width":1.9,"species":"virginica"},{"sepal_length":7.1,"sepal_width":,"petal_length":5.9,"petal_width":2.1,"species":"virginica"},{"sepal_length":6.3,"sepal_width":2.9,"petal_length":5.6,"petal_width":1.8,"species":"virginica"},{"sepal_length":7.6,"sepal_width":,"petal_length":6.6,"petal_width":2.1,"species":"virginica"},{"sepal_length":4.9,"sepal_width":2.5,"petal_length":4.5,"petal_width":1.7,"species":"virginica"},{"sepal_length":7.3,"sepal_width":2.9,"petal_length":6.3,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.7,"sepal_width":2.5,"petal_length":5.8,"petal_width":1.8,"species":"virginica"},{"sepal_length":7.2,"sepal_width":3.6,"petal_length":6.1,"petal_width":2.5,"species":"virginica"},{"sepal_length":6.5,"sepal_width":3.2,"petal_length":5.1,"petal_width":,"species":"virginica"},{"sepal_length":6.4,"sepal_width":2.7,"petal_length":5.3,"petal_width":1.9,"species":"virginica"},{"sepal_length":6.8,"sepal_width":,"petal_length":5.5,"petal_width":2.1,"species":"virginica"},{"sepal_length":5.7,"sepal_width":2.5,"petal_length":,"petal_width":,"species":"virginica"},{"sepal_length":5.8,"sepal_width":2.8,"petal_length":5.1,"petal_width":2.4,"species":"virginica"},{"sepal_length":6.4,"sepal_width":3.2,"petal_length":5.3,"petal_width":2.3,"species":"virginica"},{"sepal_length":6.5,"sepal_width":,"petal_length":5.5,"petal_width":1.8,"species":"virginica"},{"sepal_length":7.7,"sepal_width":3.8,"petal_length":6.7,"petal_width":2.2,"species":"virginica"},{"sepal_length":7.7,"sepal_width":2.6,"petal_length":6.9,"petal_width":2.3,"species":"virginica"},{"sepal_length":,"sepal_width":2.2,"petal_length":,"petal_width":1.5,"species":"virginica"},{"sepal_length":6.9,"sepal_width":3.2,"petal_length":5.7,"petal_width":2.3,"species":"virginica"},{"sepal_length":5.6,"sepal_width":2.8,"petal_length":4.9,"petal_width":,"species":"virginica"},{"sepal_length":7.7,"sepal_width":2.8,"petal_length":6.7,"petal_width":,"species":"virginica"},{"sepal_length":6.3,"sepal_width":2.7,"petal_length":4.9,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.7,"sepal_width":3.3,"petal_length":5.7,"petal_width":2.1,"species":"virginica"},{"sepal_length":7.2,"sepal_width":3.2,"petal_length":,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.2,"sepal_width":2.8,"petal_length":4.8,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.1,"sepal_width":,"petal_length":4.9,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.4,"sepal_width":2.8,"petal_length":5.6,"petal_width":2.1,"species":"virginica"},{"sepal_length":7.2,"sepal_width":,"petal_length":5.8,"petal_width":1.6,"species":"virginica"},{"sepal_length":7.9,"sepal_width":3.8,"petal_length":6.4,"petal_width":,"species":"virginica"},{"sepal_length":6.4,"sepal_width":2.8,"petal_length":5.6,"petal_width":2.2,"species":"virginica"},{"sepal_length":6.3,"sepal_width":2.8,"petal_length":5.1,"petal_width":1.5,"species":"virginica"},{"sepal_length":6.1,"sepal_width":2.6,"petal_length":5.6,"petal_width":1.4,"species":"virginica"},{"sepal_length":7.7,"sepal_width":,"petal_length":6.1,"petal_width":2.3,"species":"virginica"},{"sepal_length":6.3,"sepal_width":3.4,"petal_length":5.6,"petal_width":2.4,"species":"virginica"},{"sepal_length":6.4,"sepal_width":3.1,"petal_length":5.5,"petal_width":1.8,"species":"virginica"},{"sepal_length":,"sepal_width":,"petal_length":4.8,"petal_width":1.8,"species":"virginica"},{"sepal_length":6.9,"sepal_width":3.1,"petal_length":5.4,"petal_width":2.1,"species":"virginica"},{"sepal_length":6.7,"sepal_width":3.1,"petal_length":5.6,"petal_width":2.4,"species":"virginica"},{"sepal_length":6.9,"sepal_width":3.1,"petal_length":5.1,"petal_width":2.3,"species":"virginica"},{"sepal_length":5.8,"sepal_width":2.7,"petal_length":5.1,"petal_width":1.9,"species":"virginica"},{"sepal_length":6.8,"sepal_width":3.2,"petal_length":5.9,"petal_width":2.3,"species":"virginica"},{"sepal_length":6.7,"sepal_width":3.3,"petal_length":5.7,"petal_width":2.5,"species":"virginica"},{"sepal_length":6.7,"sepal_width":,"petal_length":5.2,"petal_width":2.3,"species":"virginica"},{"sepal_length":6.3,"sepal_width":2.5,"petal_length":,"petal_width":1.9,"species":"virginica"},{"sepal_length":6.5,"sepal_width":,"petal_length":5.2,"petal_width":,"species":"virginica"},{"sepal_length":6.2,"sepal_width":3.4,"petal_length":5.4,"petal_width":2.3,"species":"virginica"}]
*/

其中,训练集包含 130 个项目,测试集包含 14 个。如果你看看这些数据是什么样子,你会看到如下内容:

代码语言:javascript复制
{
  "sepal_length": 5.1,
  "sepal_width": 3.5,
  "petal_length": 1.4,
  "petal_width": 0.2,
  "species": "setosa"
}

我们可以看到萼片和花瓣长度和宽度四个不同特征,以及物种的标签。

为了能够将它与 Tensorflow.js 一起使用,我们需要将这些数据塑造成框架能够理解的格式,在这种情况下,对于训练数据,它将是 [130, 4] 的 130 个样本,每个样本有四个特征。

代码语言:javascript复制
import * as trainingSet from "training.json";
import * as testSet from "testing.json";

const trainingData = tf.tensor2d(
  trainingSet.map(item => [
    item.sepal_length,
    item.sepal_width,
    item.petal_length,
    item.petal_width
  ]),
  [, ]
);

const testData = tf.tensor2d(
  testSet.map(item => [
    item.sepal_length,
    item.sepal_width,
    item.petal_length,
    item.petal_width
  ]),
  [, ]
);

接下来,我们还需要对输出数据进行整形:

代码语言:javascript复制
const output = tf.tensor2d(trainingSet.map(item => [
    item.species === 'setosa' ?  : ,
    item.species === 'virginica' ?  : ,
    item.species === 'versicolor' ?  : 

]), [,])

然后,一旦我们的数据准备就绪,我们就可以继续创建模型:

代码语言:javascript复制
const model = tf.sequential();

model.add(tf.layers.dense(
    {
        inputShape: ,
        activation: 'sigmoid',
        units: 
    }
));

model.add(tf.layers.dense(
    {
        inputShape: ,
        units: ,
        activation: 'softmax'
    }
));

在上面的代码示例中,我们首先实例化一个顺序模型,添加一个输入和输出层。

你可以看到内部使用的参数(inputShape, activation, and units)超出了本文的范围,因为它们可能会根据你创建的模型、使用的数据类型等而有所不同。

一旦我们的模型准备就绪,我们就可以使用我们的数据对其进行训练:

代码语言:javascript复制
async function train_data(){
    for(let i=;i<;i  ){
      const res = await model.fit(trainingData, outputData,{epochs: });
    }
}

async function main() {
  await train_data();
  model.predict(testSet).print();
}

如果这运作良好,你可以开始用自定义用户输入替换测试数据。

一旦我们调用我们的 main 函数,预测的输出将看起来像以下三个选项之一:

代码语言:javascript复制
[,,] // Setosa
[,,] // Virginica
[,,] // Versicolor

预测返回一个由三个数字组成的数组,表示数据属于三个类别之一的概率。最接近 1 的数字是最高预测值。

例如,如果分类的输出为 [0.0002, 0.9494, 0.0503],则数组的第二个元素最高,因此模型预测新的输入很可能是 Virginica。

这就是 Tensorflow.js 中的简单神经网络!

我们只讨论了 Irises 的一个小数据集,但如果您想继续使用更大的数据集或处理图像,步骤将是相同的:

  1. 收集数据;
  2. 在训练集和测试集之间拆分;
  3. 重新格式化数据以便 Tensorflow.js 可以理解它;
  4. 选择你的算法;
  5. 拟合数据;
  6. 预测。

如果你想保存创建的模型以便能够在另一个应用程序中加载它并预测新数据,你可以使用以下行来执行此操作:

代码语言:javascript复制
await model.save('file:///path/to/my-model'); // in Node.js

完整代码

  • index.html
代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Tensorflow.js</title>
    <link rel="stylesheet" href="src/styles.css">
</head>

<body>
    <h1>使用 Tensorflow.js 在 JavaScript 中定义、训练和运行机器学习模型</h1>

    <section class="data-inputs">
        <h3>鸢尾花分类</h3>
        <p>正在训练中...</p>
        <p class="training-steps"></p>
        <div class="input-block">
            <label for="sepal-length">Sepal lenth:</label>
            <input name="sepal-length" type="number" min="0" max="100" placeholder="1.5">
        </div>

        <div class="input-block">
            <label for="sepal-width">Sepal width:</label>
            <input name="sepal-width" type="number" min="0" max="100" placeholder="0.4">
        </div>

        <div class="input-block">
            <label for="petal-length">Petal length:</label>
            <input name="petal-length" type="number" min="0" max="100" placeholder="1.0">
        </div>

        <div class="input-block">
            <label for="petal-width">Petal width:</label>
            <input name="petal-width" type="number" min="0" max="100" placeholder="0.7">
        </div>

        <button class="predict" disabled>预测</button>
    </section>

    <section class="prediction-block">
        <p>鸢尾花 预测:</p>
        <p class="prediction"></p>
    </section>

    <script src="src/index.js"></script>
</body>

</html>
  • index.js
代码语言:javascript复制
import * as tf from "@tensorflow/tfjs";
import trainingSet from "./training.json";
import testSet from "./testing.json";

let trainingData, testingData, outputData, model;
let training = true;
let predictButton = document.getElementsByClassName("predict")[];

const init = async () => {
  splitData();
  createModel();
  await trainData();
  if (!training) {
    predictButton.disabled = false;
    predictButton.onclick = () => {
      const inputData = getInputData();
      predict(inputData);
    };
  }
};

const splitData = () => {
  trainingData = tf.tensor2d(
    trainingSet.map(item => [
      item.sepal_length,
      item.sepal_width,
      item.petal_length,
      item.petal_width
    ]),
    [, ]
  );

  testingData = tf.tensor2d(
    testSet.map(item => [
      item.sepal_length,
      item.sepal_width,
      item.petal_length,
      item.petal_width
    ]),
    [, ]
  );

  outputData = tf.tensor2d(
    trainingSet.map(item => [
      item.species === "setosa" ?  : ,
      item.species === "virginica" ?  : ,
      item.species === "versicolor" ?  : 
    ]),
    [, ]
  );
};

const createModel = () => {
  model = tf.sequential();
  model.add(
    tf.layers.dense({ inputShape: , activation: "sigmoid", units:  })
  );

  model.add(
    tf.layers.dense({
      inputShape: ,
      units: ,
      activation: "softmax"
    })
  );

  model.compile({
    loss: "categoricalCrossentropy",
    optimizer: tf.train.adam()
  });
};

const trainData = async () => {
  let numSteps = ;
  let trainingStepsDiv = document.getElementsByClassName("training-steps")[];
  for (let i = ; i < numSteps; i  ) {
    let res = await model.fit(trainingData, outputData, { epochs:  });
    trainingStepsDiv.innerHTML = `Training step: ${i}/${numSteps - }, loss: ${
      res.history.loss[]
    }`;
    if (i === numSteps - ) {
      training = false;
    }
  }
};

const predict = async inputData => {
  for (let [key, value] of Object.entries(inputData)) {
    inputData[key] = parseFloat(value);
  }
  inputData = [inputData];

  let newDataTensor = tf.tensor2d(
    inputData.map(item => [
      item.sepal_length,
      item.sepal_width,
      item.petal_length,
      item.petal_width
    ]),
    [, ]
  );

  let prediction = model.predict(newDataTensor);

  displayPrediction(prediction);
};

const getInputData = () => {
  let sepalLength = document.getElementsByName("sepal-length")[].value;
  let sepalWidth = document.getElementsByName("sepal-width")[].value;
  let petalLength = document.getElementsByName("petal-length")[].value;
  let petalWidth = document.getElementsByName("petal-width")[].value;

  return {
    sepal_length: sepalLength,
    sepal_width: sepalWidth,
    petal_length: petalLength,
    petal_width: petalWidth
  };
};

const displayPrediction = prediction => {
  let predictionDiv = document.getElementsByClassName("prediction")[];
  let predictionSection = document.getElementsByClassName(
    "prediction-block"
  )[];

  let maxProbability = Math.max(...prediction.dataSync());
  let predictionIndex = prediction.dataSync().indexOf(maxProbability);
  let irisPrediction;

  switch (predictionIndex) {
    case :
      irisPrediction = "Setosa";
      break;
    case :
      irisPrediction = "Virginica";
      break;
    case :
      irisPrediction = "Versicolor";
      break;
    default:
      irisPrediction = "";
      break;
  }
  predictionDiv.innerHTML = irisPrediction;
  predictionSection.style.display = "block";
};

init();
  • styles.css
代码语言:javascript复制
body {
  font-family: "Avenir";
}

h1 {
  text-align: center;
  width: 80%;
  margin:  auto;
}

.data-inputs {
  display: block;
  width: 80%;
  margin:  auto;
}

.input-block {
  display: inline-block;
  width: fit-content;
  margin: 1em 0.5em 2em 0.5em;
}

.input-block:first-of-type {
  margin-left: ;
}

.input-block input {
  width: 7em;
  height: 2em;
}

.input-block input::placeholder {
  color: rgba(0, 0, 0, 0.3);
}

button {
  display: block;
  padding: 0.5em 1em;
  border-radius: 5px;
  font-size: 14px;
}

.prediction-block {
  display: none;
  width: 80%;
  margin:  auto;
}
  • package.json
代码语言:javascript复制
{
  "name": "Irises Classficaton",
  "version": "1.0.0",
  "description": "",
  "main": "index.html",
  "scripts": {
    "start": "parcel index.html --open",
    "build": "parcel build index.html"
  },
  "dependencies": {
    "@tensorflow/tfjs": "1.1.2"
  },
  "devDependencies": {
    "@babel/core": "7.2.0",
    "parcel-bundler": "^1.6.1"
  },
  "keywords": []
}

效果如下:

0 人点赞