はじめに
静岡Developers勉強会では、今年の勉強会のテーマとして「人工知能ハンズオン」を2016/4/23に開催しました。
その際に「Automatic Colorization(白黒画像の自動彩色)」については、間に合わずに事前に試すことが出来なかった為、勉強会当日は紹介のみに留まってしまいました。
GW期間があって試すことができましたので、その顛末を記事を書いてみました。なお、実行する場合にはメモリ不足から解消しないと2度手間になりますので注意してください。
Automatic Colorizationとは
白黒写真や動画をディープ・ラーニングを用いて自動でカラーに変換するRyan Dahlさんによるプロジェクトです。ちなみにライアン・ダール(Ryan Dahl)さんは、Node.jsの創始者でもあります。 自動彩色については他にもバークレーのコンピュータ科学者 Richard Zhangさん他、幾つかのプロジェクトがあります。
- Automatic Colorization
- Colorful Image Colorization [GitHub]
- 白黒写真が自動でカラーに『Automatic Colorization』
- Node.jsとは何か、開発者ライアン・ダール氏が語る(前編)~ノンブロッキングとはどういうことか?
日本での取り組み
早稲田大学にて、飯塚 里志さん、シモセラ エドガーさん、石川博さんが白黒写真の自動色付けを行っています。
参照: ディープネットワークを用いた大域特徴と局所特徴の学習による白黒写真の自動色付け-早稲田大学
eiji_kさんのTwitterによれば
既存のディープラーニング着色より一段上では…
— なんかのアライさん🐾Eiji-K (@Eiji_Kb) 2016年4月22日
グローバルとローカルの特徴量を融合して塗残しや勘違い塗りを減らした上、
グローバルの特徴量を差替えれば、そのスタイルを転写できるのですか…
驚嘆。@picocog白黒画像 全自動色付け pic.twitter.com/QLY9pKYdOf
試した方がいます。プログラム言語はLuaを使用しているようです。
参照: Automatic Colorization of Grayscale Images を試すメモ
トレーニング有り版
下記サイトを公開しているPavel Gonchar氏のcolornetでは、白黒写真の自動色付けのトレーニング用も含まれています。
GitHub - pavelgonchar/colornet: Neural Network to colorize grayscale images
これを使ったeiji_kさんのTwitterによれば
ディープラーニングにカラー放送のサリーちゃんを見せて、白黒放送のサリーちゃんを自動彩色させてみた。(魔法(自動彩色)の効きが割りと良かった所を抜粋して、編集) pic.twitter.com/2V1M8U4wP0
— なんかのアライさん🐾Eiji-K (@Eiji_Kb) 2016年4月27日
導入方法
VirtualBox内Ubuntu 14.04.2 LTSのPython数値計算環境「Anaconda」にて試したところ、「Segmentation fault (コアダンプ)」エラーとなって動作しなかった為、Dockerを使用することにしました。Dockerを使うことで少ないメモリで実行できるようです。
今回のDockerイメージは、TensorFlow公式サイト版で説明していきます。
yaju3d.hatenablog.jp
2016/07/13追記 Segmentation faultの回避方法 qiita.com
環境
- Windows 10 Home 64bit(Intel(R) Core(TM) i7-4700MQ CPU 2.40GHz メモリ 8.00GB)
- DockerToolbox 1.10.3 → 1.11.1
- VirtualBox 5.0.16 → 5.0.20
Dockerイメージ(TensorFlow公式サイト版)
TensorflowのサイトにあるDockerイメージにはscikit-imageがデフォルトでインストールされていないため、Jupyter NotebookのTerminalにて下記コマンドでインストールする必要があります。インストールには10分程かかります。
pip install scikit-image ︙ Successfully installed dask-0.9.0 networkx-1.11 scikit-image-0.12.3 toolz-0.7.4
※Docker stop等でコンテナが破棄されると初期化されるため、毎回インストールする必要があります。
学習済みモデルファイルの取得
学習済みモデルのファイルが「colorize-20160110.tgz.torrent 492M」というトレントファイル(.torrent)として配布されています。
"BitTorrent(ビットトレント)"とは、大容量のファイルを高速に配信する為のP2Pソフトウェアです。
ダウンロードするには専用のソフトが必要になり、私はBitComet 日本語公認サイトから辿った先の「BitComet 1.40」を使いました。
世の中にはトレントファイルではなくtgzファイルのまま公開している方がいるので、そちらからダウンロード(colorize-20160108.tgz)するのが楽かと思います。
※トレント版が20160110なので20160108と2日早いのが気になります。
解凍すると下記3つのファイルが展開されます。
- colorize.tfmodel (学習済みモデル)
- forward.py (自動彩色実行ファイル Python 2.7)
- shark.jpg (サンプルの白黒のサメ画像 224x224)
フォルダ共有による方法(追記:2016/05/19)
DockerとWindowsのフォルダ共有方法 with tensorflowのサイトを参考にしたらフォルダ共有が出来ました。この方法ならDockerコンテナにコピーする必要がないのでいいですね。
colorize-20160110フォルダをC:\Users(ユーザー名)の配下にします。
ダウンロードフォルダのままでも問題なかったです。
$ docker run -d -m 4g -p 8888:8888 -p 6006:6006 -v /c/Users/(ユーザー名)/Downloads\colorize-20160110:/notebooks b.gcr.io/tensorflow/tensorflow
この後は「実行」まで読み飛ばしても構いません。試行段階の経緯も書いているため、参考程度にお読みください。
Dockerイメージ(mokemokechickenさん版)
mokemokechickenさんのDockerファイルにはscikit-imageが含まれており、その他にもGraphvizなどもあるので今後いろいろやりたい場合には便利です。
githubサイトから「Download ZIP」ボタンで「jupyter-tensorflow-master.zip」をダウンロードし、解凍してダウンロードフォルダに展開しました。
DockerファイルからDockerイメージを作成します。
$ docker build -t tensorenv /c/Users/(ユーザー名)/Downloads/jupyter-tensorflow-master
※VirtualBoxの設定にある共有フォルダは「c/Users」になっています。"c/"は英小文字なので注意してください。
以前は出来たのですが、直近(2016/05/15)では下記エラーが出ました。
E: Unable to locate package graphviz-dev E: Unable to locate package graphviz E: Package 'pkg-config' has no installation candidate E: Unable to locate package libgdal-dev
DockerFileのRUN apt-getの直後に「update && apt-get」を付けるといいでしょう。
RUN apt-get install -y graphviz-dev graphviz pkg-config RUN apt-get install -y libgdal-dev ↓ RUN apt-get update && apt-get install -y graphviz-dev graphviz pkg-config RUN apt-get update && apt-get install -y libgdal-dev
後述するメモリ制限値の"-m"オプションを付けて実行します。"-d"オプションはコンテナをバックグラウンドで動かします。
$ docker run -d -m 4g -p 8888:8888 -p 6006:6006 tensorenv
学習済みモデルファイルのコンテナへのコピー
$ docker ps #コンテナ名(NAME)を取得 例 loving_minsky $ docker cp /c/Users/(ユーザー名)/Downloads/colorize-20160110/colorize.tfmodel loving_minsky:/home/jovyan/work
Docker内へのファイルアップロード
Jupyter NotebookにはUpload機能があるのですが、アップロードできるサイズが25MByteまでとなっています。そのため、colorize.tfmodelファイルは529MByteと巨大なため、別方法でアップロードする必要があります。
docker cpコマンドによる方法
docker run している場合、Control-Cで停止してください。
$ docker cp [コピー元ファイル] [CONTAINER ID or NAME]:[コピー先ファイル]
今回、colorize-20160110はダウンロードフォルダに展開しました。
※VirtualBoxの設定にある共有フォルダは「c/Users」になっています。"c/"は英小文字なので注意してください。
※ホストからコンテナへのコピーにdocker execコマンドを使った方法があるのですが、Docker 1.8からホストからコンテナへのコピーも docker cp コマンドでサポートされたため、修正しました。
$ docker ps #コンテナ名(NAME)を取得 例 cranky_murdock $ docker cp /c/Users/(ユーザー名)/Downloads/colorize-20160110/colorize.tfmodel cranky_murdock:/notebooks $ docker start cranky_murdock
curlコマンドによる方法
docker execコマンドを使わない方法として、Jupyter NotebookのTerminalにて下記コマンドを入力します。これによりnotebooksフォルダ配下にcolorize-20160108フォルダが出来ます。
# curl -SL https://s3.amazonaws.com/tinyclouds-storage/colorize-20160108.tgz | tar -xzC /notebooks % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 491M 100 491M 0 0 8714k 0 0:00:57 0:00:57 --:--:-- 9284k
※この方法を使用した場合、ソースリストのファイル指定時に"colorize-20160108\colorize.tfmodel"としてフォルダを指定する必要があります。
実行
Jupyter Notebookにて下記ソースコードを実行します。
import tensorflow as tf import skimage.transform from skimage.io import imsave, imread def load_image(path): img = imread(path) # crop image from center short_edge = min(img.shape[:2]) yy = int((img.shape[0] - short_edge) / 2) xx = int((img.shape[1] - short_edge) / 2) crop_img = img[yy : yy + short_edge, xx : xx + short_edge] # resize to 224, 224 img = skimage.transform.resize(crop_img, (224, 224)) # desaturate image return (img[:,:,0] + img[:,:,1] + img[:,:,2]) / 3.0 shark_gray = load_image("shark.jpg").reshape(1, 224, 224, 1) with open("colorize.tfmodel", mode='rb') as f: fileContent = f.read() graph_def = tf.GraphDef() graph_def.ParseFromString(fileContent) grayscale = tf.placeholder("float", [1, 224, 224, 1]) tf.import_graph_def(graph_def, input_map={ "grayscale": grayscale }, name='') with tf.Session() as sess: inferred_rgb = sess.graph.get_tensor_by_name("inferred_rgb:0") inferred_batch = sess.run(inferred_rgb, feed_dict={ grayscale: shark_gray }) imsave("shark-color.jpg", inferred_batch[0]) print("saved shark-color.jpg")
メモリエラー
残念ながら実行すると「MemoryError」が出力されてしまいます。
/usr/local/lib/python2.7/dist-packages/google/protobuf/internal/python_message.pyc in SerializePartialToString(self) 1072 out = BytesIO() 1073 self._InternalSerialize(out.write) -> 1074 return out.getvalue() 1075 cls.SerializePartialToString = SerializePartialToString 1076 MemoryError:
メモリを増やす
DockerToolboxで最初に作成されるdefaultマシンのメモリは1GByteとなっていますので、下記サイトを参考にVirtualBoxの設定にてdefaultマシンのメモリを増やします。
※ちなみにクラウドのAWS EC2の無料で使えるt2.microはメモリが1GByteとなっているので動作出来そうもありません。
qiita.com
defaultの電源オフの状態で設定ボタンをクリックする
1024MBから4096MBにメモリを変更
docker runの"-m"オプションを付けてメモリ制限値を指定します(※割り当てではない)。単位には b,k,m,g があります。
$ docker run -m 4g -p 8888:8888 -p 6006:6006 b.gcr.io/tensorflow/tensorflow
dockerコンテナが破棄されると初期化した状態になるため、再度scikit-imageのインストールと学習済みモデルをセットしてください。
Jupyter NotebookのTerminalにて「free」コマンドを入力するとメモリサイズが表示されます。
# free total used free shared buffers cached Mem: 4045896 1188836 2857060 167164 40364 953316 -/+ buffers/cache: 195156 3850740 Swap: 1939036 0 1939036
再実行
先ずはサンプルのshark.jpgをやってみました。変換は15秒程度です。
鉛筆画を試す
Twitterユーザーの古谷振一さん(@shtt4881)の鉛筆画が白黒写真のようにしか見えないと話題になっておりました。
参照:きれいな写真だなー……って絵だとぉ!? 鉛筆で描かれた芸能人たちが目を疑う精巧さと美しさ
むむ、白黒画像なら自動彩色してみようと試してみました(サイズ 224x224 2値画像に変換してから試す)。ちょっと微妙ですかね。
連続してやるとメモリ不足になるので、毎回Shutodownしてメモリを解消しました。
坂本龍馬を試す
顔写真だけだとつまらないので、坂本龍馬で検索した画像を試してみました。背景の草や板に色が付くようになっています。
動画の変換
下記サイトにて動画のカラー化を行っています。
前後にffmpegでの処理を行って、Automatic Colorizationをフォルダ内の画像に対してループしているとのこと。
http://www.shun.bz/20160127/1050814061.htmlwww.shun.bz
カラー化した画像ファイルをホストへコピー
docker cpコマンドでホストへファイルをコピーすることが出来ます。
$ docker ps #コンテナ名(NAME)を取得 例 cranky_murdock $ docker cp cranky_murdock:/notebooks/shark-color.jpg /c/Users/(ユーザー名)