情報学部大学生のダラダラ日記

β日記

機械学習や日記っぽいものを書きます

統計学入門(基礎統計学Ⅰ)第5章演習問題前半

第5章(前半)

5.1<一様分布>

(1)[0,6]上の一様分布の密度関数、期待値、分散 

密度関数{\displaystyle f(x) = \frac{1}{6} (0≦x≦6) } 

期待値{\displaystyle \int_0^6 xf(x)dx = \int_0^6 x\frac{1}{6}dx=3 }

分散{\displaystyle  V(X) = E(X^2)-E(X)^2}を使います。

{\displaystyle E(X^2)=\int_0^6 x^2\frac{1}{6}dx = 12 }

よって

{\displaystyle V(X)=12-3^2=3 }

(2)(1)と同じ確率分布においてチェビシェフの不等式の成立

まず、チェビシェフの不等式を示します。

いかなる不等式においても

{\displaystyle P(|X-μ|≥kσ)≦\frac{1}{k^2} }が成り立つことです。

{\displaystyle μ=3,σ=\sqrt{3} }であるため

{\displaystyle P(|x-3|≥\sqrt{3}k)≦\frac{1}{k^2} }を示せばよいです。

図示すると、

f:id:Parco1021:20200417165422p:plain

このようになるため、青で塗りつぶされた部分の面積が左辺となります。

つまり、

{\displaystyle (左辺)=2*(3-\sqrt{3}k)*\frac{1}{6}=1-\frac{k}{\sqrt{3}} }

よって

{\displaystyle 1-\frac{k}{\sqrt{3}}≦\frac{1}{k^2} }を示せばよいです。

この不等式の証明は面倒くさいので省略しますが、(右辺)-(左辺)をしてk^2>0を両辺に掛けて3次関数にして微分して~ってすればいけます。これによりチェビシェフの不等式が証明できました。

(3)[0,1]上の一様分布の歪度、尖度

{\displaystyle E(X-μ)^3=E(X^3)-3μE(X^2)+3μ^2E(X)-μ^3 }

{\displaystyle μ=E(X) }より

{\displaystyle E(X-μ)^3=E(X^3)-3μE(X^2)+2μ^3 }

歪度(わいど)は

{\displaystyle α^3=\frac{E(X-μ)^3}{σ^3} }から求まる。歪度を求める下準備をする。

{\displaystyle E(X^3)=\int_0^1x^3*1dx=\frac{1}{4},\\E(X^2)=\frac{1}{3},E(X)=\frac{1}{2} }

これらを使って

{\displaystyle E(X-μ)^3=\frac{1}{4}-3*\frac{1}{2}^2*\frac{1}{3}+3*\frac{1}{2}^3=0 }

よって歪度は0

尖度(せんど)は

{\displaystyle α^4-3=\frac{E(X-μ)^4}{σ^4}-3 }(3は正規分布と比較するための数値)

{\displaystyle E(X-μ)^4=E(X^4)-4μE(X^3)+6μ^2E(X^2)-3μ^4\\=\frac{1}{80} }

{\displaystyle σ^2=E(X-μ)^2=E(X^2)-2μE(X)+μ^2=\frac{1}{12} }

よって

{\displaystyle α^4-3=\frac{9}{5}-3=-\frac{6}{5} }

5.2

該当のデータが見つからなかったので省略

5.3<聖ペテルスブルクの逆説>

コインを繰り返し投げ、初めて表がでた時に終了する。n回目である時に {\displaystyle 2^n }円を得ることができる

(1)得られる額Xの確率分布

(2)E(X)は存在しないことを示せ

(1)コインを連続して裏を出し続けると考えると、

{\displaystyle P(X=2^k)=\frac{1}{2^k} }

(2)それでは先ほど求めた確率分布の期待値を出します。

{\displaystyle E(X)=\sum_{k=1}^∞2^k*\frac{1}{2^k}=∞ }

期待値が∞となったため存在しないことの証明となりました。この問題は聖ペテルスブルクの逆説と呼ばれており、直感的な期待値と統計的推測が異なるものです。

数学って面白い!? : 聖ペテルスブルグのパラドクス - livedoor Blog(ブログ)

5.4<最小平均2乗>

 {\displaystyle E(X-a)^2を最小にするa }とその最小値

 {\displaystyle E(X-a)^2=E(X^2)-2aE(X)+a^2 }

ここで、

{\displaystyle E(X-μ)^2=E(X^2)-E(X)^2=σ^2 }より

{\displaystyle E(X^2)=σ^2+μ^2 }

よって

{\displaystyle E(X-a)^2=σ^2+μ^2-2aμ+a^2 }

{\displaystyle E(X-a)^2=(a-μ)^2+σ^2 }

最小値は

{\displaystyle a=μ=E(X)の時、σ^2 }

 

 
後半↓↓

統計学入門(基礎統計学Ⅰ)第4章演習問題(ベイズの定理など)

第4章(確率)

4.1<ド・メレの問題>

(1) サイコロを4回投げる時、6の目が少なくとも1回出る方に掛けるか、出ない方に掛けるか

これは確率の定番の問題ですね。全て6以外の目が出る確率を求めます。1回投げた時、6以外の目が出る確率は5/6であるため

{\displaystyle (\frac{5}{6})^4=\frac{625}{1296}\leq\frac{1}{2} }

となるため、少なくとも1回出る方へかける方が良い。

(2)サイコロを2個同時に24回投げる時、(6,6)の目が少なくとも1回出る方にかけるか否か 

先ほどと同様に解く。 1回投げた時、(6,6)の目が出ない確率は1-1/36=35/36であるため

{\displaystyle (\frac{35}{36})^24≒0.508\geq\frac{1}{2} }

よって出ない方へかけたほうが良い。

4.2<ホイヘンスの14問題>

2個のサイコロを何回投げればそのうちの1回は和が12になる確率が0.9を超えるか 

先ほどの問題と似ています。和が12になる事象=(6,6)が出る事象である。つまり、(6,6)の目が出ない確率1/35をn回投げた時の確率が1-0.9=0.1以下となる最小のnを求めることを目標とする。

{\displaystyle (\frac{35}{36})^n\leq\frac{1}{10} }

これを解くとn=82となる。

4.3

30人を15人ずつ2グループに分ける分け方を求める。30人から15人を選べばもう一方のグループも一意に決まるので

{\displaystyle _{30}C_{15}}通り

4.4

r人いるとして、同じ集団に2人以上同じ誕生日の人がいる確率

今回も、1-(全員誕生日が異なる確率)を求めることを目標とします。

r人と言われるとわかりにくいので小さい具体的な人数で解いてみましょう。

r=2の時、2人の誕生日が異なる確率は364/365です。これは1人の誕生日以外をもう1人が誕生日としていればいいためです。

r=3の時、先ほどの2人が異なる確率364/365にさらにもう1人がその他2人と誕生日が異なればいいため363/365を掛けて{\displaystyle \frac{364}{365}×\frac{363}{365} }のように求めることができる。

同様に考えていくと、r人の時、{\displaystyle \frac{364}{365}×\frac{363}{365}×…×\frac{365-r+1}{365} }となる。

これでr人の誕生日が被らない確率を求めることができたので解は

{\displaystyle 1-\frac{364}{365}×\frac{363}{365}×…×\frac{365-r+1}{365} }

4.5

省略

4.6<ガリレイの問題>

3つのサイコロを投げて目の和が9になる場合と10になる場合は共に6通りしかない。これから、両者の確率は等しいと言えるか。

まず、直感的に考えると等しくなさそうですよね。カタンでも9は大きいけど10は小さいですし。カタンはサイコロ2つでしたね。すんまそん。

ではキチンと考えてみましょう。事象数を考えてみます。

9の場合、

(1,2,6)(1,3,5)(2,3,4)が6通りずつ

(1,4,4)(2,2,5)が3通りずつ

(3,3,3)は1通り

となっています(重複する並びを許さないため)。

では次に10の場合、

(1,3,6)(1,4,6)(2,3,5)が6通りずつ

(2,2,6)(2,4,4)(3,3,4)が3通りずつ

