誤差逆伝播法

順伝播では、入力値から重みを掛けて、中間層へと計算をして出力を導いた。
逆伝播では、出力値と正解の誤差を出し、最後の層、前の層と計算して重みを調整する

誤差逆伝播法
損失関数を2乗誤差の式として定義し、中間層の活性化関数を標準シグモイド関数として定義する

勾配降下法

二乗誤差を出力層、中間層、入力層に置き換えていくと、
E = 1/2 ||t – y||^2
E = 1/2 ||σ2(a1W2 + b2) – y||^2

E = 1/2 ||σ2(σ1(a0W1 + b1)*W2 + b2) – y||^2
E = 1/2 ||σ2(σ1(x0W1 + b1)*W2 + b2) – y||^2

勾配降下法は、関数のグラフを斜面に見立てて、関数の傾きを調べながら関数の値を小さくするような方向に少しずつ降りていくことで、関数の最小値を近位的に求める方法

df(x)/dx = limΔx→0 Δf(x)/Δx = {limh→0 f(x + Δx) – f(x)} / Δx
Δxが非常に小さい値であれば、
Δf(x) = f(x + Δx) – f(x)

Δx = -η df(x)/dx
xnew = xold -η df(x)/dx

DeepLearningでは、勾配降下法の確率的勾配降下法(SGD)などを利用する
訓練データからデータをN個抜き出し、N枚を学習させて計算された損失関数から、勾配降下法を用いてN枚ごとに重みを更新する。この枚数をバッチサイズという
訓練データを使いまわす回数をエポック数と呼ぶ

損失関数

重みやバイアスは損失関数が最小になるように調整される

損失関数の例: 二乗誤差
E = 1/2*|t – y|^2
※t=正解ラベル、y=NN出力
→ 二乗誤差を最小化するため、微分計算する

損失関数の例: クロスエントロピー
E = -Σt*log[e]y
※t=正解ラベル、y=NN出力
正解ラベルが0か1の値のみ持つ場合、正解ラベル1に対応する出力の自然対数を計算する
y=1, E=0

順伝播

入力値(0層目): x01 x02 x03 ※α:層の数、β:ノードの数
出力値(出力層):a21 a22 a23
wαβγ ※α:次の層の数、β:α層のノードの数(β番目)、γ:α-1層のノードの数(バイアスbの場合は記載なし)

中間層の計算
x11 = w111*a01 + w112a02 + w13a03 + b11
x12 = w121*a01 + w122a02 + w23a03 + b12
バイアスはパラメータとして入る
計算は行列を用いると
x1(中間層) = W1a0(入力層) + b1(バイアス) に置き換えられる

中間層の出力 a11, a12
a11 = σ1(x11)
a12 = σ1(x12)
σに活性化関数を選択し、x11 = 0 だった場合は、中間層の出力はa11 = σ1(0) = 0.5となる。シグモイド関数を挟むことで、出力は0 or 1 ではなくなる。

x2, w2, a1, b1を行列として出力層を表現すると
x2 = W2a1 + b2

最後の出力層では、softmax関数で非線形変換される。
softmax関数で確率に変換される。
yi = exp(xi)/ (exp(x1) + exp(x2) + … exp(xn)) (1≦i≦n)

DNN

入力値: x
重み: w
バイアス: b
活性化: σ

wx + b -> σ(wx + b) = 出力α

MNISTの場合、入力層は784ノード
つまり、画像認識の場合、入力層がピクセル数というイメージだ。
出力層では確率を表しており、確率の高い出力結果をoutputする
例えば、MNISTのように数字が0~9だと10通りだが、自動運転のように外景全てを認識させるとなると、無数に広がる
-> ということは1000万画素の画像認識の場合はノードは1000万?
-> 信号、人、建物、のように出力を絞れば可能か?
-> 人間の顔の場合は、目、鼻など特徴抽出ができるが、ルールがない場合は、頻度の問題が常に生じる??

活性化関数σにはシグモイド関数ReLu関数がよく用いられる
シグモイド関数: 1/(1+exp(-x))
ReLu関数: max(0,x)
-> 線形分離不可能なデータを分離するのに有効

tensorflowのインストール

TensorFlowをインストールします。
https://www.tensorflow.org/install?hl=ja

osは、ubuntu, macos, windows, raspbian とある。
何故か、python使ってる人は、centosではなく、ubuntuで構築してますね。何故だろう。centosはRedhat系ですが、ubuntuはDebianです。
centosだけでなく、ubuntuにも慣れておかないといけないですな。
あああああああああああああ、やることがガンガン増えますね。

