forked from zuojx1013/NyPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathocr.py
More file actions
105 lines (85 loc) · 3.77 KB
/
Copy pathocr.py
File metadata and controls
105 lines (85 loc) · 3.77 KB
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
import numpy as np
import json
from numpy import matrix
from math import pow
from collections import namedtuple
import math
import os
import random
class OCRNeuralNetwork:
LEARNING_RATE=0.1
WIDTH_IN_PIXELS=20
NN_FILE_PATH='nn_data.json'
def __init__(self,num_hidden_nodes,data_matrix,data_labels,training_indices,use_file=True):
#sigmoid函数
self.sigmoid=np.vectorize(self._sigmoid_scalar)
#sigmoid求导函数
self.sigmoid_prime=np.vectorize(self._sigmoid_prime_scalar)
self._use_file=use_file
self.data_matrix=data_matrix
self.data_labels=data_labels
if (not os.path.isfile(OCRNeuralNetwork.NN_FILE_PATH) or not use_file):
#初始化神经网络
self.theta1=self._rand_initialize_weights(160,num_hidden_nodes)
self.theta2=self._rand_initialize_weights(num_hidden_nodes,10)
self.input_layer_bias=self._rand_initialize_weights(1,num_hidden_nodes)
self.hidden_layer_bias=self._rand_initialize_weights(1,10)
#训练并保存
TrainData=namedtuple('TrainData',['y0','label'])
self.train([TrainData(self.data_matrix[i],int(self.data_labels[i])) for i in training_indices])
else:
self._load()
def _rand_initialize_weights(self,size_in,size_out):
return [((x*0.12)-0.06) for x in np.random.rand(size_out,size_in)]
def _sigmoid_scalar(self,z):
return 1/(1+math.e**-z)
def _sigmoid_prime_scalar(self,z):
return self.sigmoid(z)*(1-self.sigmoid(z))
def train(self,training_data_array):
for data in training_data_array:
#向前传播得到结果向量
y1=np.dot(np.mat(self.theta1),np.mat(data.y0).T)
sum1=y1+np.mat(self.input_layer_bias)
y1=self.sigmoid(sum1)
y2=np.dot(np.array(self.theta2),y1)
y2=np.add(y2,self.hidden_layer_bias)
y2=self.sigmoid(y2)
#后向传播得到误差向量
actual_vals=[0]*10
actual_vals[data.label]=1
output_errors=np.mat(actual_vals).T-np.mat(y2)
hidden_errors=np.multiply(np.dot(np.mat(self.theta2).T,output_errors),self.sigmoid_prime(sum1))
#更新权重矩阵与偏置向量
self.theta1+=self.LEARNING_RATE*np.dot(np.mat(hidden_errors),np.mat(data.y0))
self.theta2+=self.LEARNING_RATE*np.dot(np.mat(output_errors),np.mat(y1).T)
self.hidden_layer_bias+=self.LEARNING_RATE * output_errors
self.input_layer_bias+=self.LEARNING_RATE*hidden_errors
def predict(self,test):
y1=np.dot(np.mat(self.theta1),np.mat(test).T)
y1=y1+np.mat(self.input_layer_bias)
y1=self.sigmoid(y1)
y2=np.dot(np.array(self.theta2),y1)
y2=np.add(y2,self.hidden_layer_bias)
y2=self.sigmoid(y2)
results=y2.T.tolist()[0]
return results.index(max(results))
def save(self):
if not self._use_file:
return
json_neural_network={
"theta1":[np_mat.tolist()[0] for np_mat in self.theta1],
"theta2":[np_mat.tolist()[0] for np_mat in self.theta2],
"b1":self.input_layer_bias[0].tolist()[0],
"b2":self.hidden_layer_bias[0].tolist()[0]
}
with open(OCRNeuralNetwork.NN_FILE_PATH,'w') as jsonfile:
json.dump(json_neural_network,jsonfile)
def _load(self):
if not self._use_file:
return
with open(OCRNeuralNetwork.NN_FILE_PATH) as nnFile:
nn = json.load(nnFile)
self.theta1 = [np.array(li) for li in nn['theta1']]
self.theta2 = [np.array(li) for li in nn['theta2']]
self.input_layer_bias = [np.array(nn['b1'][0])]
self.hidden_layer_bias = [np.array(nn['b2'][0])]