pix2pixで数日遊んだら数ヶ月のお仕事の成果を超えた件


はじめに

 今年もFOSS4G年末隠し芸大会(違)の時期がやってまいりました。前回はちょっと変態じみた投稿をしましたが、今回は真面目にディープラーニング周りとFOSS4Gを絡めたお話をしてみたいと思います。

pix2pixについて

 最近pix2pixと言うプログラムがDNN界隈で話題になっておりますので、聞いたことがある方も多いかと思います。モノクロをカラーにしたりラベルを画像にしたり、イラストを作ったり等など、これもまでもエポックメイキング的なDNNが次々と発表されていきましたが、今回のこれはそれらを単一のニューラルネットワークでやっちゃいましたというとんでもないお話であります。
 もともとDNNは汎化性能が高いと言われていますが、それでもドメインをまたいだ処理に関しては難しく、特定の問題に対してネットワーク設計するのが一般的でした。
 今回のpix2pixは2つの変換前後の画像を用意するだけで勝手にスタイルを敵対的ネットワークス(DCGAN)により学んでくれるという超お手軽DNNですので、ある意味アプリのように誰でも簡単に試すことができます。

地理院タイル to OpenStreetMap

 前々からドローンとかで作成したオルソ画像からDNNでOpenStreetMapTileぽいものを作れないかなーと思いつつ、ネットワーク設計するまで重い腰が上がりませんでした。
 今回のpix2pixは左に変換前、右に変換後の画像を用意するだけですみますので、簡単にデータセットを作ることができます。
 GIS界隈の人にはご存知のことかと思いますが、WMSとかTMSとか一定の規格に従って作成されたタイル画像は同一の{z}/{x}/{y}さえ渡せば同じ場所の画像が取得できます。これは今回のような変換前後のセット画像を用意する場合に非常に簡単に作成できることを意味します。
 元々pythonで一定範囲のタイルを取得するプログラムは作っていたので、それを少し改良して作ってみました。
 広域のドローンオルソ画像は用意できなかったので、今回は皆さん大好き地理院タイルを代わりに使ってみたいと思います。注意点として地理院タイルはXYZ形式ですが、OpenStreetMapはTMS形式なので、yに関しては以下の計算式で変換する必要があります。

y = (2 ** z) - y - 1

 また、pix2pixは入力と学習用のピクセルサイズを合わせる必要があります。デフォルトがloadSize=286、fineSize=256ですので、こちらを以下のように調整します。

train.lua
   loadSize = 255,         -- scale images to this size
   fineSize = 255,         --  then crop to this size

 あと、OpenStreetMapの標準スタイルでは道路のラベルなどが含まれているため、これをそのまま学習すると、

 このような「名状しがたいラベルのようなもの」ができます。
 これはちょっとあれなのでラベルを消したタイルを作成する必要があります。
 mapnikでスタイルXMLをいじって作成しておきます。

 学習用画像は以下のような形で変換前後を左右でくっつける必要があります。

出典:地理院タイル(写真)

 さて、準備が整いましたら後は学習するだけですが、学習自体はそれほど時間をかけなくても良いようです。数日やったものと数時間やったものでは差はそこまでありません。ちょっと走らせたものでも十分な品質が有りますので、まずは数時間位学習させてプレビューしてみては如何でしょうか。
 
 今回は京都市を学習データ及び未知画像として試してみました。だいたい同じようなマス目構造をしているので正解率が高そうです。
 それではお待ちかねの結果です!









出典:地理院タイル(写真)

 若干微妙ですが、概ね正解画像に近い感じです。
 これはドローン飛ばして自動OSM作成も行けるかも? 
 やはり人間の手での修正は必要と思われますが下絵としては有りかもしれません。

旧版地形図 to 土地利用図

 某所からのお仕事で旧版地形図から土地利用図をConvNetを使って未知画像の土地利用図を作成するという案件を数ヶ月くらいでやってそこそこいい感じに分類してくれていたのですが、せっかくなのでpix2pixで同じようにやってみたらどうなるのかを試してみました。
 ・・・今思えば止めておけばよかったと思うのですが、好奇心は止まりません。

before

元画像

正解画像

分類結果画像

元プログラムはこんな感じの精度です。
7~8割の精度なのでそこそこいい感じに分類してくれてます。
但しピクセルの目が細かい分類出力データを作ろうとすると数十分はかかります。

 元プログラムでは白黒の旧版地形図を食わせて教師データの土地利用図に近い画像をConvNetにより作成するというものでした。こちらも変換前後の画像セットになるので学習データの生成は容易でした。
 予想では白黒で手書きのデータなのでそこまで精度は出ないだろうと高をくくっていたのですが・・・
 数時間学習させてどんなものんかと見てみたところ・・・
 

after

pix2pix

正解画像

 なんということでしょう。
 たった数時間の学習で数ヶ月試行錯誤した精度を上回りました。
 ちなみにこの画像作るのは一瞬です。
 元プログラムは数十分かかっていたのに・・・
 匠の遊び心に私のライフは既にZEROです。
 こんなのありかよーーー!

 ・・・と言う感じでpix2pixの汎用度は今までに類を見ないくらい凄まじいのですが、正直お仕事の種が食われる感もあり、まさしく破壊的イノベーションといえるかもしれません。
 DNN界隈では数ヶ月前の論文の内容があっという間に古くなり、キャッチアップが必須なのですが、予想よりも数段以上早く進んでいる現状に頭が痛くなります。

 長期スパンでDNN関係のお仕事をする時、ドヤ顔で成果発表した後、
「素人質問なんですが・・・それ○○でもっと簡単に精度も良くなりますよね?」
と言われて心をkillされないようにキャッチアップは日々したほうが良いかもしれません。

おまけ1

 実際のところ旧版地形図 to 土地利用図のpix2pixの結果、見た目的には精度がいいが、厳密に比較すると精度は1割を切る。これはDCGANによりそれっぽい絵を出しているだけで、厳密なインデックスカラー(18色)ではないからと思われる。
 もし正確性を求めるならば、出力層のニューロン数を調整するか、出力された結果をインデックスカラーに丸め込む必要がありそう。

おまけ2

 古地図を地理院タイル(写真)で学習させてみた結果。

 
 バグってハニー現象。昔のファミコンでカセット入れ替えしたときに似ている・・・
 元々がズレてたので、ズレているものは厳しいかもしれない。

おまけ3

 学習データを増やすとなんか精度が落ちる・・・むしろ少ないほうが良い感じ。過学習的な動き?ニューロン数が足りてないのか?

おまけ4

 ちなみに今回使用したGPUはGEFORCE GTX 1070と980M。メモリ8GBでそこそこ速い。

おまけ5

 標高タイルからCS立体図をpix2pixを使って検証してみた記事もありますので、よろしければどうぞ!