11
11
* Hiden layer of BP
12
12
* Output layer of BP
13
13
Author: Stephen Lee
14
- Program: PYTHON
14
+
15
15
Date: 2017.9.20
16
16
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
17
17
'''
18
+
18
19
import numpy as np
19
20
import matplotlib .pyplot as plt
20
21
21
-
22
22
class CNN ():
23
- conv1 = []
24
- w_conv1 = []
25
- thre_conv1 = []
26
- step_conv1 = 0
27
- size_pooling1 = 0
28
- num_bp1 = 0
29
- num_bp2 = 0
30
- num_bp3 = 0
31
- thre_bp1 = []
32
- thre_bp2 = []
33
- wkj = np .mat ([])
34
- vji = np .mat ([])
35
- rate_weight = 0
36
- rate_thre = 0
37
-
38
23
39
24
def __init__ (self ,conv1_get ,size_p1 ,bp_num1 ,bp_num2 ,bp_num3 ,rate_w = 0.2 ,rate_t = 0.2 ):
40
25
'''
@@ -63,7 +48,7 @@ def __init__(self,conv1_get,size_p1,bp_num1,bp_num2,bp_num3,rate_w=0.2,rate_t=0.
63
48
64
49
65
50
def save_model (self ,save_path ):
66
- #将模型保存
51
+ #save model dict with pickle
67
52
import pickle
68
53
model_dic = {'num_bp1' :self .num_bp1 ,
69
54
'num_bp2' :self .num_bp2 ,
@@ -82,35 +67,11 @@ def save_model(self,save_path):
82
67
with open (save_path , 'wb' ) as f :
83
68
pickle .dump (model_dic , f )
84
69
85
- print ('模型已经保存: %s' % save_path )
86
-
87
-
88
- def paste_model (self ,save_path ):
89
- #实例方法,
90
- #虽然这么写一点也不简洁。。。。
91
- #卸载这个里面的话,只是用于修改已经存在的模型,要根据读取的数据返回实例的模型,再写一个吧
92
- import pickle
93
- with open (save_path , 'rb' ) as f :
94
- model_dic = pickle .load (f )
95
- self .num_bp1 = model_dic .get ('num_bp1' )
96
- self .num_bp2 = model_dic .get ('num_bp2' )
97
- self .num_bp3 = model_dic .get ('num_bp3' )
98
- self .conv1 = model_dic .get ('conv1' )
99
- self .step_conv1 = model_dic .get ('step_conv1' )
100
- self .size_pooling1 = model_dic .get ('size_pooling1' )
101
- self .rate_weight = model_dic .get ('rate_weight' )
102
- self .rate_thre = model_dic .get ('rate_thre' )
103
- self .w_conv1 = model_dic .get ('w_conv1' )
104
- self .wkj = model_dic .get ('wkj' )
105
- self .vji = model_dic .get ('vji' )
106
- self .thre_conv1 = model_dic .get ('thre_conv1' )
107
- self .thre_bp2 = model_dic .get ('thre_bp2' )
108
- self .thre_bp3 = model_dic .get ('thre_bp3' )
109
- print ('已经成功读取模型' )
70
+ print ('Model saved: %s' % save_path )
110
71
111
72
@classmethod
112
73
def ReadModel (cls ,model_path ):
113
- #类方法,读取保存的模型,返回一个实例。
74
+ #read saved model
114
75
import pickle
115
76
with open (model_path , 'rb' ) as f :
116
77
model_dic = pickle .load (f )
@@ -123,9 +84,9 @@ def ReadModel(cls,model_path):
123
84
bp3 = model_dic .get ('num_bp3' )
124
85
r_w = model_dic .get ('rate_weight' )
125
86
r_t = model_dic .get ('rate_thre' )
126
- #创建实例
87
+ #create model instance
127
88
conv_ins = CNN (conv_get ,size_p1 ,bp1 ,bp2 ,bp3 ,r_w ,r_t )
128
- #修改实例的参数
89
+ #modify model parameter
129
90
conv_ins .w_conv1 = model_dic .get ('w_conv1' )
130
91
conv_ins .wkj = model_dic .get ('wkj' )
131
92
conv_ins .vji = model_dic .get ('vji' )
@@ -137,20 +98,22 @@ def ReadModel(cls,model_path):
137
98
138
99
def sig (self ,x ):
139
100
return 1 / (1 + np .exp (- 1 * x ))
101
+
140
102
def do_round (self ,x ):
141
103
return round (x , 3 )
142
- #卷积
143
- def Convolute (self ,data ,convs ,w_convs ,thre_convs ,conv_step ):
104
+
105
+ def convolute (self ,data ,convs ,w_convs ,thre_convs ,conv_step ):
106
+ #convolution process
144
107
size_conv = convs [0 ]
145
108
num_conv = convs [1 ]
146
109
size_data = np .shape (data )[0 ]
147
- #得到原图像滑动的小图, data_focus
110
+ #get the data slice of original image data, data_focus
148
111
data_focus = []
149
112
for i_focus in range (0 , size_data - size_conv + 1 , conv_step ):
150
113
for j_focus in range (0 , size_data - size_conv + 1 , conv_step ):
151
114
focus = data [i_focus :i_focus + size_conv , j_focus :j_focus + size_conv ]
152
115
data_focus .append (focus )
153
- #计算所有卷积核得到的特征图,每个特征图以矩阵形式,存储为一个列表data_featuremap
116
+ #caculate the feature map of every single kernel, and saved as list of matrix
154
117
data_featuremap = []
155
118
Size_FeatureMap = int ((size_data - size_conv ) / conv_step + 1 )
156
119
for i_map in range (num_conv ):
@@ -161,15 +124,15 @@ def Convolute(self,data,convs,w_convs,thre_convs,conv_step):
161
124
featuremap = np .asmatrix (featuremap ).reshape (Size_FeatureMap , Size_FeatureMap )
162
125
data_featuremap .append (featuremap )
163
126
164
- #将data_focus中的focus展开为一维
127
+ #expanding the data slice to One dimenssion
165
128
focus1_list = []
166
129
for each_focus in data_focus :
167
130
focus1_list .extend (self .Expand_Mat (each_focus ))
168
131
focus_list = np .asarray (focus1_list )
169
132
return focus_list ,data_featuremap
170
133
171
- # 池化
172
- def Pooling ( self , featuremaps , size_pooling ):
134
+ def pooling ( self , featuremaps , size_pooling , type = 'average_pool' ):
135
+ #pooling process
173
136
size_map = len (featuremaps [0 ])
174
137
size_pooled = int (size_map / size_pooling )
175
138
featuremap_pooled = []
@@ -179,39 +142,40 @@ def Pooling(self,featuremaps,size_pooling):
179
142
for i_focus in range (0 ,size_map ,size_pooling ):
180
143
for j_focus in range (0 , size_map , size_pooling ):
181
144
focus = map [i_focus :i_focus + size_pooling , j_focus :j_focus + size_pooling ]
182
- #平均池化
183
- map_pooled .append (np .average (focus ))
184
- #最大池化
185
- #map_pooled.append(np.max(focus))
145
+ if type == 'average_pool' :
146
+ #average pooling
147
+ map_pooled .append (np .average (focus ))
148
+ elif type == 'max_pooling' :
149
+ #max pooling
150
+ map_pooled .append (np .max (focus ))
186
151
map_pooled = np .asmatrix (map_pooled ).reshape (size_pooled ,size_pooled )
187
152
featuremap_pooled .append (map_pooled )
188
153
return featuremap_pooled
189
154
190
- def Expand (self ,datas ):
191
- #将三元的数据展开为1为的list
155
+ def _expand (self ,datas ):
156
+ #expanding three dimension data to one dimension list
192
157
data_expanded = []
193
158
for i in range (len (datas )):
194
159
shapes = np .shape (datas [i ])
195
160
data_listed = datas [i ].reshape (1 ,shapes [0 ]* shapes [1 ])
196
161
data_listed = data_listed .getA ().tolist ()[0 ]
197
162
data_expanded .extend (data_listed )
198
- #连接所有数据
199
163
data_expanded = np .asarray (data_expanded )
200
164
return data_expanded
201
165
202
- def Expand_Mat (self ,data_mat ):
203
- #用来展开矩阵为一维的list
166
+ def _expand_mat (self ,data_mat ):
167
+ #expanding matrix to one dimension list
204
168
data_mat = np .asarray (data_mat )
205
169
shapes = np .shape (data_mat )
206
170
data_expanded = data_mat .reshape (1 ,shapes [0 ]* shapes [1 ])
207
171
return data_expanded
208
172
209
- def Getpd_From_Pool (self ,out_map ,pd_pool ,num_map ,size_map ,size_pooling ):
173
+ def _calculate_gradient_from_pool (self ,out_map ,pd_pool ,num_map ,size_map ,size_pooling ):
210
174
'''
211
- 误差反传,从pooled到前一个map, 例如将池化层6*6的误差矩阵扩大为12*12的误差矩阵
212
- pd_pool: 是采样层的误差,list形式。。。。要改要改
213
- out_map: 前面特征图的输出,数量*size*size的列表形式
214
- return: pd_all:前面层所有的特征图的pd, num* size_map*size_map的列表形式
175
+ calcluate the gradient from the data slice of pool layer
176
+ pd_pool: list of matrix
177
+ out_map: the shape of data slice(size_map*size_map)
178
+ return: pd_all: list of matrix, [ num, size_map, size_map]
215
179
'''
216
180
pd_all = []
217
181
i_pool = 0
@@ -226,6 +190,7 @@ def Getpd_From_Pool(self,out_map,pd_pool,num_map,size_map,size_pooling):
226
190
return pd_all
227
191
228
192
def trian (self ,patterns ,datas_train , datas_teach , n_repeat , error_accuracy ,draw_e = bool ):
193
+ #model traning
229
194
print ('----------------------Start Training-------------------------' )
230
195
print (' - - Shape: Train_Data ' ,np .shape (datas_train ))
231
196
print (' - - Shape: Teach_Data ' ,np .shape (datas_teach ))
@@ -234,58 +199,53 @@ def trian(self,patterns,datas_train, datas_teach, n_repeat, error_accuracy,draw_
234
199
mse = 10000
235
200
while rp < n_repeat and mse >= error_accuracy :
236
201
alle = 0
237
- print ('-------------进行第%d次学习 --------------' % rp )
202
+ print ('-------------Learning Time %d --------------' % rp )
238
203
for p in range (len (datas_train )):
239
- #print('------------学习第%d个图像 --------------'%p)
204
+ #print('------------Learning Image: %d --------------'%p)
240
205
data_train = np .asmatrix (datas_train [p ])
241
206
data_teach = np .asarray (datas_teach [p ])
242
- data_focus1 ,data_conved1 = self .Convolute (data_train ,self .conv1 ,self .w_conv1 ,
207
+ data_focus1 ,data_conved1 = self .convolute (data_train ,self .conv1 ,self .w_conv1 ,
243
208
self .thre_conv1 ,conv_step = self .step_conv1 )
244
- data_pooled1 = self .Pooling (data_conved1 ,self .size_pooling1 )
209
+ data_pooled1 = self .pooling (data_conved1 ,self .size_pooling1 )
245
210
shape_featuremap1 = np .shape (data_conved1 )
246
211
'''
247
212
print(' -----original shape ', np.shape(data_train))
248
213
print(' ---- after convolution ',np.shape(data_conv1))
249
214
print(' -----after pooling ',np.shape(data_pooled1))
250
215
'''
251
- data_bp_input = self .Expand (data_pooled1 )
252
- # 计算第一层输入输出
216
+ data_bp_input = self ._expand (data_pooled1 )
253
217
bp_out1 = data_bp_input
254
- # 计算第二层输入输出
218
+
255
219
bp_net_j = np .dot (bp_out1 ,self .vji .T ) - self .thre_bp2
256
220
bp_out2 = self .sig (bp_net_j )
257
- # 计算第三层输入输出
258
221
bp_net_k = np .dot (bp_out2 ,self .wkj .T ) - self .thre_bp3
259
222
bp_out3 = self .sig (bp_net_k )
260
223
261
- # 计算一般化误差
224
+ #--------------Model Leaning ------------------------
225
+ # calcluate error and gradient---------------
262
226
pd_k_all = np .multiply ((data_teach - bp_out3 ), np .multiply (bp_out3 , (1 - bp_out3 )))
263
227
pd_j_all = np .multiply (np .dot (pd_k_all ,self .wkj ), np .multiply (bp_out2 , (1 - bp_out2 )))
264
228
pd_i_all = np .dot (pd_j_all ,self .vji )
265
229
266
230
pd_conv1_pooled = pd_i_all / (self .size_pooling1 * self .size_pooling1 )
267
231
pd_conv1_pooled = pd_conv1_pooled .T .getA ().tolist ()
268
- pd_conv1_all = self .Getpd_From_Pool (data_conved1 ,pd_conv1_pooled ,shape_featuremap1 [0 ],
232
+ pd_conv1_all = self ._calculate_gradient_from_pool (data_conved1 ,pd_conv1_pooled ,shape_featuremap1 [0 ],
269
233
shape_featuremap1 [1 ],self .size_pooling1 )
270
-
271
- #卷积层1的权重和阈值修正,每个卷积核的权重需要修正 12*12(map) 次
272
- #修正量为featuremap中点的偏导值 乘以 前一层图像focus, 整个权重模板一起更新
234
+ #weight and threshold learning process---------
235
+ #convolution layer
273
236
for k_conv in range (self .conv1 [1 ]):
274
- pd_conv_list = self .Expand_Mat (pd_conv1_all [k_conv ])
237
+ pd_conv_list = self ._expand_mat (pd_conv1_all [k_conv ])
275
238
delta_w = self .rate_weight * np .dot (pd_conv_list ,data_focus1 )
276
239
277
240
self .w_conv1 [k_conv ] = self .w_conv1 [k_conv ] + delta_w .reshape ((self .conv1 [0 ],self .conv1 [0 ]))
278
241
279
242
self .thre_conv1 [k_conv ] = self .thre_conv1 [k_conv ] - np .sum (pd_conv1_all [k_conv ]) * self .rate_thre
280
- # 更新kj层的权重
281
-
243
+ #all connected layer
282
244
self .wkj = self .wkj + pd_k_all .T * bp_out2 * self .rate_weight
283
- # 更新ji层的权重
284
245
self .vji = self .vji + pd_j_all .T * bp_out1 * self .rate_weight
285
- # 更新阈值
286
246
self .thre_bp3 = self .thre_bp3 - pd_k_all * self .rate_thre
287
247
self .thre_bp2 = self .thre_bp2 - pd_j_all * self .rate_thre
288
- # 计算总误差
248
+ # calculate the sum error of all single image
289
249
errors = np .sum (abs ((data_teach - bp_out3 )))
290
250
alle = alle + errors
291
251
#print(' ----Teach ',data_teach)
@@ -307,37 +267,39 @@ def draw_error():
307
267
draw_error ()
308
268
return mse
309
269
310
- def produce (self ,datas_test ):
311
- #对验证和测试数据集进行输出
270
+ def predict (self ,datas_test ):
271
+ #model predict
312
272
produce_out = []
313
273
print ('-------------------Start Testing-------------------------' )
314
274
print (' - - Shape: Test_Data ' ,np .shape (datas_test ))
315
275
for p in range (len (datas_test )):
316
- print ('--------测试第%d个图像----------' % p )
317
276
data_test = np .asmatrix (datas_test [p ])
318
- data_focus1 , data_conved1 = self .Convolute (data_test , self .conv1 , self .w_conv1 ,
277
+ data_focus1 , data_conved1 = self .convolute (data_test , self .conv1 , self .w_conv1 ,
319
278
self .thre_conv1 , conv_step = self .step_conv1 )
320
- data_pooled1 = self .Pooling (data_conved1 , self .size_pooling1 )
321
- data_bp_input = self .Expand (data_pooled1 )
322
- # 计算第一层输入输出
279
+ data_pooled1 = self .pooling (data_conved1 , self .size_pooling1 )
280
+ data_bp_input = self ._expand (data_pooled1 )
281
+
323
282
bp_out1 = data_bp_input
324
- # 计算第二层输入输出
325
283
bp_net_j = bp_out1 * self .vji .T - self .thre_bp2
326
284
bp_out2 = self .sig (bp_net_j )
327
- # 计算第三层输入输出
328
285
bp_net_k = bp_out2 * self .wkj .T - self .thre_bp3
329
286
bp_out3 = self .sig (bp_net_k )
330
287
produce_out .extend (bp_out3 .getA ().tolist ())
331
288
res = [list (map (self .do_round ,each )) for each in produce_out ]
332
289
return np .asarray (res )
333
290
334
291
def convolution (self ,data ):
335
- #返回卷积和池化后的数据,用于查看图像
292
+ #return the data of image after convoluting process so we can check it out
336
293
data_test = np .asmatrix (data )
337
- data_focus1 , data_conved1 = self .Convolute (data_test , self .conv1 , self .w_conv1 ,
294
+ data_focus1 , data_conved1 = self .convolute (data_test , self .conv1 , self .w_conv1 ,
338
295
self .thre_conv1 , conv_step = self .step_conv1 )
339
- data_pooled1 = self .Pooling (data_conved1 , self .size_pooling1 )
296
+ data_pooled1 = self .pooling (data_conved1 , self .size_pooling1 )
340
297
341
298
return data_conved1 ,data_pooled1
342
299
343
300
301
+ if __name__ == '__main__' :
302
+ pass
303
+ '''
304
+ I will put the example on other file
305
+ '''
0 commit comments