さて、tensoflowですが、pipで入れられるようです。少し重いようで、時間がかかります。
[vagrant@localhost python]$ pip install tensorflow
Successfully installed absl-py-0.8.1 astor-0.8.0 gast-0.3.2 google-pasta-0.1.7 grpcio-1.24.1 h5py-2.10.0 keras-applications-1.0.8 keras-preprocessing-1.1.0 markdown-3.1.1 setuptools-41.4.0 tensorboard-1.14.0 tensorflow-1.14.0 tensorflow-estimator-1.14.0 termcolor-1.1.0 werkzeug-0.16.0 wheel-0.33.6 wrapt-1.11.2

kerasのモジュールも入っていますね。

公式を見ると、preview build for cpu, gpuと記載があります。
Or preview build for CPU/GPU (unstable)
pip install tf-nightly

Chainerを始めよう2

chainerでlinkはimportの際にLとする

import chainer.links as L

活性化関数はF

import chainer.functions as F

linkやfunctionをまとめて管理するのがchain

class MyNeuralNet(chainer.Chain):
from chainer import Chain, optimizers, Variable
import chainer.functions as F 
import chainer.links as L 

import numpy as np 

from sklearn import datasets, model_selection 

import seaborn as sns 
import matplotlib.pyplot as plt 

class MLP(Chain):
	def __init__(self, n_hid=100, n_out=10):
		super().__init__()
		<b>
		with self.init_scope():
			self.l1 = L.Liner(None, n_hid)
			self.l2 = L.Linear(n_hid, n_out)

	def __call__(self, x):
		hid = F.relu(self.l1(x))
		return self.l2(hid)</b>

iris = datasets.load_iris()

train_data, test_data, train_label, test_label = model_selection.train_test_split(iris.data.astype(np.float32),iris.target)

model = MLP(20, 3)

optimizer = optimizers.SGD()

optimizer.setup(model)

train_data_variable = Variable(train_data.astype(np.float32))
train_label_variable = Variable(train_label.astype(np.int32))

loss_log = []

for epoch in range(200):
	model.cleargrads()
	prod_label = model(train_data_variable)
	loss = F.softmax_cross_entropy(prod_label, train_label_variable)
	loss.backward()
	optimizer.update()

	loss_log.append(loss.data)

plt.plot(loss_log)

ん?
全結合層、ランプ関数の使い方、隠れ層の扱い、フォワードプロパゲーションなどがいまいち理解できん。。

損失関数を計算してから、パラメータを更新?

全結合層は、特徴量の取り出し(畳み込みフィルタ、ReLU、プーリング層)後に、特徴量に基づく分類を行う

ランプ関数は、f(x)= max(0,x)
一変数の実関数であり、独立変数とその絶対値の平均として容易に求められる?

隠れ層は、入力層、出力層の間

Softmax関数:多くの次元からなる入力のうち、自分の値が他の値たちに比べて一番目立っているならば、その値が11に近づく関数

フォワードプロパゲーション:レイヤーを進める方向に計算

あれ、NNでいう学習とは、パラメータの更新をforeachなどで繰り返し処理するってこと??

Chainerを始めよう1

Chainerとは
-> Deep learningのモデル、実行コードを直観的に記述できるpythonのフレームワーク
-> 使用することで、ニューラルネットワークやDeep learningの理解も深まる!?

ニューラルネットワークとは、脳のニューロンのネットワークをコンピュータ上で再現したモデル

ニューラルネットワークは、入力層(l-1層)で受け取り、隠れ層(l層)を通り、出力層(l+1層)から答えを返す

正しい答えと、NNの予想した答えとの誤差を損失関数と呼ぶ。損失関数の値が小さくなるよう値を変えていくことで、NNを学習させる


NNではWeight(結合重み)とBiasという二つのパラメータを使って、目的の値を出力する関数に近いものを作る
ニューロン同士のつながりの強さがweight
ニューロン・weightの出力に足すパラメーターbias
この関数をChainerではLinkと呼ぶ

ではchainerをインストールしましょう。

