最適化計算2 楕円の当てはめ 理論編

前回の下記投稿にひきつづき,今回は楕円の当てはめです.
daily-tech.hatenablog.com

1.楕円当てはめ問題

前回の投稿では,取得したデータをプロットし,そのプロットに対して直線を当てはめました.今回はデータに対して楕円を当てはめます.イメージとしては下記のような感じです.
f:id:rkoichi2001:20180331114913j:plain

前回の投稿では「一番それっぽい直線」を求めるために,最小二乗法を使いました.今回の楕円のケースでは,「一番それっぽい楕円」を求めるために下記の複数の方法を試します.

1.最小二乗法
2.最尤推定

で,インプットとなる取得データとアウトプットとなる楕円の方程式は下記のようになります.
f:id:rkoichi2001:20180331214740j:plain

上式を見てみると,結局パラメータは増えているものの,直線当てはめの場合と似たような形の式になっていることがわかります.パラメータの正規化条件も加えて,下記のように整理します.
f:id:rkoichi2001:20180331212701j:plain

2.最小二乗法

最小二乗法を用いる場合考え方はシンプルで,直線当てはめの場合と同じ感じで式を立てます.つまり,取得データを楕円の方程式に代入し,この総和を最小にするようなパラメータを決めます.
f:id:rkoichi2001:20180331213928j:plain

上式は二次形式になっているので,直線当てはめの場合と同じように,実対称行列 MLS に対する最小固有値に対応する固有ベクトルが求めるパラメータベクトルになります.つまり,,,
f:id:rkoichi2001:20180331214335j:plain

ただーし,楕円の当てはめに対しては上記の最小二乗法では精度がそれほど出ません.下記エントリで最尤推定に関して扱いましたが,この時は直線の当てはめだったので "Ax + By + C = 0" というのが満たすべき式でした.ここで,"取得データ x, y が持つ誤差は互いに独立である"という過程のもと,尤度を最大化した結果が最小二乗法でした.
daily-tech.hatenablog.com

今回の楕円当てはめの場合では,x2,y2,xy,という項がありますが,この項に生じる誤差は明らかに独立ではありません.x, y がそれぞれ持つ独立な誤差に依存しています.このことより,楕円の当てはめに関しては最小二乗法と最尤推定法が異なります.

3.最尤推定

じゃあ,最尤推定法はどうなるのか?という話ですが,工夫して式展開することによって見かけの確率変数を作り出します.まず,取得データの座標 (x と y の両方) に対して期待値0,分散が同一の独立な誤差が加わると考え,下記のようにあらわします.
f:id:rkoichi2001:20180331220728j:plain

上式を楕円の式に代入します.
f:id:rkoichi2001:20180331223211j:plain

上式を求める過程で,真値が楕円の方程式を完璧に満たすことと,誤差の二次の項は十分小さいとして無視しました.残った項を観察すると,楕円の方程式は下記の確率分布に従うことがわかります.
f:id:rkoichi2001:20180331224014j:plain
一点大事な点ですが,楕円の場合,分散が位置によって異なることがわかります.

上記の分散を共分散行列を用いて表現すると,下記のようになります.
f:id:rkoichi2001:20180331224909j:plain

確率変数を下記のように見なすと,
f:id:rkoichi2001:20180331225622j:plain

最尤推定法から求まる評価式 J は下記のように定義されます.この評価式のことをサンプソン誤差といいます.
f:id:rkoichi2001:20180331225950j:plain

よって,最尤推定法によって楕円当てはめを行う場合,上記評価式(サンプソン誤差)を最小にするようなパラメータセットを見つける必要がありますが,サンプソン誤差を最小にする方法としては,下記エントリで扱った Fundamental Numerical Scheme を用いて解くことができます.
daily-tech.hatenablog.com

Fundamental Numerical Sceme (FNS法)

ここでは,楕円の当てはめや基礎行列推定の際に評価式として出てくるサンプソン誤差を最小化する手段として,Fundamental Numerical Sceme を扱います.

まず,サンプソン誤差は下記のように定義されます.

f:id:rkoichi2001:20180401150304j:plain