つまりこれから、和が9となる確率と10となる確率は異なり、10の方が高いことがわかる。

4.7<癌の診断>

(1){\displaystyle P(A|C)=P(A^c|C^c)=0.95,P(C)=0.005 }の時、P(C|A)を求めよ

Cは癌である事象であり、Aは検査結果が陽性である事象です。つまり今、癌である確率(事前確率)が0.005とわかっており、癌である時、検査で陽性となる確率が0.95であることがわかっています。ここから検査で陽性である時、癌である確率(事後確率)を求めます。結果から原因の確率を求めるのでベイズの定理を使います。

ベイズの定理

{\displaystyle P(H_i|A) = \frac{P(H_i)*P(A|H_i)}{\sum P(H_i)*P(A|H_i)} }

今回、原因である{\displaystyle H_iはCとC^c }があることに注意して解きます。

{\displaystyle P(C|A) = \frac{P(C)*P(A|C)}{P(C)*P(A|C)+P(C^c)*P(A|C^c)} }

上式に、{\displaystyle P(C)=0.005,P(C^c)=1-0.005=0.995, }

{\displaystyle P(A|C)=0.95,\\P(A|C^c)=1-P(A^c|C^c)=1-0.95=0.05 }

を代入すると

{\displaystyle P(C|A) = \frac{0.005*0.95}{0.005*0.95+0.995*0.05}≒0.087 }となる。計算は小数ではなく分数で計算しましょう。低いですね。

(2) (1)において、{\displaystyle P(A|C)=P(A^c|C^c)=R,P(C)=0.005 }である時、{\displaystyle P(C|A)\geq0.9 }となるRの範囲を求めよ

 同様にベイズの定理を使います。

{\displaystyle P(C)=0.005,P(C^c)=1-0.005=0.995, }

{\displaystyle P(A|C)=R,P(A|C^c)=1-P(A^c|C^c)=1-R }を代入すると

{\displaystyle P(C|A) = \frac{0.005*R}{0.005*R+0.995*(1-R)}\geq0.9 }

これを解くと、{\displaystyle R\geq0.9995 }となり、非常に高い精度が求められることがわかる。

 

統計学入門(基礎統計学Ⅰ)第3章演習問題(ブートストラップ法など)

第3章(2次元データ)

3.1

データが多く、面倒くさいのでやりません。散布図を求め、相関係数を求める問題は多くあるのでそちらをやりましょう。

3.2

タバコと肺がんの関係は統計的にあることが証明されているが、自分が喫煙者としてどう正当化すべきか、との問題でしたが思い浮かばないので省略します。

3.3

4グループ*30位の順位づけデータがあり、それぞれ好きな組み合わせでスピアマン、ケンドールの順位相関係数を求めよ。

スピアマンの順位相関係数

