「TensorFlow 谷歌神經機器翻譯」從零開始打造屬於你的翻譯系統
1 新智元編譯
機器翻譯——自動在兩種語言之間進行翻譯的任務——是機器學習中最活躍的研究領域之一。在多種機器翻譯方法中,序列到序列(「seq2seq」)模型最近取得了巨大的成功,並已經成為大多數商業翻譯系統的事實上的標準,例如谷歌翻譯。這是由於 seq2seq 模型能夠利用深度神經網路捕捉句子意義。但是,雖然 seq2seq 模型(例如 OpenNMT 或 tf-seq2seq)有大量的資料,但是缺少可以同時教知識和構建高質量翻譯系統的技能的教程。
谷歌今天公布了一個用 TensorFlow 構建神經機器翻譯(NMT)系統的教程,全面解釋 seq2seq 模型,並演示如何從零開始構建 NMT 翻譯模型。這個教程從 NMT 的背景知識講起,並提供構建一個 NMT 系統的代碼細節。接著,教程講解注意力機制(attention mechanism),這是讓 NMT 能夠處理長句子的關鍵。最後,教程提供如何複製谷歌的 NMT 系統(GNMT)中的關鍵功能,在多個 GPU 上進行訓練的詳細信息。
這一教程還包括詳細的基準測試結果,使用者可以自行複製。谷歌的模型提供了強大的開源基準,性能與 GNMT 的結果相當,在流行的 WMT"14 英語 - 德語翻譯任務上實現了 BLEU 得分 24.4 的性能。
教程還包括其他基準測試結果(英語 - 越南語,德語 - 英語)。
此外,這個教程還提供了完全動態的 seq2seq API(與 TensorFlow 1.2 一起發布),旨在使構建 seq2seq 模型更加簡潔:
使用tf.contrib.data中新的輸入管道輕鬆讀取和預處理動態大小的輸入序列。
使用padded batching和sequence length bucketing來提高訓練和推理速度。
使用流行的架構和訓練schedule訓練seq2seq模型,包括幾種類型的attention和scheduled sampling。
使用in-graph beam search在seq2seq模型中執行推理。
為多GPU設置優化seq2seq模型。
希望這一教程有助於研究界創造更多新的NMT模型並進行實驗。完整教程的GitHub地址:https://github.com/tensorflow/nmt,本文提供主要內容的翻譯介紹。
神經機器翻譯(seq2seq)教程
作者:Thang Luong, Eugene Brevdo, Rui Zhao
目錄
導言
基礎
神經機器翻譯背景知識
安裝教程
訓練——如何構建你的第一個NMT系統
嵌入
編碼器
解碼器
損失
梯度計算和優化
實踐——讓我們開始訓練一個NMT模型
推理——如何生成翻譯
中級教程
注意力機制的背景知識
Attention Wrapper API
實踐——構建一個以注意力為基礎的NMT模型
提示與技巧
構建訓練,評估和推理圖
數據輸入管道
更好的NMT模型的其他細節
雙向RNN
束搜索(Beam Search)
超參數
多GPU訓練
基準
IWSLT英語 - 越南語
WMT德語 - 英語
WMT英語 - 德語(完全比較)
其他資源
致謝
參考文獻
導言
序列到序列(seq2seq)模型(Sutskever et al.,2014,Cho et al.,2014)在機器翻譯、語音識別、文本概況等各種任務中取得了巨大的成功。本教程提供了對 seq2seq 模型的全面解釋,並演示了如何從頭開始構建一個具有競爭力的 seq2seq 模型。我們專註於神經機器翻譯(NMT)任務,這是第一個大獲成功的 seq2seq 模型的測試平台。教程中包含的代碼是輕便,高質量,生產就緒,並結合了最新的研究觀點的。我們通過以下方式實現這一目標:
使用最新的解碼器/注意力包裝 API,TensorFlow 1.2 數據迭代器
結合我們在構建循環模型和 seq2seq 模型方面的專長
提供構建最好的 NMT 模型以及複製谷歌的 NMT(GNMT)系統的提示和技巧。
我們認為,最重要的是提供可以讓人輕鬆複製的基準。因此,我們提供了完整的實驗結果,並在以下公開數據集對模型進行了預訓練:
小規模:IWSLT Evaluation Campaign 提供的 TED 演講(133K句子對)的英語 - 越南語平行語料庫。
大規模:WMT Evaluation Campaign 提供的德語 - 英語平行語料庫(4.5M句子對)。
我們首先提供構建 NMT 的 seq2seq 模型的一些基本知識,說明如何構建和訓練一個 NMT 模型。第二部分將詳細介紹構建一個有競爭力的 NMT 模式的注意力機制。最後,我們將提供一些提示和技巧,以構建最佳性能的 NMT 模型(包括訓練速度和翻譯質量),例如 TensorFlow 的最佳實踐(batching, bucketing),bidirectional RNN 和 beam search。
基礎
神經機器翻譯的背景知識
回到過去,傳統的基於短語的翻譯系統是通過將源語言的句子分解成多個部分,然後逐個短語地進行翻譯。這導致機器翻譯的結果與人類翻譯的結果很不同。人類是通讀整個源句子,理解它的含義,然後進行翻譯。神經機器翻譯(NMT)模擬了這樣的過程!
圖1:編碼器-解碼器架構,NMT的一個通用方法的示例。編碼器將源句子轉換成一個「meaning」向量,這個向量通過解碼器傳遞,產生翻譯結果。
具體來說,NMT 系統首先使用編碼器讀取源語句來構建「meaning」向量,即表示句子意義的一個數字序列; 然後,解碼器處理句子向量以輸出翻譯結果,如圖1所示。這一架構同城被稱為編碼器-解碼器架構(encoder-decoder architecture)。以這種方式,NMT 解決了傳統的基於短語的方法中翻譯局部性的問題:它可以捕獲語言的遠距離依賴性,例如性一致, 句法結構,等等,併產生更流暢的翻譯,如谷歌的神經機器翻譯系統所演示的。
NMT 模型的具體結構有所不同。序列數據的一般選擇是大多數NMT模型使用的循環神經網路(RNN)。通常,RNN用於編碼器和解碼器。但是,RNN模型在以下方面不同:(a)方向性——單向或雙向; (b)深度——單層或多層; 和(c)類型——通常是普通RNN,長短期記憶(LSTM)或循環門單位(Gated Recurrent Unit, GRU)。有興趣的讀者可以在這篇博客文章了解有關RNN和LSTM的更多信息:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
在本教程中,我們將一個單向的深度多層RNN作為示例,並將LSTM作為一個循環單元。圖2是這樣一個模型的例子。在這個示例中,我們構建一個模型來將源句子「I am a student」翻譯成一個目標句子「Je suisétudiant」。在高層水平上,NMT模型由兩個循環神經網路組成:編碼器RNN簡單地處理輸入的源辭彙,不進行任何預測; 另一方面,解碼器RNN在預測下一個單詞的同時處理目標句子。
更多信息請參閱Luong(2016)的教程(https://github.com/lmthang/thesis),本教程正是基於這個教程的擴充。
圖2:神經機器翻譯——將源句子「I am a student」翻譯成目標句子「Je suisétudiant」,這是一個深度循環架構的例子。這裡,「」表示解碼處理的開始,「 s>」提示解碼器停止。
安裝教程
要安裝本教程,你需要在系統上安裝TensorFlow。本教程要求最新版本的TensorFlow(version 1.2.1)。要安裝TensorFlow,請按照官方的安裝說明進行操作(https://www.tensorflow.org/install)。
安裝好TensorFlow之後,您可以通過運行下面的代碼下載本教程的源代碼:
git clone https://github.com/tensorflow/nmt/
訓練——如何構建你的第一個NMT系統
我們先用一些具體的代碼片段看看構建一個NMT模型的核心,詳細解釋一下圖2。我們後面會提供數據準備和完整代碼。這部分涉及model.py文件。
在底層,編碼器RNN和解碼器RNN作為輸入接收以下內容:首先是源句子(source sentence),然後是一個邊界標記「」,提示從編碼模式到解碼模式的切換,最後是目標句子(target sentence)。對於訓練過程,我們將為系統提供以下張量,它們是time-major的格式,包含單詞索引:
encoder_inputs [max_encoder_time, batch_size]: 源輸入單詞
decoder_inputs [max_decoder_time, batch_size]: 目標輸入單詞
decoder_outputs [max_decoder_time, batch_size]: 目標輸出單詞,即 decoder_inputs左移動一個時間步長,同時在右邊附一個句末標記。
為了提高效率,我們一次訓練多個句子(batch_size)。測試過程略有不同,我們會在後面討論。
嵌入
給定詞類屬性,模型必須先查找源和目標嵌入以檢索相應的辭彙表示。為了使嵌入層工作,首先要為每種語言選擇一個辭彙表。通常,選擇辭彙大小V,並且只有最常用的V辭彙被視為唯一的。其他所有辭彙都轉換成一個「unknown」字元(token),並且都得到相同的嵌入。通常在訓練期間學習嵌入的權重,每種語言一套。
同樣,我們可以構建 embedding_decoder 和 decode_emb_inp。請注意,可以選擇使用預訓練的單詞表示(例如 word2vec 或 Glove vector)來初始化嵌入權重。一般來說,給定大量訓練數據,我們可以從頭開始學習這些嵌入。
編碼器
一旦被檢索到,那麼嵌入辭彙就作為輸入被喂入主網路中,該主網路由兩個多層RNN組成——用於源語言的編碼器和用於目標語言的解碼器。這兩個RNN原則上可以共享相同的權重; 但是,在實踐中,我們經常使用兩種不同的RNN參數(這些模型在擬合大型訓練數據集時做得更好)。編碼器RNN使用零向量作為起始狀態,構建如下:
請注意,句子具有不同的長度以避免計算上的浪費,我們通過source_seqence_length 告訴 dynamic_rnn 確切的源句子長度。由於我們的輸入是 time major 的,因此設置 time_major = True。 在這裡,我們只構建一個單層LSTM,encoder_cell。在後面的部分將介紹如何構建多層 LSTM,添加 dropout,以及使用 attention。
解碼器
解碼器也需要訪問源信息,一個簡單的方法就是用編碼器的最後一個隱藏狀態(encode_state)來初始化解碼器。 在圖2中,我們將源代碼「student」的隱藏狀態傳遞到解碼器端。
這裡,代碼的核心部分是 BasicDecoder ,接收 decode_cell(類似於encoder_cell)的 decoder,一個 helper,以及作為輸出的前一個 encoder_state。通過分開 decoders 和 helpers,我們可以重複利用不同的代碼庫,例如,可以用 reedyEmbeddingHelper 替代 TrainingHelper 進行 greedy decoding。更多信息請查看 helper.py。
最後,我們還沒提到 projection_layer,它是一個密集矩陣(dense matrix),用於將頂部的隱藏狀態轉換為維度V的對數向量(logit vectors)。這個過程在圖2的頂部說明了。
損失
有了上面的 logits,現在可以計算訓練損失:
這裡,target_weights 是與 decode_outputs 大小相同的0-1矩陣,它將目標序列長度之外的位置填充為值為0。
重要注意事項:我們用 batch_size 來分割損失,所以我們的超參數對 batch_size是「不變的」。有的人將損失以 batch_size * num_time_steps 進行分割,這可以減少短句子的翻譯錯誤。更巧妙的是,我們的超參數(應用於前面的方法)不能用於後面的方法。例如,如果兩種方法都使用學習律為1.0的SGD,那麼後一種方法有效利用更小的學習率,即1 / num_time_steps。
梯度計算和優化
我們現在已經定義NMT模型的前向傳播。計算反向傳播只需要幾行代碼:
訓練RNN的重要步驟之一是梯度剪切(gradient clipping)。這裡,我們按照global norm警醒剪切。最大值max_gradient_norm通常設置為5或1。最後一步是選擇優化器。Adam優化器是常見的選擇。也需要選擇學習率(learning rate)。learning_rate的值通常在0.0001到0.001之間; 也可以設置為隨著訓練的進行,學習率降低。
在我們自己的實驗中,我們使用標準SGD(tf.train.GradientDescentOptimizer)以及可降低的學習率設置,從而產生更好的性能。具體見benchmark部分。
實踐——訓練一個NMT模型
讓我們開始訓練第一個NMT模型,將越南語翻譯成英語!代碼的入口點是 nmt.py
我們將使用一個小型的TED 演講(133K訓練樣本)的平行語料庫來進行這個實踐。我們在這裡使用的所有數據可以在下面網址找到:https://nlp.stanford.edu/projects/nmt/。我們將使用tst2012作為dev數據集,tst2013作為測試數據集。
運行以下命令下載訓練NMT模型的數據:nmt/scripts/download_iwslt15.sh /tmp/nmt_data
運行以下命令開始訓練:
上面的命令訓練一個具有128-dim的隱藏單元和12個epoch的嵌入的2層LSTM seq2seq模型。我們使用的dropout值為0.2(保持或然率為0.8)。如果不出現error,隨著訓練的困惑度值(perplexity value)降低,應該可以看到類似下面的logs:
詳細信息請參閱train.py。
我們可以在訓練期間啟動Tensorboard來查看模型的概要:
tensorboard --port 22222 --logdir /tmp/nmt_model/
以上是從英語翻譯成越南語的訓練,通過下面的代碼可以簡單地變成從越南語翻譯成英語:
--src=en --tgt=vi
推理——如何生成翻譯
在訓練NMT模型時(以及已經訓練完時),你可以得到之前模型沒見過的源句子的翻譯。這個過程稱為推理(inference)。訓練和推理(測試)之間有明確的區別:在推理時,我們只能訪問源句子,即encoder_inputs。執行解碼有很多種方法。解碼方法包括greedy解碼,採樣解碼和束搜索(beam-search)解碼。這裡,我們將討論貪心解碼策略。
它的想法是很簡單的,如圖3:
我們仍然以與訓練期間相同的方式對源句子進行編碼,以獲得encoder_state,並使用該encoder_state來初始化解碼器。
一旦解碼器接收到開始符號「
對於解碼器側的每個時間步長,我們將RNN的輸出視為一組logits。我們選擇最有可能的單詞,即與最大logit值相關聯的id作為輸出的單詞(這就是「greedy」行為)。例如在圖3中,在第一個解碼步驟中,單詞「moi」具有最高的翻譯概率。然後,我們將這個詞作為輸入提供給下一個時間步長。
這個過程繼續進行,直到生成句尾標記「 s>」作為輸出符號(在我們的代碼中是tgt_eos_id)。
圖3:Greedy解碼——訓練好的NMT模型使用greedy搜索生成源句子「Je suisétudiant」的翻譯。
令推理與訓練不同的是步驟3。推理使用模型預測的單詞,而不是總是正確的目標單詞作為輸入。以下是實現greedy解碼的代碼。它與解碼器的訓練代碼非常相似。
在這裡,我們使用GreedyEmbeddingHelper而不是TrainingHelper。由於我們預先不知道目標序列長度,所以使用maximum_iterations來限制翻譯長度。 一個啟發是解碼最多兩倍的源句子長度。
訓練好一個模型後,現在可以創建一個推理文件並翻譯一些句子:
注意,上述命令也可以在模型正在訓練時運行,只要存在一個訓練的檢查點。 詳細請參閱inference.py。
進階版:注意力機制
說完了最基本的 seq2seq 模型後,下面是進階版!
注意力機制:背景
為了建立最先進的神經機器翻譯系統,我們將需要更多的「特殊材料」:注意力機制,這是 Bahdanau 等人於 2015 年首次引入,然後由 Luong 等人在同年完善的。注意力機制的關鍵在於通過在翻譯過程中,對相關來源內容進行「注意」,建立目標與來源之間的直接連接。注意力機制的一個很好的副產品,是源和目標句子之間的對齊矩陣(如圖 4 所示)。
圖4:注意力機制可視化:源和目標句子之間的比對的例子。圖像來自論文 Bahdanau et al.,2015。
在簡單的 seq2seq 模型中,開始解碼時,我們將最後的源狀態從編碼器傳遞到解碼器。這對比較短和中等長度的句子效果很好;然而,對於長句子,單個固定大小的隱藏狀態就成了信息瓶頸。注意力機制並不是丟掉在源 RNN 中計算的所有隱藏狀態,而是讓解碼器將它們視為源信息的動態存儲器。通過這樣做,注意力機制改善了較長句子的翻譯質量。如今,注意力機製成為神經機器翻譯的首選,而且也成功應用於許多其他任務(包括圖說生成,語音識別和文本摘要)。
我們現在介紹注意力機制的一個實例,這個實例是 Luong 等人在 2015 年論文中提出的,已被用於 OpenNMT 開放源碼工具包等多個最先進的系統,TF seq2seq API 教程中也使用了這個例子。
圖5:注意力機制:Luong 等人 2015 年所述的基於注意力的 NMT 系統的例子。這裡詳細介紹了注意力計算的第一步。為了清楚起見,沒有將圖 2 中的嵌入和投射層繪製出來。
如圖 5 所示,注意力計算在每個解碼器時間步長都有發生,包括以下階段:
比較當前目標隱藏狀態與所有源狀態,獲得注意力權重「attention weight」(可以如圖 4 所示);
基於注意力權重,計算上下文矢量(context vector),作為源狀態的加權平均值;
將上下文矢量與當前目標隱藏狀態相結合,產生最終的注意力向量「attention vector」;
注意力向量作為輸入,被傳遞到下一個時間步。
注意力機制中最關鍵的是什麼?
根據 score 函數和 loss 函數的不同,存在很多不同的注意力變體。但在實踐中,我們發現只有特定的一些選擇很重要。首先是注意力的基本形式,也即目標和源之間的直接關係。 其次是將注意力向下饋送到下一個時間步長,這是告知網路過去的注意力做了什麼決定(Luong 等人,2015)。最後,score 函數的選擇往往會導致性能表現不同。
AttentionWrapper API
在部署 AttentionWrapper 時,我們借鑒了 Weston 等人 2015 年在 memory network 方面的一些術語。與可讀寫的 memory 不同,本教程中介紹的注意力機制是只讀存儲器。具體來說,源的一組隱藏狀態被作為「記憶」(memory)。在每個時間步長中,使用當前目標隱藏狀態作為「query」來決定要讀取 memory 的哪個部分。通常,query 需要與對應於各個內存插槽的 key 進行比較。在我們的介紹中,恰好將源隱藏狀態作為「key」。你可以受到記憶網路術語的啟發,得出其他形式的注意力!
由於有了 attention wrapper,用 attention 擴展普通 seq2seq 代碼就十分簡單了。這部分參考文件 attention_model.py
首先,我們需要定義注意機制,例如(Luong等人,2015):
在以前的 Encoder 部分中,encoder_outputs 是頂層所有源隱藏狀態的集合,其形狀為 [max_time,batch_size,num_units](因為我們將 dynamic_rnn 與 time_major 設置為 True)。對於注意力機制,我們需要確保傳遞的「記憶」是批處理的,所以需要轉置 attention_states。 將 source_sequence_length 傳遞給注意力機制,以確保注意力權重正確歸一化(僅在 non-padding 位置上發生)。
定義了注意力機制後,使用 AttentionWrapper 解碼單元格:
代碼的其餘部分與 Decoder 那節是一樣的!
實踐:構建基於注意力的 NMT 模型
為了實現注意力,我們需要使用 luong,scaled_luong,bahdanau 或 normed_bahdanau 中的一個,作為訓練期間的注意力 flag 的值。這個 flag 指定了我們將要使用的注意力機制。 我們還需要為注意力模型創建一個新的目錄,這樣才不會重複使用以前訓練過的基本 NMT 模型。
運行以下指令開始訓練:
在訓練完成後,使用同樣的推理指令 model_dir 做推理:
玩轉 NMT:竅門和技巧
構建訓練圖、評估圖和推理圖
在 TensorFlow 中構建機器學習模型時,最好建立 3 個獨立的圖:
首先是訓練圖,其中:
批次、bucket 和可能的子樣本從一組文件/外部輸入輸入;
包括前向和後向 op;
構建優化器,並添加訓練 op。
其次是評估圖,其中:
批次和 bucket 從一組文件/外部輸入數據;
包括 1 個訓練前向 op 和不用於訓練的其他評估 op
最後是推理圖,其中:
可能不批量輸入數據;
不會對輸入數據進行子採樣;
從佔位符讀取輸入數據
包括模型前向 op 的一個子集,也可能含有用於存儲 session.run 調用之間狀態的其他特殊輸入/輸出。
構建單獨的圖有幾個好處:
推理圖通常與其他兩個不同,因此需要分開構建;
這樣評估圖也更簡單,因為沒有了額外的反向 op;
可以為每個圖分別實現數據饋送;
各種重用都更加簡單。例如,在評估圖中,不需要用 reuse = True 重新打開可變範圍,因為訓練模型已經創建了這些變數。不需要到處使用 reuse=;
在分布式訓練中,訓練、評估和推斷分開用不同的機器做很正常。反正都需要各自建圖。因此,分開建圖也有助於你構建分布式訓練系統。
主要的問題是,在只有單機的情況下,如何在 3 個圖中共享變數 Variables。這可以通過為每個圖使用單獨的 session 來解決。訓練 session 定期保存檢查點,評估和推理 session 定期從檢查點恢復參數。
下面的例子顯示了兩種方法的主要區別。
1. 統一建圖:一個圖裡 3 個模型
2. 分別建圖:3 個 session 共享變數
注意,後一種方法很容易就能轉換為分布式版本。
另一個區別在於,我們使用了有狀態的迭代器對象,而不是使用 feed_dicts 來在每個 session.run 調用中提供數據。這些迭代器使輸入管道在單機和分布式設置中都容易得多。
其他技巧:雙向 RNN
編碼器的雙向性通常會帶來更好的性能(但由於使用了更多層,速度會有一些降低)。在這裡,我們給出一個簡單的例子,說明如何用單個雙向層構建編碼器:
其他技巧:Beam Search
雖然貪婪解碼得出的翻譯質量不錯,但是 beam search 解碼器可以進一步提高性能。Beam search 在翻譯時總是將一小部分頂級候選詞留在身邊,從而在搜索空間更好地探索所有可能的翻譯。 Beam 的大小稱為「寬度」width;大小為 10 的寬度基本就夠了。以下是 Beam search 的示例:
其他技巧:超參數
有些超參數能帶來性能的進一步提升。以下是根據我們的經驗列出的一些超參數:
優化函數:雖然在「不太熟悉」的架構里,Adam 能帶來不錯的結果,但如果你能訓練 SGD,SGD 通常會更好;
注意力:Bahadnau 風格的注意力需要解碼器雙向性才好用;Luong 風格的注意力在不同設置下都挺好。在這份教程中,我們推薦兩個變體: scaled_luong & normed bahdanau
其他技巧:多 GPU 訓練
訓練一個 NMT 模型需要好幾天。將不同的 RNN 層放在不用的 GPU 上能提升訓練速度。以下為一個例子:
你可能會發現,隨著 GPU 數量的增長,基於注意力的 NMT 模型訓練速度提升非常有限。這是因為標準注意力架構在每個時間步長使用頂層(最後一層)的輸出做為 query 注意力。這意味著每一次解碼都需要等前面的步驟完全結束了才行。因此,無法在多台 GPU 上並行解碼 RNN。
谷歌提出的 GNMT 注意力架構使用底層(第一層)輸出作為 query 注意力。因此,前一步剛剛結束就能實行注意力計算。我們實現了 GNMTAttentionMultiCell 中的架構,這是 tf.contrib.rnn.MultiRNNCell 的一個子類。 以下是使用 GNMTAttentionMultiCell 創建解碼器單元的示例:
最後的基準部分請參考原文。
原文:https://github.com/tensorflow/nmt
點擊閱讀原文查看新智元招聘信息
※「微軟 AI 「百人計劃」」新建 AI 研究院,劍指 DeepMind、谷歌大腦
※「2017上半年中國AI融資英雄榜」TOP10融資50億元,二八定律明顯
※10億+數據,ImageNet千倍:深度學習,谷歌說數據為王
※孫劍團隊提出移動端神經網路,優於谷歌MobileNet
TAG:新智元 |
※南書房行走被譯成「South study walking」,機器翻譯靠譜嗎?
※同聲傳譯被攻陷!谷歌發布Translatotron直接語音翻譯系統
※「安卓手機非常卡頓」扔進谷歌翻譯,Android Phone is very fast
※Facebook Messenger迎來全新AR功能和M翻譯器
※必應翻譯被拋棄:Twitter PWA轉用谷歌翻譯
※谷歌翻譯「安卓機卡頓」,Android is fast
※谷歌將AutoML應用於Transformer架構,翻譯結果飆升,已開源
※如何在Keras中開發神經機器翻譯系統?
※「走狗」是翻譯成「running dogs」
※無監督神經機器翻譯——UNdreaMT
※Facebook Messenger 將提供聊天翻譯功能
※五張動圖,看清神經機器翻譯里的Attention!
※LG 的最新耳機支持一鍵啟用 Google Assistant 和翻譯功能
※Ten Little Ones 中英文音頻和翻譯
※OpenAI背後的領袖Ilya Sutskever:一個計算機視覺、機器翻譯、遊戲和機器人的變革者
※谷歌的Translatotron將翻譯提升到新的水平
※Please翻譯一下your English
※Facebook Messenger更新:自動翻譯外語 引入AR體驗
※Timekettle時空壺翻譯耳機WT2 Plus使用評測
※谷歌的機器翻譯模型 Transformer,現在可以用來做任何事了