Docker 上に IPython Notebook 実行環境を作って DeepDream を動かす

DeepDream を動かしてみようと思ったら 9 割ぐらい IPython Notebook と必要なライブラリの環境整備だったのでそのまとめ.

  • 作業日
    • 2015 年 7 月 4 日
  • 作業前の筆者の状況及びそこから導かれる想定読者
    • IPython Notebook を使ったことがない.環境構築もしたことがない.
      • Mathematica は使ったことがあるかもしれない.
    • docker コマンドが動く Linux Desktop 環境を,実機,または VM 内 (Windows にインストールした VMWare 等) にもっている.
    • Deep Neural Network と呼ばれる技術について,特に知らないし,特に自分で手を動かして何かしたこもなく,業務でも当面使う予定はない.
    • インターネットからの数 GB 程度のデータダウンロードが可能である.
  • 目標
    • docker コマンドが動く環境ならどこでも DeepDream のチュートリアルを実行できるようになる.
  • 目標ではない
    • Deep Neural Network と呼ばれる技術について,何らかの知見を得る.

Deep Neural Network 素人であるところの筆者が理解できた範囲の話の背景

6 月中旬ごろ,不思議な画像を生み出す画像処理アルゴリズムが Google Brain Project に所属する研究者たちによって公表されました.

Inceptionism の背景ですが,たとえば 10 段から 30 段にもなるニューラルネットワークが存在したとき,各段の振る舞いが実際に何をやっているのかは自明な話ではありません.この疑問に対する実験の 1 つとして,特定の段のニューロンの特性を使って入力画像を強調してみたらどうなるか,というのがどうも Inceptionism の意義というか立ち位置のようです.

実際,ランダムノイズ画像に上記強調処理を行った結果何やら物体めいたものが見えてきたというのが,ブログの前半で述べられていることです.

So here’s one surprise: neural networks that were trained to discriminate between different kinds of images have quite a bit of the information needed to generate images too.

さて,異なる画像を識別するように訓練されたニューラルネットワークは,画像を生成するために必要な情報をある程度持っているのであれば,これを使って面白画像が生成できないかというのが後半パートです.

Inceptionism ブログ記事では,実際の画像強調処理の具体的なアルゴリズムは記述されていませんでしたが,7月1日になって,IPython Notebook というインタラクティブな Python 実行環境を使ってチュートリアル的に行う方法が公開されました. この GitHub リポジトリの名前が DeepDream です.

ちなみに DeepDream として新たに公開されたのは,数十行程度の反復処理アルゴリズムだけで,Inceptionism ブログ記事の画像を再現するために公開が必要だった本当にこの反復処理アルゴリズムだけであったことが分かります. DeepDream では,GoogLeNet という訓練済みニューラルネットワークを用いており,このデータは 2014 年 12 月に公開済みでした.

さて問題は,普段この種の処理と無縁な生活をしている人間にとって,まずこの IPython Notebook の実行環境を (DeepDream に必要なライブラリを揃えつつ) 整えるのが大変面倒だ,ということです. というわけで Docker の出番です.

なぜ Docker を使うのか

まず最初になぜ Docker を選んだのかについて書いておきます.筆者の気づいた範囲で,DeepDream の実行環境を整えるにあたって面倒なのは次のような点です:

  • Caffe というライブラリを正しくインストール・設定する必要がある
    • GoogLeNet のデータセットが含まれていなければならない
    • 特定 GPU / ドライバへの依存を避けるために,Caffe は CPU 処理モードになっていて欲しい
  • pip コマンドで複数の Python ライブラリをインストールする必要がある
  • IPython Notebook はブラウザをフロントエンドに使用するため,実行環境にはブラウザがインストールされている必要がある

これらの処理を,普段使用している Linux Desktop 環境を汚さず,かつ (なるべく) 再現可能な形で,Linux ディストリビューション間の非互換性に煩わされることなく行いたいというのが Docker を使用する目的です. Docker を用いることで,仮に IPython Notebook 実行環境を予期せず壊してしまっても,すぐに最初からやり直すことが可能です. また,いったんコンテナイメージを作ってしまえば,ホスト環境が変わってもすぐに同じ実験を行うことが可能です.

ほんと,Docker みたいなのが自分の学生時代にも欲しかったものです……

(Docker) ホスト Linux

以下では Ubuntu 14.04.1 64-bit 版を想定していますが,必要な環境は Docker コンテナ内に用意するため,ホスト環境に要求するのは以下の 2 点です.

  • Docker が動く
  • (表示用のブラウザを X11 経由でホスト画面に表示するため) GUI ログイン可能である

Docker のセットアップについては詳しく述べませんので,Supported installation - Docker から辿ってインストールしてみてください.

なお,以下では sudo なしで docker コマンドが実行可能なように設定されていることを前提に書かれています.その設定を望まない場合は各自 sudo を付けて読み替えてください.

Docker コンテナのダウンロードとインストール

必要なコンテナは DockerHub にアップロード済みです.

