天天看點

你想學習前端智能化嗎?從 Pipcook 開始吧!

作者 | 劉亞中 (雷姆)

大家好,今天為大家正式介紹下 Pipcook,它是淘系技術部 D2C 團隊研發的一款面向前端開發者的機器學習應用架構,我們希望 Pipcook 能成為前端人員學習和實踐機器學習的一個平台,進而推進前端智能化的程序。

本篇文章的目的也是希望大家在閱讀後,能了解到 Pipcook 已經做了哪些,以及想要做到哪些後,進而号召對前端智能化有想法和有代碼的同學們一起加入,讓前端智能化朝着我們想象中的樣子演進。

為什麼會有 Pipcook?

你想學習前端智能化嗎?從 Pipcook 開始吧!

從上面的圖中,可以看到 imgcook、idaecook、reviewcook 等等,它們統稱為前端智能化項目,比如 ideacook,解決的是如何從産品文檔生成産品代碼的場景、imgcook 解決的是如何從視覺稿生成業務代碼的問題,而 reviewcook 則是幫助我們解決一些代碼上線前的智能化回歸驗證。

那麼 Pipcook 的定位就是為上述這些智能化項目提供夯實可靠的機器學習平台,讓前端人員就能完成上面提到的那些事情。

那麼,在你決定開始使用 Pipcook 之前,不妨先問一下自己下面幾個問題:

  1. 你是否想了解機器學習?
  2. 你是否想自己動手訓練一個模型?
  3. 你是否想自己部署你的模型?
  4. 你是否想掌握不斷優化自己模型的能力?

如果你有上面的想法的話,那麼就可以繼續了解 Pipcook 了,因為 Pipcook 也正是為了幫助前端開發者解決這些問題的。

靈活、豐富的 Pipeline

看到這裡,你可以會懵到底什麼是 Pipeline,不過沒關系,我們先從一個例子開始:

{
  "plugins": {
    "dataCollect": {
      "package": "@pipcook/plugins-mnist-data-collect",
      "params": {
        "trainCount": 8000,
        "testCount": 2000
      }
    },
    "dataAccess": {
      "package": "@pipcook/plugins-pascalvoc-data-access"
    },
    "dataProcess": {
      "package": "@pipcook/plugins-image-data-process",
      "params": {
        "resize": [28,28]
      }
    },
    "modelDefine": {
      "package": "@pipcook/plugins-tfjs-simplecnn-model-define"
    },
    "modelTrain": {
      "package": "@pipcook/plugins-image-classification-tfjs-model-train",
      "params": {
        "epochs": 15
      }
    },
    "modelEvaluate": {
      "package": "@pipcook/plugins-image-classification-tfjs-model-evaluate"
    }
  }
}           

上面的 JSON 就是我們稱為一個 Pipeline 的東西,這也是 Pipcook 中的 “Pip” 的來源,我們希望每個應用就是由不同的 Pipeline 組成的,然後我們針對機器學習的流程,将 Pipeline 分為了不同的階段,并且在每個階段提供了不同的插件,這樣做的好處是可以随時更換不同的插件以快速地獲得結果,同時也隐藏掉了插件下面的技術和算法細節,進而降低 Pipeline 使用者的心智負擔,大家隻需要知道每個插件是做什麼的就可以了。

你想學習前端智能化嗎?從 Pipcook 開始吧!

上圖就是 Pipcook 中一個正常 Pipeline 的流程,他們分别是:

  • Data Collect:用于收集你要用于機器學習訓練的資料,比如圖檔、文本、音頻等;
  • Data Access:用于将上一個階段收集的資料轉換為模型可以接收的樣本集;
  • Data Process:對樣本的資料做一些額外的處理,比如圖檔尺寸的統一、把圖檔變為灰階圖、文本向量化等;
  • Model Define:用于定義你用來訓練的模型;
  • Model Load:除了可以定義模型外,我們也提供了 Model Load 插件用于加載已經訓練好的模型;
  • Model Train:将 Data Process / Data Access 的樣本,用來訓練之前在 Model Define 定義好的模型;
  • Model Evaluate:一般在模型訓練完成後,都會需要評估模型的效果如何,就跟我們的單元測試一樣;
  • Model Deploy:最後模型評估結果如果是可以接受的話,那麼就能将這個模型部署上線了,這個階段的插件就是幫助大家完成模型的部署;

