GeForce RTX-3080

深層学習にGPUを使うのは常識になっていますが,GeForce RTX 3090はコア数が10,496、GPUメモリが24GB、GeForce RTX-3080はCUDAコア数が8,704,GPUメモリが標準で10GBあるので,深層学習用にはかなり使えます.良い世の中になりました.この調子なら,来年には20万円程度で深層学習の実験環境が簡単に整いそうです.最近の深層学習はGPUメモリを大量に使う方向ですので,3080では大規模実験には力不足でA6000ぐらいが必要になることもありそうですが,だいたいの場合はバッチサイズを小さくするなどすれば動くでしょう.MSIから3080を搭載したノートPCが発売されていて(GPUメモリが16GB),値段的にはかなり高いのですが,通常の深層学習の研究には十分強力です.注意点は,このノートは最新のものなので無線LANIntel AX210になっていてUbuntu 20.04でも対応してないこと.有線LANで接続するか,TP-WN725NのようなUSB無線LAN子機を買うかする必要あります(USBに差すだけで動きます).そのうちUbuntuがAX210にも対応すると思いますが.(カーネルの再構築をしてfirmwareを読み込めば動きそうですが,そんなに暇ではありません)余談ですがMSIのノートPCのキーボードは打ちにくいです.右シフトの位置とかが最悪です.

DyGIE++備忘録

研究員や学生さんが最近実験に使っているDyGIE++を自分のGPUボックスにインストールしたときの備忘録.

DyGIE++はPyTorchで書かれた固有表現・関係・イベント抽出ツールでインストール法や使い方は下記に書かれている.
github.com

ここでは捕捉を書いておく.

  • インストール

上記本家からDyGIE++をダウンロードし展開(またはclone)したディレクトリに移動して以下を実行

conda create --name dygiepp python=3.7
conda activate dygiepp
pip install -r requirements.txt
conda develop . # Adds DyGIE to your PYTHONPATH

AllenNLPを使っているので,allennlpをインストール

pip install allennlp

  • 動作確認のためsciercデータで学習

手元のマシンはGPUが1枚しかないので(うちの研究室でもGPU4枚刺しのサーバーを何台か使えますが,多くの人は1枚でしょうから),training_config/scierc.jasonnetを編集

なぜかインストールしたscierc.jasonnetのcuda_deviceの設定が1(gpu1を指定)になっていたので,この数値を0に置き換えてファイルを保存する.ちなみにこのファイルにはNERとREとERとCorefのバランスをとるパラメータの設定がある.データセットにないものについては0にする.SciERCはNEとREとCorefのアノテーションが付いていて,Eventはない.

sciercのデータをダウンロード

bash ./scripts/data/get_scierc.sh

  • 学習

bash scripts/train.sh scierc

もし,何かの手順が悪いか,または途中で学習をとめたり,再度学習をする場合は,下記のエラーが出る.

allennlp.common.checks.ConfigurationError: Serialization directory (models/scierc) already exists and is not empty. Specify --recover to recover from an existing output folder.

この場合は,modelsディレクトリに行って,sciercディレクトリの名前を変えるか,必要なければ削除すると,エラーが解消される.

学習にはGPUメモリを5.4GB程度使用.学習時間はTitan Xで1時間ぐらい.学習されたモデルファイルは models/scierc/model.tar.gzとして保存される.

  • テスト

テストデータによる評価の例は下記のようになる.

allennlp evaluate models/scierc/model.tar.gz data/scierc/normalized_data/json/test.json --cuda-device 0 --include-package dygie --output-file models/scierc/metrics_test.json

評価結果は --output-fileで指定したファイルに出力される.今回の学習では,NERが65%, REが45%程度であり,事前学習モデルと同じぐらいの性能は出ている.

Scikit-Learn classification_report

知っている人は知っているのだと思いますが,機械学習ライブラリ scikit-learn の 関数 classification_report には digits というキーワードがあり,スコアの桁数を指定できます.
classification_report.py のソースコードを読んでいるときに気が付きました.

ネット検索すると表示桁数は変えられないという書き込みが上位に来ますが,digitsで指定できます.(scikit-learn 0.23で確認)
デフォルトでは小数点以下2桁になっています.

classification_reportは,多クラス分類の場合に学習結果をクラス毎に集計して recall, precision, F1 を表示してくれる便利ツールです.

def classification_report(y_true, y_pred, labels=None, target_names=None,
sample_weight=None, digits=2):

DeepLの翻訳が日本語に対応

昨年の2月26日に翻訳サイトDeepLの紹介をしました.そのときには,日本語対応ではないということを書きましたが,少し出遅れましたが,今月19日に日本語に対応しました.

まあ,とりあえず試してみてください.翻訳品質の高さにかなりの衝撃があります.たぶん,我々言語処理の専門家の方が衝撃が大きいかもしれません.

https://www.deepl.com/translator

