一臉懵逼的畢業設計--tensorflow.js

前言

又到了被催進度的時候,然而自己的進度卻是一片空白,之前應付了一週的開題現在發現有很多地方根本就不合理,導師自然不能幫到你什麼,所以一切到頭來還是要自己去折騰。

內容

說實話要是都和Three.js相關的內容其實還好做,偏偏裏面還涉及啓發式算法和神經網絡擬合的問題,這就很麻爪了,而且還不知道到底要不要上神經網絡。

目前的問題主要有三大塊,首先就是博弈支付矩陣的建立,其次是啓發式算法的求解,最後是動畫的完善。

不過導師想看結果,還是要從動畫下手,他給出的建議是做幾個場景,有一說一場景是比較好實現的,比如攔截,對戰,追蹤。

然鵝,實在不想動腦子去想這些動畫怎麼實現,於是先從簡單的做起,學學tensorflow.js吧。

介紹

去年的這時候我開始接觸Python的機器學習教程,甚至寫了好多學習筆記:
在這裏插入圖片描述
不過那時候沒有想走JS的路,雖然接觸到了tensorflow,但是掌握的屬實一般,tensorflow.js是去年年中接觸到的概念,彼時正好處在轉型前端的時候,瞬間對這個熟悉的概念產生了興趣,不過好景不長,龐大的前端體系還是讓我對學習這個東西分身乏術。

天道好輪迴,想靠JS水畢設,終究還是逃不開他。

一句話介紹tfjs,就是方便前端上手機器學習,這裏那線性迴歸和邏輯迴歸簡單兩大基礎Demo介紹下tfjs。

線性迴歸

import { tensor, sequential, layers, losses, train } from "@tensorflow/tfjs";
import { render, show } from "@tensorflow/tfjs-vis";

window.onload = async () => {
  const height = [154, 160, 175, 181, 188];
  const weight = [46, 44, 56, 72, 70];
  render.scatterplot(
    { name: "h-w-data" },
    { values: height.map((x, i) => ({ x, y: weight[i] })) },
    { xAxisDomain: [140, 200], yAxisDomain: [40, 80] }
  );
  function press(val) {
    return tensor(val)
      .sub(Math.min(...val))
      .div(Math.max(...val) - Math.min(...val));
  }
  const inputs = press(height),
    labels = press(weight);
  const model = sequential();
  model.add(layers.dense({ units: 1, inputShape: [1] }));
  model.compile({ loss: losses.meanSquaredError, optimizer: train.sgd(0.2) });

  await model.fit(inputs, labels, {
    batchSize: 5,
    epochs: 200,
    callbacks: show.fitCallbacks({ name: "train-process" }, ["loss"]),
  });
  const outputs = model.predict(tensor([169]).sub(154).div(34));
  outputs.mul(28).add(44).print();
};

上面是一段線性迴歸的demo,先看看引入的庫,一個是tfjs,不用多說,另一個是tfjs配套的可視化庫。

首先準備了所謂的訓練集,由height和wight組成,接着畫個散點圖,這裏指定x座標爲高,y爲重量。然後做了個歸一化操作,原因這裏就不細講了。

接着我們使用連續模型sequential,添加一層全連接層。使用均方誤差和SGD優化,batch設爲5,epoch爲200,然後畫出loss訓練的過程,最後預測169的label。

邏輯迴歸

import { tensor, sequential, layers, losses, train } from "@tensorflow/tfjs";
import { render, show } from "@tensorflow/tfjs-vis";
import { getData } from "./data";

window.onload = async () => {
  const data = getData(400);
  render.scatterplot(
    { name: "logistic" },
    {
      values: [
        data.filter((p) => p.label === 1),
        data.filter((p) => p.label === 0),
      ],
    }
  );
  const model = sequential();
  model.add(
    layers.dense({
      units: 1,
      inputShape: [2],
      activation: "sigmoid",
    })
  );
  model.compile({
    loss: losses.logLoss,
    optimizer: train.adam(0.1),
  });
  const inputs = tensor(data.map((p) => [p.x, p.y]));
  const labels = tensor(data.map((p) => p.label));
  await model.fit(inputs, labels, {
    batchSize: 40,
    epochs: 20,
    callbacks: show.fitCallbacks(
      {
        name: "train-process",
      },
      ["loss"]
    ),
  });

  window.fn = (form) => {
    const pred = model.predict(tensor([[+form.x.value, +form.y.value]]));
    pred.print();
    return false;
  };
};

首先抓四百數據,結構如下:

{
  x:number,
  y:number,
  label:number
}

接着也打出來:
在這裏插入圖片描述
其他訓練步驟類似,只不過選擇的優化器和損失函數變化了。

最後寫了段html實現傳值:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="./app.js"></script>
    <form action="" onsubmit="return fn(this)">
      x: <input type="text" name="x" /> y: <input type="text" name="y" />
      <button type="submit">預測</button>
    </form>
  </body>
</html>

注:參考JavaScript玩轉機器學習 打造你人生中的第一個AI項目

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章