穩定、可靠的前端機器學習生态

前面說完了 Pipeline,接下來說一下插件,Pipcook 為每個插件會提供獨立的運作時,在這個運作時中,我們特别增加了一種通過 JavaScript 調用到 Python 的能力——Boa。

const boa = require('@pipcook/boa');
const fs = require('fs');
const glob = require('glob').sync;
const acorn = require('acorn');

const { set, len, list } = boa.builtins();
const { DBSCAN } = boa.import('sklearn.cluster');
const { word2vec } = boa.import('gensim.models');

const cwd = process.cwd();
let files = [];
files = files.concat(glob(cwd + '/lib/**/*.js'));

const sentences = [];
const vec2word = {};
const samples = files
  .map((f) => fs.readFileSync(f))
  .map((s) => {
    let ast;
    try { ast = acorn.parse(s); } catch (e) {
      console.error('just ignore the error');
    }
    return ast;
  })
  .filter((ast) => ast !== undefined)
  .reduce((list, ast) => {
    const fn = ast.body.filter((stmt) => stmt.type === 'FunctionDeclaration');
    list = list.concat(fn);
    return list;
  }, []);

samples.forEach((sample) => sentences.push([ sample.id.name ]));

const { wv } = word2vec.Word2Vec(sentences, boa.kwargs({
  workers: 1,
  size: 2,
  min_count: 1,
  window: 3,
  sg: 0
}));

const X = sentences
  .map((s) => wv.__getitem__(s)[0])
  .map((v, i) => {
    const r = [ v[0] * 100, v[1] * 100 ];
    vec2word[r] = samples[i].id.name;
    return r;
  });

const db = DBSCAN(boa.kwargs({ eps: 0.9 })).fit(X);
const labels = db.labels_;
const n_noise_ = list(labels).count(-1);
const n_clusters_ = len(set(labels));
console.log(n_noise_, n_clusters_, set(labels));           

上面的代碼完成了以下操作:

  1. 通過 acorn 庫(JavaScript)來解析給定的 JavaScript 代碼,擷取所有的函數名;
  2. 通過調用 genmis.models 庫(Python)中的 Word2Vec 來将步驟1的函數名轉為向量表示;
  3. 通過調用 sklearn.cluster 庫(Python)中的 DBSCAN 來完成将函數名進行分類的任務;

可以看到,通過 @pipcook/boa 我們将 Python 生态與 Node.js 生态幾乎完美地結合在了一起,最後完成對給定檔案内的函數名分類(聚類)的機器學習任務,更多關于 Boa 的文章可以從下面的文章中了解:

這篇文章中,我們主要為大家解釋一個疑惑,那就是通過 Boa 調用 Python,和直接使用 Python 代碼,到底會不會導緻性能很差?我們的回答是不會,而且至少是跟純 Python 代碼保持幾乎一緻的性能。

你想學習前端智能化嗎?從 Pipcook 開始吧!

上面的圖就是為了說明這個問題而畫的。無論對于 Boa 還是 Python 來說,最下面一層都是 Python Objects,這裡包含了 Python 中所有函數的定義、變量的定義以及操作符的定義等等,然後對于 Python 代碼來說,就是通過它自己的解釋器将 Python 代碼轉換成對 Python Objects C API 的調用。

對于 Boa 來說,也是一樣的,由 V8 完成對 JavaScript 代碼的解析,然後再将對應的操作映射到 Python Objects,是以兩者的差異就在于 v8 和 Python Interrupter 對于各自代碼的執行效率了,那麼對于這一點來說,Python 和 JavaScript 都有各自的優化政策和方法,是以幾乎是不相伯仲的。

其實這裡想表達的是,雖然聽上去是要從 JavaScript 調用到 Python,但其實從實作的機制來說,并非将 JavaScript 轉成 Python 代碼,然後再由 Python 解釋器執行,而是直接與 Python 中的對象打交道,這樣也就減少了中間那層額外的開銷,是以大家可以放心使用。

