Android Smart Linkify 支持機器學習
文 / Lukas Zilka,軟體工程師,谷歌人工智慧,蘇黎世
上半周,我們發布了 Android 9 Pie,這是 Android 的最新版本,它的機器學習應用使您的手機更簡單易用。 Android 9 中有一項功能是 Smart Linkify,這是一種新的 API,可在文本中檢測到某些類型的實體時添加可點擊鏈接。 這個功能很有用,例如,當您從朋友的消息傳遞 app 中收到一個地址,想要在地圖上查找時,如果使用 Smart Linkify-annotated 文本,它就變得容易多了!
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 之間):
對於給定的文本字元串,第一個網路為非實體對象分配低分,為正確選擇了整個電話號碼的候選單詞分配高分
接下來,將重疊的生成對象刪除,促成較高得分者與較低得分者來一決高下。 現在,我們有一組對象,但仍然不知道它們的類型到底是什麼。所以現在第二神經網路將對象的類型分類,要麼是電話號碼,地址,要麼在某些情況下將之分類成非實體對象。
在我們的示例中,唯一沒有衝突的對象是 「並且明天請打電話給 857 555 3556。」(「857 555 3556」 被歸類為電話號碼),「並且明天打電話給 857 555 3556。」(「並且」 被歸類為非實體對象)。我們可以輕鬆地在屏幕上顯示的文本中為它們加上下劃線,並在點擊時運行正確的應用程序。
文字特徵
目前為止,我們已經對 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 框架的一部分。 我們相信該架構可以擴展到其他設備上的文本注釋問題,我們期待在我們的開發人員社區看到更多新的用例!
更多 AI 相關閱讀:
· Google BigQuery 中的機器學習
· MnasNet:邁向移動端機器學習模型設計的自動化之路
· 全新 AIY Edge TPU 開發板驚艷亮相
推薦閱讀:
※目前進行的工作日誌
※Android我還可以相信你多少系列文章三之通知欄
※木犀互聯網周刊(第十九期)
※紫微斗數算命占卜詳解說(A錢占卜網Android版)
※Flyme (7) 細談(不是廣告)