宙畑 Sorabatake

機械学習

衛星データとディープフェイク、CycleGANで生成した嘘のゴルフ場衛星画像は分類器を騙せるのか

CycleGANで生成した嘘のゴルフ場衛星画像で、以前宙畑で作成したゴルフ場が写っているか否かを判定する分類器を騙せるのか試してみました。

スエズ運河におけるコンテナ船の座礁事故、福徳岡ノ場から噴出した軽石、ウクライナ国境のロシア軍……これらのニュースはすべて、衛星データとセットで報道され、多くの読者・視聴者にその話題の状況を生々しく伝えられました。

近年、衛星データを用いた報道を見かけることが増えたと感じている方も多いのではないでしょうか? そして、今後も、報道における衛星データの利活用は増えることが予想されます。

一方で、衛星データに限らず画像を用いた報道には、現代において注意すべきポイントがあります。それは、報道に使われている画像が事実を写した画像なのか、フェイク画像かということです。

(1)ディープフェイクのリスク

ディープフェイクという言葉を聞いたことがある方も多いでしょう。その言葉の通り、ディープラーニング技術を活用して作成されたフェイク(偽物)画像のこと。

あたかも特定の政治家が発言を行っているような動画の投稿が行われたり、ドイツでは親会社の幹部を装う相手に、子会社の社員が電話で送金を指示され、約2600万円をだましとられたり……国内外問わず、ディープフェイクを悪用された事件が複数件発生しています。

そして、それは衛星データも例外に漏れず悪用される可能性が0ではありません。そこで、実際に衛星データのディープフェイクは作れるのか、また、それを見破ることはできるのか。宙畑で実験してみました。

※意図的なディープフェイクの悪用は厳禁です

(2)本記事で実践するディープフェイク生成

本記事では、ディープフェイクの生成を行うために、CycleGANを用います。CycleGANは、画像変換を行うことが可能な生成器です。

以前の宙畑の記事でも pix2pix という画像変換器を用いて、SAR画像を光学画像へ変換する方法が紹介されています。GANについても解説されているので、こちらを読んでおくと理解が深まると思います。

CycleGAN では pix2pix に存在していた問題点を克服することで、pix2pixでは扱えなかった変換も行えるようになりました。

pix2pixでの問題点

pix2pixでは、元のデータと変換後のデータを用意し学習させることで、未知の画像に対しても画像変換を行うことができます。pix2pixの論文では実際に、航空写真と地図を学習させることで、未知の航空写真に対しても地図を生成した結果が載っています。

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

しかし、pix2pixだと、学習の際に変換前と変換後の両方の画像が教師データとして必要になります。衛星画像だと、上の例のように、変化が無い画像であれば変換が可能ですが、今回のディープフェイクのような画像を生成する変換の場合は、変化前と変換後(例: 建物が建設される以前と建設された後)の画像データが必要になり、衛星画像のような変化に時間を要するような画像の変換は十分なデータが収集できない可能性があります。

CycleGANだと、変換前と変換後の画像(ペア画像)は必要なく、グループに分けた画像があれば大丈夫になります。

左側がpix2pixで必要だったペア画像。右側がCycleGANで必要な画像グループ。 Source : https://arxiv.org/abs/1703.10593

例えば、上記の例のような画像グループ(写真とモネの絵画)を集めれば、次の変換が行えるようになります。

・写真をモネ風の絵画にする変換
・モネの絵画を写真風にする変換

他にも、CycleGANの事例として、馬とシマウマを学習させることで、馬をシマウマに変換した動画が公開されています。

CycleGANの学習方法

CycleGANでは2個の変換器を用います。今回は次の2つの変換器を考えます。

・猫の写真をイラストに変換(変換器A)
・猫のイラストを写真に変換(変換器B)

この場合、画像は猫の写真と、猫のイラストの画像グループを集めればよくなります。

今までのGAN(pix2pix)等のタスクでは、1つの変換器で変換した生成物と教師画像(正解データ)を比較することで、ネットワーク(変換器)の更新をして学習していました。

しかし、CycleGANでは、対応する画像(教師画像)が必要なくなったはずなので、比較する画像がなくなり、このままでは評価ができなくなってしまいます。

そこで、変換器Aで変換した画像を変換器Bで変換することをやれば、元の画像が再び生成されるはずです。少しややこしいですが、今回の例ですと「写真をイラスト風に変換した画像に対して、今度は写真風の変換をかければ、元の写真に戻るはず」という考え方です。

このデータの流れは元の画像に対象が戻ってくるため、CycleGANと呼ばれる所以です。

また、この学習だけでは、変換器Aで生成された画像は何でも良くなってしまうため、もう一つの変換である「イラストの画像から2回変換して、元画像と比較する学習」も行うことで、どちらの学習でも途中の生成物も意図した画像を生成してくれるようになっていきます。

これらの学習を行うことで、CycleGANは2個の生成器を学習して、どちら側からも変換を行うことができるようになります。

(3)CycleGANを利用したDeepFake衛星画像生成

それでは実際にDeepFake画像を生成してみましょう。

利用するデータ