在性能問題解決之後,我們再說一下 Boa 對于前端智能化的意義,它将意味着我們不再需要像 nodejieba 或者是其他這樣的橋接庫了,Boa 就像一扇通往機器學習新世界的大門,從此 JavaScript 的世界中,可以以非常低的成本就能夠使用到最成熟、最前沿的機器學習生态了。

未來-面向前端開發者的應用架構

通過 Pipeline 以及 Boa,Pipcook 已經可以為開發者在機器學習道路上貢獻不少基石了,但我們認為這——仍然遠遠不夠,核心的門檻問題并沒有得到解決,比如使用 Pipeline 部署了一個模型後,然後呢?比如使用 Boa 參照 sklearn 的例子完成了一個機器學習算法的開發,然後呢?

模型的效果不好,開發者如何優化?樣本到底有沒有問題?為什麼我的這個模型最後的評估結果那麼低?這些對于毫無基礎的前端工程師來說,都是難以解決的問題,而這些問題将大部分的前端開發者攔在了機器學習之外。

是以在 Pipcook 正式釋出 1.0 版本時,我們将引入一個 PipApp 的概念,即——機器學習應用架構,它跟 Vue、React、Angular 一樣,就是幫助我們完成應用開發的,隻不過它面向的是機器學習的應用。

我們還是先來看一段代碼:

你想學習前端智能化嗎?從 Pipcook 開始吧!

在 PipApp 中,我們通過 TypeScript 的類型系統,為每個涉及到機器學習的子產品都聲明了 ml.Function 類型,并通過 ml.create(fn) 函數建立,然後在建立的時候,可以在 fn 中使用機器學習的 API,最後隻需要在任何的 Node.js 函數中調用建立的函數就可以了。

在寫好代碼後,先别着急運作,因為直接通過 ts-node/node 是無法成功執行的,因為機器學習本身是分為訓練和預測兩個階段,但是在代碼中我們并沒有看到訓練相關的代碼,這是為什麼呢?

原因是 PipApp 都封裝在了 Pipcook 的指令中了,如下:

$ pipcook train example.ts --epoch=15 --sample_path=...
...
generated the model at example.ts.im
...
$ pipcook try example.ts
$ pipcook deploy example.ts --eas-config=...           

正如上面的指令,我們将機器學習中的訓練和預測都封裝起來了,這樣使用者在寫一個機器學習應用的時候,隻需要關心我要做什麼事,以及如何跟 Node.js 其他的功能內建起來,就像今天比如要使用 Node.js 寫一個 PDF 的渲染服務,那麼你需要做的就是調用 PDF 的渲染庫,然後将它們與你的伺服器路由內建起來。

那麼未來的前端機器學習應用也是如此,通過 PipApp 表達你要做的機器學習任務類型和資料類型,然後 Pipcook 将會輔助你一步步完成從資料收集、資料處理、模型訓練到最後 ML 應用部署。

在現有的 Pipcook 1.0 規劃中,我們計劃增加 NLP 和 Vision 的能力到我們的 PipApp API 中,大家如果感興趣可以到我們的

issue#33

中參與讨論。

如何加入 Pipcook

如果你堅持讀到了這裡,一定是對于機器學習和 Pipcook 産生了一定的興趣,那麼我們非常歡迎你加入到我們的技術演進中來,貢獻你的一份力量!

你想學習前端智能化嗎?從 Pipcook 開始吧!

上圖中,我們把幾個關鍵節點已經明确地标注出來:

  • 如果你對于定義機器學習應用架構感興趣,那麼可以從 PipApp 入手
  • 如果你對于 Pipeline,還有機器學習工程架構感興趣,可以從 Pipcook Client SDK 入手
  • 如果你對于 Boa 以及提供穩定可靠的機器學習生态感興趣的,那麼可以從我們的 Plugin API 入手

另外,我們也整理了一些 Issue 友善你快速參與進來:

最後,也非常歡迎你加入到我們的 Pipcook Community 群裡一起暢所欲言:

你想學習前端智能化嗎?從 Pipcook 開始吧!
你想學習前端智能化嗎?從 Pipcook 開始吧!

關注「Alibaba F2E」

把握阿裡巴巴前端新動向