この評価式は下に凸の関数であるので,最小値を持ちます.よって,パラメータ "θ" に関して微分し,微分値が 0 となるパラメータ を求めればこの値がサンプソン誤差を最小にする値になります.評価式の θ に関する微分は下記のようになります.
f:id:rkoichi2001:20180401153950j:plain

結局は上式,∇θJを0にするようなθを求めることに帰着します.但し,評価式は θ に関しての複雑な閉形式になっており,ストレートに ∇θJ = 0 を解くことができません.そのため,反復計算をします.また,上記の行列式が 0 になるということは,固有値が0となる固有ベクトルが存在するはずで,この固有ベクトルが求めるべき "θ" になります.アルゴリズムの手順を書き出すと....

f:id:rkoichi2001:20180407150022j:plain

θJ = 0 の条件を満たすために,X を固有値分解して最も "影響の小さい" 固有ベクトルを取り出して X を再度固有値分解して,,,,というループでついには X の null space とそれを張る固有ベクトル (=解) が見つかるという流れですが,固有値分解を繰り返すと null space にたどり着くの下りがいまいちピンときてません...が,数学屋さんじゃないので次行きます.

最適化計算0 最尤推定と最小二乗法

最適化計算の勉強をするにあたって,そもそも最小二乗法の下記の評価式
f:id:rkoichi2001:20180331123431j:plain
がどこから来るのかをまとめておきます.参考文献は金谷先生の教科書・PDFです.

1.正規分布と最小二乗法

誤差モデルがガウス分布に従う場合,期待値0,分散 σ2 の誤差 ε の確率密度は下記のようになります.
f:id:rkoichi2001:20180331124254j:plain

実際の例として,,,

長さ15cmの物差しを作る生産工程があったとして,この工程の製造誤差がガウス分布に従っていたとします.この時,1000本の物差しを後から検品するとほぼ15cm(ε = 0)の物差しがほとんどになるはずですが,中には14.9cm(ε = -0.1)だったり15.1cm(ε = 0.1)の物差しが出てくると思います.この時,誤差の分布が上記の図のようになります.つまり,ほぼ 15cm の物差しがほとんどで,誤差が大きいものはほとんどないという形になります.

2.尤度と最尤推定

理論的には y = fθ(x) という数式にしたがう物理現象があるとします.ここで,関係式のパラメータセット θ が不明であり,実験を通してこれらのパラメータを取得しなければならなかったとします.この時,実験データに誤差が全くなければパラメータ個数分データを取得して方程式を解けばパラメータは求まります.しかし実際には実験データは誤差を含むので,複数のデータを取得して評価する必要があります.ここでは,複数データを用いて一番それっぽいパラメータを決定する方法として最尤推定法を導入します.

2.1 誤差のモデル化

パラメータは数式を解いて求まるので,”誤差” をモデル化して数式に乗せてあげないといけません.そこで,下記のようにモデル化します.
f:id:rkoichi2001:20180331140324j:plain

ここで,誤差が期待値0,分散 σ2ガウス分布に従うとすると,誤差が ε になる確率は次のようになります.
f:id:rkoichi2001:20180331131104j:plain

実験データ一つ一つに対して理論式からのズレ(誤差)が定義できて,またそのズレ(誤差)が起こる確率は次のようになります.
f:id:rkoichi2001:20180331140453j:plain

2.3 最尤推定

N個の実験データを取得できているとすると,この”N個の実験データを発生させる確率が最も高いパラメータ”を求めるのが一番自然かと思います.この考え方を最尤推定法”といいます.それぞれの誤差が生じる確率は数式としてわかっていますので,これを掛け算で求めていけば,N個の実験データが生じる確率が下記のように求まり,これを”尤度”といいます.
f:id:rkoichi2001:20180331140656j:plain

ということで,誤差が正規分布に従っていると仮定する場合,上式の
f:id:rkoichi2001:20180331133042j:plain
の部分を最小にしてあげれば確率が最大になることがわかります.着目点として,上記の評価式では分母の σ が定数であるため ∑ の外に出せます.このために,直線当てはめの場合はパラメータの正規化の方法によらず同一解が求まります.