{\displaystyle r_s=1-\frac{6}{n^3-n}\sum_i(R_i-R_i')^2}

6が出てくることに違和感がありますが、これは順位(1,2,...n)の2乗の和、つまりΣn^2の1/6からきています。詳しい導出方法は別途ご覧ください。

スピアマンの順位相関係数 統計学入門

ケンドールの順位相関係数

i,j(1,2,...n)があり、{\displaystyle R_iとR_j}の上下関係が同じである場合には+1,異なる場合には-1とします。それらをすべての組み合わせ{\displaystyle nC_2}パターン全て行い、加算したものをGとすると

{\displaystyle r_k=\frac{G}{n(n-1)/2}}

分母はn個から2個選ぶnC2からきています。

 

これらの相関係数からわかる通り、30順位をやるのは骨が折れるので5まで圧縮します。以下のデータの数値は危ないと思う技術や行動の順位です。

カラム={原子力,自動車,銃,喫煙,バイク}

A={1,2,3,4,5}

B={1,4,2,3,5}

これのA,Bの順位相関係数を求めます。

{\displaystyle r_s=1-\frac{6}{5^3-5}((1-1)^2+(2-4)^2\\+(3-2)^2+(4-3)^2+(5-5)^2)=0.7}

次はケンドールの順位相関係数を求めます。

(1,1)と(2,4)は+1

(1,1)と(3,2)は+1

(1,1)と(4,3)は+1

(1,1)と(5,5)は+1

(2,4)と(3,2)は-1

(2,4)と(4,3)は-1

(2,4)と(5,5)は+1

(3,2)と(4,3)は+1

(3,2)と(5,5)は+1

(4,3)と(5,5)は+1

全て足すと8-2=6です。

{\displaystyle r_k=\frac{6}{5(5-1)/2}=0.6}

3.4<ブートストラップ>

まず、乱数を生成しサンプリングをし、さらにサンプル内の相関係数を求めるプログラムを書きます。

f:id:Parco1021:20200409174009p:plain

そして次にこれを200回繰り返し、相関係数ヒストグラムを作ります。

f:id:Parco1021:20200409174215p:plain

f:id:Parco1021:20200409174239p:plain

このように、母集団から標本を繰り返し抽出し、母集団の性質を推定する方法をブートストラップ法といいます。本データではサンプリングして相関係数を求めた結果、大体0.5ぐらいであることがわかります。

 

今回のコードもgithubへあげています。

github.com

 

 

 

 

 

統計学入門(基礎統計学Ⅰ)第2章演習問題

はじめに

今回は統計学入門(東京大学出版)の第2章の演習問題を解いていきます。

※注意※

本書には解答のみ載っており、導出過程が書かれていません。そのためこのような記事を書こうと思いました。筆者は統計については勉強中ですので誤り等ありましたら教えていただけると嬉しいです。

第2章

2.1は調べても出て来なかったので省略します。

2.2<ジニ係数>

データ{\displaystyle x_1,x_2,...x_n}がある時、

{\displaystyle \sum_i^n\sum_j^n|x_i-x_j|/n^2}

平均差と言います。つまり、全ての要素の組み合わせの差の絶対値の平均です。なので差の平均ですね。

 

{\displaystyle \sum_i^n\sum_j^n|x_i-x_j|/2n^2\overline{x}}

ジニ係数と言います。

詳細は以下のサイトを見てください。ザックリいうと"どれだけ不平等か"を示す時に使われるものです。

bellcurve.jp

今回はA:0,3,3,5,5,5,5,7,7,10

B:0,1,2,3,5,5,7,8,9,10

C:3,4,4,5,5,5,5,6,6,7

について平均差とジニ係数を求めます。それぞれ手計算で平均差を計算してもいいのですが、さすがに10*10の100通りを3回やるのは面倒なのでスクリプトを書きました。

f:id:Parco1021:20200405223347p:plain

わざわざ関数にする必要はなかったのですが、平均差とジニ係数それぞれわかりやすくするためにしました。定義通り計算していくだけです。

 

2.3<エントロピー>

エントロピーとは簡単に言うとどれだけ乱雑かをしめすものです。

{\displaystyle H(p_1,p_2,...p_k) = -\sum_i^kp_ilogp_i}

の形で示されます。{\displaystyle p_i}は相対頻度です。つまり総データ数100においてある事象が10回である時、{\displaystyle p_i=10/100}となります。また、対数の底は2か10を使うのが一般的です(今回は10としています)。

問題は与えられたデータ(現在と10年前の学生100人の出身地のデータ)を集中性の観点から分布を比較せよ、というもの。これには先に述べた通りエントロピーを使う。

f:id:Parco1021:20200405224304p:plain

 この出力からわかる通り、現在も10年前においてもエントロピー、つまり集中性はあまり変化していない。よって現在も10年前も出身地のバラつきはあまり変化していないといえる。

 

2.4<諸得点>

2.2におけるBについて、標準得点と偏差値得点を求める。

標準得点は各データを{\displaystyle z_i=(x_i-\overline{x})/s}とすることである。このようにすることで調整後の平均は0となり、標準偏差sは1となる。

 

偏差値得点は先ほど導出した{\displaystyle z_i}をさらに{\displaystyle T_i=10z_i+50}とすることである。これにより聞き馴染みのある偏差値を導出することができる。平均は50となり標準偏差は10となる。

f:id:Parco1021:20200405225641p:plain

確認のため変更後の平均と標準偏差も求めなおしてみました。0.99999となっていたり、2.22e-17(=2.22^10^-17)となってしまっていますがそれはビット数の都合で省略されてしまっているからです。キチンと出力できているように思えます。

 

あとがき

今回はお試しで2章を解いてみました。想像以上に時間がかかってしまったので3章以降で同様の記事を書くかどうかは決めていません。

 

演習問題の各コードはgithubに挙げておきます。参考までに。

github.com

 

 

【参考書感想】Pythonで動かして学ぶ!あたらしい機械学習の教科書第2版

はじめに

機械学習を学ぶにあたり、少しですが何冊か参考書を読んだのでこれから何回かにわけて感想を書いていきたいと思います。

今回は僕が機械学習系統で初めて読んだ本です。

 

読んだ当時、参考程度に僕は

  • 機械学習機械学習と深層学習って何が違うの??モデル???ナニソレ
  • Python→趣味で少し触った程度。参考書等は読んだことがない

 

紹介 

本書のコンセプトはタイトル通り「機械学習Pythonで実際に手を動かしながら勉強しよう!」です。

対象者は読んでみた限りですがPythonについて何も知らなくてもいいと思います。機械学習については無知で構いません。自分がそうだったので。そこから十分本書を理解できます。

はじめに結論を言いますが、本書は自分的に入門書としてかなり良書だと思っています。理由は追々。

目次

自分は5~7章、9章を重点的に読みました。

Pythonの環境すらない方も読者の対象なので安心です。第1章でPythonの導入をします。本書ではAnaconda、Jupyter Notebookを使います。

2章ではPythonの基本を学びます。if文や四則演算、リストなど簡単なものを学びます。

4章では機械学習に使用する数学、線形や微積Pythonのコードではどのように記述するのかなどを記しながら丁寧に説明してくれます。大学で数学を履修していない方でも読むことができると思います。さすがに高校数学はある程度できないとアレかもしれませんが…。

と、ここまで機械学習のための準備の章が4つありましたがこれだけで150ページ弱かけて丁寧に書かれています。

あとは目次通りの内容です。

感想

はじめに良書だといいました。それは全体を通じて計算過程がほとんど省略されておらず、「なんでこの変形になった!?」と困惑することもストレスとなることも少なかったからです。また、図も多くの場面で説明として使われています。さらに当然本書のコンセプトであるPythonのコードでの説明もされています。これにより図、数式、コードの多方面から理解することが可能です。

parco1021.hatenablog.com

 

実際この辺の記事は参考文献にも挙げている通り本書を参考にして書いています。当然読んでいるだけでは理解が難しいところもあるので本書を見ながら紙に数式を書き自分で解いて~とすることで理解が深まります。

注意点として本書の主は教師あり学習・深層学習なので教師なし学習についてはクラスタリングのことのみ書かれており、強化学習については書かれていません。

また、僕自身機械学習のお勉強を始めて数カ月しか経っていません。本書がどの程度網羅できているかはわかりません。あくまで本書に書かれている範囲はとても丁寧に記述が為されておりわかりやすかったということです。

 

さいごに

本書は入門書としてとても良いと思います。おそらく立ち位置はオライリーのゼロから作るディープラーニングと同じです。あちらは訳本ですので合う合わないがあると思います(僕は合いませんでした)。そういった方にもおすすめです。

 

 

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

VAEを理論的に理解する

はじめに

今回は、VAE(Variational AutoEncoder)について数式面のみのアウトプットをしたいと思います。VAEとはなんたるか、実装方法等には触れません。そこではじめに参考文献を示します。

参考文献

Variational Autoencoder徹底解説 - Qiita

AutoEncoder, VAE, CVAEの比較 〜なぜVAEは連続的な画像を生成できるのか?〜 - Qiita

オートエンコーダ:抽象的な特徴を自己学習するディープラーニングの人気者 - DeepAge

猫でも分かるVariational AutoEncoder

イェンセン(Jensen)の不等式の直感的理解 - Qiita

正規分布間のKLダイバージェンス - Qiita

本題

初めに目的を明確にしましょう。下に簡単なVAEのモデルを示します。

 

f:id:Parco1021:20200223170120p:plain

 

{\displaystyle EncoderへXを入力します。そして潜在変数zのためのパラメータμおよびσを出力します。}

{\displaystyle そしてzをDecoderへ入力することで本来求めたい\hat{X} を出力します。}Encoderで直接潜在変数{\displaystyle z}を生成するのではなく、{\displaystyle zのためのパラメータμとσ}を生成することが重要です。

ここで推定したいモデルはDecoder側の{\displaystyle p(X)}ですね。この{\displaystyle p(X)}の尤度(尤もらしさ)を最大にするパラメータ{\displaystyle θおよびϕ}最尤推定法を用いて求めます。

また、色々都合がいいので対数尤度{\displaystyle logp(X)}を最大にします。

f:id:Parco1021:20200223175638p:plain

1行目は確率の加法定理を用いています。同時分布{\displaystyle p(X,z)においてz}について加算すると{\displaystyle X}の分布になるということですね。
2行目は{\displaystyle \frac{q(z|X)}{q(z|X)}=1}を掛けているだけです。

3行目はイェンセンの不等式を使いました。上に凸な関数{\displaystyle f(x)}において{\displaystyle f(E[x])≥E[f(x)]}が成り立つといったものです。

4行目は変分下限を新しく定義しました。変分下限はELBO(evidence lower bound)とも呼びます。複雑な確率分布において周辺尤度は厳密には計算することができません。よって周辺尤度の下限{\displaystyle L(X,z)}をなるべく大きくすることで{\displaystyle logp(X)}へ近づけます。下からすくっていくイメージですね。

 

では対数尤度と変分下限の差は何を示すのかを確認しましょう。

f:id:Parco1021:20200223190656p:plain

{\displaystyle KL[]}KLダイバージェンスと言います。簡単に言うと両者の距離を表すものですが絶対値は取らないので厳密な距離ではないことには注意してください。

2行目の第1項は{\displaystyle \int q(z|X)dz=1}を掛けているだけです。

3行目の第1項は{\displaystyle p(X)}{\displaystyle z}に依存しないため積分記号の内へ入れています。第2項は乗法定理から{\displaystyle p(X,z)=p(z|X)p(X)}を代入しています。

4行目は{\displaystyle log}を分解しています。そしてこれから第1項が消えることがわかります。

6行目は対数をまとめています。

 

ここでもう一度変分下限について整理してみます。

f:id:Parco1021:20200223211235p:plain

{\displaystyle logp(X)}は固定値であるため目的とする"L(X,z)を最大化すること"は'第2項を最小化すること'と同義となりました。

では第2項に着目してみましょう。

f:id:Parco1021:20200225214501p:plain

最小化したい第2項がさらに3つの項へ分解されました。

2行目はベイズの定理{\displaystyle p(X|Y)=\frac{p(Y|X)p(X)}{p(Y)}}を代入し、対数の法則から分解しました。

3行目はまず{\displaystyle p(X)}{\displaystyle q_φ(z|X)}に依存しないため期待値の外へ出します。そして今後のために{\displaystyle logp_θ(X|z)}を別で記述します。

3行目の第1項がKLダイバージェンスの記述ができるので4行目において置き換えています。

これを最小化したいのですが少しよくわからないので変分下限の式に代入してみましょう。

f:id:Parco1021:20200225214731p:plain

代入することで{\displaystyle logp(X)}が消えました。この式を最大化(変分下限は最大化、先ほどのKLダイバージェンスは最小化)したいのでしたね。そのために第1項を小さくし、第2項を大きくしたいということです。それでは各項に注目します。

第1項

第1項は正則化項(Regularization Parameter)です。KLダイバージェンスの形をしているので当然{\displaystyle p(z)}{\displaystyle q(z|X)}の分布が近ければ近いほどこの値は小さくなります。

f:id:Parco1021:20200225215521p:plain

 

2行目~3行目の導出は正規分布のKLダイバージェンスの導出となり複雑なので理解しなくていいと思います。一応リンク載せます。

qiita.com

 

第2項

f:id:Parco1021:20200225212223p:plain

まずは直感的に理解してみましょう。{\displaystyle q(z|X)}はencoder部分で{\displaystyle p(X|z)}はdecoder部分です。つまりencoderに関してdecoderの対数尤度を求めているということです。これからわかるように当然この式は最大化したいものということです。

画像の各ピクセルを0~1に調整し、ベルヌーイ分布を仮定するとlog{\displaystyle p(X|z)}は以下のようになります。

f:id:Parco1021:20200225213927p:plain

{\displaystyle y}はNNの出力です。

 

 

第1項は潜在変数の事前分布とencoderの分布の差を示す。正則化項。

第2項は入出力の差。

 

 

最後に図としてまとめます。

f:id:Parco1021:20200225220354p:plain

このφおよびθを学習します。 

 

しかしこのままだと確率分布を経由しているため誤差逆伝播法を使用することができません。なので{\displaystyle ε~N(0,I)}としてノイズを発生させ、{\displaystyle z=μ+εσ}とすることで確率分布を経由せずに誤差を逆伝播させることが可能となります。この手法をReparameterization Trickといいます。

 

さいごに

いかがでしたでしょうか。僕自身この確率分布だ~なんだ~の部分はとても苦手としているので非常に理解に時間がかかりました。VAE自体は少し前の技術なのですが今もなお研究が行われているそうですね。僕の卒業研究の選択肢の1つとなりそうです。

是非とも上記のQiita等もご覧になって多くの記事を参考にしてみてください。添え字等間違っていることがあったら(こっそり)教えてください。

 

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

線形基底関数モデルの最適解

はじめに

前回、D次元の線形回帰モデルを解きました。

parco1021.hatenablog.com

話を1次元に戻します。線形回帰モデルを解くとイメージとしては下図のようになります。

f:id:Parco1021:20200206165132p:plain



{\displaystyle y=ax+b }の形ですね。しかしこの分布を見ているとこのようにも見えると思います。

f:id:Parco1021:20200206165016p:plain

汚くてすみません!!

このように、直線よりも曲線を用いた方がより分布に合っています。基底関数を用いてこのような曲線の関数を導出することが線形基底関数モデルの考え方です。

基底関数

まず基底関数について説明します。読んで字の如く関数を表現するためのベース、つまり基底となる関数です。もっとざっくり言うとグニャグニャしている線(曲線)を基底関数を組み合わせて表現しよう!といった感じです。…???同じことを言ったような気がしますが次第にわかると思います。

ガウス基底

{\displaystyle Φ_j(x)=exp\left\{-\frac{(x-μ_j)^2}{2s^2}\right\} }

f:id:Parco1021:20200206171820p:plain

引用元:ガウス関数

ただのガウス関数(正規分布)ですね。{\displaystyle s }は分散のようなイメージでいいと思います。つまり大きくするとそれだけ広範囲に影響が出ます(=グラフの山が潰れて広がるイメージ)。広範囲に影響を及ぼすことはよろしくないので小さい方が望ましいと思います。小さすぎるのもアレだけど。。。{\displaystyle μ_j }ガウス関数の中心位置ですね(山のテッペンの位置)。{\displaystyle s,μ_j }ともに設計者が決めるパラメータで変数は当然{\displaystyle x }のみです。

 

多項式基底

{\displaystyle Φ_j(x)=x^j }

つまり{\displaystyle Φ(x)=1,x,x^2,x^3・・・ }となるわけです。こちらの方が馴染みがあるので扱いやすいかもしれません。

 

解いてみよう

まず、今回解く対象である線形基底関数モデルを明記します。

{\displaystyle y(x,\boldsymbol{w})=\sum_{j=0}^{M} w_jΦ_j(x)=\boldsymbol{w}^T\boldsymbol{Φ}(x) }

ここで、{\displaystyle M }対象となるデータを何分割して基底関数を使うかを示しています。そして{\displaystyle w }は重みを表しています。つまり、M=3であるとしたら対象のデータをx軸方向に3分割して分割したそれぞれに適した重みwを計算します。そして導出した最適な重みを先ほど述べた基底関数に掛けることで曲線を実現させます。当然分割した各々は干渉し合います。

…わかりにくいですね。図示します。

f:id:Parco1021:20200206203406p:plain

 

フリーハンドですみません…。このように、M=3であるため3つのガウス基底で表現を試みます。この3つ各々に重みwを掛けて"いい感じ"にします。最後の項{\displaystyle w_3とΦ_3(x) }は係数のための処理です。

 

それでは、重み{\displaystyle \boldsymbol{w} }の最適解を求めていきましょう。タイトルの通り平均二乗誤差Jを使います。

{\displaystyle J(\boldsymbol{w})=\frac{1}{N}\sum_{n=0}^{N-1} (y(x,\boldsymbol{w})-t_n)^2=\frac{1}{N}\sum_{n=0}^{N-1} (\boldsymbol{w}^T\boldsymbol{Φ}(x)-t_n)^2 }

この形、どこかで見覚えがありませんか???そう、線形回帰モデルと同じ形をしています。

{\displaystyle J(\boldsymbol{w})=\frac{1}{N}\sum_{n=0}^{N-1} (\boldsymbol{w}^T\boldsymbol{x}_n-t_n)^2 }parco1021.hatenablog.com

 

{\displaystyle \boldsymbol{x}_nが\boldsymbol{Φ}(x) }へ変わっただけですね。なのでほとんどの処理は線形回帰モデルのものを応用できそうです。

  • 1次元データ{\displaystyle x_nをM次元(≒何分割するか)のベクトル\boldsymbol{Φ}(x_n) }に変換
  • {\displaystyle M次元入力された各入力\boldsymbol{x}_n }に対して線形回帰モデルを解く

以上のようにすることで線形回帰モデルと同様に処理することが可能であると考えられます。

つまり{\displaystyle 重み\boldsymbol{w} }の最適解は

{\displaystyle \boldsymbol{w}=(\boldsymbol{Φ}^T\boldsymbol{Φ})^{-1}\boldsymbol{Φ}^T\boldsymbol{t} }

となります。但し、

f:id:Parco1021:20200206202538p:plain

このような基底関数をN行M列に並べたものを計画行列(デザイン行列)と言います。

今回はxを一次元入力としましたが、仮にxが多次元であっても{\displaystyle x_n→\boldsymbol{x}_n }とすることで同様に扱うことができます。

 

参考文献

Pythonで「線形回帰」と&quot;確率版の線形回帰&quot;である「ベイズ線形回帰」 - Qiita

第9回 線形回帰[後編]:機械学習 はじめよう|gihyo.jp … 技術評論社

計画行列(デザイン行列)とは何か:PRML編 - 北野坂備忘録

ガウス基底モデル(μ, σランダム調整モデル)

 

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

D次元線形回帰モデルを平均二乗誤差を用いて解く

※自分のはてなブログの編集都合上、行列表現がTexで表現できないため画像を挿入します。すみません。※

導入

線形回帰モデルとは

例えば直線モデルについて考えてみます。以下の図を見てください。

 

f:id:Parco1021:20200203134035p:plain

引用元:線形単回帰分析の仕組みをわかりやすく解説! | 全人類がわかる統計学

 

散らばっている点を"それっぽい"直線にしています。直線の式であるので{\displaystyle y(x)=w_0x_o+w_1 }といった形になっています。この{\displaystyle w_1およびw_0 }を求めることが「線形回帰モデルを解く」ということです。

 

本記事の目的

では、本記事の目的を明確にします。先に紹介した直線モデルは1次元モデルであり、それぞれ{\displaystyle w_0,w_1 }を求めることは難しくないです。しかしこれが2次元、3次元あるいはより高次元となった場合にも解くことは可能でしょうか?逐一解いてみても良いと思いますが本記事では高次元である{\displaystyle D }次元を想定します。

今回解く対象の{\displaystyle D }次元線形回帰モデルを示します。

{\displaystyle y(\boldsymbol{x})=w_0x_0+w_1x_1+・・・+w_{D-1}x_{D-1}+w_D }

{\displaystyle w_D }は切片を表します。今回は切片を省略し、以下の式を対象とします。

{\displaystyle y(\boldsymbol{x})=w_0x_0+w_1x_1+・・・+w_{D-1}x_{D-1} }

対象の式をより簡略化して書きたいと思います。行列表記を用いると

f:id:Parco1021:20200203155302p:plain

この{\displaystyle \boldsymbol{w} }が今回着目する文字です。所謂"重み"に似たやつです。

 

では早速解いてみましょう。今回、平均二乗誤差{\displaystyle J }で解きます。

f:id:Parco1021:20200203161319p:plain

ここで目的を明確にしておきます。目的は{\displaystyle y(\boldsymbol{x}) }を誤差の少ない関数とすることです。具体的には損失関数{\displaystyle J }を最小とする最適な{\displaystyle \boldsymbol{w} }を見つけることです。最小とする、つまりみんな大好き微分をします。

行列の計算に慣れていない方はここから紙とペンで実際に解きながら読むことをおすすめします。

 

解く

では早速{\displaystyle w_i }微分しましょう。

f:id:Parco1021:20200203180553p:plain

{\displaystyle w_i }微分すると{\displaystyle x_{n,i} }となることに注意すると

f:id:Parco1021:20200203180052p:plain

となります。注意ですが{\displaystyle x_{n,i} }のnはデータ数、iは(0~D-1)をとります。

{\displaystyle Jを最小にするwは、全てのw_iに対して傾きが0すなわち偏微分したら0となります。このwを求めます。 }

f:id:Parco1021:20200203181517p:plain

このまま{\displaystyle \boldsymbol{w} }について解いてしまいたいですが{\displaystyle x_{n,i} }が邪魔ですね。この方程式は全ての{\displaystyle i }において成り立つため、

f:id:Parco1021:20200203182027p:plain

 となります。ここからさらにわかりやすくするためにベクトル表現でまとめると、

f:id:Parco1021:20200203182555p:plain

簡略化すると、

f:id:Parco1021:20200203183045p:plain

分配法則を用いて、

f:id:Parco1021:20200203183346p:plain

f:id:Parco1021:20200203184353p:plain

このままではΣが邪魔で解きにくいですね。行列表現を用いてΣを消すように試みましょう。

f:id:Parco1021:20200204121601p:plain

f:id:Parco1021:20200204122042p:plain

新しく{\displaystyle \boldsymbol{X} }を導入することでΣを無くすことができました。

では、同様にして第2項も簡略化しましょう。

f:id:Parco1021:20200204123603p:plain

Σを消すことができたので元の方程式を置き換えてみます。

f:id:Parco1021:20200204124749p:plain

あとはこれを{\displaystyle \boldsymbol{w} }について解きます。まずは両辺転置を取ります。

f:id:Parco1021:20200204170848p:plain

これをガンガン解いていきます。

f:id:Parco1021:20200204172327p:plain

これがD次元線形回帰モデルの解です。この式を用いるとxが何次元であっても、すなわちDが何であっても最適な{\displaystyle \boldsymbol{w} }が得られます。お疲れさまでした。

切片を無視していましたね。あと少しです。

切片がある時

では、切片がある時を考えましょう。切片がある時ってどういう時でしょう?初めに示した式を再掲します。

{\displaystyle y(\boldsymbol{x})=w_0x_0+w_1x_1+・・・+w_{D-1}x_{D-1}+w_D }

これを以下のように見ます。

{\displaystyle y(\boldsymbol{x})=w_0x_0+w_1x_1+・・・+w_{D-1}x_{D-1}+w_Dx_D }

この{\displaystyle w_Dが切片ですね。このw_Dを常に出力させたいのでx_Dを常に1とすれば良いのです。このようにD+1次元目のxを常に1とすることで切片を実現させることが可能です。 }つまりD次元線形回帰モデルの解は変えなくて良いです。

 

さいごに 

行列の諸々を忘れていて理解に少し時間がかかってしまいました。しかし1つ1つ紐解いていくと徐々に理解ができて楽しかったです。

 

まとめ

D次元線形回帰モデル

{\displaystyle y(\boldsymbol{x})=w_0x_0+w_1x_1+・・・+w_{D-1}x_{D-1} }

f:id:Parco1021:20200203155302p:plain

の解は

f:id:Parco1021:20200204175037p:plain

但し、

f:id:Parco1021:20200204175133p:plain

 

参考文献

最小二乗法の解の導出 - 機械学習に詳しくなりたいブログ

 

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

 

 

 

誤差逆伝播法についてできるだけ丁寧に初心者がまとめる

導入

はじめに

勾配法において、損失関数を重みにおいて偏微分しそれを用いて重みを更新します。その手法の一種として以前に数値微分法という微分の定義に基づき、近似を用いることで勾配を求める手法をまとめました。今回は勾配を求める手法の1つとして誤差逆伝播法についてできるだけ丁寧にまとめたいと思います。僕自身その道について未だ初心者であるので同じような方の助けになれば幸いです。

parco1021.hatenablog.com

 

おねがい

本記事は勉強中の筆者が書いたものです。ゆえに少し解釈違いがあったり、文字が違っていたりするかもしれません。そういった場合にはコメントまたは下の問い合わせフォームから教えていただけると幸いです。

また、誤差逆伝播法を学ぶにあたり文章を読むだけでなく手元に紙とペンを用意して数式を書きながら読んでいただければ理解が捗ると思います。

誤差逆伝播法って聞くと…??

僕は未だ自分でモデルを組む等したことがありません。なので誤差逆伝播法についての認識は"勾配を求めるいい感じの方法"ぐらいでしかないです。その認識は実際に使ってみないと変わらないと思うので今のところはこれで良しとします。

大学の講義や教科書でのBackpropの説明はほとんど,「教師あり学習の文脈で多層パーセプトロンを識別器あるいは関数近似器として訓練する」という文脈でなされます.そのため,初学者はBackpropは教師あり学習のためのアルゴリズムであると誤解してしまうケースが多々あるのではないかと思います.しかし後で説明する通り,Backpropは単に損失関数の微分を効率的に計算する手法の1つであって教師あり学習とか教師なし学習とかは関係ありません

引用元:https://qiita.com/Ugo-Nama/items/04814a13c9ea84978a4c#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB

だそうです。僕は講義で習っておらず、現場でも使っていないのでその誤認はしていないので気を付けます。

ニューラルネットモデル

今回扱うニューラルネットモデルを以下に示します。

f:id:Parco1021:20200112181056p:plain

 今回は、簡略化のために中間層を1層とします。それぞれの変数の定義をします。

  • {\displaystyle x }…入力
  • {\displaystyle v,w }…重み
  • {\displaystyle h(),g() }…活性化関数
  • {\displaystyle b_j=\sum_{i=0}^{D} w_{ji}x_i }

→前の層からの出力(x)に重み(w)を掛けたものを全ての矢印において行っている

  • {\displaystyle z_j=h(b_j) }

→先ほど求めたbを活性化関数に引数として渡す。これにより求めたzが次の層へ渡される

  • {\displaystyle a_k=\sum_{j=0}^{M} v_{kj}z_j }
  • {\displaystyle y_k=g(a_k) }
  • {\displaystyle t_k }…教師データ

{\displaystyle δ }については後述します。

 

誤差逆伝播

では、誤差逆伝播法についてやっていきましょう。誤差逆伝播は簡単に言うと、出力層の重み{\displaystyle v }を更新してから中間層の重み{\displaystyle w }を更新するように、入力層→出力層ではなく、出力層→入力層へと流れていく様子からこの名前が付けられました。バックプロパケーション誤差逆伝搬法とも呼ばれます。

最終的にバックプロップによって最小化したい損失関数は以下のようになります。

{\displaystyle E(v,w)=\frac{1}{N}\sum_{n=0}^{N-1} E_n(v,w) }

この式の意味するところは損失関数を学習に使うデータ数{\displaystyle N }だけ足して平均したものが目的となる関数であるということです。

この関数を最小化するために勾配を求めます。つまり各データ{\displaystyle n }に対する勾配{\displaystyle \frac{∂E_n}{∂w} }を得なければなりません。求めて平均をとることで{\displaystyle \frac{∂E}{∂w} }が得られます。当然、{\displaystyle wだけでなく、v }における勾配も求める必要があります。

{\displaystyle \frac{∂E}{∂v} }を求める

連鎖律を用いて{\displaystyle \frac{∂E}{∂v}を求めます。 }

{\displaystyle \frac{∂E}{∂v}=\frac{∂E}{∂a}\frac{∂a}{∂v} }

となるのでそれぞれ分解します。繰り返しになりますが、{\displaystyle v }{\displaystyle jk }間の重みであり、{\displaystyle aはj層 }からの入力総和です。

まず、

{\displaystyle \frac{∂a}{∂v}=\frac{∂}{∂v_kj}(\sum_{j} v_{kj}z_j)=\frac{∂}{∂v_kj}( v_{k0}z_0+v_{k1}z_1+…v_{kj}z_j) }=z_jとなります。

次に、

{\displaystyle δ^{(2)}_k= \frac{∂E}{∂a} }とすると

{\displaystyle \frac{∂E}{∂v_kj}=δ^{(2)}_kz_j}となり簡単な式になりました!

f:id:Parco1021:20200130171048p:plain>ちょっと待ちなさい!{\displaystyle δ^{(2)}_k}っていったいなんなのよ!

ごめんなさいお母さん!!

{\displaystyle δ^{(2)}_k= \frac{∂E}{∂a}=\frac{∂E}{∂y}\frac{∂y}{∂a}=\frac{∂E}{∂y}g'(a) }

{\displaystyle \frac{∂y}{∂a} }{\displaystyle y=g(a) }となっているので当然ですね。例えば損失関数を二乗誤差とし、係数など諸々を無視する{\displaystyle \frac{∂E}{∂y}は大体y-t }となります。{\displaystyle yは出力であり、tは教師データです。}ゆえに概要としては結合先で生じた誤差に関する変数といった感じです。

つまり、{\displaystyle \frac{∂E}{∂v_kj}は、}結合元のニューロンの出力{\displaystyle z_j}と結合先での誤差{\displaystyle δ^{(2)}_k}を掛けたものであることがわかります。

重みの更新規則は

{\displaystyle v^{r+1}_{kj}=v^r_{kj}-α\frac{∂E}{∂v_{kj}}=v^r_{kj}-αδ^{(2)}_kz_j}となります。{\displaystyle αは定数です。}

以上で重み{\displaystyle v}については終わりです。次は中間層周りの重み{\displaystyle w}についてです。

 

{\displaystyle \frac{∂E}{∂w} }を求める

では{\displaystyle \frac{∂E}{∂w}}を求めていきましょう。数式が一見複雑そうに見えますが、内容としてはこれまでと同様レベルです。一緒に頑張りましょう。

{\displaystyle \frac{∂E}{∂w}=\frac{∂E}{∂b}\frac{∂b}{∂w} }となります。

ここで先ほどと同様に結合先への総和{\displaystyle b}があるので

{\displaystyle \frac{∂E}{∂b}=δ^{(1)}_j}とします。

{\displaystyle \frac{∂b}{∂w}=\frac{∂}{∂w_ji}(\sum_{i} w_{ji}x_i)=\frac{∂}{∂w_ji}( w_{j0}x_0+w_{j1}x_1+…w_{ji}x_i) =x_i}

よって

{\displaystyle \frac{∂E}{∂w}=δ^{(1)}_jx_i }となり、先ほど同様簡単な形になりました!

f:id:Parco1021:20200130171048p:plain

 

…はい。例のごとく{\displaystyle δ^{(1)}_j}が何を指すのか調査しましょう。k層があるのでΣを用います。

{\displaystyle δ^{(1)}_j=\frac{∂E}{∂b}=\sum_{k}\frac{∂E}{∂y_k}\frac{∂y_k}{∂a_k}\frac{∂a_k}{∂z_j}\frac{∂z_j}{∂b_j}}

{\displaystyle \frac{∂E}{∂y}\frac{∂y}{∂a}=δ^{(2)}_k }であり、{\displaystyle \frac{∂a}{∂z}=v_{kj} }であり、さらに{\displaystyle \frac{∂z}{∂b}= h'(x)}となります。

これらを用いると{\displaystyle δ^{(1)}_j }

{\displaystyle δ^{(1)}_j=h'(b_j)\sum_{k}v_{kj}δ^{(2)}_k }となります。

この式と以下の図に着目してみてください。本来のNNは入力層→出力層(左から右)へと処理が為されるのに対し、中間層の{\displaystyle δ^{(1)}_j}を求めるために出力層から{\displaystyle δ^{(2)}_k}と中間層~出力層間の重み{\displaystyle v}を掛け合わせたものを逆方向へ伝達させていることがわかります。

{\displaystyle δ^{(2)}_k}は先ほども述べた通り出力層の誤差です。誤差を逆方向へ伝播させていることから誤差逆伝播法と言います(と思います)。

 

f:id:Parco1021:20200201203215p:plain

{\displaystyle \frac{∂E}{∂w}が求まったので重みwの }更新規則を書きます。
{\displaystyle w^{r+1}_{ji}=w^r_{ji}-α\frac{∂E}{∂w_{ji}}=w^r_{ji}-αδ^{(1)}_jx_i}

 

ここまで、誤差逆伝播法について数式を交えつつ解説してきました。次はより抽象的に図を主としてイメージを掴みます。

 

誤差逆伝播法のまとめ

①NNにxを入力し、b,z,a,さらに出力yを得て全て保持しておく

入力し出力を得るのでここは普通に順伝播(左から右)

f:id:Parco1021:20200201210825p:plain

 

 

②教師データtと出力yから出力層の誤差δを計算する。そして逆方向へ伝播し、重みvと乗算しΣ計算することで中間層の誤差を計算する

f:id:Parco1021:20200201212023p:plain

 

③δを用いて重みを更新する 

f:id:Parco1021:20200201213547p:plain

 

さいごに

いかがでしたでしょうか。数式は多かったと思いますが1つ1つ丁寧に追っていけば大学1年生レベルのものであることがわかると思います。誤差逆伝播法を使うと何がメリットで何がデメリットなのかわからないので今後調べていきたいと思います。例えば誤差逆伝播法は"人間っぽい"考え方ではないから別の手法を考えていると研究室の先輩が輪講で言ってたような言ってなかったような…みたいな。

 

参考文献

qiita.com

 

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

Pythonでcsvを分割して読み込む(改訂版)

はじめに

半年ほど前に似たような記事を書いたのですが、それは自分が使用したコードを貼り付けただけで全く参考にならなさそうだったので簡略化したものをもう一度書くことにしました。

前回の↓

Python3で大容量のcsvファイルを分割して読み込む - 情報学部大学生のダラダラ日記

 

使用するcsvとコード

スクリーンショットで失礼します。以下のcsvを使います。

f:id:Parco1021:20191228182704p:plain

import pandas as pd

reader = pd.read_csv('tagA.csv'chunksize=5)

for r in reader:
    print(r)

chunksizeなどの説明は以前の記事に書いたのでそちらをご覧になってください。簡単に言うとchunksizeで指定した数で分割して読み込みます。なのでこのコードだと5個ずつデータを分割します。そして今回データ数は10個なので10/5で2回に分けて読み込みます。

 

結果

f:id:Parco1021:20191228181452p:plain

ご覧の通り5個ずつ2回に分けて読み込んでいることがわかります。

もう少しいじってみる

分割して読み込んだのはいいとして、これを少しいじってみます。

コード
import pandas as pd

reader = pd.read_csv('tagA.csv'chunksize=5)

for r in reader:
    row = []
    for index,rows in r.iterrows():
        print(rows[1])
        row.append(rows[1])
    print("#分割の区切り")
    print(row)

iterrows()とすることで列ごと見ることができます。具体的にはこのコードにおけるrowsはrow[0]にid、row[1]にはtagが入っています。これをさらに別々に出力させることもでき、今回はリストにも入れてみました。

出力

f:id:Parco1021:20191228185655p:plain

今回はfor文の中でリストを初期化しているのでこのような出力となっていますが、外でやった場合、全データのtagのリストとなります。また、iterrows()をiteritems()とすることで行で見ることができるので用途によって使い分けが必要です。
また、今回出力させていませんが、indexにはインデックス(0,1,...9)が入っています。

さいごに

使用機材のメモリにのらない時に多く使われる印象のあるchunksizeというオプションですが、考えようによっては他にも良い使い方がありそうだな~と思いました。

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

2019年の終わり、それはPython2の終わり。

僕は知らなかったのですが、Python2がサポート終了するのが2020年1月1日に大分前から決まっていたようです。公式のドキュメントはこちら↓

www.python.org

「Python2の日没」ですって。オシャレ。

ドキュメントによると、2000年にPython2が始まり、2006年にPython3が作られた?のですが、初めはPython3がよろしくなかったらしくPython3へ移行する人があまりおらず、結局Python2を使う人とPython3使う人が共存してしまい、両方改良を続けていたようです。

こうなってしまった原因として、2系と3系で互換性がないことが挙げられます。僕も最初ネットを参照しながらPythonを書いていたらネットには2系と3系が混在しており、エラーが無くならず心が折れかけました。例としては2系ではprint "Hello World"であるのに対し、3系ではprint ("Hello World")のようになります。僕は3系しか使ったことがないので他にはわかりませんが、多くの違いがあり、全くの別言語らしいです。

話を戻して、両方改良するのはさすがに公式さんも大変だったらしく、2008年に「2015年にサポートを終了する」というアナウンスをしたそうです。しかし、2014年にそれは厳しいと判断し、2020年に終了すると先延ばしにしました。

今は2019年12月末。あと少しでPython2のサポートが終了します。Python2しか使ってない!って人も、2to3というPython2を3へ変更するモノがあるらしいので応急措置ですが大丈夫です。あくまで応急措置なのでPython3のお勉強をしなければなりませんが…。

あとどれだけでサポートが終了するか示すサイトもあるぽいです。

Python 2.7 Countdown

あと10日と4時間です。

f:id:Parco1021:20191221193057p:plain

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

数値微分法についてまとめてPythonで色々してみる

 勾配法あたりでやたらと見る数値微分法について調査し、まとめてみました。

 今回、理論的なことは以下の書籍を参照し、図とプログラムは1から自作したものであり、特にプログラムは筆者がその場で簡易的に考え実装したものです。変数名などおかしい点がありますがご容赦ください。

数値微分法とは

 勾配法においてはある重み{\displaystyle w_1 }において、誤差関数{\displaystyle E(w) }{\displaystyle w }に関して偏微分したものの符号を入れ変えたもの{\displaystyle -\frac{∂E}{∂w} }の方向に重み{\displaystyle w_1 }を更新します。この偏微分という動作をしなくても近似を使うことによって重みの更新をしちゃおう!というのが数値微分法の目的です。

 

 まず、微分の定義を思い出します。

{\displaystyle \lim_{h \to 0} \frac{f(x+h)-f(x)}{h} }

これが見慣れた形ですが今回は文字を変えて

{\displaystyle \lim_{ε \to 0} \frac{E(w_1+ε)-E(w_1)}{ε} }

とします。

f:id:Parco1021:20191215170236p:plain

余談ですが、式だけだとわかりづらいので僕が誰かに微分の定義を説明する時は上みたいな図を描いてこのεを0にもってくとその点での接線になるでしょ??って言います。

 

まず、数値微分法のうち、2点近似を紹介します。図は↑と同様で、式は

{\displaystyle \frac{E(w_1+ε)-E(w_1)}{ε} }です。

 数値微分法では極限などを使わず、手動で限りなく小さいεを設定することで勾配を近似します。例えばεを0.001と設定し、{\displaystyle E(w)=w^3 }{\displaystyle w_1=3 }とすると、

微分法:{\displaystyle E'(3)=27 }

数値微分法(2点近似):{\displaystyle E'(3)≒27.009001‬ }となり、誤差は約0.01ほどになります。

 

 では、より誤差を減らす方法はないの?と思ったそこの奥様!あります。三点近似(中心差分)という手法です。図は先ほどと異なります。

f:id:Parco1021:20191215173433p:plain

そして式は

{\displaystyle \frac{E(w_1+ε)-E(w_1-ε)}{2ε} }です。

試しに先ほどの2点近似と同様の条件で計算してみると

数値微分法(3点近似):{\displaystyle E'(3)≒27.000001‬‬ }となり、誤差が0.000001にまで減りました。

 

Pythonで観測

式自体は単純なものなので書く必要もないと思いますが、通常の微分したものとの差をグラフに描画するプログラムを書きます。

import matplotlib.pyplot as plt
%matplotlib inline

Ew = lambda w: w**3
Gw = lambda w: 3*w**2
e = 0.001
w = [-10000,-100,0,2,16,64,100,1000,10000]
_two = []
_three = []

def normal(w):
    E_dashn = Gw(w)
    return E_dashn
    
    
def three_point(w,e):
    E_dashth = (Ew(w+e)-Ew(w-e)) / (2*e)
    return E_dashth

def two_point(w,e):
    E_dashtw = (Ew(w+e)-Ew(w)) / e
    return E_dashtw

for i in range(len(w)):
        _two.append(two_point(w[i],e)-normal(w[i]))
        _three.append(three_point(w[i],e)-normal(w[i]))

plt.plot(w,_two,label='2point')
plt.plot(w,_three,label="3point")
plt.show()

プログラムは単純なものです。式Ewとそれを微分した式Gwを用意し、wを変化させた時の2点近似と3点近似と通常微分との値の差を取っています。

 

結果

f:id:Parco1021:20191215192757p:plain

グラフを観ると、2点近似は単調増加しており、3点近似は変化していません。これは今回の{\displaystyle E(w)がw^3}であることと、それぞれの式を観れば自明です。そして2点近似と3点近似の優劣は関数{\displaystyle E(w) }が変わっても変化しないでしょう。よって計算量が増加するというデメリットがありますが、3点近似を使う方がより誤差を減らすことができます。

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

2次方程式や3次方程式の解と係数の関係の導出方法

 解と係数の関係、知っていますでしょうか。結構な頻度で使われるので受験を経験した人達は覚えていると思います。しかしセンター試験レベルだとせいぜい使っても2次方程式の解と係数の関係ぐらいなので暗記でも乗り越えられるのですが、突然3次方程式の解と係数の関係を使う問題がでた時に困ります。そんな時に導出方法を知っていると役に立つと思うので知らない受験生は知り得です。

2次方程式の解と係数の関係

2次方程式{\displaystyle ax^2+bx+c=0 }が2つの解{\displaystyle α,β }を持つとき、

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }

が成り立ちます。僕は「マイナス(-)を忘れる奴はば(ba)か(ca)」と覚えろと教わりました。まず、2つの方法で2次方程式における関係を導出してみます。

 

 

1つ目は解の公式を使います。

 x=\frac{-b±\sqrt{b^2-4ac}}{2a}

この場合、解は{\displaystyle α,β }なので

{\displaystyle α+β=\frac{-b+\sqrt{b^2-4ac}}{2a}+\frac{-b-\sqrt{b^2-4ac}}{2a}=\frac{-2b}{2a}=-\frac{b}{a}}

{\displaystyle αβ=\frac{b^2-(b^2-4ac)}{4a^2}=\frac{c}{a} }

となります。

 

2つ目は因数定理を使います。

※因数定理

{\displaystyle f(x)が(x-α)を因数(掛け算として表したときにその個々の数のこと)持つことはf(α)=0となるための必要十分条件である }

 

これを使うことにより

{\displaystyle ax^2+bx+c=0がα,βを解に持つ⇔A(x-α)(x-β)=0 }とすることができます。

右辺を展開すると

{\displaystyle Ax^2-A(α+β)x+Aαβ=0 }となります。そこで元の式と比較すると

{\displaystyle a=A }

{\displaystyle b=-A(α+β) }

{\displaystyle c=Aαβ }となるのでここから

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }が求められます。

 

2つ導出方法を紹介しましたがどちらを覚えるべきでしょうか?どちらも覚えてほしいですが重要なのは2つ目です。理由は解の公式は4次式までしかありませんし、とてもじゃありませんが覚えるなんて不可能に近いです。とりあえず2つ目の方法を使って3次方程式の解と係数の関係を求めてみます。

{\displaystyle ax^3+bx^2+cx+d=0 }が3つの解{\displaystyle α,β,γ }を持つとき、因数定理より

{\displaystyle A(x-α)(x-β)(x-γ)=0 }となります。展開すると

{\displaystyle Ax^3-A(α+β+γ)x^2+A(αβ+βγ+γα)x-Aαβγ=0 }となるので係数比較すると

{\displaystyle α+β+γ=-\frac{b}{a} }

{\displaystyle αβ+βγ+γα=-\frac{c}{a} }

{\displaystyle αβγ=-\frac{d}{a} }となります。

まだ2次と3次しか見ていませんが何か規則性が"観えて"きますね。ムムッ

1次の時は{\displaystyle α=-\frac{b}{a} }ですし多分解を足したら同じ結果になるんでしょうね。あとは解を掛けたら定数項/aとか。

さいごに

 今回は手計算でごり押し風に3次までやりましたが5次あたりからきつくなると思います。なのでn次として一般化しなければならないのですが、そこは僕も受験生時代お世話になった以下のサイトさんがやっててくれました。

mathtrain.jp

上のサイトにあるならやらなくていいんじゃないかという声が聞こえてくる気がしますが、高校数学あたりの公式の証明って良い頭の体操になるんですよ。それに"調べれば"出てくるという仮定つきなので調べなくても誰かの目に留まればいいなって感じです。自己満です。頭の体操としてやったのでサイトを観ていません。なのでもし間違っているところ等あればこっそり教えてください。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

予測損失と経験損失について簡単にまとめる

 機械学習の大きな目的は訓練データから未知のデータ、すなわちテストデータに対する損失を小さくすることです。予測損失(テストデータ)と経験損失(訓練データ)についてまとめてみます。

予測損失

 予測損失というよりも汎化誤差という言葉の方が親しみがあるのではないでしょうか。また、他にも期待損失などとも言うようです。仮説{\displaystyle h }の予測損失{\displaystyle R(x) }が、損失関数として{\displaystyle l }、テストデータ{\displaystyle (X,Y) }の分布{\displaystyle D }を用いて以下のように定義されます。

{\displaystyle R(h) = E_{(X,Y)~D}[l(h(X),Y)]}

つまり、テストデータの分布に対してのテストデータの損失の期待値ということです。しかし、テストデータの分布は未知であるためこの予測損失{\displaystyle R(x) }を計算することはできないです。目標は観測データのみからできるだけ{\displaystyle R(x) }を小さくする仮説{\displaystyle h }を求めることです。

経験損失

 標本誤差、経験誤差とも言われています。データ{\displaystyle (X_1,Y_1),(X_2,Y_2),.....(X_n,Y_n) }が観測され、仮説と損失関数を先ほどと同じ文字に設定すると観測データに対する仮説{\displaystyle h }の経験損失{\displaystyle R ̃(h) }は以下のようになります。

 {\displaystyle R ̃(h) =∑_{(i=1)}^nl(h(X_i),Y_i) }

先ほどの予測損失と異なり、観測データは明らかになっているので{\displaystyle R ̃(h) }は求めることが可能です。

 特にこの時、確率{\displaystyle 1/n }{\displaystyle (X_i,Y_i) }を取る時、確率分布を{\displaystyle D_1 }とすると上式は

{\displaystyle R ̃(h) = E_{(X,Y)~D_1}[l(h(X),Y)] }

と表すことができる。この式は予測損失の式ととても似ていますね。違いは従っている確率分布です。つまり、データが同一の確率分布に従うとき、

{\displaystyle R ̃(h) ≒ R(h) }

とすることができます。

結局???

 予測損失を最小にしたいのはわかっていただけたと思います。簡単に説明すると"予測損失を最小にすることが(実質的に)機械学習の主たる目的だから"です。ではなぜ経験損失を求める必要があるのでしょうか?それは上でも述べた通り、経験損失と予測損失が近似できるからです。流れは以下のような感じです。

 

予測損失が最小となるよう仮説を設定したい

テストデータの分布は未知であるため値が求められない

予測損失と近似できる経験損失がある

経験損失は実測値から求められる

 

という感じです。今回は理論的な部分から予測損失(汎化誤差)にアプローチしてみましたが、応用的な部分から観てみるとなぜ予測損失を最小にしたいかが感覚的にわかってくると思います。以下のサイトをご覧になってみてください。

訓練誤差と汎化誤差の理論計算 - Qiita

参考文献

以下の書籍を参考に書きました。

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

モデルを蒸留するのではなくデータセットを蒸留する(論文紹介②Dataset Distillation)

蒸留とは

 中学生の時に化学で学んだ蒸留について、

蒸留(じょうりゅう、Distillation)とは、混合物を一度蒸発させ、後で再び凝縮させることで、沸点の異なる成分を分離・濃縮する操作をいう。

引用元:Wikipedia

 深く、大きいモデルが優秀であることは想像に難くありません。しかし、実際にはそのような大きいモデルが使用できないが機械学習モデルを使用したい場面があります(ラズパイとかでやる時など)。そのような時に、深く大きいニューラルネットワークの知識を蒸留し、より浅く小さいニューラルネットワークへ学習させるために使われるものです。特に大きいモデルを教師モデル、小さいモデルを生徒モデルと言います。つまり性能をできるだけそのままに教師モデルから生徒モデルへ知識の継承を行うことを目的としています。これについての元論文は以下です。

Distilling the Knowledge in a Neural Network,Geoffrey Hinton, Oriol Vinyals, Jeff Dean,2015,https://arxiv.org/abs/1503.02531

日本語でまとめられた文献もあります。

Deep Learningにおける知識の蒸留 | Code Craft House

論文紹介

今後、本記事での画像等の引用は全てこの論文からです。

引用数は9でタイトルはそのまま「データセットの蒸留」です。

概要

 先ではモデルの蒸留を行っていましたが本論文ではデータセットの蒸留をします。具体的には膨大なデータセットをサンプリングすることなく、各クラスごとに新たな画像を生成することでデータセットを圧縮している。

f:id:Parco1021:20191127182634p:plain

引用元:Dataset Distillation

 

イメージとしては上のような感じ。このように新たに画像を生成することで数万枚のデータセットが10~300枚へと蒸留することができている。

アルゴリズム

f:id:Parco1021:20191127184527p:plain

引用元:Dataset Distillation

<!--以下自己解釈

蒸留後データセット{\displaystyle x ̃ }を初期化する。

元データ{\displaystyle x }を取得する。

ある重み{\displaystyle }θ_0^{(j )}において勾配を求め、より良い重み{\displaystyle }θ_1^{(j )}を決定

元データと{\displaystyle }θ_1^{(j )}を使ってロス関数を計算する。

ロス関数の勾配から蒸留後データセット{\displaystyle x ̃ }を更新する。

-->

実験結果

まず、上記のアルゴリズムを繰り返し行う2パターンの実験を行う。

上のアルゴリズムを拡張して2つの方法を用意する。

(a)重み{\displaystyle θ }の更新を複数回行う

(b){\displaystyle x ̃ }の更新を複数回行う

f:id:Parco1021:20191127190345p:plain

引用元:Dataset Distillation

 

実験対象としてMNISTとCIFAR10が用いられたが、(a),(b)どちらの場合にも複数回行った方が正確となっている。

 

次に、ベースライン条件として以下の4つの条件を用意し、それとデータセットを蒸留した時の結果を比較する。

ベースライン条件

  1. ランダム
  2. 学習効果の高かった上位20%
  3. k-means法
  4. 各画像の平均

結果が以下です。ベースライン条件よりも良い結果になっていることがわかります。

f:id:Parco1021:20191127193422p:plain

引用元:Dataset Distillation 

さいごに

 今回は蒸留という手法の新しいアプローチを行った論文でした。どのようなクラスからどのような画像が生成されたかは参考文献の公式リンクから観てみてください。carクラスだったりが1つの画像になっているのは結構面白いです。

英語キチィ~

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

スポンサーリンク