DevFest Shikoku 2017 で登壇してきた
書くの遅すぎだろという気がするけれど 2017-11-18 に開催された DevFest Shikoku に参加してきた。
東京からの招待枠ということで登壇をしてきた。
会場とかほげほげ
会場は徳島大学。
当日入りだったのでたどり着けるか心配していたけど、空港まで車で迎えに来てもらったりして至れり尽くせり。
久しぶりに大学に来て、ちょっと懐かしい気持ちに。
大学でスタッフの方々と合流してしっぽくうどんを食べたけど、写真は撮り忘れた。
うどんうまい。
発表内容
そんなこんなで僕は TensorFlow の話をしてきた。
TensorFlow がリリースされてちょうど 2 年くらいなので、それを振り返るような内容。
他の人達の発表も Haskell、Android、Goと多彩で楽しかった。
東京だと発表が多くて同じジャンルをひとつの部屋にまとめることが多いけど、今回は一部屋なので普段聞かないジャンルの話を聞けたのは結構新鮮だったかもしれない。
これはこれで良い。
わりと感慨深かったこと
今回は主催者側に修士の学生の子がいて、参加者も大学生が結構多かったそうな。
しかも TensorFlow がちゃんと研究室で使われたりしているらしくて、なんか嬉しかった。
なんというか TensorFlow に限った話じゃないけど、この分野、大学の研究と産業の距離がほんと近くなったよなあと感じる。
良いことだ。
懇親会
協賛の Sansan さんのおかげで寿司と唐揚げとピザがもさもさ出てきた。
ありがたや。
Sansan さんは徳島にリモートのオフィスがあるとのこと。 これだけ通信技術が発達した時代にオフィスが全部東京にあるの納得いかないので、こういうのすごく羨ましい。
写真 OK かどうか確認するのが面倒なので、基本的に人の写真はなっしんぐ。
次の日
飛行機を遅めにして、徳島をぶらぶら散策。
阿波おどり会館 pic.twitter.com/m4smJtqlay
— Shuhei Fujiwara (@shuhei_fujiwara) 2017年11月19日
徳島の水道水 pic.twitter.com/BHac3vp5Xz
— Shuhei Fujiwara (@shuhei_fujiwara) 2017年11月19日
— Shuhei Fujiwara (@shuhei_fujiwara) 2017年11月19日
最後に徳島ラーメンを食べて、あとは流れで。
Google Cloud Storage に画像データを置くときは TFRecord を使った方が良さそうという教訓
これは TensorFlow Advent Calendar 2017 の 1 日目の記事です。
もちろん主張したいことはタイトルの通りです。
順を追って、かつドラマチックに説明していきましょう。
TFRecord って何?
TensorFlow 用のデータフォーマットです。 詳しくはこのあたりを見ると良いと思います。
今回重要なポイントは複数の画像ファイルを 1 つの TFRecord に詰め込むことが可能という点です。
TFRecord を使うデメリット
実は僕は TFRecord 別に使わなくても良いんじゃね派でした。 なので、まずはデメリットから挙げておきましょう。
- バイナリファイルなので人間が目で見てデータを確認できない
- 何かデータに手を加えたくなったときに、ごっそり作り直しになるので大変面倒臭い
僕は両方とも結構重大な問題だと思っていたのですが、それでも TFRecord を使おうと思うような事件が起こったのです。
今まで画像データをどう扱っていたか
画像を適当なストレージ(僕は Google Cloud Storage を使っていました)に置いて、以下のような CSV ファイルをセットで作成していました。
image,label gs://hoge/1.jpg,0 gs://hoge/2.jpg,1 gs://hoge/3.jpg,1 gs://hoge/1.jpg,0 ...
この CSV ファイルを逐次的に読み込んで、さらに書かれている画像とラベルも逐次的に読み込んでキューに入れて...という処理を学習の裏で複数スレッドで回します。
こうすることで学習に使う画像データが大量にあってもメモリに載せずに処理できますし、学習を走らせるスレッドはキューからデータを取り出していけば I/O の処理を待つ必要もなくなります。
事件
ちょっと大きめのデータで回してやろうと思って、 60 GB 分くらいの jpg を Cloud Storage にコピーしていたときのことでした。
何気なく Cloud Storage の課金表を見て、コピーはクラス A のオペレーションで課金対象であることに気付きます。
「えーっと、今 Regional のバケットに 2000 万枚くらいの画像をコピーしようとしてるから、 0.05$ x 2000 で 100$...」
え!?この処理完了したら 100$ 掛かるの!?
慌てて処理を中断しました。
コピーは 1 回きりなのでまだしも、学習をするときに読み込みの処理があるので 1 epoch ごとに結構なお金が持っていかれる計算になります。
このあたりの課金は普通に使っていたらそんなに意識しなくても良いかもしれませんが、機械学習などで大量のデータを扱うときにはきちんと計算をした方が良いでしょう。
まあ 2000 万個のファイルをコピーしようとした方が悪いと言われたらぐうの音も出ません。
どうすれば良いのか
TFRecord の出番です。
TFRecord ならば複数の画像ファイルを 1 つのファイルにまとめることができます。
こうして僕は画像ファイルはバラで扱うのではなく TFRecord で扱うことを夜空に誓ったのでした。
その他 TFRecord の方が良さそうな場面
単純に読み込みが速くなるので、データをキューに入れていく処理が勾配の計算などに追いついていない場合は TFRecord の方が良いと思います。
このあたりはちゃんと検証していないので、実際に TFRecord を使わないとデータ読み込みが追いつかなかったというケースを持っている人がいたら教えてください。
つまり結論は
- Cloud Storage を使う場合はデータのファイル数を程々で抑えた方が課金の面で良い
- なので大量の画像ファイルをそのまま扱うのは危険で、TFRecord に複数ファイル詰めるようにした方が良さそう
ということです。
ただ、データの読み込み周りは情報が少なくて何がベストプラクティスなのかよくわからないので、詳しい人がいたら教えて頂けると嬉しいです。
余談
最初は某記事に敬意を表してタイトルを
Google Cloud Storage で危うく 10 万円くらい溶かしそうになった人の顔
とする予定だったのですが、さすがに Google に怒られる気がしたのでやめておきました。