TensorFlow是谷歌基於DistBelief進行研發的第二代人工智能學習系統,其命名來源於自己的運行原理。Tensor(張量)意味着N維數組,Flow(流)意味着基於數據流圖的計算,TensorFlow爲張量從流圖的一端流動到另外一端計算過程。javascript
TensorFlow是一個將複雜的數據結構傳輸至人工智能神經網中進行分析和處理過程的系統。目前被普遍的運用在語音識別或圖像識別等多項機器學習和深度學習領域,它可在小到一部智能手機、大到數千臺數據中心服務器的各類設備上運行。html
TensorFlow的數據流運做模型以下圖: java
TensorFlow.js 是一個開源的用於開發機器學習項目的 WebGL-accelerated javascript 庫。使用它能夠在瀏覽器上建立CNN(卷積神經網絡)、RNN(循環神經網絡)等等,且可使用終端的GPU處理能力訓練這些模型。react
#機器學習研究的範圍 那麼,學習機器學習以前,對於其中的一些概念咱們須要有所瞭解。git
咱們解決一個問題有兩種模式:一種叫作模型驅動(model driven),經過研究對象的物理、化學等機理模型,對對象進行建模,從而解決問題,好比咱們熟知的牛頓三定律,對於上面那個公式就是咱們已知輸入x和機理模型f(),須要求解咱們想要獲得的y;而另一種叫作數據驅動(data driven),隨着人們遇到的問題愈來愈複雜,尋找對象機理模型的代價愈來愈大,反之數據獲取的代價愈來愈小,因而科研工做者開始從另外角度思考問題,是否能夠經過這些數據來分析獲得我想要的東西,即我知道一些的樣本(x,y)或者我只知道x,我想分析這些來獲得對象的模型f(),進而當我再次擁有一個x的時候,我就能夠獲得我想要的y,若是不是那麼嚴格的來說,全部這種數據分析的方法均可以算做機器學習的範疇。github
因此一個機器學習一般應該包括的基本要素有:訓練數據,帶參數的模型,損失函數,訓練算法。訓練數據做用自沒必要說;帶參數的模型是用來逼近f();損失函數是衡量模型優劣的一個指標,好比模型識別分類的準確度;訓練算法也能夠叫作優化函數,用於不斷更新模型的參數來最小化損失函數,獲得一個較好的模型,或者叫作學習機。接下來將介紹一些機器學習中的基本概念,可能沒有很強的連貫性。web
模型是對真實世界中問題域內的事物的描述,而不是對軟件設計的描述。在機器學習中,模型的的具體還以有點相似於:帶有一些待訓練參數,用於逼近前文提到的f()的參數集合。在參數空間,f()只是一個點,而我提到的模型也是一個點,而且因爲參數能夠變,因此我要作的只是讓我模型的這個點儘量的接近真實f()的那個點。算法
器學習的模型算法有不少,可是比較經常使用的模型能夠歸納爲三種:json
現實生活中,模型無處不在,如世界地圖、圖表等等均可以被認爲是模型。爲了說明模型是什麼,咱們舉一個例子:Barcelona 房子價格隨房間數的變化。 canvas
而後,咱們將這兩個數據使用一個 2D 圖形展現,每一個座標軸對應一個參數。 如今,咱們在此基礎上預測下第 6 個或者以上房間的房子價格。 固然,這個模型還不夠好,主要體如今如下方面:對於第一個問題,咱們能夠添加樣本數來解決,好比添加 100 萬個數據。 對第二個問題,咱們能夠添加更多的座標軸。在 2D 圖形上咱們能夠畫一條直線,在 3D 座標軸裏咱們能夠畫一個平面。
對於如何處理 3D 以上的情形,好比 4D 甚至是 1000000D 呢,咱們能夠用數學和計算超平面來處理這種狀況,而神經網絡是一個很好的處理工具。在生物學中,一個典型的神經網絡結構主要由:樹狀突、軸突和突觸構成。
在機器學習中。簡化後的神經則是下面這樣的:
在機器學習中,如下部分是必須的:
激活函數的使用很是有用,它是神經網絡的精髓所在。沒有激活函數的話神經網絡不可能很智能。緣由是儘管在網絡中你可能有不少神經,神經網絡的輸出總會是一個線性迴歸。咱們須要一些機制來改變這個獨立的線性迴歸爲非線性的以解決非線性的問題。 下圖展現了線性函數轉換到非線性函數的過程:
在上面的 2D 線性迴歸示例裏,在圖表中畫條線就足以讓咱們開始預測新數據了。然而,「深度學習」的目的是要讓咱們的神經網絡學着畫這條線。能夠參考下面的連接來學習:訓練模型(Training Models)
畫一條簡單的線咱們只須要包括一條神經的很是簡單的神經網絡對於訓練模型來講是相對簡單的狀況,但其它的模型作的要複雜的多,好比歸類兩組數據就比較難了。例如,「訓練學習」如何畫出下面的圖像:
對於上面的狀況來講並非很複雜,每一個模型都是一個世界,全部這些模型的訓練的概念都差很少。首先是畫一條隨機的線,而後在一個循環算法中改進它,修復每一個循環中的錯誤。這種優化算法又叫作梯度降低法 (Gradient Descent),還有更多複雜的算法如 SGD、ADAM,概念都相似。爲了理解梯度降低法,咱們須要知道每一個算法 (線性迴歸、邏輯迴歸等) 有不一樣的代價函數 (cost function) 來度量這些錯誤。
代價函數總會收斂於某個點,它多是凸或非凸函數。最低的收斂點將在 0% 錯誤時被發現,咱們的目標就是到達這個點。
但咱們使用梯度降低算法時,咱們開始於一個隨機的點,可是咱們不知道它在哪。想象一下你在一座山上,徹底失明,而後你須要一步一步的下山,走到最低的位置。若是地形複雜 (像非凸函數),降低過程將更加複雜。
我不會深刻的解釋什麼是梯度降低算法。你只須要記住它是一種優化算法,用來訓練 AI 模型以最小化預測產生的錯誤。這個算法須要時間和 GPU 來計算矩陣乘法。收斂點一般在第一輪執行中難以達到,因此咱們須要對一些超參數 (hyperparameter) 如學習率(learning rate)進行調優,或者添加一些正則化 (regularization)。
通過反覆的梯度降低法,咱們達到了離收斂點很近的地方,錯誤率也接近 0%。這時候,咱們的模型就建立成功,能夠開始進行預測了。
##1,建立神經網絡 TensorFlow.js 給咱們提供了一個簡單的辦法來建立神經網絡。首先,咱們將先建立一個 LinearModel 類,添加trainModel方法。對這類模型我將使用一個序列模型 (sequential model),序列模型指的是某一層的輸出是下一層的輸入,好比當模型的拓撲結構是一個簡單的棧,不包含分支和跳過。
在trainModel方法裏咱們將定義層 (只須要使用一個,這對於線性迴歸問題來講足夠了):
import * as tf from '@tensorflow/tfjs';
/**
* Linear model class
*/
export default class LinearModel {
/**
* Train model
*/
async trainModel(xs, ys){
const layers = tf.layers.dense({
units: 1, // Dimensionality of the output space
inputShape: [1], // Only one param
});
const lossAndOptimizer = {
loss: 'meanSquaredError',
optimizer: 'sgd', // Stochastic gradient descent
};
this.linearModel = tf.sequential();
this.linearModel.add(layers); // Add the layer
this.linearModel.compile(lossAndOptimizer);
// Start the model training!
await this.linearModel.fit(
tf.tensor1d(xs),
tf.tensor1d(ys),
);
}
...more
}
複製代碼
該類的使用方法以下:
const model = new LinearModel();
// xs and ys -> array of numbers (x-axis and y-axis)
複製代碼
##2,使用 TensorFlow.js 進行預測 預測的部分一般會簡單些,訓練模型須要定義一些超參數,相比之下,進行預測很簡單。咱們將在 LinearRegressor 類裏添加該方法:
import * as tf from '@tensorflow/tfjs';
export default class LinearModel {
...trainingCode
predict(value){
return Array.from(
this.linearModel
.predict(tf.tensor2d([value], [1, 1]))
.dataSync()
)
}
}
複製代碼
而後咱們調用該函數填入參數進行預測:
const prediction = model.predict(500); // Predict for the number 500
console.log(prediction) // => 420.423
複製代碼
固然,咱們提供了在線運行環境:
stackblitz.com/edit/linear…
有不少模型均可以在 TensorFlow.js 中使用,並且,你可使用 TensorFlow 或 Keras 建立模型,而後導入到 TensorFlow.js。好比,你可使用 posenet 模型 (實時人類姿態模擬) 來作些好玩的事情:
項目地址: github.com/aralroca/po… 它的使用也很是簡單,首先導入這個模型:import * as posenet from '@tensorflow-models/posenet';
// Constants
const imageScaleFactor = 0.5;
const outputStride = 16;
const flipHorizontal = true;
const weight = 0.5;
// Load the model
const net = await posenet.load(weight);
// Do predictions
const poses = await net
.estimateSinglePose(
imageElement,
imageScaleFactor,
flipHorizontal,
outputStride
);
複製代碼
而後爲模型添加測試數據:
{
"score": 0.32371445304906,
"keypoints": [
{
"position": {
"y": 76.291801452637,
"x": 253.36747741699
},
"part": "nose",
"score": 0.99539834260941
},
{
"position": {
"y": 71.10383605957,
"x": 253.54365539551
},
"part": "leftEye",
"score": 0.98781454563141
},
// ...And for: rightEye, leftEar, rightEar, leftShoulder, rightShoulder
// leftElbow, rightElbow, leftWrist, rightWrist, leftHip, rightHip,
// leftKnee, rightKnee, leftAnkle, rightAnkle
]
}
複製代碼
下面是示例代碼: github.com/aralroca/fi… ##4,從 Keras 導入模型 們能夠從外部導入模型到 TensorFlow.js,在下面的例子裏,咱們將使用一個 Keras 的模型來進行數字識別 (文件格式爲 h5)。爲了達到目的,咱們須要使用 tfjs_converter。
pip install tensorflowjs
複製代碼
而後,使用轉換工具:
tensorflowjs_converter --input_format keras keras/cnn.h5 src/assets
複製代碼
如今,你能夠將模型導入到 JS 代碼裏了:
// Load model
const model = await tf.loadModel('./assets/model.json');
// Prepare image
let img = tf.fromPixels(imageData, 1);
img = img.reshape([1, 28, 28, 1]);
img = tf.cast(img, 'float32');
// Predict
const output = model.predict(img);
複製代碼
僅需幾行代碼,你就可使用 Keras 中的數字識別模型。固然,咱們還能夠加入一些更好玩的邏輯,好比,添加一個 canvas 來畫一個數字,而後捕捉圖像來識別數字。
項目地址: github.com/aralroca/MN…若是硬件不行,在瀏覽器上訓練模型可能效率很是低下。TensorFlow.js 藉助了 WebGL 的接口來加速訓練,但即便這樣它也比 TensorFlow Python 版本要慢 1.5-2 倍。
可是,在 TensorFlow.js 以前,咱們基本不可能不靠 API 交互在瀏覽器使用機器學習模型。如今咱們能夠在咱們的應用裏 離線的 訓練和使用模型。而且,無需與服務端交互讓預測變得更快。
原文連接:aralroca.com/2018/08/24/… 參考:機器學習基本概念 TensorFlow.js基本概念