2017年08月17日

しばらく重回帰分析をやります!

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

暑いとやる気が起こらなくてブログもさぼっていましたが、また投稿します。

しばらくは重回帰分析の例を紹介していきます。

なかなか面白いのでご期待ください。

では、次回から始めます。

posted by tsurutsuru at 07:54| Comment(0) | 日常茶飯事

2017年08月12日

時々基本に戻って基本事項を再確認しておきましょう・・・ディープラーニングとニューラルネットワークとの関係

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

いまこの本を学習しています。自分への覚書きとしてこのブログで理解できた(と思っている)箇所を逐次ご紹介しています。

ところが、往々にして自分がいま何を学習しているのか分からなくなることがあります。

そういう時は基本に戻るのが一番です。

再度ディープラーニングとニューラルネットワークとの関係を確認しておきます。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ディープラーニングとニューラルネットワークとの関係ですが、本には次のように書いてあります。

  ディープラーニングは、層を深くしたディープなニューラルネットワークです。

さて、ここでニューラルネットワークの学習の手順を確認しておきます。

(前提)ニューラルネットワークは、適応可能な重みとバイアスがあり、その重みとバイアスを訓練データに適応するように調整することを学習と呼ぶ。ニューラルネットワークの学習は次の4つの手順で行う。

〔ステップ1(ミニバッチ)〕
訓練データの中からランダムに一部のデータを選び出す。その選ばれたデータをミニバッチと言い、ここでは、そのミニバッチの損失関数の値を減らすことを目的とする。

〔ステップ2(勾配の算出)〕
ミニバッチの損失関数を減らすために、各重みパラメータの勾配を求める。勾配は、損失関数の値を最も減らす方向を示す。

〔ステップ3(パラメータの更新)〕
重みパラメータを勾配方向に最小量だけ更新する。

〔ステップ4(繰り返す)〕
ステップ1、ステップ2、ステップ3を繰り返す。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

上記の本で学習しようとしていることはこれだけです。

細かいテクニック的なことがたくさん書いてあるので少し混乱しますが、本質はこれだけです。

ですから、それほど難しいことは書いてないのです。

もしも、上記の本を学習されている方で途中で分からなくなったらこの基本を思い出されるといいと思います。



posted by tsurutsuru at 03:48| Comment(0) | 日常茶飯事

2017年08月11日

ディープラーニング本のサンプルプログラム(4)・・・4章のgradient_methodt.pyなど

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

この本を学習しています。

この本の構成は次の通りです。

1章 Python入門
2章 パーセプトロン
3章 ニューラルネットワーク
4章 ニューラルネットワークの学習
5章 誤差逆伝播法
6章 学習に関するテクニック
7章 畳み込みニューラルネットワーク
8章 ディープラーニング
付録A Softmax-with-Loss レイヤの計算グラフ
参考文献

この学習本のサンプルプログラムを紹介しています。

今回は4章のさnです。サンプルプログラムです。

そのまえに損失関数の簡単な説明をしときます。

損失関数としては次の二つがよく使われます。

2乗和誤差:
sonshitu-f1.jpg

交差エントロピー誤差:
sonshitu-f2.jpg
このlogは底がeの自然対数です。

ちなみにy=-log xのグラフは次のようになります。
Figure_44.png

ファイル名:3dgraph1.py
----------------------------------------------------------------
# 3Dグラフの描画

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

#  対象の関数
# f(x,y) = x**2 + y**2

def func(x,y):
return x**2 + y**2

x = np.arange(-5,5,0.25)
y = np.arange(-5,5,0.25)

X, Y = np.meshgrid(x,y)

Z = func(X,Y)

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z)
plt.show()
----------------------------------------------------------------

実行結果です。
Figure_41.png

f(x0, x1)=x0^2 + x1^2のグラフです。

ファイル名:gradient_1d.py
----------------------------------------------------------------
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


def numerical_diff(f, x):
h = 1e-4 # 0.0001
return (f(x+h) - f(x-h)) / (2*h)


def function_1(x):
return 0.01*x**2 + 0.1*x


def tangent_line(f, x):
d = numerical_diff(f, x)
print(d)
y = f(x) - d*x
return lambda t: d*t + y

x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")

tf = tangent_line(function_1, 5)
y2 = tf(x)

plt.plot(x, y)
plt.plot(x, y2)
plt.show()
----------------------------------------------------------------

実行結果です。
Figure_421.png

数値微分の例です。

関数f(x)=0.01x^2 + 0.1xのグラフとx=5における接線のグラフです。

ファイル名:gradient_2d.py
----------------------------------------------------------------
# coding: utf-8
# cf.http://d.hatena.ne.jp/white_wheels/20100327/p3
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D


def _numerical_gradient_no_batch(f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x)

for idx in range(x.size):
tmp_val = x[idx]
x[idx] = float(tmp_val) + h
fxh1 = f(x) # f(x+h)

x[idx] = tmp_val - h
fxh2 = f(x) # f(x-h)
grad[idx] = (fxh1 - fxh2) / (2*h)

x[idx] = tmp_val # 値を元に戻す

return grad


def numerical_gradient(f, X):
if X.ndim == 1:
return _numerical_gradient_no_batch(f, X)
else:
grad = np.zeros_like(X)

for idx, x in enumerate(X):
grad[idx] = _numerical_gradient_no_batch(f, x)

return grad


def function_2(x):
if x.ndim == 1:
return np.sum(x**2)
else:
return np.sum(x**2, axis=1)


def tangent_line(f, x):
d = numerical_gradient(f, x)
print(d)
y = f(x) - d*x
return lambda t: d*t + y

if __name__ == '__main__':
x0 = np.arange(-2, 2.5, 0.25)
x1 = np.arange(-2, 2.5, 0.25)
X, Y = np.meshgrid(x0, x1)

X = X.flatten()
Y = Y.flatten()

grad = numerical_gradient(function_2, np.array([X, Y]) )

plt.figure()
plt.quiver(X, Y, -grad[0], -grad[1], angles="xy",color="#666666")#,headwidth=10,scale=40,color="#444444")
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.xlabel('x0')
plt.ylabel('x1')
plt.grid()
plt.legend()
plt.draw()
plt.show()
----------------------------------------------------------------

実行結果です。
Figure_422.png

関数f(x0, x1)=x0^2 + x1^2のグラフの各点での勾配をベクトルで表しています。

ファイル名:gradient_method.py
----------------------------------------------------------------
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
from gradient_2d import numerical_gradient


def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x
x_history = []

for i in range(step_num):
x_history.append( x.copy() )

grad = numerical_gradient(f, x)
x -= lr * grad

return x, np.array(x_history)


def function_2(x):
return x[0]**2 + x[1]**2

init_x = np.array([-3.0, 4.0])

lr = 0.1
step_num = 20
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)

plt.plot( [-5, 5], [0,0], '--b')
plt.plot( [0,0], [-5, 5], '--b')
plt.plot(x_history[:,0], x_history[:,1], 'o')

plt.xlim(-3.5, 3.5)
plt.ylim(-4.5, 4.5)
plt.xlabel("X0")
plt.ylabel("X1")
plt.show()
----------------------------------------------------------------

実行結果です。
Figure_43.png

これは、関数f(x0, x1)=x0^2 + x1^2が最小値を取る点を勾配降下法を使って求めている様子を示しています。

初期値は(x0, x1)=(-3, 4)です。

今回はここまでです。

続きは次回で。

posted by tsurutsuru at 17:57| Comment(0) | 日常茶飯事