宙畑 Sorabatake

機械学習

Pix2Pixで宅地利用調査から任意の衛星画像を生成するアルゴリズムを作る

簡単な塗り絵のような画像を作るだけで、お好みの衛星画像を生成するアルゴリズム制作にチャレンジしてみました。ハート形や六角形の池を作ることにも成功しています。

お絵描きをするように衛星画像を生成する方法があるとしたら、使ってみたいと思いませんか?

今回、宙畑では、任意の色を選び、簡単な塗り絵のような画像を作るだけで、お好みの衛星画像を生成するアルゴリズム制作にチャレンジしてみました。

※本記事で利用したコード及びデータは以下にアップロードしています。
※ご自身でコードを動かしてみたい方は以下からダウンロードの上で実行してみてください。
https://github.com/sorabatake/Pix2Pix

やりたいことのイメージ Credit : 国土地理院ウェブサイト

(1)本記事で実施すること、解析手法、利用するデータ

利用する手法とデータ

今回は宙畑でも何回か取り上げられている pix2pix という画像生成手法を利用していきます。

pix2pix では、元の画像と変換後の画像を用意し、学習をすることで画像を変換できるようになります。pix2pixが発表された論文でも実際に航空写真から地図を生成する例が載っています。

Source : https://arxiv.org/abs/1611.07004

画像の条件としては、入力(変換前)画像と出力(変換後)画像が1対1でペアになっている必要があります。

今回は衛星画像を出力画像にしたいため、学習用に同じ範囲の場所で色がついた地図等を用意する必要があります。

画像は国土地理院の宅地利用動向調査成果のデータを利用します。これは、都市圏の土地利用データで、1974年から1997年の間のデータは地理院タイルとして提供されています。今回は近畿圏の1991年のものを利用しました。

同じく地理院タイルでは、年代別の写真として、1987年~1990年の上空の写真が提供されているので、同じタイル座標の宅地利用画像を入力画像として、出力を上空の写真にします。

宅地利用動向調査成果(入力画像) Credit : 国土地理院ウェブサイト
上空写真(出力画像) Credit : 国土地理院ウェブサイト

宅地利用動向調査では、17の分類コードに分かれており、コード毎に違った色が割当られています。

最終的に出来上がるモデルでは、入力画像の色を塗り替えることで、新しい土地の上空写真が出来上がる想定です。

(2)想定するディレクトリ構造

手に入れた入力画像と出力画像をpix2pixの仕様に合わせてディレクトリに分けていきます。また、検証用にトレーニング用画像とテスト用画像に分けておきます。

map2sat_checkpointsとmap2sat_resultsディレクトリは実験結果等のデータを格納する場所で、testとtrainフォルダは後で処理した画像が入る先なので空で大丈夫です。

map2sat ディレクトリのtrainA・trainBとtestA・testBに画像を入れていきますが、Aと付く方には出力画像を、Bと付く方には入力画像を入れます。(学習時に設定する値で変換の方向を変えることもできます。)

また、画像はAとBでファイル名が揃っていることを確認してください。

trainA: 1.png(空中写真), …
trainB: 1.png(宅地利用動向調査画像), …

testA: test-1.png(空中写真), …
testB: test-1.png(宅地利用動向調査画像), …

map2sat_original は後で自身で描いた地図等の正解データの無い入力画像だけのデータを入れていきます。

(3)実行環境とコード

公式でPyTorch実装のpix2pixが利用できるようになっているので、そのコードを利用します。

https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix

今回は Google Colaboratory 上で動かせるように jupyter notebook (ipynb)形式にしてあります。ローカルでも可能ですが、学習の際には GPU 環境が必要になります。

また、Google Colaboratory を利用する場合も設定でGPUが利用できるランタイムに変更の必要があるため、上部メニューの「ランタイム」→「ランタイムのタイプを変更」を選択して表示される設定画面からGPUを選択してください。

Google Colaboratoryを利用する場合、ランタイムが再起動する場合にアップロードしたデータが消えてしまうため、画像はGoogle Driveにアップロードして連携します。

まず、pix2pix を実行できるようにするためにコードを持ってきます。

!git clone https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix

続いて、作業を行いやすくするために、ダウンロードしたディレクトリを利用するようにします。

import os
os.chdir('pytorch-CycleGAN-and-pix2pix/')

pix2pixで必要になるライブラリをインストールします。

!pip install -r requirements.txt

学習用データ生成

pix2pixでは学習に変換前と変換後が横に並んだ画像を学習で利用するため、その画像を生成するコードが用意されています。

!python datasets/make_dataset_aligned.py --dataset-path /content/drive/MyDrive/map2sat

これを実行すると、先程は空のディレクトリだった、trainとtestに画像が生成されます。

Credit : 国土地理院ウェブサイト

学習

学習を行います。

