Android Smart Linkify 支援機器學習

Android_開發者發表於2018-08-22

文 / Lukas Zilka,軟體工程師,谷歌人工智慧,蘇黎世

上半周,我們釋出了 Android 9 Pie,這是 Android 的最新版本,它的機器學習應用使您的手機更簡單易用。 Android 9 中有一項功能是 Smart Linkify,這是一種新的 API,可在文字中檢測到某些型別的實體時新增可點選連結。 這個功能很有用,例如,當您從朋友的訊息傳遞 app 中收到一個地址,想要在地圖上查詢時,如果使用 Smart Linkify-annotated 文字,它就變得容易多了!

Android Smart Linkify 支援機器學習
Smart Linkify 是現有 Android Linkify API 的最新版本。 它採用小型前饋神經網路(每種語言 500kB),低延遲(谷歌 Pixel 手機上不到 20 毫秒)和小推理程式碼(250kB),並採用與智慧文字選擇相同的機器學習技術(作為 Android Oreo 的一部分發布),現在也能建立連結。

在 Android 中,Smart Linkify 作為開源文字分類 API 推出(作為生成連結的方法)。 使用 TensorFlow 訓練模型並將其匯出到由 TensorFlow Lite 和 FlatBuffers 支援的自定義推理庫。 這些模型的 C ++ 推理庫在此處作為 Android 開源框架的一部分提供,並在每個文字選擇和 Smart Linkify API calls 上執行。

尋找物件

在文字中查詢電話號碼和郵寄地址是一個難題。 不僅是因為人們五花八門的編寫方式,而且各類物件的呈現方式通常也很模糊(例如:“確認號碼:857-555-3556” 不是電話號碼,即便它呈現了與電話號碼類似的形格式)。

為了尋求解決方案,我們設計了一種推理演算法,其核心是兩個小的前饋神經網路。 該演算法足以執行除地址和電話號碼外的各種實體物件的程式分塊。

總的來說,該系統架構如下:給定的輸入文字首先被分成單詞(基於空格分離),然後生成所有可能的限定最大長度的單詞子序列(在我們的示例中為 15 個單詞),並且對於每個候選單詞,打分神經網路根據它是否代表有效物件來分配一個值(介於 0 和 1 之間):

Android Smart Linkify 支援機器學習
對於給定的文字字串,第一個網路為非實體物件分配低分,為正確選擇了整個電話號碼的候選單詞分配高分
接下來,將重疊的生成物件刪除,促成較高得分者與較低得分者來一決高下。 現在,我們有一組物件,但仍然不知道它們的型別到底是什麼。所以現在第二神經網路將物件的型別分類,要麼是電話號碼,地址,要麼在某些情況下將之分類成非實體物件。

Android Smart Linkify 支援機器學習
在我們的示例中,唯一沒有衝突的物件是 “並且明天請打電話給 857 555 3556。”(“857 555 3556” 被歸類為電話號碼),“並且明天打電話給 857 555 3556。”(“並且” 被歸類為非實體物件)。我們可以輕鬆地在螢幕上顯示的文字中為它們加上下劃線,並在點選時執行正確的應用程式。

文字特徵

目前為止,我們已經對 Smart Linkify 在一串文字中定位和分類實體物件的方式進行了綜述。 在這裡,我們還將詳細介紹如何處理文字並將其提供給網路。

假設在輸入文字中的實體物件候選者,網路的任務是確定該實體物件是否有效,然後對其進行分類。 為此,網路需要知道實體物件周圍的上下文(除了實體本身的文字字串)。 在機器學習中,通過將這些部分表現為獨立的特徵來完成。 實際上,輸入文字被分成若干部分,分別饋送到網路:

Android Smart Linkify 支援機器學習
給定候選實體跨度,我們會提取:左邊上下文:實體之前的五個單詞,實體開始:實體的前三個單詞,實體結束:實體的最後三個單詞(如果碰到重疊,可以與前一個特徵重複,或者沒有那麼多單詞的話將直接填充),右上下文:實體後的五個單詞,實體內容:實體內部的單詞包和實體長度:實體的單詞數量的大小。 然後將它們連線在一起並作為神經網路的輸入饋送。
特徵提取用單詞操作,我們使用字元 n-gram 和大寫特徵將單個單詞表示為適合作為神經網路輸入的真實向量:

