python: ディープラーニング用語(関数と基礎的な方法)
備忘録です。
今回は、仕組みではなくディープラーニングに関する用語をまとめた備忘録。ざっとチェックできるように記述します。
基本用語
変数
- データを入れる箱
- 箱とデータは別物
- 箱の中をのぞけばデータがわかる(参照)
次元(言葉の指すものに注意)
- 3次元ベクトル → ベクトルの要素数が3
- 3次元配列 → 要素ではなく軸の数が3
関数
変数間の対応関係を決める(処理する)
テンソル
ベクトルや行列を拡張させたN次元の数の集まり
ブロードキャスト
形状の違う行列とスカラ値との掛け算などではスカラ値がかける対象の行列に拡張されてその後で、要素ごとの演算が行われる
3点リーダー(Python)
- a=bはaが指すメモリ位置がbと同じになる
- a[...] = b(3点リーダー)はデータが上書きされ変数が指すメモリ位置は変わらない
決定境界
学習後のニューラルネットワークが作る分離領域
活性化関数と計算方法
パーセプトロン
複数の信号を入力として受け取り、一つの信号を出力する
- パラメータとして重みとバイアス(発火のしやすさー閾値)を持つ
- 単層のパーセプトロンは線形領域だけしか表現できないが、多層のパーセプトロンは非線形領域を表現可能
- 重みを決定する作業を人の手で行う必要がある
線形回帰
- 実数値であるyをxの値から予測することが回帰
- 予測するモデルが線形であれば線形回帰
ニューロン
ディープラーニングの技術は、人間の神経細胞(ニューロン)の仕組みを模したシステム
活性化関数
全結合層で求めた値(h=xW+b)は線形な変換。これに非線形な効果を与えるもの。ニューラルネットワークの表現力を増やす
ステップ関数
シグモイド関数
- ネイピア数を使用し下記の式を適用 $$ h(x) = \frac{1}{1+exp(-x)}$$
- 実数を返す
- 入力信号が重要でなければ小さな値を出力(入力が0に近ければ出力は0に近い)、入力信号が重要であれば大きな値を返す
- 出力信号の値は0から1の間
ネイピア数
- e = 2.71828
e-x乗
$$e^{0} = 1$$
$$e^{-1} = 1/2.71828=0.367879$$
$$e^{-2} = 1/2.71828/2.71828=0.135335$$
ReLu関数
- 入力が0を超えていれば入力をそのまま出力し、0以下なら0を出力する
$$h(x)=x(x>0)$$
$$h(x)=0(x<=0)$$
恒等関数
- 入力をそのまま出力する関数
ソフトマックス関数
- 出力の各ニューロンが全ての入力信号から影響を受ける
- 出力層が全部でn個あるとし、k番目の出力ykを求める計算式
$$yk = \frac{exp(ak)}{\sum_{i=0}^{n}exp(ai)}$$
- 分子・・入力信号akの指数関数
- 分母・・全ての入力信号の指数関数の和
- ソフトマックス関数は0〜1の間の実数で、総和は1となる。つまり確率として解釈
- 出力層の大小関係とソフトマックス関数適用後の大小関係は変わらないため出力層のソフトマックス関数は省略するのが一般的
ベクトルの内積
$$X * Y = x_1y_1 + x_2y_2 + x_3y_3・・・+ x_ny_n$$
※XとYはベクトルとする
- ベクトルの内積は2つのベクトルがどれだけ同じ方向を向いているかを表す。
- ベクトルの長さが1の場合に限定すると2つのベクトルが全く同じ方向を向いていれば、そのベクトルの内積は1、逆向きであれば-1になる。
- 内積の計算はnp.dot()もしくは@を使用して計算。
- 行列の積も対応する行と列の内積で求める。
ニューラルネットワークの計算
- ニューラルネットワークの計算は行列の計算としてまとめて行える
- 重み付き和の計算の後、次層のノードで活性化関数の計算を行う
- 最後の出力層では、回帰問題では恒等関数、2クラス分類問題ではシグモイド関数、多クラス分類問題ではソフトマックス関数を使用するのが一般的
バッチ
ディープラーニングの学習
損失関数
- どれだけ性能が劣るかを表す指標(逆に考えればどれだけ性能が優れているかを表せる)
- それがどれだけ悪いかをスカラとして算出
- 多クラス分類を行う場合・・・交差エントロピー誤差を用いる
- 交差エントロピー誤差は各クラスの確率と教師ラベルから求める
二乗和誤差
- ニューラルネットワークの出力と教師データの各要素の2乗を計算し、その総和で表す
$$E = \frac{1}{2}\sum_{k}(yk-tk)^2$$
one-hot表現
- 正解ラベルを1それ以外を0で表す表現
交差エントロピー誤差
$$E = -\sum_{k}t{k} log y{k}$$
- 教師データがone-hot表現の場合、不正解の場合tkは0になるため、実際の計算は正解ラベルのtk=1の部分だけになる
(例:tk=1に対する出力が0.2の場合、E = - log0.2だけの計算)
ミニバッチの際の交差エントロピー誤差
- 一個当たりの平均の損失関数を求める
$$ L = -\frac{1}{N}\sum_{n}\sum_{k}t_{nk}logy_{nk}$$
損失関数の算出
- 損失関数は全ての訓練データを対象として求める必要があり、訓練データが100個あれば、その100個の損失関数の和を指標とする
- 交差エントロピー誤差の場合、上記の1つの損失関数を求める式の総和になるため下記の式で求める(Nで割り正規化し、1個あたりの平均の損失関数を求める)
- $$E = -\frac{1}{N}\sum_{n}\sum_{k}t{nk} \log y{nk}$$
ミニバッチ学習
- ビックデータのような巨大なデータの場合、全てのデータを対象とした損失関数を求めるのは現実的ではないため、一部のデータを全体の近似として利用する
微分
- 微分とはある瞬間の変化の量を表したもの
$$\frac{df(x)}{dx} = lim_{h→0}\frac{f(x+h)-f(x)}{h}・・・(1)$$- 左辺・・・f(x)のxについての微分を表す記号
数値微分
- 上記の式のように微小な差分(例:h=1e-4など)によって関数の変化量(の近似)を求めること
丸め誤差
- 少数の小さな範囲において数値が省略されること
前方差分
- xと前方のみの差分 ((1)の計算式)
中心差分
- xを中心としてその前後の差分を計算する
$$\frac{df(x)}{dx} = lim_{h→0}\frac{f(x+h)-f(x-h)}{2h}$$
解析的微分
- y = x**2の微分は下記のように求められる
$$\frac{dy}{dx} = 2x$$
多変数関数
- 複数の入力変数を持つ関数
偏微分
- 多変数関数において一つの入力変数のみに注目して他の変数を定数と考えて微分すること
例)
$$f(x_0, x_1) = x_0^2 + x_1^2$$
このような式がある場合、偏微分は下記の二つ
$$\frac{∂f}{∂x_0}$$
$$\frac{∂f}{∂x_1}$$
- 偏微分は複数ある変数の中でターゲットとする変数を一つに絞り、他の変数はある値に固定する
高階微分
最適なパラメータ
- 損失関数が最小値をとるときのパラメータの値
勾配
- 全ての変数の偏微分をベクトルとしてまとめたもので、勾配が示す方向は関数の値を最も減らす方向
勾配法
- 勾配をうまく利用して関数の最小値を探す
- ただし、勾配法が指す方向が本当に最小値なのかどうかは保証はできない
- 現在の場所から勾配方向に一定の距離だけ進み、移動した先でも同様に勾配を求め、またその勾配方向へと進むというように繰り返し勾配方向への移動を繰り返すことで関数の値を徐々に減らしていく
$$x_0 = x_0 - η\frac{∂f}{∂x_0}$$
$$x_1 = x_1 - η\frac{∂f}{∂x_1}$$
η
- 更新の量(学習率)を表し、1回の学習でどれだけ学習すべきかどれだけパラメータを更新するかを決める。
- 値は前もって何らかの値に決めておく
勾配降下法
- 最小値を探す勾配法(下記のαを人の手で決める)
- $$ x ← x - αf'(x)$$
ニュートン法
- 2階微分を利用してαを自動で調整
- $$ x ← x - \frac{f'(x)}{f''{x}}$$
勾配上昇法
- 最大値を探す勾配法
ニューラルネットワークの学習のアルゴリズム
ニューラルネットワークは適応可能な重みとバイアスがあり、この重みとバイアスを訓練データに適応するように調整をすることを「学習」と呼ぶ。ニューラルネットワークの学習は次の4つの手順で行う。
- ミニバッチ
- 訓練データの中からランダムに一部のデータを選び出す(ミニバッチ)
- その損失関数の値を減らすことを目的とする
- 勾配の算出
- ミニバッチの損失関数を減らすために、各重みのパラメータの勾配を求める
- 勾配は損失関数の値を最も減らす方向を示す
- パラメータの更新
- 重みパラメータを勾配方向に微少量だけ更新する
- 繰り返す
- ステップ1、ステップ2、ステップ3を繰り返す
重みとバイアスの積和演算
h = xW + b
$$(h_1, h_2, h_3, h_4) = (x_1, x_2)\begin{pmatrix}w_11&w_12&w_13&w_14\\w_21&w_22&w_23&w_24\end{pmatrix}+(b_1, b_2, b_3, b_4)$$
ミニバッチで計算を行うときの行数と列すうの例
x(N行x2列) @ W(2行x4列) + b(1行x4列) = h(N行x4列)
※Nがバッチ数
誤差逆伝播法
- 予測値の計算では左側から右側へ値を伝播(順伝播)する。そして、パラメータ更新のために必要な勾配の局所的な計算を逆方向に値を伝播し行う方法
- 順伝播は数値微分によって損失関数の勾配を求めているがこれは計算に時間がかかるが逆伝播は高速に処理ができる
※∂ デル(偏微分を表す)
y = f(x)の逆伝播
$$E\frac{∂y}{∂x}$$
$$y = f(x) = x^{2}$$なら
$$\frac{∂y}{∂x}=2x$$
加算の逆伝播
- 順伝播が加算である場合の逆伝播は入力された値をそのまま次のノードへ流す(1を乗算するだけの計算のため)
乗算の逆伝播
- 順伝播の際の入力信号をひっくり返した値を乗算して下流へ流す
行列の積の逆伝播
- 上流からの勾配に順伝播時の入力を入れ替えた行列を転置した行列を乗算して流す(形状を調整している
除算の逆伝播
- 順伝播の出力の2乗にマイナスをつけた値を乗算して下流へ伝播する
分岐ノードの逆伝播
- 順伝播では同じ値がコピーされて分岐する。逆伝播では上流からの勾配の和を流す
Repeatノードの逆伝播
- 順伝播で分岐ノードが複数ある場合(複数の分岐先にコピーを送る)、逆伝播では上流からの勾配の総和(Sum)
sumノードの逆伝播
- 順伝播ではN*Dの行列の総和を流す。逆伝播では上流からの勾配を全ての矢印に分配する(Repeat)
expの逆伝播
- 逆伝播はそのexpを乗算して下流へ伝播する
sinの逆伝播
- 逆伝播はcos(x)
ReLu関数レイヤの逆伝播
- 順伝播時の入力が0より大きければ上流の値をそのまま流す
- 順伝播時の入力が0以下であれば逆伝播時は0になるので、下流への信号がそこでストップする
sigmoid関数レイヤの逆伝播
- sigmoidレイヤは順伝播の出力だけから計算することができる
$$y=\frac{1}{1 + exp(-x)}$$この式で逆伝播の計算を行う場合
$$\frac{∂L}{∂y}y(1-y)$$
Affine関数レイヤの逆伝播
- 行列の積を幾何学の分野でアフィン変換という
- このレイヤの逆伝播は下記の式で表せる
$$\frac{∂L}{∂X} = \frac{∂L}{∂Y}・W^T$$
$$\frac{∂L}{∂W} = X^T・\frac{∂L}{∂Y}$$
softmax関数レイヤの逆伝播
- 出力と教師ラベルの差分(エントロピー誤差など)を返す
- この差分(誤差)を前のレイヤに伝えることでニューラルネットワークの出力を教師ラベルに近づけるように学習する
- 誤差が小さいと前のレイヤでの学習が小さく済む
tanh関数の逆伝播
- $$\frac{∂tanh(x)}{∂x} = 1 - y^2 $$
トポロジー
- 計算グラフのつながり
計算グラフ
- 計算の過程をグラフで表したもの(複数のノードとエッジによって表現される)
- 微分を効率よく計算できる
エッジ
- ノード間を結ぶ直線
合成関数
- 複数の関数によって合成される関数
$$z = (x + y)^{2}$$は
$$z = t^{2}$$
$$t = (x + y) $$ の二つの式からなる
連鎖律(チェインルール)の原理
- ある関数が合成関数で表される場合、その合成関数の微分は、合成関数を構成するそれぞれの関数の微分の積によって表すことができる
- 上記の合成関数では、【xに関するzの微分】が、【tに関するzの微分】と【xに関するtの微分】の積によって表される
$$\frac{∂z}{∂x} = \frac{∂z}{∂t} \frac{∂t}{∂x}$$
$$\frac{∂z}{∂t} = 2t$$
$$\frac{∂t}{∂x} = 1$$
$$\frac{∂z}{∂x} = \frac{∂z}{∂t} \frac{∂t}{∂x} = 2t・1 = 2(x+y) $$
最適化
- 最適なパラメータを見つける問題を解くこと
- 学習時に下記のオプティマイザーを呼び出しパラメーターを更新する
SGD
- 最適化の一つ
- 勾配方向にパラメータを更新するというステップを何度も繰り返して徐々に最適なパラメータに近づける(確率的勾配降下法)
$$ W ← W - η\frac{∂L}{∂W}$$
重みパラメータ・・・W
損失関数の勾配・・・$$\frac{∂L}{∂W}$$
学習係数(実際には0.01や0.001といった値を前もって決めておく)・・・η
- 関数の形状が等方的でないと、非効率な経路(ジグザグ)で探索することになる
Momentum
物体が勾配方向に力を受け、その力によって物体の速度が加算される物理法則を求める
$$ v ← αv - η\frac{∂L}{∂W}$$
$$ W ← W + v$$
速度・・・v
- SGDと比べてx軸方向へ早く近づくことができ、ジグザグの動きを軽減することができる
AdaGrad
- パラメータの要素ごとに適応的に学習係数を調整しながら学習を行う手法
$$ h ← h + \frac{∂L}{∂W} @ \frac{∂L}{∂W}$$
$$ W ← W - η\frac{1}{\sqrt{h}}\frac{∂L}{∂W}$$
- 最初に大きく動き、それいに比例して更新のステップが小さくなるように調整され、y軸方向への更新度合いが弱められてジグザグの動きが軽減される
Adam
- MomentumとAdaGradを融合した方法
- ハイパーパラメータのバイアス補正が行われている
重みの初期値
- 誤差逆伝播法において全ての重みの値が均一に更新されてしまうため、重みの初期値を0にすると正しい学習が行えない(重みを均一な値に設定してはいけない)
Xavierの初期値
- 各層のアクティベーションが同様の広がりの分布になるように、前層のノードがn個のとき、平均0,標準偏差1n√1nである正規分布から初期値を生成するもの
- 主にシグモイド関数等を活性化関数として用いた時に効果を発揮
Heの初期値
過学習の抑制
Weight decay
- 過学習を抑え汎化性能を高めるテクニック。重みパラメータが小さくなるように学習を行うことを目的とした手法
- 学習の過程において大きな重みを持つことに対してペナルティを課す
- 重みをWとしたときに重みの2乗ノルム (ノルム=長さの概念の一般化)のWeight decayとして下記を損失関数に加算
$$\frac{1}{2}λW^2$$
- λは正則化の強さをコントロールするハイパーパラメータで、大きく設定すればするほど、大きな重みを取ることに対せて強いペナルティをかせる
- 重みの勾配を求める計算で、誤差逆伝播法による結果に正則化項の微分λWを加算する
L1ノルム、L2ノルム、L∞ノルム
W = (w1, w2, w3....wn)とすると
- L1ノルム・・・|w1| + |w2| + |w3|....|wn|
- L2ノルム・・・√w12 + w22 + w32.....wn2
- L∞ノルム・・・各要素の絶対値の中での最大のものmax(W, key=abs)
- ラムダを設定しレイヤの設定をする際に同時にセットする
Dropout
- 過学習を抑制するために用いられる方法
- 訓練時にニューロンをランダムに消去しながら学習する手法
- テスト時は全てのニューロンを伝達し、各ニューロンの出力に対して訓練時に消去した割合を乗算して出力する
- 上記の結果からアンサンブル学習と同じ効果を擬似的に一つのネットワークで実現していると考えられる
検証データ
- 一般的にハイパーパラメータを調整する際に使用するデータ
- 訓練データは重みやバイアスのパラメータの学習に利用
- テストデータは汎化性能をチェックするために最後に利用する
- 検証データが準備されていない時は、たとえば訓練データから20%程度検証データとして分離する
Batch Normarization
- 各層で適度な広がりを持つように強制的にアクティベーションの分布を調整する手法
- Batch Normalizationレイヤとしてデータ分布の正規化を行うレイヤをニューラルネットワークに挿入
- 利点
- 学習を早く進行させることができる(学習係数を大きくすることができる)
- 初期値にそれほど依存しない
- 過学習を抑制する(Dropoutなどの必要性を減らす)
- ミニバッチのデータを平均0、分散1のデータに変換する
$$μB ← \frac{1}{m}\sum_{i=1}^m xi$$
$$σ_B^2 ← \frac{1}{m}\sum_{i=1}^m (xi-μB)^2$$
$$\hat{x}_i ← \frac{xi-μB}{\sqrt{σ_B^2+ε}}$$
- Batch Normレイヤでこの正規化されたデータに対して固有のスケールとシフトで変換を行う
$$y_i ← γ\hat{x}_i + β$$
-
- m個の入力データの集合・・・B
- 平均・・・μB
- 分散・・・$$σ_B^2$$
- 小さな値・・・ε
- パラメータ・・・γ、β
- Barch Normを使用することで学習の進行を促進させることができ、また、重みの初期値に依存しない
ハイパーパラメータ
パラメータは重みやバイアスで勾配法などで求めていく。ハイパーパラメータは人の手で決定するパラメータ。ハイパーパラメータとして学習係数やWeight decay係数などを最適化する
ハイパーパラメータの最適化
- ハイパーパラメータの良い値が存在する範囲を、最初は大まかに設定し、その範囲の中からランダムにハイパーパラメータを選び出し、そのサンプリングした値で検証データを使用して認識精度の評価を行い、複数回繰り返して徐々に絞り込んでいく
- 大まかに・・・対数スケールで実施する(10**-3 ~ 10**3くらいのように)
- 時間を短縮・・・学習のためのエポックを小さくして、1回の評価に要する時間を短縮する
ベイズ最適化
ベイズの定理を中心とした数学を駆使してより厳密に効率よくハイパーパラメータの最適化を行う
畳み込みニューラルネットワーク(CNN)
全結合
- 隣接している層のニューロンが全て連結されている
- 出力の数も任意に決めることができる
- データの形状が無視される(例えば画像などの3次元データは1次元のデータにする必要がある等)ため形状に関する情報を生かすことができない
CNN
- 各層を流れるデータは形状のあるデータ(例えば3次元データ)
- 形状を維持するため正しくそのデータを理解できる
特徴マップ
- 畳み込み層の入出力データ
- 入力特徴マップ・・・畳み込み層の入力データ
- 出力特徴マップ・・・畳み込み層の出力データ
畳み込み演算
- 入力データに対してフィルターのウィンドウを一定の間隔でスライドさせながら適用する
- 各所でフィルターの要素と入力に対応する要素を乗算しその和を求める(積和演算)
- その結果を出力の対応する場所へ格納
CNNの重み
- フィルターのパラメータが重みに当たる
CNNのバイアス
- 畳み込み演算を行った後にそのデータに対して加算する
- バイアスは1つで適用後のすべての要素にその1つを加算する
パディング
- 畳み込み演算を行うたびに縮小されてしまうとある時点で出力サイズが1になってしまい、それ以上畳み込み演算ができなくなるため、畳み込み層の処理を行う前に入力データの周囲に固定のデータ(例:0など)を埋め出力サイズを調整する
- 例えば(4,4)の入力データの周りに幅1のパディングを行う等(周りを0で囲む形)(4, 4)の入力データに幅1のパディングを行うと(6, 6)のデータになる
ストライド
- フィルターを適用する位置の間隔
- ストライドを大きくすると出力サイズは小さくなる
- 例:(7, 7)の入力データに(3, 3)のフィルターをかけるとストライドが1なら出力サイズは(5, 5)、ストライドが2なら出力サイズは(3, 3)となる
- 出力サイズの計算方法
- 入力サイズを(H, W)、フィルターサイズを(FH, FW)、出力サイズを(OH, OW)、パディングをP、ストライドをSとすると下記の式で求められる
$$OH = \frac{H + 2P - FH}{S} + 1$$
$$OW = \frac{W + 2P - FW}{S} + 1$$
3次元データの畳み込み演算
- 入力データとフィルタのチャンネル数を同じにすること(入力データが3次元ならフィルターも3次元となる)
- フィルターのサイズは好きな値に設定できるが、チャンネルごとのフィルタのサイズは同じにする
- 画像のような3次元のデータ(縦、横、チャンネル)の入力データに対して畳み込み演算を行うには各チャンネルごとに入力データとフィルタの畳み込み演算を行い、それらの結果を加算して一つの出力を得る
3次元データの並べ方
- 3次元のデータを多次元配列として並べる場合は(channel, height, width)の順に並べる
- 通常出力は1枚(チャンネル数が1)の特徴マップになる
- 出力のチャンネル方向にも複数持たせるには、3次元のデータを持った複数のフィルタを持たせる(フィルタは4次元となる)(output_channel, input_channel, height, width)
- 例)チャンネル数3、サイズ(5, 5)のフィルターが20個ある場合(20, 3, 5, 5)となる
バイアス
- チャンネルごとに1つ(channel, 1, 1)設置
バッチ処理
- 各層を流れるデータを4次元データとして格納する
- (batch_num, channel, height, width)
- 4次元のデータ(batch_num個のデータ)に対して畳み込み演算を行う
- batch_num回分の処理を1回にまとめて行う
プーリング層
- 縦、横方向の空有感を小さくする演算
- 学習するパラメータがない。下記の最大値を取る、または、平均値をとるだけの処理
- チャンネル数は変化しない(チャンネルごとに独立して処理を行う)
Maxプーリング
- 小さくしたい大きさにするために、入力の対象領域(プーリングサイズ のサイズ)の最大値を取得する
- 画像認識などで使用
- ストライドも使用する
- プーリングのウィンドウサイズ(対象領域のサイズ)とストライドは同じ大きさにする
Averageプーリング
- 入力データの微小なずれに対してロバスト(強い、頑健)
ニューラルネットワークの高速化
ビット精度
- numpyの浮動小数点数は標準で64ビットのデータ型を使用
- ニューラルネットワークの推論及び学習は32ビットの浮動小数点数で問題なく行え、32ビットの方が高速に計算できる
- numpyで32ビットの浮動小数点数を使用するにはデータ型をastype()でnp.float32または、'f'と指定する
- ニューラルネットワークの推論は16ビットで認識精度をほとんど劣化させないが、一般的なCPUやGPUでは演算自体は32ビットで行われてしまう
- 学習した重みを保存する場合は16ビットが有効になる(32ビットの半分の容量で保存可能)
バス帯域
データを転送する帯域
CuPy
NVIDIA製のGPUを使用してへ入れt計算を行うことができるライブラ
https://www.preferred.jp/ja/projects/cupy/
CuPyはNumpyと同じ使い方ができる。裏でGPUを使用して計算