ちなみに,訳文の品質は非常に高く,インクリメンタルな翻訳もできるのですが,並列句の解析を間違えることがあります.

「PCの付属品にはライセンスや後のサポートで必要な物が含まれています」を訳すと,"The accessories of the PC include everything you need for licensing and support."となり,ライセンスとサポートを並列句として訳してしまいます.人間でも間違えますし,別の状況ではこの解釈が正しい場合もありますので,常識がないと正確に文を捉えられない例になっていて,元来難しいのですが.

CPU or GPU

2011年の言語処理学会年次大会でGPUを使った言語処理の発表をした頃は、現在の深層学習ブームの前であったこともあり、言語処理におけるGPUの利用はあまり注目されていなかった。反対に、現在は「ちょっと偏り過ぎでは」と懸念するほど、GPUを使った深層学習+言語処理が研究の主流になっている。

とにかく、現在の深層学習はGPUなくては研究できない。GPUは本来は画像処理を高速に実施するための専用装置であったが、その並列計算機構を一般の計算にも利用するための開発環境が提供されたことで、大量の行列やテンソルの計算が必要となる深層学習の高速化になくてはならないものとなっている。たとえば、CPUで計算すると数日かかる学習がGPUを使えば数時間で終わるというぐらいの違いがある。これは、パラメータ探索のために学習を何度も行わなければならない深層学習の研究を実際に行う際には決定的な違いになる。

少し前置きが長くなったが、このことは今の深層学習に携わっている人にとっては常識なので目新しい情報ではない。ではここで、少しCPUの未来を見てみよう。もし、GPUではなくCPUのマルチコア化が究極的に進んだらどうなるか。CPUメーカーのAMDがEPYC 7702という新しいCPUの生産を始め、HPなどのサイトから搭載サーバを購入できる。7702は64コアのCPUで、普通のCPUの命令セットが64コア並列で動作する。実際にはさらに1つのコアで2つのスレッドを動かせるので、128並列の計算が可能。HPでは2wayのサーバーが購入できるので合計256スレッドの計算が1台のマシンで可能になる。現状ではサーバーの価格が800万円ぐらいになるためあまりお徳感はないが、CPUの値段が下がってくれば、GPUとの競合になりそうだ。

現在のGPUは数千個のセルが搭載されているので、並列度で言えばGPUが上回っているが、実際の処理速度はそう単純ではない。CPUと比べてGPUで計算する場合には次のような弱点がある。

  • GPUのクロック数(1~1.5GHz)がCPU(3~4GHz)より低い。つまり単純な処理速度が1/3程度。
  • GPU・CPU間のデータ転送はデータバスを通るため遅く、大量のデータ転送には向かない。
  • GPU側で並列処理の効果が出るのは、まったく同じコードをまったく同じ処理として大量に実行する場合のみ。コードが同じでも条件分岐があれば、分岐に相当する数だけ処理速度が低下する。たとえば、if (a>0) {処理1} else {処理2}のコードがあった場合は、処理1に分岐したセルが実行中は、処理2に分岐したセルが休んでいる。逆も同じ。つまり、並列度が半分になる。このように、GPU上のコードに条件分岐があるとその分実際の並列実行度は下がっていく。
  • GPU側のメモリは上位のV100でも32GBに限定される。大きなデータをランダムにアクセスするような処理をGPUにやらせるには、GPU側のメモリが不足する。
  • GPU上の並列計算が、少数のデータ(変数)を集中的に更新するようなコードになっていると、アクセス待ちが発生し並列度が上がらない。または、並列に書き込んでしまうと処理結果が想定した結果にならない。

もし、AMDから数百スレッドの計算ができるCPUが出れば、学習データのサイズやモデルの条件にはよるが、CPU側での計算がGPUより速くなるケースが増えて行く。さらにもっと先の未来では、数千コアのCPU(たぶん命令セットがRISCのように最小限)が深層学習用の計算資源の中心になっているかもしれない。

deepfake

トランプ大統領が、ニュースメディアに向かって、君たちはフェイクニュースだと反論する。そんな時代。この場合は、本当にニュースがフェイクなのかリアルなのか知る由もないが、とにかく巷にフェイクが溢れ始めている。

