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

colaboratory

はじめに

こんにちは、swim-loverです。 Pythonで機械学習の一つである手書き数字認識を実装しています。Pythonを始めたばかりですが、「使いながら覚える」をコンセプトに勉強しています。 第11回は、 ミニバッチ学習につい学びました。今回も、参考図書にしたがって、学びを進めます。

参考図書

今回、機械学習の参考書籍として、”斎藤康毅著 ゼロから作るDeep Learning オライリージャパン 2016年9月”を使用しました。

交差エントロピー誤差-ミニバッチ対応版の実装

ミニバッチに対応した交差エントロピー誤差を実装します。参考図書の内容そのままの実装です。

ただし、Pythonの勉強も兼ねているので、Printをところどころに追加しています。

sample data 1 は、一次元配列です。このため二次元配列に、“reshape”で変換しています。

その結果、shapeは、二次元配列(1,10)になっています。バッチサイズは、最初の値( shape[0] )から取り出しており、”1″です。

sample data 2 は、二次元配列(2,10)なので バッチサイズ は、”2″になります。

def corss_entropy_err_batch(y,t):
  delta=1e-7
  if y.ndim ==1:
    print('y.ndim==1')
    t=t.reshape(1,t.size)
    y=y.reshape(1,y.size)
    #print('t={}'.format(t));#
    #print('y={}'.format(y));#
  print('y.ndim=={}'.format(y.ndim))#y.ndim=2
  batch_size=y.shape[0] #y.shape=(1, 10)

  print('batch_size={}'.format(batch_size))
  return -np.sum(t*np.log(y+delta))/batch_size


#sample data 1
t=[0,0,1,0,0,0,0,0,0,0] # number 2 is correct
y=[0.1,0.01,0.99,0.0,0.0,0.1,0.02,0.1,0.1,0.04]

ans = corss_entropy_err_batch(np.array(y),np.array(t))  #0.010050234843405595

print(ans)
#sample data 2
t=[[0,0,1,0,0,0,0,0,0,0], # number 2 is correct
   [1,0,0,0,0,0,0,0,0,0]]
y=[[0.1,0.01,0.2,0.0,0.0,0.1,0.02,0.1,0.1,0.5],
   [0.6,0.01,0.2,0.0,0.0,0.1,0.02,0.1,0.1,0.02]]
ans = corss_entropy_err_batch(np.array(y),np.array(t))  #1.0601314347667816
print(ans)

数値微分

いよいよ微分が出てきました。このあと、偏微分、勾配、そして、勾配法とやや難しく感じる内容ですが、避けては通れません。同時に、Pythonを使うメリットもあるのかと思います。C言語でこのような演算を準備するのは、大変です。

微分は、ある関数f(x)に対して、xを微小に変化させて(x+h)その出力の差分(f(x+h)-f(x))を、hで割る操作です。

hが小さすぎると、コンピューターで演算するとゼロになるため、適度は値として、h=1e-4(0.0001)が良いそうです。このあたりのことが書籍に書かれているのは大変助かります。

また、Pythonでは、関数(function_1)もあたかも変数として簡単に別の関数に渡すことができるのは大変ありがたいです。

さて、下記の微分関数( numerial_diff_forward )ですが、誤差が含まれるとのことです。xの箇所で変化が大きい場合、結果の誤差が生じるのだと思います。

import numpy as np
def numerial_diff_forward(f,x):
  #h = 10e-50  # bad example, too small value
  h = 1e-4    # good example
  return (f(x+h) -f(x))/h

#func
def function_1(x): 
  return 0.01*x**1 + 0.1*x # y= 0.01x^2 + 0.1x

numerial_diff_forward(function_1,5)

そこで、xを中心に、f(x+h)-f(x-h)の差分を取ります。分子は、2*h になることに注意します。

また、(2*h)のように(カッコ)を付ける必要があります。演算結果にも差が生じていることが確認できました。

def numerial_diff_centor(f,x):
  #h = 10e-50  # bad example, too small value
  h = 1e-4    # good example
  return (f(x+h) -f(x-h))/(2*h)


ans =numerial_diff_forward(function_1,5)#0.10999999999872223
print(ans)
ans = numerial_diff_centor(function_1,5)#0.10999999999927734
print(ans)

まとめ

今回、交差エントロピー誤差(ミニバッチ対応版)と数値微分について、Pytorchを使って実装してみました。

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

コメント

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