!python train.py --dataroot /content/drive/MyDrive/map2sat --name map2sat --model pix2pix --batch_size 64 --gpu_ids 0 --checkpoints_dir /content/drive/MyDrive/map2sat_checkpoints --direction BtoA --n_epochs 1000 --n_epochs_decay 200

学習過程の様子は map2sat_checkpoints のところに保存されていきます。学習は1200epoch 行います。
※1epochは学習用画像を一通り学習したという単位

1epoch目

生成した画像
元画像

最初の epoch ですが、既に線路の輪郭や建物も見えてきます。

200epoch目

生成した画像
元画像

色もしっかりと付きだして、遠目で見ればどちらが本物かも分かりにくくなっています。

1200epoch目

生成した画像
元画像

川や木の生成も自然な形に近づいている気がします。

テストデータで検証

では、今度は学習時には使われていなかったテスト画像でも生成を試してみます。

!python test.py --dataroot /content/drive/MyDrive/map2sat/ --name map2sat --model pix2pix --gpu_ids 0 --checkpoints_dir /content/drive/MyDrive/map2sat_checkpoints --direction BtoA --results_dir /content/drive/MyDrive/map2sat_results

入力画像 Credit : 国土地理院ウェブサイト
元画像
生成した画像

やはり未知のデータに対しては少し精度は悪くなり、広めの土地は生成が難しいようですが、もとの特徴のようなものは再現ができてきている気がします。

入力画像を編集する

では、次に地図には本来なかったものを書き込んで空中写真に新しく生成されるかを確認していきます。

入力画像
出力画像

例えば左側の真ん中辺りに新しく橋を作ってあげたり、右上の運動場の場所に人工的な形の池等も追加してみます。

池などを追加した入力画像 Credit : 国土地理院ウェブサイト

今回から入力画像に対して出力画像がなくなるので、テスト実行時の引数の値が変わります。入力画像のみの場合は、最初にディレクトリを作成した、 map2sat_original/testB のディレクトリへ地図画像を入れておきます。

!python test.py --dataroot /content/drive/MyDrive/map2sat_original/ --name map2sat_original --model test --checkpoints_dir /content/drive/MyDrive/map2sat_checkpoints --direction BtoA --results_dir /content/drive/MyDrive/map2sat_results --dataset_mode single --netG unet_256 --norm batch

実行すると次の画像が結果ディレクトリに生成されます。

川に架かる橋が3本に増え、六角形の池も出現させることができました。

形が崩れる場合もありますが、ある程度は元の画像に新しく要素を追加できることが確認できました。

ハートの池等も上手く収まると生成できます。

ゼロから町の地図を作ってみる

今度は、自分でゼロからペイント等のツールを用いて地図を描いて、そこから生成してみます。描いてみた地図はこちらです。

真ん中に大きめの川と湖につながる地域を意識してみました。今度はこの地図から空中写真へ変換してみます。出来上がった画像は次のものです。

崩れているところも多いですが、元の地図を参考に道路や川等が生成されていることが確認できました。もう少し細かく書き込んでみるとよりリアルに近づいていくかもしれません。

精度を上げていくには

精度等を上げていくには、学習画像数を増やしてみたり、pix2pixの内部のニューラルネットワークの変更等が必要になってきそうです。

CycleGANといった手法でもできるので、他の手法を試してみるのもいいかもしれません。

ただ、このデータセットでは、区画の情報だけで、建物の細かい情報や、飛行場等の特殊な土地のものは学習が難しいかもしれませんので、似たような色分けされている、より詳細な地図画像等を使うとよりリアルな空中写真が生成できるかもしれません。

(4)今回作成したアルゴリズムの活用方法

①任意の街づくりを子供と楽しみ、夏休みの自由研究テーマとする

まず、お子さんがいる読者の方は、ぜひ本アルゴリズムを用いて、子供と任意の衛星画像生成を試してみてください。

②生成した衛星画像を教師データとして利用する

今回のアルゴリズムで生成する衛星データの精度をさらに上げることができれば、以前の宙畑の記事のように、生成された画像を画像分類タスクの学習データの水増しに利用して精度を上げる等も分類対象によっては可能になるかもしれません。

(5)まとめ

以上、宅地利用調査を用いて、簡単な塗り絵のような画像を作るだけで、お好みの衛星画像を生成するアルゴリズム制作にチャレンジしてみました。

衛星データは高価なため、教師データを揃えることにも相応のお金がかかります。その点、任意の衛星データを生成するアルゴリズムができれば、衛星データ解析の大きなコストダウンに繋げられる可能性があります。文中にもあったように、現時点では、区画の情報だけで、建物の細かい情報や、飛行場等の特殊な土地のものは学習が難しいかもしれません。しかしながら、今後精度の高い衛星データを生成するアルゴリズムが生まれることで、衛星データ解析のハードルを大きく下げる可能性があります。

また、塗り絵のようなものを用意するだけで、任意の衛星データを生成できるという点も単純に面白い試みでした。ぜひ読者の皆さんも試してみてください。