3.最尤推定法を用いた最小二乗法(直線当てはめ)の導出

ここでは,2の最尤推定法の考え方を用いて直線当てはめの評価式を導出してみます.まず,理論式は下記のようになります.
f:id:rkoichi2001:20180331142121j:plain

ここで,数式 Ax + By + C の誤差は y と x 両方によって決まり,y と x のそれぞれの誤差を考慮すると,期待値0,分散 (A2 + B2) σ2の誤差が乗ることになります.つまり,最尤推定法から求まった式に代入すると下記のようになります.
f:id:rkoichi2001:20180331143635j:plain

ここで,直線当てはめに関しては最小化する評価式が上記のようになることがわかりました.直線当てはめの場合は,A2 + B2 + C2 = 1としても,A2 + B2 = 10 としても,A, B, C の定数倍に関しては不変であるので結果が変わらないことがわかります.つまり,下記二つの評価式のどちらを用いても,求まる結果は同じになります.
f:id:rkoichi2001:20180331145051j:plain

上記の説明で明らかになった通り,最小二乗法ではそれぞれの変数に対して誤差モデルに独立な正規分布を仮定し,最尤推定法を用いて取得データが起こる確率が最大になるようにパラメータを求めていることがわかります.

参考文献

参考文献1

3次元コンピュータビジョン計算ハンドブック

3次元コンピュータビジョン計算ハンドブック

参考文献2
画像の三次元理解のための最適化計算[Ⅰ]

つくばチャレンジ2018参加チーム募集

ということで,下記のエントリ
daily-tech.hatenablog.com

を書いてちょうど一年.再びこの時期がやってきました....そうです,つくばチャレンジ2018の参加募集開始です.(正確には 4/6 からエントリが始まるのでまだ参加募集は始まっていませんが.)

今年は3次元復元をマスターして,つくばチャレンジに生かすという大目標があります!が,昨年と同じくなかなか思うようには進まないもんですね...ただ,今年は4回目の参加ということで,完走します (゚Д゚)ノ(と,言わせてください.)

今年は下記の3つをやります!

1.ハードを変える.

 今年で4回目の参加になりますが,ハードを変えます!自分の作りこみが甘かったせいか,接触が悪くて止まったりということが頻発して時間を取られてしまうことが多かったので,思い切ります.で,さすがに今から自作は無理なのでつくばチャレンジ関係者の方が立ち上げてくれている下記サイトの i-Cart mini を使います.自作ロボットをやめるのは,,,,少し寂しいですが,しかたないですね!
t-frog.com

2.レーザースキャナを使う.

 こちら, SI2017 で北陽電機の方とお話しさせていただく機会があり,なんとレーザスキャナを貸していただけることになりました.(北陽電機さん,本当にありがとうございました.この御恩は必ずや...)自腹で買うには結構値が張るのであきらめていたのですが,これと i-Cart mini でひとまず ROS のパッケージをそのまま使ってどの程度動かせるかを見ようと思っています.
www.hokuyo-aut.co.jp

3.画像ベースの3D地図を作成し,カメラで自己位置推定する.

 あくまでも「画像処理だけで完走する!」という当初からのコンセプトは変えずこれからもやっていこうと思っていますが,今年は前年作った画像処理ベースの自己位置推定をもう少し発展させます.具体的にはコースの写真を一眼レフで撮影して3D地図を作成し,ロボットが自走するときにその地図のなかでどこを走っているかを判断させます.今やっている行列の勉強とかもこのためにやっている感じですが,ロボットに応用するところまで持っていけると今年の成果としては花丸です!

まずは試走会一回目(6/30)の基本走行完了をマイルストンとして作業を進めていきます!

ということで,皆様応援よろしくお願いします!!!

最適化計算1 直線の当てはめ 実験編

ということで,下記で理論をまとめたので直線当てはめの実験です.
daily-tech.hatenablog.com

ステップとしては7つあって,下記のステップに沿って実装してます.x