docker pull nyaruru/deepdream-ipython-notebook

セキュリティが気になる人・自分で再現を試みたい人は,deepdream-ipython-notebook/dockerfile/ で Dockerfile を確認することができます.

何か問題・改善点がありましたら GitHub 上のNyaRuRu/deepdream-ipython-notebook までお知らせください. また,今回は github.com/visionai/clouddream をベースイメージに使わせていただいており,Caffe のセットアップ等大部分の処理はそちらで行われています.

Docker コンテナの実行

まず,コンテナ内からホストへの X11 接続を許可しておきます.

xhost +local:

DeepDream を一通り実行するだけであれば,以下のように docker コマンドを実行するだけで十分です.

docker run -i -t --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro nyaruru/deepdream-ipython-notebook

上手くいけば,コンテナ内で Firefox が起動され,そのウィンドウがホスト GUI 環境に表示されるはずです. 終了するには,ターミナル上で Ctrl-C を実行すれば OK です.

docker コンテナ起動時に --rm オプションを付けていることに注意してください.この結果,コンテナ終了時に作業内容は全て失われますが,もう一度実行しなおすことで確実に動く状態からやり直すことが可能です.

DeepDream IPython Notebook チュートリアルの実行

Docker コンテナを起動すると,すでに IPython Notebook が起動しているはずです.DeepDream のディレクトリが表示されているはずですので,そこから dream.ipynb を選択します.

f:id:NyaRuRu:20150705091726p:plain

IPython Notebook が表示されます.Mathematica 経験者であれば,あの Notebook みたいなもの,と思えばとっつきやすいかも.

上の方に ▸ ボタンがありますので,それを押していくとチュートリアルの内容が上から順に実行されてきます.

f:id:NyaRuRu:20150705091711p:plain

以下の箇所を実行することで,チュートリアルのサンプル設定での DeepDream が画像を強調処理していく様子をリアルタイムに見ていくことができます.

_=deepdream(net, img)

デフォルトのパラメータは,関数定義に書いてあるとおり以下のようになります.

  • ter_n=10
  • octave_n=4
  • octave_scale=1.4
  • end='inception_4c/output'

さらに DeepDream を楽しむために

パラメータを変える

こちらについても詳細についてはチュートリアルに書かれています.たとえば,

net.blobs.keys()

を実行することでニューロン層のリストが表示されます.強調処理に使う層を inception_3b/5x5_reduce に変更してみるというのが

_=deepdream(net, img, end='inception_3b/5x5_reduce')

の行っていることです.

ホスト環境のディレクトリを Docker コンテナ内に見せる

ここまで来ると,実際に色々な画像で実験してみたくなります. Docker のホストとコンテナでファイルをやり取りする方法はいくつかあるかと思いますが,ここでは -v オプションでホストの特定ディレクトリをコンテナ内に公開することにします.

docker run -i -t --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro -v $HOME/Pictures:/opt/pictures nyaruru/deepdream-ipython-notebook

これで,ホスト環境の $HOME/Pictures がコンテナ内の /opt/pictures と共有されます. たとえば foobar.jpg を $HOME/Pictures に置いたとします.IPython Notebook のデータを読み込んでいる次の行を探してください.

img = np.float32(PIL.Image.open('sky1024px.jpg'))
showarray(img)

これを,

img = np.float32(PIL.Image.open('/opt/pictures/foobar.jpg'))
showarray(img)

に書き換え,フォーカスを合わせた状態で実行 ▸ ボタンを押します. これで画像が読み込めれば成功です. あとは改めて deepdream を行っている行を実行します. 結果は,ブラウザの「画像に名前を付けて保存」で保存してもいいでしょうし,Python で

frame=deepdream(net, img)
PIL.Image.fromarray(np.uint8(frame)).save("/opt/pictures/foobare_result.jpb")

と書いても良いでしょう.

その他の実装

github.com/jcjohnson/cnn-vis にて,独立実装による Inceptionism の再現実験が試みられています.こちらでは,MIT Places データセットに対して訓練された GoogLeNet のデータを用いることで,建物に反応する (と思われる) ニューロン層を使った実験も行われています.

Future Work

今回の Dockerfile はあくまで IPython Notebook チュートリアルの実行を目標としているので,DeepDream の処理を動画に対して行ったり,GPU を使って高速化したりはまた別リポジトリで行いたいと思っています.

そのうえで,いくつか気になっている点としては,

  • Caffe が CPU モードで動くのはいいんだけど,CPU 1 コアしか使っていない気がする.
  • ホスト環境のファイル受け渡しが若干面倒なので何とかしたい.
  • ベースにしている Docker イメージから引き継いだ特性として,コンテナ内のユーザーが root な のが若干気にいらない.出来れば root でブラウザを動かしたくない.

あたりでしょうか.この辺はまた時間が取れたら見ていきたいところです,

Docker とか Caffe とか普段触ることがないので,詳しい方ぜひおすすめテクニック等教えてください.