以前の宙畑の記事で利用された、ゴルフ場のデータを利用していきます。

このデータセットは、衛星画像にゴルフ場が写っている(1)か、写っていない(0)かの分類タスクでした。

このデータセットを利用することで、次の2つの変換を行うことができるようになります。
・ゴルフ場の写っている画像をゴルフ場の写っていない画像へ変換
 → ゴルフ場を消す
・ゴルフ場の写っていない画像をゴルフ場の写っている画像へ変換
 → ゴルフ場を出現させる

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

学習とテスト用のデータは次のようにしてあります。

・testA: テスト用画像(ゴルフ場が写っている)
・testB: テスト用画像(ゴルフ場が写っていない)
・trainA: 学習用画像(ゴルフ場が写っている)
・trainB: 学習用データ(ゴルフ場が写っていない)

※ 今回はAをゴルフ場が写っている、Bが写っていないにしてありますが、逆でも問題ありません

・golf_checkpoints: 学習中にネットワーク情報を保存する場所
・golf_results: テスト結果を保存する場所

実行環境とコード

公式でPyTorch実装のCycleGANが利用できるようになっているので、そのコードを利用します。
https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix

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

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

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

Google Driveに連携しなくてもアップロードで問題ありませんが、ファイルパスの記述に気をつけてください。上記の「想定するディレクトリ構造」の通りにデータがGoogle Drive上にあれば次のようなパスになっています。

from google.colab import drive
drive.mount('/content/drive')

dataset_path = '/content/drive/MyDrive/golf'
checkpoints_path = '/content/drive/MyDrive/golf_checkpoints'
results_path =  '/content/drive/MyDrive/golf_results'

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

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

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

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

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

!pip install -r requirements.txt

学習

学習を行っていきます。自分でコードを追加する必要はなく、train.py を実行してパラメータを追加することで、設定を変更できます。

!python train.py --dataroot /content/drive/MyDrive/golf --name golf --model cycle_gan --batch_size 4 --gpu_ids 0 --checkpoints_dir /content/drive/MyDrive/golf_checkpoints

実際の学習では次のパラメータも変更する必要があるかもしれません。
–batch_size: バッチサイズを変更できます。GPUの容量によって変更してください。
–n_epochs, –n_epochs_decay: 学習のエポック数です。デフォルトだと(epoch: 100, epoch_decay: 100)で200エポックに設定されています。

次のグラフは、私の環境で学習をしながら画像の誤差をプロットしていったものですが、学習が進むにつれて、ネットワーク全体的に誤差が小さくなっていくことが確認できます。

200 epoch までの誤差をプロットしていったグラフ

テスト

学習と同じようにテスト用のコードは用意されているので、必要なパラメータを渡してテストを実行します。

!python test.py --dataroot /content/drive/MyDrive/golf --name golf --model cycle_gan --no_dropout --results_dir /content/drive/MyDrive/golf_results --checkpoints_dir /content/drive/MyDrive/golf_checkpoints --direction AtoB

–direction を ‘AtoB’ または ‘BtoA’ で変換方向を指定する必要があります。

テスト結果

それでは実際に生成された画像を確認していきます。特に上手くいったものをいくつか取り上げています。

ゴルフ場を消す

左側が実際の衛星写真で右側がフェイクのゴルフ場が消える処理を加えたものです。山の中であれば、周りの山の濃い色にすることができていて、平地でも畑などの周りと同じような風景に馴染むようにゴルフ場が消えていますが、ゴルフ場のコース跡は消した後も見える感じがしますね。

ゴルフ場を新しく出現させる

こちらも、左側が実際の衛星写真で右側がゴルフ場を出現させる処理を加えたものです。元は畑の広めの場所をゴルフ場のようなものに変換できています。

(4)過去の分類器を実際に欺けているのか確認

続いて、ゴルフ場分類の記事で学習を行った分類器を、実際に生成したフェイクデータで騙すことができるのかを試してみます。ちなみに記事の分類器のゴルフ場が写っているかを判断できる精度は正答率9割程度でした。

先に実際の衛星画像で判定してみます。どれだけゴルフ場が写っていそうかを確率0~1 の範囲で表します。

ゴルフ場あり 99.988%

ゴルフ場はほぼ確実に写っていると判定されています。
続いて、ゴルフ場を取り除いた画像で試します。

ゴルフ場あり 6.47%

50%以下であれば、「ゴルフ場なし」と判定されるため、今回のCycleGANでは分類器も騙せているDeepFake画像を生成できていることが確認できました。

(5)まとめ

今回のように、CycleGANを用いることで衛星画像についてもDeepFake画像を生成し本来の画像とは異なるものを出現させたり、消したりできることを確認できました。

Google Colaboratory のような環境があれば、コードを書かずに容易に実行できてしまうため、悪用は厳禁ですが、実際のゴルフ場の出現等をやっていて、逆にゴルフ場がありそうな場所(候補地)を見つけるために利用できそうな技術のような気もします。

今後衛星画像やデータを眺めるときも、この情報は本物なのかという考えも頭の隅に置いておく必要がありそうですね。