ニューラルネットワークで手書き文字認識
- 2016.09.08
- Neural Network Python
前回の記事でニューラルネットワークを使って為替レートを予測してみましたが、
せっかくなので、それを少し改良してTensorflowのチュートリアルと同じく手書き文字認識を試してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
import cv2 import numpy as np from itertools import * digit_w=28 digit_h=28 dim_in=digit_w*digit_h dim_out=10 hidden_count=128 learn_rate=0.005 limit=50000 #weight and bias w1 = np.random.rand(hidden_count, dim_in)-0.5 w2 = np.random.rand(dim_out, hidden_count)-0.5 b1 = np.random.rand(hidden_count)-0.5 b2 = np.random.rand(dim_out)-0.5 # activation function def activation(x): return np.maximum(0, x) #return 1.0/(1.0+np.exp(-x)) # differential def activation_dash(x): return (np.sign(x) + 1) / 2 #return (1-activation(x))@activation(x) #forward calculation def forward(x): #return w2 @ activation(w1 @ x + b1) + b2 return np.dot(w2,activation(np.dot(w1,x)+b1))+b2 # backpropagation def backward(x, diff): global w1, w2, b1, b2 #v1 = (diff @ w2) * activation_dash(w1 @ x + b1) #v2 = activation(w1 @ x + b1) v1=np.dot(diff,w2)*activation_dash(np.dot(w1,x)+b1) v2=activation(np.dot(w1,x)+b1) w1 -= learn_rate * np.outer(v1, x) b1 -= learn_rate * v1 w2 -= learn_rate * np.outer(diff, v2) b2 -= learn_rate * diff #column and row number of mnist images image_shape=np.zeros((10,2),dtype=int) #number of all mnist data data_num=np.zeros((10,1),dtype=int) #count number of mnist data images=[] for idx in range(0,10): images.append(cv2.imread("mnist_img/mnist_train"+str(idx)+".jpg",0)) #load images image=images[idx] image_shape[idx,0]=len(image[:,1])/digit_h image_shape[idx,1]=len(image[1,:])/digit_w-1 data_num[idx]=image_shape[idx,0]*image_shape[idx,1] train_count=int(sum(data_num)) train_x=np.zeros((train_count,dim_in)) train_y=np.zeros((train_count,dim_out),dtype=int) #load input data cnt=0 temp_num=0 for idx in range(0,10): print ("load image:"+str(idx)) train_y[temp_num:temp_num+int(data_num[idx]),idx]=1 #set output data temp_num+=int(data_num[idx]) image=images[idx] for i in range(0,image_shape[idx,0]): for j in range(0,image_shape [idx,1]): temp=image[digit_h*i:digit_h*(i+1),digit_w*j:digit_w*(j+1)]/255.0 #cut images train_x[cnt]=[flatten for inner in temp for flatten in inner] #flatten matrix cnt+=1 #main idxes = np.arange(train_count) _error=limit*[0] batch_size=100 for epoc in range(limit): np.random.shuffle(idxes) error = 0 cnt=0 for idx in idxes: y = forward(train_x[idx]) diff = y - train_y[idx] error += diff ** 2 cnt+=1 backward(train_x[idx], diff) if cnt==batch_size: break _error[epoc]=error print(epoc+1,error.sum(),y) result=train_count*[0] for idx in range(train_count): result[idx]=forward(train_x[idx]) #accuracy rate eval=np.argmax(train_y,axis=1)==np.argmax(result,axis=1) print (float(eval.sum())/eval.size) np.savetxt("estimated.csv",result,delimiter=",") np.savetxt("train_y.csv",train_y,delimiter=",") np.savetxt("error.csv",_error,delimiter=",") np.savetxt("w1.csv",w1,delimiter=",") np.savetxt("w2.csv",w2,delimiter=",") np.savetxt("b1.csv",b1,delimiter=",") np.savetxt("b2.csv",b2,delimiter=",") |
文字のデータはネットを探してjpg化されたものを拾ってきました。
0から9までの手書き文字がそれぞれ1枚ずつ用意されていて、
それをグレースケールで一次元のデータとして読み込んでいます。
※値は255で正規化。
データが読み込めたら後は、学習させるだけです。
上のプログラムに記載されているノード数、学習回数、学習率で実行すると、
約94%の正答率でした。学習したデータに対する正答率なので、もう少し高くても良い気もしますが、
特に何の工夫もしていませんので、こんなものでしょうか。
やる気があれば、ディープラーニングのプログラムを組んで、もう一回試してみたいです。
-
前の記事
機械学習ライブラリを使わずニューラルネットワークで為替レートを予測する 2016.06.19
-
次の記事
Unityの起動失敗と対策 2016.12.05