実在しない人物の写真を生成するシステムを構築するためのコストについて StyleGANから
StyleGANとこの記事の目的
ほぼ1年前の話題になりますが、GPUで有名な半導体メーカーである NVIDIA の研究として、StyleGANというものが発表され、話題になりました。
記事
gigazine.net
動画解説
www.youtube.com
技術的な情報
qiita.com
2012年に「Googleの猫」が登場してから技術者の間で意識されていた、機械学習によるリアルな画像描写が可能となり、メリットとして肖像権を意識しない画像の生成が可能になる一方で、デメリットとしてフェイク画像によるネットメディアの信憑性の低下が現実のものとなりそうだなと思ったものです。
少し調べてみることで、この定性的な評価に対して、応用範囲の幅と定量的な評価がラフにできましたので記事にします。
最新のStyleGAN
githubを追いかけたところ、Ver2に更新されて、StyleGAN2なるものが存在していました。こちらは、TensorFlowによるStyleGANの実装です。
ReadMeには、学習にかかるリソースの評価や実際に生成された画像へのリンクがあり、ここから更に詳細な評価ができます。
人の顔以外の画像
リンク先に、Google Driverがあり、ここには人の顔以外に、車、馬、猫、教会などの生成データを見ることができます。
curated-images - Google ドライブ
馬
drive.google.com
足元などでおぼつかないところもありますが、ほぼ表現できていると思います。
車
drive.google.com
こちらがティピカルな例だと思うのですが、実物だと見せるにはもう少し時間がかかる印象です。
商用レベル、例えば、AdobeのStock Photoの中で販売するというという意味合いで考えると、人物については販売可能性があるようですが、車などになるともう少しという状況だと思います。
stock.adobe.com
コスト
コストについては、人の顔(Flickerというサイトの高品質画像)で1024x1024の画質の構成を考えたとき、NVIDIA DGX-1 with 8 Tesla V100 GPUsを用いて、8 GPUでの演算をすると、9日と18時間かかるとあります。
NVIDIAのV100 GPUをGoogleのクラウドサービスで借りた場合、1時間あたりのGPU毎のコストは、一時間あたり$2.48USDのようです。
GPU の料金 | Compute Engine ドキュメント | Google Cloud
2.48USD x 8 GPU x (9日x24時間 + 18時間) =4642.56USDとなります。1ドルあたり109円と考えると、505,039円、つまりおおよそ50万円となります。
言い換えれば、各対象(人、車、猫)などに対して、1024x1024の画像生成をするために必要な時間とコストは、管理費などを除いて 10日と50万円となります。
(別の設定では、5日6時間という内容もありますが、ここは控えめに見て)
ただし、実用的なレベルという意味ですと、もう少し高い解像度の画像が必要です。
PCの解像度は、最近のノートPCですと1980x1024ぐらいが一般的です。高解像度という意味では、4000x4000ぐらいの解像度があればいいのではないでしょうか。
(それ以上の場合、別の機械学習を用いて、高解像度化するという手法もあると思います)
1辺あたりの大きさが四分の一の256x256の場合、同等の分析が4日と18時間という結果がありますので、逆算すると、10日/50万円と倍のコストが掛かると考えられます。
十分なデータセットがあることが前提であり、データを揃えることは面倒な作業ではありますが、これを除けば、
各オブジェクトに対して、有効性を確認するためのコストが 10日 , 50万円
それを商用化するために、必要なコストが 20日, 100万円
と見ることができるのではないでしょうか。
まとめ
StyleGANについての現状を確認しました。システム生成に必要なコストは1要素あたり10日 50万であり、実用化には更に倍のコストが掛かることがわかりました。
対象となるオブジェクトについては、収集できた画像の質次第ではあると思いますが、必ずしもうまくいくとは限らず、ここはリスクを持つのが現状だと思います。
ただ、一旦うまく行けば、商用化することが可能なのではないかと言うのが、現段階での印象です。
コストについては、GPUの性能向上が進めば、より廉価に展開できるのではないでしょうか?
ムーアの法則がまだ活きているのであれば、数年もすると個人が手が出せるレベルのコストで自動生成することが可能になることが予想できます。
法制度やビジネススキームの整備もありますが、画像生成によるメリット・デメリットが社会に及ぼす影響については、控えめに見て、ここ5-10年ぐらいで検討すべき議題になるだろうと感じました。
あるいは、もう少し早くても違和感がないかもしれません。
次元拡張したRNNでの画像処理。実行は量子コンピュータ。できればNeural ODEを用いて。
画像の識別処理にはCNNが一般的ですが、FFNNであれ、CNNであれ、ベクトルで処理していることにやや違和感があります。
画像は2次元ですので、行列のまま処理する方がむしろ自然に感じます。
行列のままであれば、縦横無尽にRNNの概念を適応することができるので、前後左右の情報を解釈したNetworkを組むことができるはずです。
この場合、計算はテンソルで考えることになります。
そうなると、計算が膨大になるはずですが、量子コンピュータを用いることで、同時処理ができるのではないかと思っています。
また、RNNを用いることで、離散→連続処理による恩恵を得ることもできそうです。
実現性については割と先の話になりそうですので現在ではタイミングでは思考実験までしか出来ないと思います。
この記事では、思考実験を行うための問題設定までをしてみます。
イントロダクション
画像処理はCNN(畳み込みニューラルネットワーク)が一般的です。
CNNでは、周囲のNxNの領域を取りそれを1つの特徴量として圧縮する(=畳み込む)ことで、周辺の情報に対する関係性を確保しています。
例えば、7x7の画像を3x3で畳み込む場合、畳み込んだ後のデータは 3x3=9次元として処理します。
参照:
CS231n Convolutional Neural Networks for Visual Recognition
よりシンプルなFNNでは7x7=49次元のデータとして処理をするわけですが、どちらのパターンにしても画像をベクトル(=1階のテンソル)で処理しています。
表現したい対象が2次元であるならば、行列(=2階のテンソル)で表現することで連続性を有意味にして描写することができるのではないかと思うのです。
その背景には、RNNの存在があります。RNNでは、サンプリング対象が時系列データである場合に有効なニューラルネットワークです。
直前のデータを学習した際の結果を、次のデータの学習にフィードバックすることを繰り返し行うことで、前後関係を学習結果に反映することができます。
前後関係という概念は、数直線上に設定された、いわば一次元のデータになります。概念的には、一次元上に構成されているRNNを二次元に拡張可能ではないか?というアプローチです。
拡張自体の数学的アプローチは後ほど考えるとして、厄介なのは計算量です。ベクトル(=一階)量のデータでも計算には時間がかかるのに、行列で解釈した場合に発生する処理量は膨大なものになるはずです。
現在のコンピュータの実行速度では、実験的なことはできたとしても、実用化に必要な複雑な計算に対しては到底追いつかないと予測できます。
そこで気になるのは、やはり量子コンピュータの存在です。
量子コンピュータは、量子が持つ複数の状態を利用して、複数の計算を同時に実行することが出来る為、並行処理を非常に高速に実現できるとされています。
その中でも特に近年注目されている量子アニーリング(量子焼きなまし法)は解候補の任意の集合から任意の目的関数の最小値を探す一般的な方法を提供してくれるようで、今回の様に指数関数的(かはまだ不明ですが..?)に増える計算量に追いつくことができる唯一の手段だと言えます。
また、RNNを軸におくことには、別のメリットもあります。Neural ODEの存在です。
ニューラル常微分方程式 / Neural Ordinary Differential Equations - neuralnetな日記
Neural ODEの特徴のひとつに、連続的な時系列のモデルを実現可能であることが挙げられます。
従来であれば、一つの学習器に入れることができるデータの大きさは固定されており、データに欠損がある場合は、なんらかの形でデータを保管する必要がありました。
Neural ODEを活用することで、仮に欠損情報があったとしても、それを無視して計算を進めることができる様になり、精度のさらなる向上が期待できます。
単純なRNNですと、勾配消失問題などの問題により思う通りに収束してくれないことが分かっており、現在の主流はLSTMです。
これを踏まえると各種実験については、RNNを基礎として検討した上で、LSTMまでの拡張をゴールとしておくのが妥当だと考えられます。
テンソルによるRNNの2次元拡張
入力データをx, 中間データを z, 出力結果を yとした時、RNNの伝播式は以下の様に表現できます。
z(t) = activation_hidden( W_xh * x(t) + b_xh + W_hh * z(t-1) + b_hh )
y(t+1) = activation_out( W_hy * z(t) + b_hy )
参考: https://www.renom.jp/ja/notebooks/tutorial/basic_algorithm/LSTM/notebook.html
ここで、W_oo は行列(二階のテンソル)、x(t)、b_oo、z(t)、y(t)はベクトル(一階のテンソル)です。
activation_oo はReLUやSoftmaxなどのなんらかの活性化関数です。
入力層である xをベクトルから行列として扱うのであれば、Wは三階のテンソルということになります。
演算の拡張をするためには、積、和のオペレーションに加え、活性化関数をどの様に扱うかが論点になります。
一般的なRNNの拡張であるLSTMを視野に入れるのであれば、これらを用いてLSTMの表現を確認しておくべきです。
また、次項に繋げるという意味でも、計算量がどのぐらい増えるかを把握しておく必要があります。
まとめると、RNNの画像への拡張において必要な考察は以下の通りとなります。
- 演算拡張のための積、和の定義と活性化関数の表現
- それを用いたLSTMの表現
- 計算量の試算
量子コンピューターによる計算の実現可能性
一般公開されている量子コンピュータは無いと思っていましたが、IBMさんが公開していました。
IBM Quantum Computing で計算してみよう
pythonによるオペレーションが可能なようであり、現在は5から32キュービットの量子コンピュータが利用可能なようです。
quantum-computing.ibm.com
記事を見る限り、量子コンピュータでは計算方法はやはり特殊なようです。
ところまで進めれば良いと思います。
次元拡張したRNNをNeural ODEを用いて解く
Neural ODE(ニューラル常微分方程式)は、文字通り常微分方程式によりニューラルネットワークを解く手法を提供しています。
自然数個のノードによって構成されている離散ネットワークを連続化しています。
連続化することで必ずしも同じステップにデータがある必要はなくなるため、データが不揃いであったとしても、柔軟に処理をすることができます。
RNNはもともと時系列データに向けられて構築されているので、連続化について高い親和性があるように見えます。
ただし、これを次元拡張したLSTMに対して適応するには、複数のステップが必要です。
まず、具体的にRNNをNeural ODEに適応させる必要があります。その後、RNNをLSTMへ拡張させる必要がありますが、これについは正直に申し上げて、イメージが沸いてないのも事実です。
その後、同様の作業を次元拡張したネットワーク上で行う必要があります。
量子コンピュータと直接紐づけるのは難易度が高いので、単純に必要な理論とコードを淡々と書いていくことで進めることとします。
- 一般的なRNNをNeural ODEで解くための理論を構築し、コードを書く
- 一般的なLSTMをNeural ODEで解くための理論を構築し、コードを書く
- 次元拡張したRNNをNeural ODEで解くための理論を構築し、コードを書く
- 次元拡張したLSTMをNeural ODEで解くための理論を構築し、コードを書く
ここまで到達すれば、おそらくこの先の視野が広がると思います。
汎用ロボットのアーキテクチャについて 続き2
前回の記事はこちらです。
汎用ロボットのアーキテクチャについて 続き1 - neuralnetな日記
次に、アルファのブレインとボディの接続について検討します。データの送り方は、データを流し続けるストリーミングタイプと、一度だけデータを送付するワンショットタイプがありそうです。
ボディからブレインに入力可能な情報は以下の通りです。
ストリーミングデータを受け取り、メッセージキューで処理することになりそうなので、クラウドのIoTソリューションが向いていそうですが、一旦は単体サーバーで進めてみます。
余談になりますが、クラウドのIoTソリューションですと、PubSubができるようです。カーシェアリングの車の貸し借りのような感覚で、ロボットのボディを貸し借りする世界観も想像に難くありません。
こちらは、GoogleのIoTソリューションです。
cloud.google.com
次にボディの出力は以下の通りです。
- スピーカー(答えるため、また音楽を流すため)
- 赤外線出力(リモコン操作)
- ディスプレイ(表情を表現するため)
- 移動(キャタピラ移動)
出力はすこし複雑で、ワンショットとストリーミングで流すものがありそうです。また、ボディで完結するものもあるかもしれません。
基本的には、自律的な発言には意思決定が必要なので、ブレインからキックする必要があります。
スピーカーでの回答、実行単位はワンショットもしくは文脈の長さによってはストリーミングです。
スピーカーでの音楽は、ストリーミングです。
赤外線出力は、リモートから送信パターンを送付するものとし、データをワンショットで送付することとします。
ディスプレイは、表情パターン(にっこり、笑う、悲しい、眠る、しゃべる、うれしそうにしゃべる、忙しくしゃべる、普通等)のみを送付し、表示はボディが行うことします。転回する際にデータを送付するワンショットとします。
移動は、左右に対して、-1,0,1の3パターンを送付するものとします。(右,左)=(1,1)は前進、(右,左)=(1,-1)は左に回転等です。また、電圧のレベルを1から10で決定します。指令が出ているときのみ動くと考えれば、ストリーミングのほうが適切です。
まとめると以下の通りです。
カメラ情報 | 入力:ボディからブレイン | 映像 | ストリーミング |
マイク情報 | 出力:ボディからブレイン | 音声 | ストリーミング |
温度/湿度情報 | 入力:ボディからブレイン | テキスト | ストリーミング |
スピーカー(回答) | 出力:ブレインからボディ | 音声 | ストリーミングもしくはワンショット |
スピーカー(音楽) | 出力:ブレインからボディ | 音声 | ストリーミング |
赤外線出力 | 出力:ブレインからボディ | テキスト | ワンショット |
ディスプレイ | 出力:ブレインからボディ | テキスト | ワンショット |
キャタピラ移動 | 出力:ブレインからボディ | テキスト | ストリーミング |
仮に、移動をワンショットで行う場合は、緊急停止等のボディのみで終始する仕組みがあったほうがよいかなと思いましたが、アルファでは、ボディ側に周辺を把握するセンサー等がないので実装が困難であったのと、ストリーミングが切れたら停止するという対応ができるので、その方向で検討を進めます。
逆に、ボディがアルファよりリッチな場合や、将来的に、安全性を考慮しなければいけない場合は、ボディがある程度自律的に安全性を判断して緊急停止するなどの動きを取り入れる必要がありそうです。
思い付きで、音楽を再生できる機能を搭載する設計にしましたが、同じ流れでいうと、ディスプレイに映像を表示できる機能があってもよくなります。どちらも、このロボットが完全なサービス提供者という立ち位置であれば自然なのですが、ロボットがパートナーであると考えると、逆に不自然さを感じます。ドラえもんは歌が下手であり、音楽を流すロボットではなく、音楽をともに聴くロボットだからです。当たり前な話ですが、汎用ロボットであっても目的に応じて搭載する機能が変わってくるため、ベータの設計では、それを意識したほうがよさそうです。
本題に戻ります。これだけ複数のセッションがある場合、全体的なセッション管理が必要です。LTEの場合、IPアドレスも同的に変わる可能性があるため、どのレイヤーでセッション維持するかを検討する必要もありそうです。
当初想定していた仕様
汎用ロボットのアーキテクチャについて - neuralnetな日記
では、セッションをつなげに行くのはボディからという想定です。これは、ボディの通信手段が常に変わる事を想定しており、ネットワークアドレスが普遍なものがブレインしか存在しないためです。
暗に、従来のwebのホスト名およびIPアドレスを使用すると宣言しています。
なお、この段階で基本的にはブレインとボディはサーバークライアント方式を採用しており、その制約を受けることになります。具体的に言うと、あるボディに別のロボットのブレインが接続しに行くということが困難な構成になります。SIP(もしくはそれに類似した機能)などを導入し、双方向の通信を可能にすることで、ネットワークの構成がより柔軟になり、ロボットの相互接続性が広がると思います。このあたりは、どちらの設計思想が将来求められてくるかに依存するのだと思います。
Session Initiation Protocol - Wikipedia
今回はシンプルに、ブレインサイドにWebサーバーを立てて、そことGET/POSTを通じてセッション管理を行う前提で話を進めていきます。
汎用ロボットのアーキテクチャについて 続き1
次に、ボディに必要な部品をリストアップします。
まず大まかに候補をリストアップした後で、詳細の見直しを行います。
難易度とコストと期間を把握することが目的です。
※ 金額は送料別です。
1) 本体
hiramineさんのHW一覧から単三充電器と電池ケースを除いたもの: 9,163円
2) カメラ
同じくWebカム:2,031円
Raspberry PiにはCSIインターフェイスがあるので他の候補も考えます。
カメラ候補その2 RaspberryPiカメラモジュール 3,080円
正規品です。
他、割安のものだと
ラズパイ用 高画質 カメラモジュール - Camera Module for Raspberry Pi 920円
for raspberry pi カメラモジュールIR Camera高速冷却赤外線LED ラズベリーパイ Raspberry Pi 3 b+ / Pi Zero W使用OV5647 5MP 2,859円
というものもありました。
CANDY Pi Lite ラズパイ用LTE通信モジュール【CANDY-PI-LITE-LTE】:15,980円
ワイヤレス充電モジュール:1,050円
バッテリーはこちらの記事を参考にAnker PowerCore 10000 が良いかと思います。
http://densikousaku.com/archives/45
出力はUSBなので、USBからmicroUSDへの接続ケーブルが別途必要です。 100円ショップで買えるものですので、+108円と考えます。
なお、通常のRaspi3は5000mAhで6時間動くようです。
https://ichibariki.hatenablog.com/entry/2017/10/29/160454
温度湿度センサー 気圧付き 1,080円
こちらのサイトを参考にさせていただきました。
赤外線発信機 583円
指向性が心配です。
https://qiita.com/_kazuya/items/62a9a13a4ac140374ce8
スピーカー 770円
USBマイク 179円
こちらのようです。
「BU-Bauty いつでもどこへも携帯可能!世界最小USBマイク PC Mac用USBマイク 超小型 超ミニ 22mmx18mmx5mm」
ディスプレイ 3,320円
RasPiは再起動後に時間がリセットされてしまいます。RTCモジュールも将来的に必要になりそうですので前提とします。 990円
このまま機材を購入し、実装に進みたい気持ちでいっぱいですが、目的が違うのと、残念ながら時間がないので、このぐらいで止めておきます。
LTEモジュールのコストが嵩むところですが、概ね4万円+半月もあれば構築が可能そうです。
汎用ロボットのアーキテクチャについて
クラウド上にLinuxサーバーを起き、その上で自律可能なラジコン制御プログラムを展開します。
ボディの実装として、タミヤのモーターキットに制御用OS+LTEモジュールを設置し、更にマイク、スピーカー、カメラ、赤外線出力を実装したものを用意します。
これにより、簡単なクラウド型のロボットが作れます。つまり、現在の技術群を持って、ある程度人に役立つロボットが実装できるはずです。
仮にこのロボットをアルファと呼びます。
アルファに対して、詳細と拡張を考えてみたいと思います。拡張したものをベータと呼びます。この記事では、アルファとベータを通じて今の段階で分かる現実的な汎用ロボットのアーキテクチャを思考実験してみたいと思います。
アルファの目的は、簡単なコミュニケーション、音楽、そして赤外線による家電の操作です。ワンルーム程度のスペースを動き回り、必要に応じて自ら充電するぐらいのものを想定します。それなりに役に立ちつつ人から好まれる存在の原型です。
ベータの目的は、汎用ロボットユニットです。拡張可能で、表面的でもある程度、自律的なものであると良いと思います。役に立ちつつ好まれる存在という位置づけは保持します。また、ロボット三原則の実装まで取り入れれば良いかなと思っています。
想定する結論
あらかじめ、この記事を通じて言いたかった事を書きますと、将来のロボットのアーキテクチャは、おそらく以前から描かれていたようなものとは異なりそうという事です。
まず、汎用ロボットでは、いわゆる脳と体は分離されそうです。脳であるコンピューティング部分をクラウドに置くことで、常に機能をアップグレード可能です。ボディはただの外部との接触点に過ぎず、単体としてロボットが成立する必要性がなさそうです。
次に、それ故ですが、ロボットは単体で機能するというより、群体のような存在になりそうです。1つのクラウドコンピュータ上に複数のパーソナリティが存在し、単一のパーソナリティが複数のボディを扱うことができるような位置づけになると思います。
最後に、個体の概念が目的志向なものになりそうです。ロボットにおける個体という概念は特定の情報範囲を保護する為のファイヤウォール機能という位置付けに過ぎず、人に対するユーザーインターフェイスとしてのパーソナリティは、教育、パートナーシップの構築、警備などの特別な目的がない限り、誰もに好まれるような汎用的な人格になると思います。
というのが、当初予測なのですが、果たしてどのようになるか興味深いところです。(対極的な結果として、従来通りのロボット像が浮かび上がる可能性もあるとも思っています)
では、はじめてみます。
思考実験その1:アルファの実現可能
その1では、調査を通じてアルファを構築可能な手順を作ります。成果物はいわゆる設計なので、実装の影響を受けます。(つまり、今回は設計まで行いますが作ってみたら違いましたは全然起こりえることですのでお知りおきください)
構築する対象は
1) ハードウェア(タミヤのタンクキットとRasberryPiもしくはAndroid、各種センサー)
2)クラウド上のシステム(Google Cloud上のLinux)
の2つのコンポーネントです。
1)がボディ、2)がブレインといったところでしょうか。
ボディ部分
まず、ボディですが様々なリファレンスがあります。私のお気に入りはこちらの記事で、RasberryPiとwifiによる実装です。
こちらの拡張版まで行くと、カメラの搭載まで一気に進める事ができます。
ハードウェア側の制御OSはAndroidにしたかったのですが(ディスプレイや電源などの理由により)、ここまで実装が進んでいるものがあるので、こちらをベースにさらなる拡張をすることで、アルファのボディを目指します。
差分は以下です。
センサーはカメラが既に搭載されていますから、追加でマイク、スピーカー、赤外線出力をつけれれば目的が達成できます。ポートの空きがあるかと、求めるパーツが世の中に販売されているかが大事になってくるかと。
電源の換装はそれほど難しくないと思いますが、無線式充電器の有無がポイントです。また、充電の状態を制御用OSに取り込むようにしたいと思います。
通信ですが、ワンルーム程度であれば、WiFiでも機能すると思います。が、ベータでは、5Gも視野に入れたいので、是非ともLTEモジュールへ換装したいところです。
ブレイン部分
クラウドサービス上にLinuxを用意します。おそらくどこでも良いのですが、個人的な知識から、Google CloudとUbuntuで進めます。
ブレインとボディどちらをSSLのサーバーとして設定するかはセキュリティとボディの所有権制御の観点から非常に興味深いテーマですが、一旦は、ボディがクライアントであり、起動後にブレイン側にSSL接続する方針で進めます。
ブレイン側のサーバーに展開するバックグラウンドプロセスは、以下の様なものになるはずです。
- カメラ情報を受け続けるプロセス
- マイク情報を受け続けるプロセス
- センサーと時間の情報から、何らかの意思決定をし、音声もしくは赤外線出力をアウトプットするプロセス
ここまで書いて、ロボットにディスプレイが無い事に気づきました。Android端末の流用であれば、ディスプレイがビルトインされていますが、RasberryPiですと、ハード、ソフト共に追加が必要です。(ディスプレイを追加する事で、表情を表現したいと思いました)
ついでに温度/湿度センサーも追加したいと思います。不快な温度で自律的にエアコンつける仕様です。
まとめると、
ボディ部分
- ベースはhiramineさんの実装(タミヤのタンクにRasberryPi、カメラ実装済)
- 電源を充電式のものとし無線充電を導入(自律的に充電可能にするため)
- 通信をLTEにする(将来的な宅外での通信を可能にするため)
- 入力 カメラ(周囲の画像を得るため)
- 入力 マイク(周囲の音を拾うため)
- 入力 温度/湿度センサー(暑さ、不快指数を把握するため)
- 出力 スピーカー(答えるため、また音楽を流すため)
- 出力 赤外線出力(リモコン操作)
- 出力 ディスプレイ(表情を表現するため)
- 出力 移動(キャタピラ移動)
ブレイン部分
- Google Cloud上のubuntu
- ボディからブレインにSSL接続
- カメラ情報を受け続けるプロセス
- マイク情報を受け続けるプロセス
- 温度/湿度情報を受け続けるプロセス
- 入力系プロセスと時間から、何らかの意思決定をし出力系を通じて出力するプロセス(移動を含む)
という項目を深掘りしていきます。
続きはこちらです。
汎用ロボットのアーキテクチャについて 続き1 - neuralnetな日記
損失関数の出力サンプル / Output sample of Loss function
SMEと交差エントロピーの具体的な出力を見て見ます。交差エントロピーに非対称性があること、複数次元の出力の出力の仕方がわかると思います。
import numpy as np # 2乗和誤差 def mean_squared_error(y, t): # ニューラルネットワークの出力と教師データの各要素の差の2乗、の総和 return 0.5 * np.sum((y-t)**2) # 交差エントロピー誤差 def cross_entropy_error(y, t): delta = 1e-7 # マイナス無限大を発生させないように微小な値を追加する return -np.sum(t * np.log(y + delta))
以下を参照させていただきました: Python vs Ruby 『ゼロから作るDeep Learning』 4章 損失関数 (loss function) の実装 - Qiita
そもそもの違いを見ます。数字の差にあまり意味はありません。
t = 0.5 # 正解データ y = 0.4 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t))
MSE: 0.0049999999999999975 CEE: 0.45814524093709313
MSEでは、位置による距離は変わりません。交差エントロピーは位置により出力が変化します。
t = 0.8 # 正解データ y = 0.7 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t)) t = 0.6 # 正解データ y = 0.5 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t)) t = 0.2 # 正解データ y = 0.1 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t))
MSE: 0.005000000000000009 CEE: 0.2853398408652799 MSE: 0.0049999999999999975 CEE: 0.41588818833597924 MSE: 0.005000000000000001 CEE: 0.4605168185989092
t = 0.95 # 正解データ y = 0.85 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t)) t = 0.15 # 正解データ y = 0.05 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("CEE:" , cross_entropy_error(y,t))
MSE: 0.0049999999999999975 CEE: 0.15439287125818693 MSE: 0.004999999999999999 CEE: 0.4493595410333986
MSEは入れ替えても出力は変わりません。交差エントロピーは入れ替えると出力が変化します。
t = 0.5 # 正解データ y = 0.4 # 出力データ print("MSE:" , mean_squared_error(y,t)) print("MSE:" , mean_squared_error(t,y)) print("CEE:" , cross_entropy_error(y,t)) print("CEE:" , cross_entropy_error(t,y))
MSE: 0.0049999999999999975 MSE: 0.0049999999999999975 CEE: 0.45814524093709313 CEE: 0.27725879222398614
3次元における出力を見てみます。
t = [0.1, 0.3, 0.7] # 正解データ y = [0.0, 0.2, 0.8] # トライデータ print("MSE:" , mean_squared_error(np.array(y),np.array(t))) print("CEE:" , cross_entropy_error(np.array(y),np.array(t)))
MSE: 0.015000000000000006 CEE: 2.250841187246052
損失関数の種類 / Types of Loss Function
機械学習における損失関数(Loss Function)の位置付けは、作成した学習ロジックに対する評価指標です。
正解データ z (zは実数の集合) に対し、入力データ x (xは実数の集合) を学習ロジックf に投入して得られたデータ y (yは実数の集合でzと同じ配列数) があった時、yがzに近ければ近いほど、 学習ロジック f は優秀であるといえます。
「近い」という尺度の概念は、1つの数直線上の評価です。つまり、ただの1次元の数字になるので、y = f(x) と z に対する損失関数 L (y, z) は 実数への写像になります。
2点間を測る指標です。片方(z)の方がより「正しく」て、検査対象(y)が正しいデータにどれだけ近いかを測るのが損失関数だと思えば、大まかな把握ができると思います。
ただし、いわゆる距離ではありません。zから見たyの損失とyから見たzの損失は必ずしも一致しないため、対象律が成立していません。距離函数 - Wikipedia
損失関数としては「クロスエントロピー (交差エントロピーとも言います、cross entoropy)」と「平均二乗誤差/MSE (Mean Squared Error)」がよく使用されています。
より直感的なのは、平均二乗誤差です。2つの実数 a ,b があった場合、比較に二乗平方根
がよく使われます。発想としては、これを複数の変数に対応して、平方根を外したものになります。平方根はとってもとらなくても順序は特に変わらないので、無駄な計算を省くために外しているものと考えると良いと思います。
こちらのサイトによくまとまっています。
クロスエントロピーは、もう少し複雑で、2つデータを、それぞれのデータがもつ複雑さを表す指標(自己情報量と言います)で比較する手法です。
平均二乗誤差(MSE)は、回帰分析で使用されます。データ分類ではクロスエントロピーを使用します。
それぞれの具体的な出力をこちらの記事に書きました。
損失関数の出力サンプル / Output sample of Loss function - neuralnetな日記