なるほど!Google翻訳のアルゴリズム
みなさんこんにちは。
株式会社キスモの役員の寺澤です。
本日は、精度が高いと言われている、Google翻訳の技術をアルゴリズムの観点で紹介しようと思います。
arxivという国際論文が投稿されているサイトで、今年の6月に、GoogleのデータサイエンティストたちがAttention is All you NeedというタイトルでGoogle翻訳の技術であるTransformerという深層ネットワークを公開しました。
Transformerというとアニメや映画のトランスフォーマーを思い起こしますね。油断して適当に検索したらその作品がでます 笑
この論文は外国のデータサイエンティストの中でもすぐに話題になり、後にGoogleが公式で公開され、日本でも記事となりました。
Google公式の記事(英語注意): https://research.googleblog.com/2017/08/transformer-novel-neural-network.html
日本の記事: http://gigazine.net/news/20170901-transformer-neural-network-language-understanding/
実はこの論文が公開された直後に一度読んでみましたが、当時はあまりアルゴリズムを理解できませんでした。
今回はそのリベンジを含めてアルゴリズムを理解してきましたが、何故かあっさり理解できました 笑
さて、前置きはこれくらいにしておいて、解説に移ります。かなりコアな内容になるので、初心者は要注意です。
Google翻訳の技術、Transformerの構造とは?
前述の記事を読んでいただければ概要は理解できると思いますが、大まかに言うと、
- 既存のモデル(RNNベース、CNNベース)のものよりも精度が高く、学習時間の削減にも成功した。
- 着想はRNN、CNNベースのものとは変わらず、元の文全体を意識して、翻訳を行うモデルである。
- 既存モデルとの他の優位性は、文中の単語の意味を理解していることにある。
3番目に関しては、例えば英文の"it"が何を指すか(動物なのか、あるいは道路なのかなど)を理解した上で翻訳をします。
参考記事中の翻訳タスクでは、英文の"it"をフランス語では動物、道路を指す単語をそれぞれ"qu'il"、"qu'elle"と翻訳する事に成功しています。
Transformerは、Self-Attentionという、CNNに使われる畳み込みにもRNNに使われる再帰構造にも頼らない構造を使っています。
Transformerの動き方は前述の記事で紹介されていましたが、実際のアルゴリズムはどうなっているのか、説明していきましょう。
Transformerのアルゴリズム(概要)
Transformerのネットワーク構造は上図となります。本記事では、入力・エンコード・デコード・出力の順に説明します。
図ではそれぞれ下部分、左の灰色部分、右の灰色部分、右上の出力部分となります。
Transformerのアルゴリズム(入力する前に)
まず、入力する文と出力する文(翻訳元の文、翻訳した文両方)は、既存のRNNと違って、単語の位置の情報を与えなければなりません。
これは、Position Embeddingsというアルゴリズムで単語の位置を与えてやります(単語にインデックスを付けるだけですが)。
この手法は、Facebookが今年の5月に公開したCNNベースの翻訳モデルでも用いられました。これをたった1ヶ月で追い上げるGoogleすごいですよね。
論文では、このアルゴリズムをさらに改善したPositional Encodingというアルゴリズムを使って、単語の位置情報を与えます。
数式は以下のようになり、この式を適用したベクトルPEの列とベクトル化した単語列がネットワークへの入力となります。
上式のposは単語の位置、iはベクトル化した単語の次元数(インデックス)を指し、交互にsinとcosをとっているようです。
このアルゴリズムを適用する事で、単語の位置を相対的にも考慮して学習する事ができるようです。
しかし、論文の検証結果では、通常のPosition Embeddingsを使ったTransformerのモデルと比較したところ、ほぼ同等のスコアでした(若干提案手法の方が優勢でした)。
Transformerのアルゴリズム(エンコードレイヤー)
さて、いよいよ学習・推論のアルゴリズムに入ります。まずは入力する文(翻訳元の文)に対応するエンコードレイヤーについて説明していきましょう。
後のデコード層にも使われますが、基本的には、Multi Head-Attention層とFeed Forward層の二本柱になっていまして、
それぞれの層の直後にresidual層、正規化層が挟まっています。このネットワークを一つのエンコードレイヤーとして扱い、このレイヤーを複数連結したものがエンコード層となります。
residual層は、ResNetを知っている人ならばアルゴリズムは想像つくでしょうが、Multi Head-Attention層はTransformerのコア技術になりますね。
これらの層を順に説明していきましょう。
Multi Head-Attention層
Multi Head-Attention層は上図の右のような構造をとります。
Multi Head-Attention層への入力は、図の通り、3つとなっております。入力の最初の層にこれがくる事になりますが、単語の入力をどう3つにするんだと思うでしょう。
実は、今回は、入力ベクトル同じものを3つ入力します。3つの入力はそれぞれ、query、key、valueと呼ばれ、query、keyから重みを作り、その重みを適用したvalueを出力します。
エンコードレイヤー内でのこの層はSelf-Attentionと呼ばれますが、同じ単語ベクトルから計算するためにこう呼ばれているのでしょう。
さらにこの中では、さらにScaled Dot-Product Attentionという層が存在し、Multi Head-Attention層の肝となります。
図では左の構造になります。(図にはMaskという層が現れていますが、後述するデコードレイヤーでのみ用います。)
だいたい図の通りですが、入力ベクトルであるquery、key、valueをそれぞれ、Q、K、Vとすると、Scaled Dot-Product Attentionは以下の数式で計算が行われます。
図のScaleに当たる部分が、ハイパーパラメータd_kの平方根を割る箇所となります。
ハイパーパラメータで割るのはチューニング可能にして、調整が効くようにするためでしょうが、どうして平方根を挟むのでしょうか。
ハイパーパラメータd_kに平方根を取る理由ですが、値の大きいd_kで割ってしまったら、勾配が非常に小さくなり、勾配消失問題に繋がるためです。
Multi Head-Attention層ではこのアルゴリズムを用いますが、入力するQ、K、Vはそれぞれ対応する全結合層を挟んだ後、h個のQ、K、Vのペアを並列して、
Scaled Dot-Product Attention層に通します。入力は、処理済みのh個のQ、K、Vのペアを入力としますが、Scaled Dot-Product Attention層は対応するh個だけ用意します。
出力したh個のベクトルは連結し、再び全結合層に通して出力されます。これがMulti Head-Attention層の一連の流れとなります。
ただし、前述の全結合は、論文内では全てパラメータ行列との内積だけで表現されております。同様に参考に読んだgithubのコードでは、通常の全結合層に通し、場合によってはreluも通していました。見た感じですと、論文内では前者以上の説明はありませんでしたが、学習具体によって差し替えるのもありですね。
後に説明する翻訳後の結果に通すデコードレイヤーでは、形を変えてこの層を使います。
Feed Forward層
長々とMulti Head-Attention層の説明をしましたが、Feed Forward層は見慣れた構造となっております。
単純に全結合、relu、全結合の順に入力を通していきます。ただし、全結合の代わりにカーネルサイズが1の畳み込み層を用いても良いようです。
参考にしたgithubのコードでも畳み込みを使っていました。
residual層
residual層ではResNet(Residual Network)でも用いられた手法で、入力の残差を学習する事で、ネットワークの層を深くするという着想を元に生まれました。
何が行われているかは単純で、レイヤーに入力したベクトルとその入力をしたレイヤーから出力されたベクトルの和を取るだけです。
ここでは、Multi Head-Attention層への入力と出力の和、Feed Forward層への入力と出力の和を取ります。
論文内では、エンコードレイヤーを6つ連結し、更にエンコードレイヤーと似た構造のデコードレイヤーも6つ用意しているものがベースのモデルとなっています。
そのことを考えると確かに深い構造になりますね。そのことを見据えて用意したのでしょう。
正規化層
正規化です。入力したベクトルの値の平均を1に、分散を0にするものです。
Transformerのアルゴリズム(デコードレイヤー)
エンコードレイヤーの説明が長くなりましたが、今度は出力する文(翻訳結果の文)に対応するデコードレイヤーについて説明します。
デコードレイヤーと似た構造を取り、デコードレイヤーに登場した層を使っていきます。ただし、Masked Multi Head-Attention層という層が新たに加わり、Masked Multi Head-Attention層、Multi Head-Attention層、Feed Forward層の順の連結を1つのデコードレイヤーとします。
こちらでも例外なく、各層の出力直後にresidual層と正規化層が現れたり、複数レイヤーの連結も行います。
ここでは、(Masked) Multi Head-Attention層の扱い方がエンコードレイヤーとは変わりますので、それらの説明を行います。
Masked Multi Head-Attention層
基本的には、Multi Head-Attention層とは変わりませんが、
Scaled Dot-Product Attention内のsoftmax関数を通す直前の値にマスキングを適用します。式にするとこういう形になるでしょうか。
エンコードレイヤーでは、入力の文全体を意識して学習を行います。しかしデコードレイヤーでは翻訳文が頭から順番に出力され、翻訳した単語とそれ以前に出力した単語列のみを意識しています。
例えば、「私はトムです」は「I'm Tom」と訳せますね。しかしモデルは「最初に"I'm"」が来ても、次に何が来るかを計算しなければなりません。厳密には「最初に"I'm"」が出力するかわからない段階があります。
「それ以前に出力した単語列のみを意識」するとは、"I'm"を翻訳文として出力するべきとは理解したものの、それ以降は何を出力するべきか核心に至っていない状態での意識の事です。
そこで、出力されているはずのない単語(出力する単語を選ぶ前の時点の単語)ベクトルに関しては、上式のようなマスクを適用します(論文内ではに差し替えています)。
Multi Head-Attention層
Masked Multi Head-Attention層に続く、Multi Head-Attention層では、queryに図で言う、直前のMasked Multi Head-Attention層の出力を受け取り、key、valueがエンコードレイヤーの最終出力を受け取ります。いわゆるSelf-Attentionとは違う入力になりますね。
このような入力にする事で、翻訳元の文と、時系列で言う過去の翻訳の出力を加味した学習や推論を行えるようにします。
以上で説明した層を組み合わせネットワークがデコードレイヤーとなります。
Transformerのアルゴリズム(出力)
出力はデコードレイヤーの最終出力を全結合層、ソフトマックス層の順番に通し、出力した単語列に続く次の単語を予測します。
論文内では記載されていないようですが、損失関数は交差エントロピーで問題ないでしょう。
Transformerのアルゴリズム(その他)
このネットワークでも例外なくdropoutは用います。
論文内では、residual層の直前と、Scaled Dot-Product Attentionの最後の内積の直前に適用しています。
終わりに
以上がGoogleの翻訳技術であるTransformerの全貌となります。数式や長文ばかりではわかりにくいと思いますので、
一応原論文に加えて私が参考にしたgithubのソースコードのURLも置いておきます。
余裕があれば紹介した論文を引用した論文でも紹介しようと思いましたが、こうも長くなってしまったので省略します。
スコアや計算量など、評価に関する部分も論文に任せます。
これを機にGoogleの翻訳技術を再現してみるのはいかがでしょうか。
いずれ余裕ができた時には、Neural Network Consoleなどでの再現実装も検討しようと思います。
以上、寺澤でした。
参考文献
- Attention is All you Need https://arxiv.org/pdf/1706.03762.pdf
- 本稿で解説したネットワークの論文です。
- Convolutional Sequence to Sequence https://arxiv.org/pdf/1705.03122.pdf
- 本稿で解説したネットワークが参考にした、畳み込みベースの翻訳モデルの論文です。
- A TensorFlow Implementation of the Transformer: Attention Is All You Need https://github.com/Kyubyong/transformer
- 本稿で解説したネットワークのTensorFlowによる実装です。これと論文を参考に勉強しました。
もっとキスモのことを知りたい方は
こちらをご覧ください!
Neural Network Console(NNC)を用いたAutoEncoderの作成
杉浦です。株式会社キスモにインターンとして在籍しています。
機械学習を学んで4ヶ月。
やっと少し分かってきたかなという感じでして、今回はインターンで学んだAutoEncoderを紹介しようと思います。
1. そもそも AutoEncoder って?
上図のように、InputとOutputに同じ画像を与えることを考えます。この時、中間層の次元を絞ることで、このニューラルネットは入力画像に対して次元削減を行なっています。つまり、このニューラルネットは入力画像を出力で再現すべく、入力画像の画像らしさを特徴量として抽出することを学習していきます。
この例の場合、入力画像を次元削減することをEncodeと呼び、Encodeしたものに対して、Decodeすることで入力画像の再現を行います。このEncodeする部分をAutoEncoderと言います。
2. Fashion-MNIST
今回用いたDatasetsはFashion-MNISTです。
最近できたDatasetsらしく、MNISTが簡単すぎることや、使われすぎていることから生まれた流行りものです。
今回は、このDatasetsから画像のみを使用しました。
3. NNC で AutoEncoder を作ってみる
今回私が試行錯誤を重ねてやっと作った最高のネットがこちら。
とは言ってもNNCを使うと、いろんなネットをすぐに試せて非常に楽です。
私がDeep learningを楽に学べている9割はNNCのおかげですね。
このネットの特徴は、Convolution、Poolingによって28x28の大きさだった画像が、一次元のベクトルになっていることです。
そこからDeconvolutionを用いてDecodeすることで入力画像の再現を出力画像とします。
今回学習にはFashion-MNISTから画像を300枚、テストに100枚を用いました。
4. 結果
これは実際のNNCによるテストデータを用いた、Evaluation結果です。
左が入力、右は出力画像で、靴は靴らしい形をとっていることや、服は装飾が消えていること、なんとズボンは勝手に二股になっていることがわかります。
ちなみに中間層を出すのもNNCなら簡単です。
この中間層からは、1回目のPoolingでは画像の構造らしきものを捉えており、
2回目のPoolingではだいぶ抽象化され、画像の角を取らえているように見えます。
3回目のPoolingは出力が一次元ベクトルなので、画像としてはグレースケールの濃淡だけになります。
5. 感想
このようにNNCを用いると、まだまだ初心者の私でもこんな感じでなんでもできちゃいます。
ですがキスモの社員方々のサポートのおかげでここまで理解することができました。
最後までお付き合いいただきありがとうございました!
株式会社キスモ
インターン生 杉浦 太郎
もっとキスモのことを知りたい方は
こちらをご覧ください!
30秒でネットワークが組める!?Neural Network Consoleを用いた機械学習
キスモインターン生の内山です!
僭越ながら、技術ブログ1発目を務めさせていただきます!
本ブログでは、弊社が関心を抱いている技術や日頃の業務から得られた知見などを定期的に紹介していきます。
本日ご紹介させていただくのは、8月中旬にSony社がオープンソースとしてリリースしたNeural Network Console(以下、NNC)です。
このNNC、本当に革命的です…!
コーディング一切なしで、パズルのように簡単にネットワークが組めちゃうんです。
弊社では、
- モデルのコーディングの時間を減らせること
- よって要件定義やデータ整形に時間が多く割けること
- モデルの分析・改変が容易になること
- 結果の可視化が容易にできること
などを加味して、社内でNNCを活用し始めました!
では、NNCを使うと機械学習がどれほど楽になるかをMNISTデータを用いた手書き文字認識で説明していきたいと思います。
まずはお馴染みのCNN(畳み込みニューラルネットワーク)のモデルを組んでいきましょう。
畳み込み層、プーリング層、誤差関数などを組み込んでできたモデルがこちら!
CNNの基礎知識さえあれば、コーディングを一切せず、30秒でモデルが組めます。
そして1クリックで学習、推論が開始でき、今回のモデルでテストデータに対して、精度98.09%が出ました。
さらに学習結果、推論結果もグラフ、表で自動出力してくれます。
これならプログラミングを学習したことのない人でも、理論の理解さえあれば簡単にMNISTの文字認識で98%の精度を出すことができます。
ただ、ここまではコードを書ける人ならさほど難しくないと思います。
実際僕自身もpythonを本格的に勉強し始めて半年ほどですが、ここまでなら問題なく組むことができます。
NNCではここからさらにモデルを自動改良してくれる機能が付いています。
これがかなり便利なんです。
自動で層を増やしたり、層の形を変えたりして、より精度の高いモデルを探索してくれます。
先ほどのモデルを自動改良させると、最も精度の高いモデルはこのようになりました。
このモデルの自動改良により、精度は98.79%まで向上しました!
一般的に、モデルが複雑になるほど計算量が増えていくため、必ずしも精度が高ければ良いというわけではありません。
扱う題材によって、許容できる計算時間や要求される精度は異なりますよね。
NNCでは計算時間と精度の関係を表すグラフも自動生成されるため、どのモデルを採用するかという議論がしやすくなります。
ありがたい機能ですね。
今回ご紹介させてもらったのはNNCの機能の一部ですが、非常に便利なツールだということがお分かりいただけたかと思います。
このNNCの登場によって、ますますデータサイエンスの分野が発展していくと嬉しい限りです。
今ご覧いただいている皆さんも、ぜひ一度このツールを使ってみてくださいね!
最後まで読んでいただき、ありがとうございました!
株式会社キスモ
インターン生 内山敦史
もっとキスモのことを知りたい方は
こちらをご覧ください!
技術ブログ、はじめます。
こんにちは、
株式会社キスモでデザイナー兼エンジニアをしているkodamayuです。
これまで弊社キスモでは、社内勉強会の資料や機械学習のノウハウを公開する場がありませんでした。これらを社内で燻らせているのはもったいない…!
そこで、私たちが考えていること、私たちが持っている知見をみなさんに共有するために、弊社でも技術ブログを書くことになりました。
さて、弊社は代表取締役を含め、役員の多くが現役のエンジニアです。
彼らが持つ、今流行りの人工知能・機械学習技術から、社内での取り組みまで、弊社の様々な情報をこの場で発信していこうと思っております。
どうぞ「kysmo's blog」を宜しくお願いします。