0.直線の係数定義
1.プロット用のデータを生成する.
2.フィッティングする誤差混入データを生成する.
3.生成したデータに対して,正規分布ベースの誤差をのせます.
4.最小二乗法を適用するマトリクス M を計算します.
5.固有値問題を解いて,パラメータベクトルを求めます.
6.最小二乗法で求まった直線(推定直線)を使ってデータを生成します.
7.推定直線のデータをプロットします.

ということで,結果は下記のようになりました.青が正しい直線,緑が推定直線です.当然ながら,誤差の分散を大きくしていくと青と緑の直線が合わなくなってきます.

※一点実装上の注意として!
2日くらいはまったのですが,Ax + By + C = 0 で求める係数のスケールが大きく違う (C >> A や C >> B, C << A や C << B) というような状況になると,丸め誤差の影響が顕著になってきてうまく推定直線が求まりません.これを回避するために,M行列を作成するときにスケーリングを行っています.


誤差分散 0.5
f:id:rkoichi2001:20180329075556p:plain

誤差分散 10
f:id:rkoichi2001:20180329075534p:plain

下記,実験に使った全コードです.

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np

def generateVecFromLine(a, b, c, minVal, maxVal, period):
  nCols = (maxVal - minVal) / period + 1
  
  if abs(a) > abs(b):
    yVec = np.linspace(minVal, maxVal, nCols)
    yVec = np.reshape(yVec, (yVec.shape[0], 1))    
    xVec = - (b / a) * yVec - (c / a)
  else:
    xVec = np.linspace(minVal, maxVal, nCols)
    xVec = np.reshape(xVec, (xVec.shape[0], 1))
    yVec = - (a / b) * xVec - (c / b) 
  
  return np.matrix(np.concatenate((xVec, yVec), axis=1))

def addGaussError(data, avg, stdv):
  dataWError = data + np.random.normal(avg, stdv, data.shape)
  return dataWError
  
def generateMMatrix(data):
  
  xLen = max(data[:, 0])[0, 0] - min(data[:, 0])[0, 0]
  yLen = max(data[:, 1])[0, 0] - min(data[:, 1])[0, 0]
  factor = max(xLen, yLen)
  
  a = np.matrix(factor * np.ones((data.shape[0], 1)))
  P = np.concatenate((data, a), axis = 1)
  return P.T * P, factor
  
def calcLineParamsFromEigenVector(M):
  lamdas, v = np.linalg.eigh(M)
  print(v[:, np.argmin(lamdas)])
  return v[:, np.argmin(lamdas)]
                      
if __name__ == "__main__":
  print("Line Fitting Sample")

  # 0. 直線の係数定義
  A = -0.01
  B = 0.025
  C = 1
  
  # 1. 直線上のデータを生成する.(真値)
  dataOrg = generateVecFromLine(A, B, C, -100, 100, 0.01)

  # 2. 誤差混入用データを生成する.(真値)
  dataSampled = generateVecFromLine(A, B, C, -50, 50, 10.0)  
  fig, ax = plt.subplots(ncols = 1, figsize=(10, 10))
  plt.xlim(-100, 100)
  plt.ylim(-100, 100)
  ax.plot(dataOrg[:, 0], dataOrg[:, 1])
  
  # 3. 真値に対して,誤差を付与する.
  dataWError = addGaussError(dataSampled, 0.0, 5.0)
  ax.scatter(dataWError[:, 0], dataWError[:, 1], s = 2, edgecolors="red")
  
  # 4. 行列 M を作成する.
  M, factor = generateMMatrix(dataWError)
  
  # 5. 固有値問題を解く
  vEig = calcLineParamsFromEigenVector(M)
   
  # 6. 最小二乗法で求まった直線からデータ生成
  dataEstEig = generateVecFromLine(vEig[0, 0], vEig[1, 0], vEig[2, 0] * factor, -100, 100, 0.01)
  
  # 7. 推定直線をプロット
  ax.plot(dataEstEig[:, 0], dataEstEig[:, 1])
  
  fig.show()

  print("vEig : ")
  print(vEig)

  print("M : ")
  print(M)
  
  print("Factor : ")
  print(factor)
  

最適化計算1 直線の当てはめ 理論編

