近兩年人工智能,機器學習等各類概念漫天飛舞,那人工智能,機器學習,深度學習這些名詞之間是什麼關係呢?javascript
若是用三個同心圓來解釋的話,人工智能是最大的圓,機器學習是中間的圓,深度學習是最小的圓。具體解釋就是:html
今天咱們要介紹的TensorFlow.js是由Google的AI團隊發佈一款機器學習框架,基於DeepLearn.js(已經中止更新)。這款機器學習框架的特色是使用JavaScript語言,在瀏覽器中就可使用它提供的各類API來進行建模和訓練,而且支持Node.js。因此對於前端來講,是走進機器學習世界最便捷的路徑了。前端
這裏有一個利用TensorFlow.js實現的機器學習的小遊戲demo,你們能夠感覺一下。嘗試一下java
這篇文章基於TensorFlow.js的英文官方文檔寫成,重點在於TensorFlow.js的入門,關於機器學習更多的知識點可參考Google機器學習課程。web
讓咱們開始吧!npm
第一種方式是經過<script></script>直接引入,在瀏覽器中運行下面的代碼,在控制檯中能夠看到結果。api
<html> <head> <!-- Load TensorFlow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.0"> </script> <!-- Place your code in the script tag below. You can also use an external .js file --> <script> // Notice there is no 'import' statement. 'tf' is available on the index-page // because of the script tag above. // Define a model for linear regression. const model = tf.sequential(); model.add(tf.layers.dense({units: 1, inputShape: [1]})); // Prepare the model for training: Specify the loss and the optimizer. model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); // Generate some synthetic data for training. const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]); const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]); // Train the model using the data. model.fit(xs, ys, {epochs: 10}).then(() => { // Use the model to do inference on a data point the model hasn't seen before: // Open the browser devtools to see the output model.predict(tf.tensor2d([5], [1, 1])).print(); }); </script> </head> <body> </body> </html>
第二種方式是經過npm或yarn將TensorFlow.js的庫引入到你的項目中。數組
yarn add @tensorflow/tfjs npm install @tensorflow/tfjs
你能夠在你的main.js中添加以下代碼:瀏覽器
import * as tf from '@tensorflow/tfjs'; // Define a model for linear regression. const model = tf.sequential(); model.add(tf.layers.dense({units: 1, inputShape: [1]})); // Prepare the model for training: Specify the loss and the optimizer. model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); // Generate some synthetic data for training. const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]); const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]); // Train the model using the data. model.fit(xs, ys, {epochs: 10}).then(() => { // Use the model to do inference on a data point the model hasn't seen before: model.predict(tf.tensor2d([5], [1, 1])).print(); });
若是不懂上面代碼的含義不要着急,繼續看後面的一些基礎概念和用法。框架
Tensor和Variable是TensorFlow.js中最基礎的兩種數據形式。那他們究竟是什麼意思呢?
Tensor在谷歌翻譯中是「張量」的意思,「張量」這個詞是數學和物理中的一個術語,咱們暫且不深究它的意思,你只須要記住,Tensor(張量)是不可變的,相似於const,一旦定義就不能改變它的值。
Variable就很容易理解了,它是變量的意思,顧名思義,它的值是能夠改變的。
總之,Tensor(張量)不可變,Variable(變量)可變。
張量一般是一個0到多維的數組,構造張量時會用到shape屬性,用來規定這是一個幾行幾列的數組。
請看下面構造一個張量的例子。shape用來規定這個張量是兩行三列的數組,而後能夠看到最後的輸出,咱們獲得了一個兩行三列的二維數組。
// 2x3 Tensor const shape = [2, 3]; // 2 rows, 3 columns const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape); a.print(); // print Tensor values // Output: [[1 , 2 , 3 ], // [10, 20, 30]]
也能夠用下面這種方式,直接表示這是一個兩行三列的二維數組。
// The shape can also be inferred: const b = tf.tensor([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]); b.print(); // Output: [[1 , 2 , 3 ], // [10, 20, 30]]
然而實際上,咱們一般使用 tf.scalar, tf.tensor1d, tf.tensor2d, tf.tensor3d 和 tf.tensor4d來構造張量。tf.scalar是構造一個零維數組,也就是一個數字,tf.tensor1d是構造一位數組,tf.tensor2d是構造二維數組,以此類推。例如:
const c = tf.tensor2d([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]); c.print(); // Output: [[1 , 2 , 3 ], // [10, 20, 30]]
或者使用tf.zeros生成全是0的數組,tf.ones生成全是1的數組,例如:
// 3x5 Tensor with all values set to 0 const zeros = tf.zeros([3, 5]); // Output: [[0, 0, 0, 0, 0], // [0, 0, 0, 0, 0], // [0, 0, 0, 0, 0]]
而Variable(變量)只能經過Tensor(張量)生成。咱們可使用assign給變量從新賦值。例如:
const initialValues = tf.zeros([5]); const biases = tf.variable(initialValues); // initialize biases biases.print(); // output: [0, 0, 0, 0, 0] const updatedValues = tf.tensor1d([0, 1, 0, 1, 0]); biases.assign(updatedValues); // update values of biases biases.print(); // output: [0, 1, 0, 1, 0]
TensorFlow.js提供了各類向量運算的API,咱們能夠稱這些爲Operations。下面是張量平方和張量相加的例子:
const d = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]); const d_squared = d.square(); d_squared.print(); // Output: [[1, 4 ], // [9, 16]] const e = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]); const f = tf.tensor2d([[5.0, 6.0], [7.0, 8.0]]); const e_plus_f = e.add(f); e_plus_f.print(); // Output: [[6 , 8 ], // [10, 12]]
並且TensorFlow.js還提供了鏈式運算,請看例子:
const sq_sum = e.add(f).square(); sq_sum.print(); // Output: [[36 , 64 ], // [100, 144]] // All operations are also exposed as functions in the main namespace, // so you could also do the following: const sq_sum = tf.square(tf.add(e, f));
上面咱們介紹了張量,變量和一些基礎運算,下面咱們引入「Model(模型)」這個概念。
模型就是一個函數,給定這個函數特定的輸入,會返回特定的輸出。
因此請記住,模型就是一個函數而已。
咱們來看一個定義模型的例子, 如下代碼構造了一個 y = a x ^ 2 + b x + c 的函數表達式,給定一個x,咱們會獲得一個y。
代碼中tf.tidy()看不懂請忽略,咱們將在下一節介紹,它只是用來清除內存。
// Define function function predict(input) { // y = a * x ^ 2 + b * x + c // More on tf.tidy in the next section return tf.tidy(() => { const x = tf.scalar(input); const ax2 = a.mul(x.square()); const bx = b.mul(x); const y = ax2.add(bx).add(c); return y; }); } // Define constants: y = 2x^2 + 4x + 8 const a = tf.scalar(2); const b = tf.scalar(4); const c = tf.scalar(8); // Predict output for input of 2 const result = predict(2); result.print() // Output: 24
可是一般,咱們會使用一個更高級的API去構造模型,那就是用 tf.model 的形式,這裏的model只是模型的總稱,並無 tf.modal 這個方法。TensorFlow中最經常使用的是 tf.sequential,例如:
const model = tf.sequential(); model.add( tf.layers.simpleRNN({ units: 20, recurrentInitializer: 'GlorotNormal', inputShape: [80, 4] }) ); const optimizer = tf.train.sgd(LEARNING_RATE); model.compile({optimizer, loss: 'categoricalCrossentropy'}); model.fit({x: data, y: labels});
上面代碼中必定有不少你不理解的地方,好比什麼是 tf.layer?什麼是 tf.train.sgd?這裏能夠先忽略細節,先從整體上體會這些基本概念,關於 tf.train.sg 等咱們在後面的文章介紹。若是你忍不住,就本身去查吧!給你 官方API文檔 好了。
TensorFlow.js使用GPU來加速運算,因此合理地釋放內存是一件很必要的事情。TensorFlow.js提供了dispose函數來釋放內存,請看例子:
const x = tf.tensor2d([[0.0, 2.0], [4.0, 6.0]]); const x_squared = x.square(); x.dispose(); x_squared.dispose();
可是一般實際中咱們會面對不少的張量和操做,這時候 tf.tidy 更加方便,由於它是批量釋放內存,請看例子:
// tf.tidy takes a function to tidy up after const average = tf.tidy(() => { // tf.tidy will clean up all the GPU memory used by tensors inside // this function, other than the tensor that is returned. // // Even in a short sequence of operations like the one below, a number // of intermediate tensors get created. So it is a good practice to // put your math ops in a tidy! const y = tf.tensor1d([1.0, 2.0, 3.0, 4.0]); const z = tf.ones([4]); return y.sub(z).square().mean(); }); average.print() // Output: 3.5
使用 tf.tidy 有兩個要點:
關於 TensorFlow.js 的基礎概念介紹完了,可是這只是咱們探索機器學習的一個工具而已,具體的實踐還須要更多的學習,後面有時間我也會跟你們一塊兒學習,並及時分享。