はじめに
こんにちは、swim-loverです。 Pythonで機械学習の一つである手書き数字認識を実装しています。Pythonを始めたばかりですが、「使いながら覚える」をコンセプトに勉強しています。 第13回は、 偏微分、勾配(gradient)について学びました。ついでに、3Dプロットについても使ってみました。今回も、参考図書にしたがって、学びを進めます。
参考図書
機械学習の参考書籍として、”斎藤康毅著 ゼロから作るDeep Learning オライリージャパン 2016年9月”を使用しました。
勾配(gradient)のPlot
前回、勾配(gradient)の3点について、勾配の値を算出しました。
つぎは勾配をベクトル図で確認してみます。
Pythonコードが複雑になってきました。
・numerical_grad(f,x)が一箇所の勾配を求める関数
・np.arange()で入力の座標データ(x0,x1)を作る。
・meshgrid()で、(0,0),(0,1),(1,0),(1,1)のようなデータの組(X,Y)を作る
・X,Y配列をnp.arrayで作り、転置を.Tで作る。(縦長の行列にする)
・numerical_grad_multi(f,X)で、Xは複数の座標を持っていて、numerical_grad_multi(f,X)から、numerical_grad(f,x)を繰り返しよんでいます。
・enumerate(X)で一組のidx,x(x0,x1)を取り出すことができる。
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
def numerical_grad(f,x):
#h = 10e-50 # bad example, too small value
h = 1e-4 # good example
grad=np.zeros_like(x) #make zero data
for idx in range(x.size):
tmp = x[idx]
#calc f(x+h)
x[idx]=tmp + h #add h only x[idx]
fxh1 = f(x)
#calc f(x-h)
x[idx]=tmp - h #subs h only x[idx]
fxh2 = f(x)
#calc grad about ixd
grad[idx]=(fxh1-fxh2)/(2*h)
x[idx]=tmp #restore tmp
return grad
def numerical_grad_multi(f, X):
grad = np.zeros_like(X)
for idx, x in enumerate(X):#extract index and x data
grad[idx] = numerical_grad(f, x) #call child func
return grad
def func_x0_x1(x):
return x[0]**2+x[1]**2
x0 = np.arange(-2, 2.0, 0.25) # make x0 data
x1 = np.arange(-2, 2.0, 0.25) # make x1 data
X, Y = np.meshgrid(x0, x1) #make lattice point
#print("array X len={}\n".format(X.size))
X = X.flatten() #convert one dim
Y = Y.flatten() #convert one dim
indata = np.array([X,Y]).T
grad = numerical_grad_multi(func_x0_x1,indata).T #convert 2xN to Nx2
print(grad.shape)
plt.figure()
plt.quiver(X, Y, -grad[0]/np.sqrt(pow(grad[0],2)+pow(grad[1],2)), -grad[1]/np.sqrt(pow(grad[0],2)+pow(grad[1],2)),np.sqrt(pow(grad[0],2)+pow(grad[1],2)),cmap="jet")
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.xlabel('x0')
plt.ylabel('x1')
plt.grid()
plt.draw()
plt.show()
ベクトルのPlotには、quiver()を用いています。ベクトルの大きさについては、矢印の長さではなく、カラーで表記するようにしました。
矢印の方向は、関数の値を最も減らす方向になります。参考図書にも重要ポイントであると書かれています。
まとめ
今回、勾配(gradient)のPlotを行いました。Pythonコードとしては、やや複雑になってきました。
引き続き、ニューラルネットワークの学習について学んでいきたいと思います。
組み込み系ソフトエンジニアをしています。これまでフロントエンド技術は避けてきましたが、食わず嫌いをやめて、勉強を始めました。
趣味は、水泳、ロードバイク、ランニング、登山です。
組み込み系技術ネタ、勉強したフロントエンド技術、たまに趣味の運動について発信していきます。
どうぞよろしくお願いします。
コメント