応用数学
線形代数学
行列
画像は行列として考えると、特異値分解は、画像の圧縮に使える。機械学習の学習の際、事前学習の際に用いられる。
行列の積は連立方程式
\left\{
\begin{array}{ll}
x_1+4x_2&= 7\\
2x_1+6x_2&=10
\end{array}
\right.
ここで、数式を以下の行列に置き換えられる。
\boldsymbol{A}=
\begin{pmatrix}
1 & 4\\
2 & 6
\end{pmatrix}
,
\boldsymbol{X}=
\begin{pmatrix}
x_1 \\
x_2
\end{pmatrix}
,
\boldsymbol{Y}=
\begin{pmatrix}
7 \\
10
\end{pmatrix}
\boldsymbol{A}\boldsymbol{X}=\boldsymbol{Y}
上記の行列は、逆行列(インバース)を使って解ける
\boldsymbol{A^{-1}}\boldsymbol{A}\boldsymbol{X}=\boldsymbol{A^{-1}}\boldsymbol{Y}
\boldsymbol{X}=\boldsymbol{A^{-1}}\boldsymbol{Y}
行列式(determinant)
正方行列の大きさ
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix}
=ad-bc
固有値・固有ベクトルの求め方
$ある行列\boldsymbol{A}$ に対して、以下の様な式が成り立つ様な、特殊なベクトル$\overrightarrow{x}$と、右辺の係数$\lambda$がある。
\boldsymbol{A}\overrightarrow{x}=\lambda\overrightarrow{x}
$行列\boldsymbol{A}$とその特殊なベクトル$\overrightarrow{x}$の積は、ただのスカラー数$\lambda$とその特殊なベクトル$\overrightarrow{x}$の積と同じ値になる。
特殊なベクトル$\overrightarrow{x}$とその係数$\lambda$を、行列$\boldsymbol{A}$に対する、固有ベクトル、固有値という。
具体例
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}
\begin{pmatrix}
1 \\
1
\end{pmatrix}
=
\begin{pmatrix}
5 \\
5
\end{pmatrix}
=5
\begin{pmatrix}
1 \\
1
\end{pmatrix}
固有値λ=5
固有ベクトル(のうちの1つ)
\overrightarrow{x}=
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}
$$\overrightarrow{x} は固有ベクトルで1つに決まらない$$
固有値と固有ベクトルの問題
\begin{pmatrix}
3 & 2 & 0\\
0 & 2 & 0\\
0 & 0 & 1
\end{pmatrix}
の固有値、固有ベクトルを求めよ
\boldsymbol{A}=\begin{pmatrix}
3 & 2 & 0\\
0 & 2 & 0\\
0 & 0 & 1
\end{pmatrix}、
\lambdaを固有値とする\\
\boldsymbol{A}\overrightarrow{x}=\lambda\overrightarrow{x}\\
(\boldsymbol{A}-\lambda\boldsymbol{I})\overrightarrow{x}=\overrightarrow{0}
\overrightarrow{x}\neq\overrightarrow{0}より\\
\begin{vmatrix}
\boldsymbol{A}-\lambda\boldsymbol{I}
\end{vmatrix}=0
\begin{vmatrix}
3-\lambda & 2 & 0\\
0 & 2-\lambda & 0\\
0 & 0 & 1-\lambda
\end{vmatrix}=0\\
(3-\lambda)(2-\lambda)(1-\lambda)=0\\
\lambda=3 , 2 , 1\\
\begin{pmatrix}
3 & 2 & 0\\
0 & 2 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix}=3
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix} よってx_2=0 , x_3=0\\
\begin{pmatrix}
3 & 2 & 0\\
0 & 2 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix}=2
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix} よってx_1=-2x_2 , x_3=0\\
\begin{pmatrix}
3 & 2 & 0\\
0 & 2 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix}=1
\begin{pmatrix}
x_1\\
x_2\\
x_3
\end{pmatrix} よってx_1=0 , x_2=0 \\
したがって
\lambda=3の時\overrightarrow{x}=
\begin{pmatrix}
1\\
0\\
0
\end{pmatrix}の定数倍\\
\lambda=2の時\overrightarrow{x}=
\begin{pmatrix}
2\\
-1\\
0
\end{pmatrix}の定数倍\\
\lambda=1の時\overrightarrow{x}=
\begin{pmatrix}
0\\
0\\
1
\end{pmatrix}の定数倍\\
固有値分解
行列を分解することができる。→計算上有利。分類が可能。
$行列\boldsymbol{A}は、正方行列。この行列は、固有値を対角線上に並べた行列でそれ以外の成分は0$\
$行列\boldsymbol{V}は、行列\boldsymbol{A}の固有ベクトル$
\boldsymbol{A}\boldsymbol{V}=\boldsymbol{V}\boldsymbol{A}\\
上記は以下の様に変形できる。
\boldsymbol{A}=\boldsymbol{V}\boldsymbol{A}\boldsymbol{V}^{-1}\\
(具体例)
\boldsymbol{A}=
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}、
\lambdaを固有値とする\\
\boldsymbol{A}\overrightarrow{x}=\lambda\overrightarrow{x}\\
(\boldsymbol{A}-\lambda\boldsymbol{I})\overrightarrow{x}=\overrightarrow{0}
\overrightarrow{x}\neq\overrightarrow{0}より\\
\begin{vmatrix}
\boldsymbol{A}-\lambda\boldsymbol{I}
\end{vmatrix}=0\\
\begin{pmatrix}
1-\lambda & 4\\
2 & 3-\lambda
\end{pmatrix}=0\\
(3-\lambda)(1-\lambda)-2\times 4=0\\
\lambda^2-4\lambda-5=0\\
(\lambda-5)(\lambda+1)=0\\
\lambda=5 , -1\\
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}
\begin{pmatrix}
x_1\\
x_2
\end{pmatrix}=5
\begin{pmatrix}
x_1\\
x_2
\end{pmatrix} よってx_1=x_2\\
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}
\begin{pmatrix}
x_1\\
x_2
\end{pmatrix}=-1
\begin{pmatrix}
x_1\\
x_2
\end{pmatrix} よってx_1=2、x_2=-1\\
\begin{pmatrix}
1 & 4\\
2 & 3
\end{pmatrix}=
\begin{pmatrix}
1 & 2\\
1 & -1
\end{pmatrix}
\begin{pmatrix}
5 & 0\\
0 & -1
\end{pmatrix}
\begin{pmatrix}
\frac{1}{3} & \frac{2}{3}\\
\frac{1}{3} & -\frac{1}{3}
\end{pmatrix}^{-1}
\\
特異値分解
正方形以外の行列も分解できる。
$以下の様に、\overrightarrow{v}$に最終的に同じ様に
変形できるベクトルであれば、特異値分解ができる。
\boldsymbol{M}\overrightarrow{v}=\sigma\overrightarrow{u}\\
\boldsymbol{M}^{T}\overrightarrow{u}=\sigma\overrightarrow{v}
$上記の様に、特殊な単位ベクトル(\overrightarrow{v}、\overrightarrow{v})$があるならば特異値分解ができる。
\boldsymbol{M}=\boldsymbol{U}\boldsymbol{S}\boldsymbol{V}^{T}
\boldsymbol{M}^{T}=\boldsymbol{V}\boldsymbol{S}^{T}\boldsymbol{U}^{T}
これらの積は
\boldsymbol{M}\boldsymbol{M}^{T}=\boldsymbol{U}\boldsymbol{S}\boldsymbol{V}^{T}\boldsymbol{V}\boldsymbol{S}^{T}\boldsymbol{U}^{T}
=\boldsymbol{U}\boldsymbol{S}\boldsymbol{S}^{T}\boldsymbol{U}^{T}
$つまり\boldsymbol{M}\boldsymbol{M}^{T}$を固有値分解すれば、特異値が求められる。
この行列で算出される特異値は2乗されていることに注意。
$\boldsymbol{M}\boldsymbol{M}^{T}$は左特異ベクトル
$\boldsymbol{M}^{T}\boldsymbol{M}$は右特異ベクトル
統計学
集合
記号説明。→別途作成
確率
####頻度確率(客観確率)とベイズ確率(主観確率)
頻度確率・・・「くじ引き」など $\frac{発生する数}{全部の数}$として計算する。数学的な考え方。
ベイズ確率・・・信念の度合い。事前の観測結果に基づいて得られた情報から割り出す。例えば、4人に1人くらいの割合で発生する。
確率の定義
P(A)=\frac{n(A)}{n(U)}=\frac{事象Aが起こる数}{すべての事象の数}
それでは、事象Aが発生しない確率を求める場合。
P(\bar{A})=1-P(A)=1-\frac{n(A)}{n(U)}=1-\frac{事象Aが起こる数}{すべての事象の数}
####条件付き確率
#####ある事象Bが与えられた下で、Aとなる確率
P(A | B)=\frac{P(A \cap B)}{P(B)}=\frac{n(A \cap B)}{n(B)}
例題
袋の中に赤い玉 3 個と白い玉 2 個が入っている。赤い玉は A,B,C の文字が,白い玉に は A,B の文字が,それぞれ 1 個に対して 1 文字ずつ記されている。以下の問いに答えよ。
問 5.2.1 出てきた玉が赤色であったとき,それに記されている文字が B である確率。
P(Bである|赤色である)=\frac{「赤い玉」かつ「B」である数}{「赤い玉」数}=\frac{1}{3}
問 5.2.2 出てきた玉に記されている文字が A であったとき,その玉の色が白色である 確率。
P(白色である|Aである)=\frac{「A」かつ「白い玉」である数}{「A」数}=\frac{1}{2}
#####独立な事象の同時確率
お互いの発生には因果関係のない事象Aと事象Bが同時に発生する確率
P(A \cap B)=P(A)P(B | A)=P(A)P(B)
P(A \cup B)=P(A)+P(B)-P(A \cap B)
#####ベイズ則
P(A)P(B | A)=P(B)P(A | B)
統計
####記述統計学と推測統計学
ディープラーニングでは、記述統計学を主に使う
####確率変数と確率分布
確率変数・・・事象と結び付けられた変数(事象そのものを指す)
確率分布・・・事象の発生する確率の分布(離散値であれば表に示せる)
####期待値
その分布における、確率変数の平均値 or 「あり得そう」な値
離散的な確率変数の期待値E(f)=
\sum_{k=1}^{n} P(X=x_k)f(X=x_k)
連続する確率変数の期待値E(f)=
\int P(X=x)f(X=x)dx
####分散と共分散
#####分散
・データの散らばり具合
・データの各々の値が、期待値からどれだけズレているのか平均したもの
\begin{align}
分散Var(f) &=
E \Bigl( \bigl( f_{(X=x)}-E_{(f)} \bigr) ^2 \Bigr)\\
&=E \Bigl( \bigl(f_{(X=x)} \bigr) ^2 + \bigl( E_{(f)} \bigr) ^2 -2 \bigl( f_{(X=x)}E_{(f)} \bigr) \Bigr)\\
&=E \bigl(f_{(X=x)} \bigr) ^2 +E \bigl( E_{(f)} \bigr) ^2 -2E \bigl( f_{(X=x)}E_{(f)} \bigr)\\
&=E \bigl(f_{(X=x)}^2 \bigr) +\bigl(E_{(f)}\bigr)^2 -2\bigl(E_{(f)}\bigr) \bigl(E f_{(X=x)} \bigr)\\
&=E \bigl(f_{(X=x)}^2 \bigr) + \bigl(E_{(f)}\bigr)^2 -2 \bigl(E_{(f)}\bigr)^2\\
&=E \bigl(f_{(X=x)}^2 \bigr) -\bigl(E_{(f)}\bigr)^2
\end{align}
2乗をとった後なら絶対値をとる必要がなくなる。
2乗の平均をかけた後に、平均の2乗えお引くことで、分散を求められる。
#####共分散
・2つのデータ系列の傾向の違い
・正の値→似た傾向
・負の値→逆の傾向
・ゼロを取れば関係性に乏しい
\begin{align}
共分散Cov(f,g)
&=E \Bigl( \bigl( f_{(X=x)}-E(f) \bigr) \bigl( g_{(Y=y)}-E(g) \bigr) \Bigr)\\
&=E(fg)-E(f)E(g)
\end{align}
####分散と標準偏差
\begin{align}
標準偏差 \sigma
&=\sqrt{Var(f)} \\
&=\sqrt{E \Bigl( \bigl( f_{(X=x)}-E_{(f)} \bigr) ^2 \Bigr)}
\end{align}
####様々な確率分布
ベルヌーイ分布
・コイントスのイメージ
・裏と表で出る割合が等しくなくとも扱える。
P(x| \mu) = \mu^x(1- \mu)^{1-x}
マルチヌーイ(カテゴリカル)分布
・サイコロを転がすイメージ
・各面の出る割合が等しくなくとも扱える
二項分布
・ベルヌーイ分布の多試行版
P(x| \lambda , n) = \frac{n!}{x!(n-x)!} \lambda^x(1- \lambda)^{n-x}
ガウス分布
・釣鐘型の連続分布
真の分布が分からなくてもサンプルが多ければ正規分布に近づく!
N(x; \mu , \sigma^2) = \frac{1}{2\pi \sigma^2}exp \Bigl( -\frac{1}{2 \sigma^2} \bigl(x- \mu \bigr)^2 \Bigr)
####自己情報量
※I は情報量,p(X)は事象 X の発生する確率。
\begin{align}
I = \log_2 \frac{1}{p(X)}=-\log_2 \Bigl( p(X) \Bigr)
\end{align}
上記式より、n枚のコインを1枚投げて1枚の表が出たという事象の情報量は何bitになるのか
\begin{align}
I &=-\log_2 \Bigl( {}_n \mathrm{C}_1 \bigl( \frac{1}{2} \bigr)^n \Bigr)\\
&=-\log_2 \Bigl( {}_n \mathrm{C}_1 \Bigr) -\log_2 \bigl( \frac{1}{2} \bigr)^n \Bigr)\\
&=-\log_2 \bigl( n \bigr) -\log_2 \bigl( \bigl( \frac{1}{2} \bigr)^n \bigr)\\
&=-\log_2 \bigl( n \bigr) +n
\end{align}
####シャノンエントロピ
エントロピが最大になるところが実際に発生する確率。
具体例
シャノンエントロピーは自己情報量の平均である。ある離散的な事象の確率分布 を𝑃(𝑥)としたとき,シャノンエントロピーとしてふさわしいものは。
-\sum P(x) \log \Bigl(P(x) \Bigr)
####ダイバージェンス
#####カルバック・ライブラー ダイバージェンス
同じ事象・確率変数における異なる確率分布P、Qの違いを表す
機械学習
線形回帰モデル
回帰問題とは
○ある入力(離散あるいは連続値)から出力(連続値)を予測する問題
■ 直線で予測する場合を線形回帰
回帰で扱うデータとは
○入力(各要素を説明変数または特徴量と呼ぶ)
■ m次元のベクトル(m=1の場合はスカラ)
○出力(目的変数)
■スカラー値(目的変数)
●線形回帰モデル
○回帰問題を解くための機械学習モデルの1つ
○教師あり学習(教師データから学習)
○入力と$\textbf{m}次元パラメータの線形結合$を出力するモデル
■慣例として真の値 $\theta$ に対して、予測値(パラメータから予測した値)を
$\hat{\theta}の様に、\hat{}(ハット)$を付けて表記できる。
パラメータ:\boldsymbol{w}=(w_1,w_2,・・・,w_m)^{T}\in\boldsymbol{R^m}\\
線形結合:\hat{y}=\boldsymbol{w^{T}}\boldsymbol{x}+w_0 = \sum_{j=1}^{m}w_ix_j+w_0
データ分割/学習
データの分割とは、
手持ちのデータを「学習用データ」と「検証用データ」に分割する。
理由:モデルの汎化性能を測るため。
手持ちのデータだけに対してうまく予想できるだけでは意味がない。未知のデータにうまく対応出せる。
##ハンズオン
###線形回帰モデル-Boston Hausing Data-
線形単回帰分析
非線形回帰モデル
- 現実的に非線形回帰の方が需要が多いため、非線形回帰について検討する必要がある。表現応力に乏しい、線形回帰モデルのクラスを拡張する。
- 非線形回帰の考え方:基底関数を説明変数に掛けることで特徴空間にとばす
y_{i}=f(\boldsymbol{x}_{i})+\epsilon_{i}\\
y_{i}=\sum_{i=1}^{m}w_{j}\phi_{j}(\boldsymbol{x}_{i})+\epsilon_{i}
線形回帰と似ているが、実際には、ある関数$f(x)$により別の値を利用する。
基底関数を用いることで、パラメータの推定は線形回帰と同様の手法が使用可能になる。
基底関数
- 基底関数を用いたモデルは、パラメータに関して線形であるため解析が容易であり、しかも入力変数に関しては非線型になるという特徴を持っている。(C・M・ビショップ著 パターン認識と機械学習 上より抜粋)
- 多項式関数(スプライン関数): $(\phi_{j})=f(x^{j})$
- ガウス型基底関数:$\exp\Bigl(\frac{x-\mu_{j}^{2}}{2h_{j}}\Bigr)$ この関数は、ガウス分布の確率密度関数と似ている、
非線形回帰関数
\begin{align}
&説明変数: \boldsymbol{x_{i}}=(x_{i1},x_{i2},・・・,x_{im})\in\boldsymbol{R^m}\\
&非線形関数ベクトル:\boldsymbol{\phi(\boldsymbol{x}_{i})}=(\phi_1(\boldsymbol{x}_{i}),(\phi_2(\boldsymbol{x}_{i}),・・・,(\phi_k(\boldsymbol{x}_{i}))^{T}\in\boldsymbol{R^k}\\
&非線形関数の計画行列:\boldsymbol{\Phi^{train}}=(\boldsymbol\phi(\boldsymbol{x}_{i}),(\boldsymbol\phi(\boldsymbol{x}_{i}),・・・,(\boldsymbol\phi(\boldsymbol{x}_{i}))^{T}\in\boldsymbol{R^{n\times k}}\\
&最尤法による予測値:\boldsymbol{\hat{y}}=\boldsymbol{\Phi}(\boldsymbol{\Phi}^{(train)T}\boldsymbol{\Phi}^{(train)})^{-1}\boldsymbol{\Phi}^{(train)T}\boldsymbol{y}^{(train)} \\
\end{align}
基底展開法も線形回帰と同じ枠組みで推定可能
- 未学習(underfitting)と過学習(overfitting)
- 学習データに対して、十分小さな誤差が得られないモデル→未学習 ■ (対策)モデルの表現力が低いため、表現力の高いモデルを利用する
- 小さな誤差は得られたけど、テスト集合誤差との差が大きいモデル→過学習
- (対策1) 学習データの数を増やす
- (対策2) 不要な基底関数(変数)を削除して表現力を抑止
- (対策3) 正則化法を利用して表現力を抑止
正則化法
過学習とは、テスト用のデータには精度が上がるが、汎化性がなくなり、実際のデータでは、精度が下がる。
正則化法(罰則化法)
過学習を回避する方法として、モデルの複雑さに伴って罰則を大きくする方法。
- 過学習:テスト誤差が大きい・・テストに強いが本番(未知のデータ)に弱い
- 複雑なモデルを適用すると発生しがち
- 正則化法:過学習を回避する方法 モデルの複雑さに伴いペナルティを課す
- リッジ推定(L2ノルムを利用):MSEの値をパラメータ空間の原点に近い所(0)に近づける。
- ラッソ推定(L1ノルムを利用):MSEの値をパラメータの一部を0になるように近づける→次元削減
L2ノルム
|x_{1}|+|x_{2}|+ \cdots +|x_{n}|
L1ノルム
\sqrt{|x_{1}|^{2}+|x_{2}|^{2}+ \cdots +|x_{n}|^{2}}
モデル選択
- 適切なモデルを選択するために性能評価を行う そのために訓練データ、テストデータの確保が必要
- ホールドアウト法:訓練データとテストデータを分割 大量データでない限り性能評価の制度は悪い
- クロスバリデーション(交差検証):すべてのデータを訓練データ、テストデータに使用可
ロジスティック回帰モデル
- ロジスティック回帰モデルは分類問題を解くモデル
- 出力関数にシグモイド関数を適用し、結果が必ず0〜1になる→0.5以上なら
- シグモイド関数のパラメータで勾配を調整
- 出力結果を確率で表し、結果が0.5以上なら1、それ未満なら0として分類問題を推定
最尤推定
- ベルヌーイ分布
- 数学において、確率pで1、確率1 − p で0をとる、離散確率分布 (例:コインを投げ)
- 「生成されるデータ」は分布のパラメータによって異なる (この場合は確率p)
ベルヌーイ分布に従う確率変数Y
\begin{align}
Y& \sim Be(p)\\
P(y)&=p^{y}(1-p)^{1-y}
\end{align}
- 同時確率
- あるデータが得られた時、それが同時に得られる確率
- 確率変数は独立であることを仮定すると、それぞれの確率の掛け算
- 尤度:結果から分布のパラメータがどれほど有り得そうかを表したもの
- 最尤推定とは尤も有り得そうなパラメータを推定する手法(尤度関数を最大化するようなパラメータを選ぶ推定方法)
- 「尤度関数にマイナスをかけたものを最小化」し、「最小2乗法の最小化」を合わせる
最尤推定の際、対数をとることで、偏微分を簡易にできる。
\begin{align}
P(y)&=p^{y}(1-p)^{1-y}\\
log \Bigl(P(y)\Bigr) &=ylog(p)+(1-y)log(1-p)\\
\frac{\partial P}{\partial p} &= \frac{y}{p}-\frac{1-y}{1-p}\\
&= \frac{y(1-p)-p(1-y)}{p(1-p)}
\end{align}
勾配降下法
- 最尤法では解析的にパラメータを求めるのが困難
- 勾配降下法:学習によりパラメータを更新し、最適値を求める手法
確率的勾配降下法
- 勾配降下法はパラメータ更新に計算量を要する
- 確率的勾配法:ランダムにデータを1つ選び更新 勾配降下法はN個のデータにつき1回更新するところを確率的勾配法では1個のデータにつき1回で更新できる
- ミニバッチ勾配降下法:一定数のデータの集まりを1つの学習単位として更新 データ1個の計算よりも計算が高速に
モデル評価
- 適切なモデルを選択するために性能評価を行う
- 正解率:予測に対する結果が正しいかどうかの指標
- 適合率:見逃しを許容し、誤判定を許容しない場合の指標(迷惑メール)
- 再現率:見逃しを許容せず、誤判定を許容する場合の指標(がん検診)
- F値:適合率と再現率はトレードオフのため、見逃しと誤判定の最適値を適用する際の指標
ハンズオン
主成分分析
- 主成分分析:大量データの構造を捉える手法
- 情報量を保ちつつ、次元圧縮する→分散が最大となる方向に線形変換
- 分散値=固有値
K近傍法/K平均法 (k-means)
- K近傍法:分類問題のための手法
- K平均法:クラスタリング手法
- Kの値はどちらも事前に決定、大きさにより結果も変わる
##SVM(サポートベクトルマシン)
- クラス分類のための機械学習手法(主に2クラス分類)
- 回帰(予測)、新規性検出にも扱われる
- 出力は事後確率は得られない。
- 事後確率をベイズ理論に基づき推論を行う方法もあり、RVM(関連ベクトルマシン)
- 非線形分類
モデルパラメータがある凸最適化問題の解としても止まるため、局所解があればそれが大域解にもなる
####ラグランジュ乗数方
##Section1: 入力層~中間層
- 入力層のそれぞれの入力に関して、重みが掛け合わされて加算された値が第一の中間層のユニットに入力される。
- $重み w_{ij} は、入力$iと 中間層ユニットjに関してそれぞれ値が決定されている。(ネットワークのパラメータ)
##Section2: 活性化関数
- NN において、次の層への出力を決定する非線形の関数。
- 非線形であることは NN にとって本質的に重要。
- ON/OFF を次の層に強めに渡すのか、弱めに渡すのか、ということで、そこで人間らしさ的なものを出している。
例1: シグモイド関数
\frac{1}{1+e^{-h}}
- シグモイド関数の特徴
- 0 ~ 1 の値をとる。
- 絶対値が大きくなると、勾配が小さくなってしまう。→ 勾配消失問題
- ゼロにならない。 → スパース化できない。計算量が無駄に発生してしまう。
例2: ReLU関数
f(x) = \left\{
\begin{array}{ll}
x & (x \geq k) \\
0 & (x \lt k)
\end{array}
\right.
- ReLU関数の特徴
- 現世代では第一の選択肢となる関数 (必ずしも最適というわけではない)
- プラスであれば勾配はゼロにはならない。
- 0をとることでスパース化のメリットがある。
例2: ステップ関数
f(x) = \left\{
\begin{array}{ll}
1 & (x \geq k) \\
0 & (x \lt k)
\end{array}
\right.
- ステップ関数の特徴
- NNで使用。
- 0と1のみをとる。 → 逆誤差伝播では、情報がなくなる。
###【誤差関数】
- 二乗和誤差
E_{n}(w)=\frac{1}{2} \sum_{k=1}^{n} (k_{i}-y_{i})^{2}
- 分類問題に関してはクロスエントロピー関数を利用するのが普通。
###【出力層の活性化関数】
- 中間層と出力数で活性化関数を利用する目的が異なるので、同一である必要はない。
- 回帰問題の場合: 恒等関数 $ y=x $ ← 誤差関数は二乗誤差
- ロジスティック回帰: シグモイド関数 $ \frac{1}{1+e^{-h}} $ ← 誤差関数は交差エントロピー
- 分類問題: ソフトマックス関数 $ \frac{e^{u}i}{\sum_{k=1}^{K}1+e^{u}k} $ ← 誤差関数は交差エントロピー
##Section4: 勾配降下法
- 勾配降下法
- 一回のパラメータ更新に訓練データすべてを利用する。
- 計算量 (空間・時間) が訓練データ n に対してnの数倍必要となる。
- 確率的勾配降下法(SGD)
- サンプルのうち 1 つのデータごとにパラメータの更新を行う。
- 学習結果はサンプルのデータ順に依存する。
- 計算量と収束速度の面でメリットがある。
- ミニバッチ勾配降下法
- 狭義の確率的勾配降下法では、GPU等のSIMDのメリット等を生かせないため、ある程度の数のサンプルをまとめて1回のパラメータ更新に利用する。
- 文脈によっては、SGD(確率的勾配降下法) に含める場合もある。
- 訓練データ1周を「エポック」としてカウントする。
##Section5: 誤差逆伝播法
- 誤差(関数)をパラメータで微分した関数を利用し、出力層側から、ネットワークのパラメータ更新を行う。
- 最小限の計算で、(数値微分ではなく) 解析的にパラメータの更新量を計算する手法。
- 逆伝播をすることで、不要な再帰的計算(探索)を避けるという意味もある。
#確認テストの考察
import numpy as np
ディープラーニングは、結局何をやろうとしているか2行以内で述べよ。 また、次の中のどの値の最適化が最終目的か。 全て選べ。
①入力値[ X] ②出力値[ Y] ③重み[W]④バイアス[b] ⑤総入力[u] ⑥中間層入力[ z] ⑦学習率[ρ]
■ 考察
- ディープラーニングは、機械学習の識別能力の凡化性能を大幅に向上させるためのシステム。
- 誤差を最小化するパラメータを発見すること。
最適化は、③重み[W]と④バイアス[b]最終目的は②出力値の最適化と思われるが、入力データとして訓練データや検証データが与えられた場合だけではなく、 未知の入力に対しても出力値が最適化されていることが必要と考えられる。(汎化性能)
次のネットワークを紙にかけ。
この図式に動物分類の実例を入れてみよう。
■ 考察
動物の例を入れる
この数式をPythonで書け。
■ 考察
def compute_u(W, x, b):
return W @ x.T + b # ← 該当の数式の Python 実装
#以下確認用コード
W = np.array([1,2,3,4])
x = np.array([4,3,2,1])
b = 10
print (compute_u(W,x,b))
30
1-1のファイルから 中間層の出力を定義しているソースを抜き出せ。
■ 考察
中間層出力
z = functions.relu(u)
print_vec("中間層出力", z)
y=f(x)において $ \frac{Δy}{Δx} $ が定数 (xの値によらず一定) の場合に、
f(x)は線形関数で、それ以外が非線形関数
配布されたソースコードより該当する箇所を抜き出せ。
■ 考察
z1 = functions.sigmoid(u)
①なぜ、引き算でなく二乗するか述べよ
②下式の1/2はどういう意味を持つか述べよ
■ 考察
単純にマイナスで表現された数を扱いたくないため。
微分をした際に「降りてくる」2とこの 1/2 が打ち消しあい 1 となり、計算が簡略化されるため。
①~③の数式に該当するソースコードを示し、一行づつ処理の説明をせよ。
■ 考察
①
def softmax(x):
i
は引数としてとらず、すべての f(u)
をリストとして返す関数である。
②
np.exp(x)
NumPy の exp 関数を利用している。(関数定義と同様、すべての x に関して個別に計算を行う形である。)
③
np.exp(x), axis=0
u
のすべての要素のに関して、 exp
を底として指数の合計をとっている。
①~②の数式に該当するソースコードを示し、一行づつ処理の説明をせよ。
■ 考察
①
def cross_entropy_error(d, y):
引数dは、教師データのエントロピー ( one-hot-vector 形式でも可 ) である。
②
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))
y,dは正規化 (合計が1となっていること) されていることが前提である。
1e-7 をプラスしているのは、log 演算に引数 0 を渡すことを防ぐため。
この関数では、 yはゼロ以上であることが前提である。(負であってはならない。)
該当するソースコードを探してみよう。
network[key] -= learning_rate * grad[key]
オンライン学習とは何か2行でまとめよ
■ 考察
ユーザーの操作等、リアルタイムで取得・更新されるデータに対して、
そのデータを用いて誤差逆伝播法(確率的勾配降下法)を行い、随時にリアルタイムで学習係数wとbを更新していくこと。処理が軽いことが重要。
全データを複数に分割したバッチの1つに対して、以下の処理を行う。
t+1時点でのパラメータ Wは、 t時点でのパラメータ Wから、 t時点での誤差 Eの傾き (勾配) に比例した量 (比例係数: 学習係数 ϵ) を引いたものである。
誤差逆伝播法では不要な再帰的処理を避ける事が出来る。 既に行った計算結果を保持しているソースコードを抽出せよ。
■ 考察
誤差逆伝播
def backward(x, d, z1, y):
print("\n##### 誤差逆伝播開始 #####")
grad = {}
W1, W2 = network['W1'], network['W2']
b1, b2 = network['b1'], network['b2']
# 出力層でのデルタ
delta2 = functions.d_sigmoid_with_loss(d, y)
## (1)↑ここで シグモイド関数とクロスエントロピーの合成関数の導関数の値を求めている。
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
## (2)↑ここで (1) の値 (delta2) を利用している。
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
## (3)↑ここでも (1) の値 (delta2) を利用している。
# 中間層でのデルタ
delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)
## (4)↑ここでも (1) の値 (delta2) を利用している。
2つの空欄に該当するソースコードを探せ
■ 考察
① $ \frac{\partial E}{\partial y}\frac{\partial y}{\partial u} $
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
② $ \frac{\partial E}{\partial y}\frac{\partial y}{\partial u}\frac{\partial u}{\partial w_{ji}} $
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
#演習結果と考察
###DN06_Jupyter演習
【演習実施結果】
from google.colab import drive
drive.mount('/content/drive')
import numpy as np
中間層の活性化関数
シグモイド関数(ロジスティック関数)
def sigmoid(x):
return 1/(1 + np.exp(-x))
ReLU関数
def relu(x):
return np.maximum(0, x)
ステップ関数(閾値0)
def step_function(x):
return np.where( x > 0, 1, 0)
出力層の活性化関数
ソフトマックス関数
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x))
ソフトマックスとクロスエントロピーの複合関数
def softmax_with_loss(d, x):
y = softmax(x)
return cross_entropy_error(d, y)
誤差関数
平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2
クロスエントロピー
def cross_entropy_error(d, y):
if y.ndim == 1:
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)
# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if d.size == y.size:
d = d.argmax(axis=1)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
活性化関数の導関数
シグモイド関数(ロジスティック関数)の導関数
def d_sigmoid(x):
dx = (1.0 - sigmoid(x)) * sigmoid(x)
return dx
ReLU関数の導関数
def d_relu(x):
return np.where( x > 0, 1, 0)
ステップ関数の導関数
def d_step_function(x):
return 0
平均二乗誤差の導関数
def d_mean_squared_error(d, y):
if type(d) == np.ndarray:
batch_size = d.shape[0]
dx = (y - d)/batch_size
else:
dx = y - d
return dx
ソフトマックスとクロスエントロピーの複合導関数
def d_softmax_with_loss(d, y):
batch_size = d.shape[0]
if d.size == y.size: # 教師データがone-hot-vectorの場合
dx = (y - d) / batch_size
else:
dx = y.copy()
dx[np.arange(batch_size), d] -= 1
dx = dx / batch_size
return dx
シグモイドとクロスエントロピーの複合導関数
def d_sigmoid_with_loss(d, y):
return y - d
数値微分
def numerical_gradient(f, x):
h = 1e-4
grad = np.zeros_like(x)
for idx in range(x.size):
tmp_val = x[idx]
# f(x + h)の計算
x[idx] = tmp_val + h
fxh1 = f(x)
# f(x - h)の計算
x[idx] = tmp_val - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2 * h)
# 値を元に戻す
x[idx] = tmp_val
return grad
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
N, C, H, W = input_data.shape
out_h = (H + 2pad - filter_h)//stride + 1
out_w = (W + 2pad - filter_w)//stride + 1
img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
return col
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
N, C, H, W = input_shape
out_h = (H + 2pad - filter_h)//stride + 1
out_w = (W + 2pad - filter_w)//stride + 1
col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)
img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]
return img[:, :, pad:H + pad, pad:W + pad]
from google.colab import drive
drive.mount('/content/drive')
import numpy as np
中間層の活性化関数
シグモイド関数(ロジスティック関数)
def sigmoid(x):
return 1/(1 + np.exp(-x))
ReLU関数
def relu(x):
return np.maximum(0, x)
ステップ関数(閾値0)
def step_function(x):
return np.where( x > 0, 1, 0)
出力層の活性化関数
ソフトマックス関数
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x))
ソフトマックスとクロスエントロピーの複合関数
def softmax_with_loss(d, x):
y = softmax(x)
return cross_entropy_error(d, y)
誤差関数
平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2
クロスエントロピー
def cross_entropy_error(d, y):
if y.ndim == 1:
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)
# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if d.size == y.size:
d = d.argmax(axis=1)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
活性化関数の導関数
シグモイド関数(ロジスティック関数)の導関数
def d_sigmoid(x):
dx = (1.0 - sigmoid(x)) * sigmoid(x)
return dx
ReLU関数の導関数
def d_relu(x):
return np.where( x > 0, 1, 0)
ステップ関数の導関数
def d_step_function(x):
return 0
平均二乗誤差の導関数
def d_mean_squared_error(d, y):
if type(d) == np.ndarray:
batch_size = d.shape[0]
dx = (y - d)/batch_size
else:
dx = y - d
return dx
ソフトマックスとクロスエントロピーの複合導関数
def d_softmax_with_loss(d, y):
batch_size = d.shape[0]
if d.size == y.size: # 教師データがone-hot-vectorの場合
dx = (y - d) / batch_size
else:
dx = y.copy()
dx[np.arange(batch_size), d] -= 1
dx = dx / batch_size
return dx
シグモイドとクロスエントロピーの複合導関数
def d_sigmoid_with_loss(d, y):
return y - d
数値微分
def numerical_gradient(f, x):
h = 1e-4
grad = np.zeros_like(x)
for idx in range(x.size):
tmp_val = x[idx]
# f(x + h)の計算
x[idx] = tmp_val + h
fxh1 = f(x)
# f(x - h)の計算
x[idx] = tmp_val - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2 * h)
# 値を元に戻す
x[idx] = tmp_val
return grad
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
N, C, H, W = input_data.shape
out_h = (H + 2pad - filter_h)//stride + 1
out_w = (W + 2pad - filter_w)//stride + 1
img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
return col
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
N, C, H, W = input_shape
out_h = (H + 2pad - filter_h)//stride + 1
out_w = (W + 2pad - filter_w)//stride + 1
col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)
img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]
return img[:, :, pad:H + pad, pad:W + pad]
【考察】
- ネットワークの形を変化させることの具体的なイメージがついた。
- 講義で、誤差関数として、2値分類・多クラス分類に交差エントロピー誤差、回帰に二乗和誤差を利用していた。しかし、未だに、正解というものがないのので、今後、臨機応変に試していきたい。
###DN15_Jupyter演習2
【演習実施結果】
# サンプルとする関数
#yの値を予想するAI
def f(x):
y = 3 * x[0] + 2 * x[1]
return y
# 初期設定
def init_network():
# print("##### ネットワークの初期化 #####")
network = {}
nodesNum = 10
network['W1'] = np.random.randn(2, nodesNum)
network['W2'] = np.random.randn(nodesNum)
network['b1'] = np.random.randn(nodesNum)
network['b2'] = np.random.randn()
# print_vec("重み1", network['W1'])
# print_vec("重み2", network['W2'])
# print_vec("バイアス1", network['b1'])
# print_vec("バイアス2", network['b2'])
return network
# 順伝播
def forward(network, x):
# print("##### 順伝播開始 #####")
W1, W2 = network['W1'], network['W2']
b1, b2 = network['b1'], network['b2']
u1 = np.dot(x, W1) + b1
#z1 = relu(u1)
## 試してみよう
z1 = sigmoid(u1)
u2 = np.dot(z1, W2) + b2
y = u2
# print_vec("総入力1", u1)
# print_vec("中間層出力1", z1)
# print_vec("総入力2", u2)
# print_vec("出力1", y)
# print("出力合計: " + str(np.sum(y)))
return z1, y
# 誤差逆伝播
def backward(x, d, z1, y):
# print("\n##### 誤差逆伝播開始 #####")
grad = {}
W1, W2 = network['W1'], network['W2']
b1, b2 = network['b1'], network['b2']
# 出力層でのデルタ
delta2 = d_mean_squared_error(d, y)
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
# 中間層でのデルタ
#delta1 = np.dot(delta2, W2.T) * d_relu(z1)
## 試してみよう
delta1 = np.dot(delta2, W2.T) * d_sigmoid(z1)
delta1 = delta1[np.newaxis, :]
# b1の勾配
grad['b1'] = np.sum(delta1, axis=0)
x = x[np.newaxis, :]
# W1の勾配
grad['W1'] = np.dot(x.T, delta1)
# print_vec("偏微分_重み1", grad["W1"])
# print_vec("偏微分_重み2", grad["W2"])
# print_vec("偏微分_バイアス1", grad["b1"])
# print_vec("偏微分_バイアス2", grad["b2"])
return grad
# サンプルデータを作成
data_sets_size = 100000
data_sets = [0 for i in range(data_sets_size)]
for i in range(data_sets_size):
data_sets[i] = {}
# ランダムな値を設定
data_sets[i]['x'] = np.random.rand(2)
## 試してみよう_入力値の設定
#data_sets[i]['x'] = np.random.rand(2) * 10 -5 # -5〜5のランダム数値
# 目標出力を設定
data_sets[i]['d'] = f(data_sets[i]['x'])
losses = []
# 学習率
learning_rate = 0.07
# 抽出数
epoch = 1000
# パラメータの初期化
network = init_network()
# データのランダム抽出
random_datasets = np.random.choice(data_sets, epoch)
# 勾配降下の繰り返し
for dataset in random_datasets:
x, d = dataset['x'], dataset['d']
z1, y = forward(network, x)
grad = backward(x, d, z1, y)
# パラメータに勾配適用
for key in ('W1', 'W2', 'b1', 'b2'):
network[key] -= learning_rate * grad[key]
# 誤差
loss = mean_squared_error(d, y)
losses.append(loss)
print("##### 結果表示 #####")
lists = range(epoch)
plt.plot(lists, losses, '.')
#グラフの表示
plt.show()
【考察】
- 実装上、順伝播の際の活性化関数の変更 (例: sigmoid → relu) と、誤差逆伝播における導関数の変更がセットであることを認識した。
- 訓練データは単純な線形なものであったが、訓練データにおける x の範囲を変更しただけでも、モデルの収束に大きな影響が発生することを実感できた。
- 環境の構築は、自分で構築できることが条件であることを再認識できた。