[vagrant@localhost python]$ pip install chainer
Collecting chainer
Downloading https://files.pythonhosted.org/packages/dc/bf/b561706d4e86f055841c7a5a414b5e5423bea230faa92abf5422c82cf995/chainer-6.4.0.tar.gz (876kB)
100% |████████████████████████████████| 880kB 641kB/s
Requirement already satisfied: setuptools in /home/vagrant/.pyenv/versions/3.5.2/lib/python3.5/site-packages (from chainer) (20.10.1)
Collecting typing<=3.6.6 (from chainer) Downloading https://files.pythonhosted.org/packages/4a/bd/eee1157fc2d8514970b345d69cb9975dcd1e42cd7e61146ed841f6e68309/typing-3.6.6-py3-none-any.whl Collecting typing_extensions<=3.6.6 (from chainer) Downloading https://files.pythonhosted.org/packages/62/4f/392a1fa2873e646f5990eb6f956e662d8a235ab474450c72487745f67276/typing_extensions-3.6.6-py3-none-any.whl Collecting filelock (from chainer) Downloading https://files.pythonhosted.org/packages/93/83/71a2ee6158bb9f39a90c0dea1637f81d5eef866e188e1971a1b1ab01a35a/filelock-3.0.12-py3-none-any.whl Requirement already satisfied: numpy>=1.9.0 in /home/vagrant/.pyenv/versions/3.5.2/lib/python3.5/site-packages (from chainer) (1.15.0)
Collecting protobuf<3.8.0rc1,>=3.0.0 (from chainer)
Downloading https://files.pythonhosted.org/packages/81/59/c7b0815a78fd641141f24a6ece878293eae6bf1fce40632a6ab9672346aa/protobuf-3.7.1-cp35-cp35m-manylinux1_x86_64.whl (1.2MB)
100% |████████████████████████████████| 1.2MB 1.2MB/s
Requirement already satisfied: six>=1.9.0 in /home/vagrant/.pyenv/versions/3.5.2/lib/python3.5/site-packages (from chainer) (1.11.0)
Installing collected packages: typing, typing-extensions, filelock, protobuf, chainer
Running setup.py install for chainer … done
Successfully installed chainer-6.4.0 filelock-3.0.12 protobuf-3.7.1 typing-3.6.6 typing-extensions-3.6.6

はや、数秒ですね。
[vagrant@localhost python]$ pip list
Package Version
—————– ———
awscli 1.16.198
beautifulsoup4 4.6.1
botocore 1.12.188
certifi 2018.4.16
chainer 6.4.0

import chainer

print(chainer.print_runtime_info())

Platform: Linux-2.6.32-754.14.2.el6.x86_64-x86_64-with-centos-6.10-Final
Chainer: 6.4.0
NumPy: 1.15.0
CuPy: Not Available
iDeep: Not Available
None

DNN(ディープニューラルネットワーク)

DNNはディープラーニングの一種
多数ライブラリが公開されているが、中でも”chainer”と”TensorFlow”が有名

chainerはPreferred Networksが開発、TensorFlowはGoogle

TensorFlow
https://www.tensorflow.org/

Chainer
https://tutorials.chainer.org/ja/

import data
import numpy as np 

mnist = data.load_mnist_data()
x_all = mnist['data'].astype(np.float32)/255
y_all = mnist['target'].astype(np.int32)

y_all = dense_to_one_hot(y_all)

x_train, x_test = np.split(x_all, [60000])
y_train, y_test = np.split(y_all, [60000])

tensorflowの特徴
– ニューラルネットワークだけでなく、機械学習、数値計算をカバー
– 低レベル処理も可能
– GPU利用が用意
– 複数デバイスの並列処理が容易
– 直観的に構築できる
– 難易度が高い
– 利用人口が多い

chainerの特徴
– 直観的かつシンプル
– 初心者に優しい
– 複雑な計算グラフに対応できる
– GPUでの高速処理
– 計算速度が遅い

いよいよ来たか、という感じです。
比較すると、まずはChainerで基礎をやって、それからTensorFlow って流れの方が良さそうですかね。

ディープラーニングの基礎

ニューラルネットワークとは
-> ニューロンに該当する多数のユニットから構成
-> 各ユニットは入力に対して、ユニット間の重みを加味した非線形な演算を行った結果を出力する
「入力層」→「中間層1層」→「出力層」

ディープラーニングとは
-> ニューラルネットワークの層を多数重ねたもの
「入力層」→「中間層3層」→「出力層」
-> ディープラーニングでは、バックプロパケーションと呼ばれるアルゴリズムを使用し、誤差が段々と少なくなるよう重みを調整

ディープラーニングのモデル
Deep Neural Network: DNN
→ ニューラルネットワークの層を多層にしたモデル
AutoEncoder
→ 出力と入力が一致
Convolutional Neural Network
→ 主に画像解析に用いられるモデル
Recurrent Neural Network
→ 主にテキスト解析や時系列解析に用いられる