TensorFlow.js 中的核心概念

TensorFlow.js 是一個(gè)開(kāi)源的用于開(kāi)發(fā)機(jī)器學(xué)習(xí)項(xiàng)目的 WebGL-accelerated javascript 庫(kù)惜犀。TensorFlow.js 可以為你提供高性能的、易于使用的機(jī)器學(xué)習(xí)構(gòu)建模塊,允許你在瀏覽器上訓(xùn)練模型,或以推斷模式運(yùn)行預(yù)訓(xùn)練的模型草冈。TensorFlow.js 不僅可以提供低級(jí)的機(jī)器學(xué)習(xí)構(gòu)建模塊锌畸,還可以提供高級(jí)的類似 Keras 的 API 來(lái)構(gòu)建神經(jīng)網(wǎng)絡(luò)蝙砌。

一、張量:tensors

tensor 是 TensorFlow.js 的數(shù)據(jù)中心單元:由一組數(shù)值組成的一維或多維數(shù)組松忍。Tensor 實(shí)例的 shape 屬性定義了這個(gè)數(shù)組的形狀(例如:數(shù)組的每個(gè)維度有多少個(gè)值)蒸殿。

最主要的 Tensor 構(gòu)造函數(shù)是 tf.tensor 函數(shù)

// 2x3 Tensor
const shape = [2, 3]; // 可以看做是兩行三列組成
const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape);
a.print(); 
// 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]]

但是,在構(gòu)建低階張量時(shí)挽铁,為了提高代碼的可讀性伟桅,我們推薦使用下列的函數(shù):

// 0階張量,即標(biāo)量
tf.scalar(3.14).print(); // 3.140000104904175叽掘, 默認(rèn)dtype 是 float32
tf.scalar(3.14, 'float32').print(); // 3.140000104904175
tf.scalar(3.14, 'int32').print(); // 3
tf.scalar(3.14, 'bool').print(); // 1

// 1階張量
tf.tensor1d([1, 2, 3]).print(); // [1, 2, 3]

// 2階張量
// Pass a nested array.
tf.tensor2d([[1, 2], [3, 4]]).print();
// Pass a flat array and specify a shape.
tf.tensor2d([1, 2, 3, 4], [2, 2]).print();
// ouput
//    [[1, 2],
//   [3, 4]]

// 3階張量
// Pass a nested array.
tf.tensor3d([[[1], [2]], [[3], [4]]]).print();
// Pass a flat array and specify a shape.
tf.tensor3d([1, 2, 3, 4], [2, 2, 1]).print();
// output
//    [[[1],
//      [2]],

//     [[3],
//      [4]]]

// 4階張量
// Pass a nested array.
tf.tensor4d([[[[1], [2]], [[3], [4]]]]).print();
// Pass a flat array and specify a shape.
tf.tensor4d([1, 2, 3, 4], [1, 2, 2, 1]).print();
// output
//    [[[[1],
//       [2]],

//      [[3],
//       [4]]]]

上述 5個(gè)低階張量的表示方法楣铁,除了 scalar 和 tensor1d 兩方法沒(méi)有 shape 屬性外,其它的都會(huì)傳入values更扁、shape盖腕、dtype 三個(gè)參數(shù),注意有無(wú) shape 傳入時(shí)浓镜,values 的表示方式溃列。
TensorFlow.js 也提供了把 Tensor 實(shí)例中的所有元素的值重置為 0 和 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]]

// 2X2 Tensor with all values set to 1
tf.ones([2, 2]).print(); 
// output 
//     [[1, 1],
//     [1, 1]]

在 TensorFlow.js 中,張量值是不可改變的膛薛;一旦創(chuàng)建听隐,你就不能改變它的值。相反哄啄,如果你執(zhí)行 operations(ops) 操作雅任,就可以生成新的張量值。

二咨跌、變量:variables

variables 是用一個(gè)張量值初始化的沪么。不像張量(tensor),值不可改變锌半。你可以使用 assign 方法給一個(gè)存在的變量(variable)分配一個(gè)新的張量:

const initialValues = tf.zeros([5]);
const biases = tf.variable(initialValues); // 初始化偏差(距離原點(diǎn)的截距或偏移)
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]

變量(variable)主要是用于在模型訓(xùn)練時(shí)禽车,進(jìn)行數(shù)據(jù)的保存和更新。

三、操作:operations(ops)

tensors 可以用保存數(shù)據(jù)殉摔,而 operations 可以操作數(shù)據(jù)州胳。TensorFlow.js 提供了多種適用于張量的線性代數(shù)和機(jī)器學(xué)習(xí)的運(yùn)算的 operations。由于張量是不可改變的钦勘,所以 operations 操作并不會(huì)改變 tensors 的值陋葡,而是返回新的張量。
1彻采、operations 提供了類似 square 等一元運(yùn)算:

const x = tf.tensor1d([1, 2, Math.sqrt(2), -1]);
x.square().print();  // or tf.square(x)
// [1, 4, 1.9999999, 1]

const x = tf.tensor1d([1, 2, 4, -1]);
x.sqrt().print();  // or tf.sqrt(x)
// [1, 1.4142135, 2, NaN]

2腐缤、operations 提供了類似 add、sub 等二元運(yùn)算:

const a = tf.tensor1d([1, 2, 3, 4]);
const b = tf.tensor1d([10, 20, 30, 40]);

a.add(b).print();  // or tf.add(a, b)
// [11, 22, 33, 44]