フェイクの最先端を行くのがディープフェイク。特に画期的なのが、深層学習を使って人間の顔を生成する技術の進歩。GANと呼ばれる敵対的学習は、Generative Adversarial Network の略で、2014年にモントリオール大学の Ian Goodfellow が神経回路網国際会議NIPSで発表してから、多くの注目を集めている。GANの学習の仕方の特徴は、通常のニューラルネットと違って、画像を生成するGeneratorネットワークと画像がホンモノかニセモノかを見分けるDiscriminatorネットワークの2つを同時に学習していくところにある。Generatorは自分が生成するニセモノ画像が、Discriminatorにニセモノと検知されないように徐々に絵が上手くなっていく。Generatorはゼロから画像を生成しているので、どれがホンモノの画像かを教えられていない。何度も画像を生成するうちに、徐々にこんな画像ならDiscriminatorを騙せるということを学んでいく。Discriminatorもゼロから学習されるので、最初の検知力はゼロ状態からだんだん検知の腕を挙げていく。2つの敵対するニューラルネットワークが切磋琢磨するわけだ。このように説明するのは簡単だが、実際のGANの学習は、綱渡りの学習で、GeneratorとDiscriminatorが同じ強さで成長していくように学習を調整しないと良いGeneratorができない。学習に失敗すると、砂嵐のような画像を出すGeneratorが出来てしまう。

さて、話をディープフェイクに戻す。現在の顔生成の最先端を体験できるのが www.whichfaceisreal.com である。このサイトは、ワシントン大学のJevin West助教 と Carl Bergstrom教授が公開している、ゼロから生成された「この世に存在しない人の顔」と実在の人間の写真を顔を人間が見分けられるかをテストするサイト。ぜひディープフェイクの恐ろしさを体感するためにチャレンジしてほしい。かなりの場合、確信を持って見分けることは難しい。NVIDIA社のStyleGANを使って生成した画像と本当の写真を集めたFFHQ画像データセットから選んだ顔写真を2つ並べている。たとえば以下の2つのうち1つはニセモノ生成画像(上記サイトから引用)。

f:id:YutakaSasaki:20190726134850j:plain:w200
f:id:YutakaSasaki:20190726134845j:plain:w200

あまりに出来がいいので、モンタージュのような技術のように思うかもしれないが、実際は全然違う。ニセモノ画像のどの一部を切り取っても、マッチする元の画像は存在しない。白いキャンバスにGeneratorが顔の絵を描いているのである。これは明らかで、Generatorには、実際の写真画像はまったく見せていない。Generatorは、どう描くとDiscriminatorに見破られるかを学んでいくうちに、見破られないコツを学習して、ホンモノと見分けられない顔画像が描けるようになったのである。

さて、最後にホンモノとニセモノの見分け方があります。顔画像データから学習してい性質上、尤もらしい顔画像を生成するように学習しています。つまり、背景は特定のパターンがないので、ぼやけたり歪んだものになりがちです。背景に明瞭な直線や文字、明らかな風景が写っていれば、それはホンモノです。また、ニセモノ画像の一部に渦を巻いたような不自然なものが出やすいです。しかし、中には、たまたま背景がぼやけた(または単色)のホンモノ写真があります。この場合、背景では見分けられません。このような場合は、髪の毛で判定します。背景にはみ出してる、髪の毛、1本1本がきれいに出ている画像がホンモノです。これは、背景を生成するとき、髪の毛の物理モデルに持っているわけではないので、細い髪の毛1本をきれいに生成できないGANの宿命です。これはほとんど見分けられますが、まれにホンモノ画像の髪の毛もぼやけている場合があり、ニセモノもたまたま変な特徴が出ていない場合は、基本的には見分けられません。ニセモノ画像は、GANの学習の性質上、人物と背景の境界がホンモノよりぼやける傾向があるので、そこで分かるかもしれませんが、ホンモノも少しボケた写真のときは、多くの場合はどちらがホンモノかは分かりません。それぐらい顔画像の生成技術は高くなっています。

ちなみに女性の写真がホンモノ。

SNL2019まもなく

SNL2019がいよいよ明後日に迫りました。

準備は順調です。会場もいい感じで埋まりそうですが、
まだ当日参加も可能です。

Maximilianが講演のタイトルと内容を少し変更して、連想記憶と階層構想の
埋め込みの関係について、何か新しいことを話してくれることにしたようです。

Title: Representation Learning in Symbolic Domains

Abstract: Many domains such as natural language understanding,
information networks, bioinformatics, and the Web are characterized by
problems involving complex relational structures and large amounts
of uncertainty. Representation learning has become an invaluable approach
for making statistical inferences in this setting by allowing us to
learn high-quality models on a large scale. However, while complex
relational data often exhibits latent hierarchical structures, current
embedding methods do not account for this property. This leads not only
to inefficient representations but also to a reduced interpretability of
the embeddings.

In the first part of this talk, I will discuss methods for learning distributed
representations of relational data such as graphs and text. I will show how
these models are related to classic models of associate memory and that a simple
change in training procedure allows them to capture rule-like patterns on
relational data. In the second part of the talk, I will then introduce a novel
approach for learning hierarchical representations by embedding relations into
hyperbolic space. I will discuss how the underlying hyperbolic geometry allows
us to learn parsimonious representations which simultaneously capture hierarchy
and similarity. Furthermore, I will show that hyperbolic embeddings can
outperform Euclidean embeddings significantly on data with latent hierarchies,
both in terms of representation capacity and in terms of generalization ability.