字元 N-grams。 並非使用標準單詞嵌入技術來代表單詞,而是為模型中的每個單詞保留單獨的向量,由於儲存較大,對移動裝置來說並不可行,因此我們使用雜湊字元嵌入。 這個技術將該單詞表示為一定長度的所有字元子序列的集合。 使用長度為 1 到 5。這些字串被額外雜湊並對映到固定數量的桶(有關該技術的更多詳細資訊,請參閱此處)。 最終模型僅儲存每個雜湊桶的向量,而不是每個字/字元子序列,這樣可以精簡大小。 我們使用的雜湊符號的嵌入矩陣有 20,000 桶和 12 個維度。

二進位制功能,指示單詞是否以大寫字母開頭。 這對網路來說很重要,因為郵政地址中的大寫是非常獨特的,並且有助於網路區分。

培訓資料集

我們想要很容易地訓練網路,但是並沒有明顯的資料集來完成這項任務,因此我們提出了一種訓練演算法,可以從實際部分生成合成示例。 具體地說,我們從 Web(使用 Schema.org 註釋)收集了地址,電話號碼和命名實體(如產品,地點和公司名稱)和其他隨機單詞的列表,並使用它們來合成神經網路的訓練資料。 我們按原樣獲取實體物件並圍繞它們生成隨機文字上下文(來自 Web 上的隨機單詞列表)。 此外,我們在電話號碼的負面培訓資料中新增 “確認號碼:” 或 “ ID:” 等短語,以教會網路在這些情況下禁止電話號碼匹配。

使之有效執行

我們必須使用許多附加技術來培訓網路並進行實際的移動部署:

將嵌入矩陣量化為 8 位。 我們發現,通過將嵌入矩陣值量化為 8 位整數,我們可以在不影響效能的情況下將模型的大小減小近4倍。

在選擇和分類網路之間共享嵌入矩陣。 這可以在幾乎毫髮無傷的情況下使模型縮小 2 倍,改變實體之前/之後的上下文的大小。 在移動螢幕上,文字通常很短,沒有足夠的上下文,因此網路也需要在培訓期間接觸到這一點。

從分類網路的正面示例中建立人為的負面示例。 例如,對於正面示例:“今天給我打電話 857 555-3556”,標籤為 “電話”,我們生成 “今天給我打電話 857 555-3556” 作為帶有 “其他” 標籤的反面示例。 這教導分類網路更精確地面對實體跨度。 如果不這樣做,不管跨度如何,網路將只是一個檢測器,用來檢測輸入中的某個地方是否有電話號碼,僅此而已。

國際化很重要

我們使用的自動資料提取可以更輕鬆地訓練特定語言的模型。 但是,使它們能夠適用於所有語言是一項挑戰,需要專家仔細檢查語言的細微差別,並獲得可接受的培訓資料量。 我們發現,適應所有拉丁文指令碼語言的那個模型運作良好(例如捷克語,波蘭語,德語,英語),但對於中文,日文,韓文,泰文,阿拉伯文和俄文則需要單獨的模型。 Smark Linkify 目前支援 16 種語言,但我們正在嘗試支援更多語言的模型,考慮到移動模型的大小限制以及不在空格上分割單詞的語言,這尤其具有挑戰性。

下一步

雖然這篇文章中描述的技術能夠快速準確地註釋文字中的電話號碼和郵政地址,但是對航班號,日期和時間或 IBAN 的識別,目前只能使用標準正規表示式這類更傳統的技術來實現。 但是,我們正在研究建立日期和時間的 ML 模型,特別是用於識別訊息傳遞上下文中普遍存在的非正式相對日期/時間規範,例如 “下週四” 或 “三週內”。

小型號和二進位制大小以及低延遲對於移動部署非常重要。 我們開發的模型和程式碼是開源的,可作為 Android 框架的一部分。 我們相信該架構可以擴充套件到其他裝置上的文字註釋問題,我們期待在我們的開發人員社群看到更多新的用例!

相關文章