3肛响、支持鏈?zhǔn)讲僮鳎?/strong>

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 sq_sum = e.add(f).square();
sq_sum.print();
// Output: [[36 , 64 ],
//          [100, 144]]

// 所有的操作都暴露在函數(shù)的命名空間中岭粤,也可以進(jìn)行下面操作,得到相同的結(jié)果
const sq_sum = tf.square(tf.add(e, f));

四特笋、模型和層

從概念上看剃浇,一個(gè)模型就是一個(gè)函數(shù),給定相應(yīng)輸入得到期望的輸出猎物。
在 TensorFlow.js 中虎囚,有兩種創(chuàng)建模型的方式:
1、通過(guò)使用 ops 直接創(chuàng)建模型

// Define function
function predict(input) {
  // y = a * x ^ 2 + b * x + c
  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

這是一個(gè)二元方程式求解的表示法蔫磨。
2淘讥、也可以使用高級(jí) API tf.model 來(lái)構(gòu)建以層定義的模型,這在深度學(xué)習(xí)中是一種常用的抽象形式
下面簡(jiǎn)單的線性回歸的定義為例:

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)});

上述例子中通過(guò)創(chuàng)建一個(gè)線性回歸模型堤如,調(diào)用 simpleRNN 層蒲列,通過(guò) sgd 優(yōu)化算法訓(xùn)練,得到期望效果搀罢。
在 TensorFlow.js 中有很多不同類型的層(layers)表示法蝗岖,例如 tf.layers.simpleRNN, tf.layers.gru, 和tf.layers.lstm等等。

五榔至、內(nèi)存管理:dispose 和 tf.tidy

由于抵赢,tensorFlow.js 使用了 GPU 加速數(shù)學(xué)運(yùn)算,在使用張量和變量時(shí)唧取,管理 GPU 的內(nèi)存是必不可少的铅鲤。
TensorFlow.js 提供了 disposetf.tidy 兩個(gè)函數(shù)來(lái)幫助處理內(nèi)存:
1、dispose
你可以調(diào)用一個(gè)張量或變量來(lái)清除和釋放它的 GPU 內(nèi)存兵怯。

const x = tf.tensor2d([[0.0, 2.0], [4.0, 6.0]]);
const x_squared = x.square();

x.dispose();
x_squared.dispose();

2、tf.tidy
在做大量張量操作時(shí)腔剂,使用 dispose 可能很笨重媒区。TensorFlow.js 提供了另一個(gè)功能 tf.tidy,它在 JavaScript 中扮演著類似的角色,除了 gpu 支持的張量袜漩。
tf.tidy 會(huì)執(zhí)行一個(gè)功能绪爸,清除任何創(chuàng)建的中間張量,釋放它們的 GPU 內(nèi)存宙攻。但它不會(huì)清除內(nèi)部函數(shù)的返回值奠货。

// tf.tidy takes a function to tidy up after
const average = tf.tidy(() => {

// tf.tidy 會(huì)清除在這個(gè)函數(shù)內(nèi)的張量使用的所有GPU內(nèi)存,而不是返回的張量座掘。
// 即使在像下面這樣的一個(gè)簡(jiǎn)短的操作序列中递惋,也會(huì)創(chuàng)建一些中間的張量。所以溢陪,把 ops 放在 tidy 函數(shù)中是一個(gè)好的選擇

  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 將有助于防止應(yīng)用程序中的內(nèi)存泄漏萍虽。當(dāng)內(nèi)存被回收時(shí),它也可以用來(lái)更小心地控制形真。

3杉编、兩個(gè)注意點(diǎn)

  • 傳遞給 tf.tidy 函數(shù)是同步的,不會(huì)返回一個(gè) Promise 對(duì)象咆霜。建議保留更新UI的代碼邓馒,或者在tf.tidy之外發(fā)出遠(yuǎn)程請(qǐng)求。
  • tf.tidy 不會(huì)清理變量蛾坯。變量通常貫穿于機(jī)器學(xué)習(xí)模型的整個(gè)生命周期中光酣,在 TensorFlow.js 中,即使是在 tf.tidy 里創(chuàng)建偿衰,js也不會(huì)清理它們挂疆;但是,你可以手動(dòng)調(diào)用 dispose下翎。

六缤言、補(bǔ)充

類似還有EnvironmentConstraints视事、Initializers胆萧、Regularizers.

戳我博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俐东,隨后出現(xiàn)的幾起案子跌穗,更是在濱河造成了極大的恐慌,老刑警劉巖虏辫,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚌吸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡砌庄,警方通過(guò)查閱死者的電腦和手機(jī)羹唠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)奕枢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人佩微,你說(shuō)我怎么就攤上這事缝彬。” “怎么了哺眯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵谷浅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我奶卓,道長(zhǎng)一疯,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任寝杖,我火速辦了婚禮违施,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瑟幕。我一直安慰自己磕蒲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布只盹。 她就那樣靜靜地躺著辣往,像睡著了一般。 火紅的嫁衣襯著肌膚如雪殖卑。 梳的紋絲不亂的頭發(fā)上站削,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音孵稽,去河邊找鬼许起。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菩鲜,可吹牛的內(nèi)容都是我干的园细。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼接校,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼猛频!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蛛勉,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鹿寻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后诽凌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體毡熏,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年侣诵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痢法。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恬试。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疯暑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哑舒,我是刑警寧澤妇拯,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站洗鸵,受9級(jí)特大地震影響越锈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜膘滨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一甘凭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧火邓,春花似錦丹弱、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至纤勒,卻和暖如春坯苹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摇天。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工粹湃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泉坐。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓为鳄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親坚冀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子济赎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容