最近の投稿,行列やら最適化やら数学ネタ中心の投稿が続いてますが,これ全部「三次元復元」の理解のためです.おもった以上に数学のハードルが高く,一度きっちりと勉強しようと思いやり始めたらまあ時間がかかること...ここからは最適化の勉強をしていきます.今回の投稿では,ノイズを含むデータに対して直線を当てはめるという一番基本的なケースですが,主に金谷先生・菅谷先生の本・論文を拾い集めてきてまとめます.

1.直線当てはめ問題

実験で取得したデータをプロットしてまとめることって,高校とか大学の実験で結構やったと思います.実験なので所得したデータが何か既知の理論式に支配されているという前提で進めると思うのですが,取得データにはもちろん誤差が含まれるので完全にきれいには直線に乗りません.この時に,エクセルとか使って「一番それっぽい直線」を計算して求めたと思います.この「一番それっぽい直線」を求めるのが直線当てはめ問題です.
f:id:rkoichi2001:20180326072517j:plain

2.一番それっぽい直線とは??

問題設定で「一番それっぽい直線」と書きましたが,「一番それっぽい」の定義を決めてあげないといけません.この種の直線当てはめ問題では,最小二乗法がよくつかわれますが,最小二乗法で使う評価式は下記になります.
f:id:rkoichi2001:20180326073727j:plain

上記の評価式ですが,実験で取得したデータが理論的には何かの直線上 "Ax + By + C = 0" に存在するとしたときに, それぞれの取得データ(点)と直線の距離が最も小さくなるような直線を求めています. ちなみに,直線を "y = ax + b" として最小二乗法を計算すると,評価式は下記のようになります.
f:id:rkoichi2001:20180326075622j:plain

この評価式では,評価データと直線の距離が最も小さくなるような直線ではなく,理論式と実験データの y の値のずれが最も小さくなる直線を計算しています.x を実験時に比較的正確に入力できるような場合はこちらのほうが感覚的には有用な気がしますね.

3.計算方法

計算方法ですが,自分が勉強した感じ,1.評価式の微分を 0 として計算する方法2.評価式を二次形式に変換して固有値問題に帰着させる方法の二つがありましたが,ここでは2の線形代数アプローチで計算方法を求めてみます.

満たしたい方程式

まず,取得データが直線に乗るはずだという前提があると思いますので,下記の連立一次方程式群ができます.
f:id:rkoichi2001:20180326081530j:plain

上記Px = 0 をできる限り満たすベクトル x を求めるために,最小二乗法の評価式を使います.
f:id:rkoichi2001:20180327060935j:plain

式変換から,評価式が二次形式になりました.ここで,PTP=M は実対称行列であり,このことよりMは
1.固有値固有ベクトルすべて実数
2.対角化できる
ので,スペクトル分解して最小固有値を計算してあげれば最小固有値に対応する単位ベクトルが求める直線の係数ベクトルになります.

行列Mのスペクトル分解

n x n の対称行列 M に対して,n個の固有値 λ1, λ2, ... λn が存在し,対応する固有ベクトルは互いに直交するので,この正規直交系を u1, u2, ... un とします.この時,正規直交系からなる行列 U は直交行列であり M は下記のように対角化できます.
f:id:rkoichi2001:20180327061433j:plain

上記スペクトル分解を用いて評価式の二次形式を再度考察します.
f:id:rkoichi2001:20180327063154j:plain

ということで,最小固有値に対する固有ベクトル x が直線のパラメータとなることがわかります.

4.最小2乗法

つまり,,,,整理して書くとこの問題は下記のようになります.
f:id:rkoichi2001:20180327064557j:plain

参考文献

参考文献1

3次元コンピュータビジョン計算ハンドブック

3次元コンピュータビジョン計算ハンドブック

参考文献2
画像の三次元理解のための最適化計算[Ⅰ]

行列の特徴 まとめ

対称行列の特徴

1.対称行列の異なる固有値に対応する固有ベクトルあh互いに直交する.
2.n x n 対称行列の固有値はすべて実数であり,n個の互いに直交する単位ベクトルの固有ベクトル u1, u2, .... un を持つ.