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

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

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

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

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

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

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


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

![名状しがたいラベルのようなもの](https://qiita-image-store.s3.amazonaws.com/0/58671/d341eded-02aa-4717-fc8f-da69e1970309.jpeg)


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

　学習用画像は以下のような形で変換前後を左右でくっつける必要があります。
![学習用画像](https://qiita-image-store.s3.amazonaws.com/0/58671/0d898393-2c98-8a15-7ff3-425a34fd8ddb.jpeg)
[出典：地理院タイル（写真）](http://maps.gsi.go.jp/development/ichiran.html)


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

<br/>
<br/>
<br/>
<br/>


![地理院タイル to OSM](https://qiita-image-store.s3.amazonaws.com/0/58671/573784a1-8dde-1f2b-2433-29e1a709bb57.png)
[出典：地理院タイル（写真）](http://maps.gsi.go.jp/development/ichiran.html)

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

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

## before
`元画像`
![input_15-29133-12868.png](https://qiita-image-store.s3.amazonaws.com/0/58671/cd2fec8a-5370-6d17-d93b-7bda7e02ce9c.png)
`正解画像`
![target-img15_29133_12868.png](https://qiita-image-store.s3.amazonaws.com/0/58671/919fcbed-18da-9221-8fcc-3a16341f8280.png)
`分類結果画像`
![result-img15_29133_12868-pix5.png](https://qiita-image-store.s3.amazonaws.com/0/58671/bafd5325-370e-5071-9221-d3b14286f7c0.png)
`元プログラムはこんな感じの精度です。
７～８割の精度なのでそこそこいい感じに分類してくれてます。
但しピクセルの目が細かい分類出力データを作ろうとすると数十分はかかります。`

　元プログラムでは白黒の旧版地形図を食わせて教師データの土地利用図に近い画像をConvNetにより作成するというものでした。こちらも変換前後の画像セットになるので学習データの生成は容易でした。
　予想では白黒で手書きのデータなのでそこまで精度は出ないだろうと高をくくっていたのですが・・・
　数時間学習させてどんなものんかと見てみたところ・・・
　
## after
`pix2pix`
![pix2pix](https://qiita-image-store.s3.amazonaws.com/0/58671/69246993-95c5-7bec-531e-fca28d5770fb.jpeg)
`正解画像`
![target-img15_29133_12868.png](https://qiita-image-store.s3.amazonaws.com/0/58671/919fcbed-18da-9221-8fcc-3a16341f8280.png)


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

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

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


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

### おまけ２
　古地図を地理院タイル（写真）で学習させてみた結果。
![地理院タイル（写真） to 古地図](https://qiita-image-store.s3.amazonaws.com/0/58671/20fb3b38-7965-f72d-9635-3676a4940006.jpeg)
　
　バグってハニー現象。昔のファミコンでカセット入れ替えしたときに似ている・・・
　元々がズレてたので、ズレているものは厳しいかもしれない。

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

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

### おまけ５
　標高タイルからCS立体図をpix2pixを使って[検証してみた記事](http://qiita.com/wayama_ryousuke/items/8e6c2b091603a30d294f)もありますので、よろしければどうぞ！