Pythonで機械学習 手書き数字認識 学習処理 Part(14)

colaboratory

はじめに

こんにちは、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コードとしては、やや複雑になってきました。

引き続き、ニューラルネットワークの学習について学んでいきたいと思います。

コメント

タイトルとURLをコピーしました