1111 * Hiden layer of BP
1212 * Output layer of BP
1313 Author: Stephen Lee
14- Program: PYTHON
14+ 1515 Date: 2017.9.20
1616 - - - - - -- - - - - - - - - - - - - - - - - - - - - - -
1717 '''
18+
1819import numpy as np
1920import matplotlib .pyplot as plt
2021
21-
2222class 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-
3823
3924 def __init__ (self ,conv1_get ,size_p1 ,bp_num1 ,bp_num2 ,bp_num3 ,rate_w = 0.2 ,rate_t = 0.2 ):
4025 '''
@@ -63,7 +48,7 @@ def __init__(self,conv1_get,size_p1,bp_num1,bp_num2,bp_num3,rate_w=0.2,rate_t=0.
6348
6449
6550 def save_model (self ,save_path ):
66- #将模型保存
51+ #save model dict with pickle
6752 import pickle
6853 model_dic = {'num_bp1' :self .num_bp1 ,
6954 'num_bp2' :self .num_bp2 ,
@@ -82,35 +67,11 @@ def save_model(self,save_path):
8267 with open (save_path , 'wb' ) as f :
8368 pickle .dump (model_dic , f )
8469
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 )
11071
11172 @classmethod
11273 def ReadModel (cls ,model_path ):
113- #类方法,读取保存的模型,返回一个实例。
74+ #read saved model
11475 import pickle
11576 with open (model_path , 'rb' ) as f :
11677 model_dic = pickle .load (f )
@@ -123,9 +84,9 @@ def ReadModel(cls,model_path):
12384 bp3 = model_dic .get ('num_bp3' )
12485 r_w = model_dic .get ('rate_weight' )
12586 r_t = model_dic .get ('rate_thre' )
126- #创建实例
87+ #create model instance
12788 conv_ins = CNN (conv_get ,size_p1 ,bp1 ,bp2 ,bp3 ,r_w ,r_t )
128- #修改实例的参数
89+ #modify model parameter
12990 conv_ins .w_conv1 = model_dic .get ('w_conv1' )
13091 conv_ins .wkj = model_dic .get ('wkj' )
13192 conv_ins .vji = model_dic .get ('vji' )
@@ -137,20 +98,22 @@ def ReadModel(cls,model_path):
13798
13899 def sig (self ,x ):
139100 return 1 / (1 + np .exp (- 1 * x ))
101+
140102 def do_round (self ,x ):
141103 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
144107 size_conv = convs [0 ]
145108 num_conv = convs [1 ]
146109 size_data = np .shape (data )[0 ]
147- #得到原图像滑动的小图, data_focus
110+ #get the data slice of original image data, data_focus
148111 data_focus = []
149112 for i_focus in range (0 , size_data - size_conv + 1 , conv_step ):
150113 for j_focus in range (0 , size_data - size_conv + 1 , conv_step ):
151114 focus = data [i_focus :i_focus + size_conv , j_focus :j_focus + size_conv ]
152115 data_focus .append (focus )
153- #计算所有卷积核得到的特征图,每个特征图以矩阵形式,存储为一个列表data_featuremap
116+ #caculate the feature map of every single kernel, and saved as list of matrix
154117 data_featuremap = []
155118 Size_FeatureMap = int ((size_data - size_conv ) / conv_step + 1 )
156119 for i_map in range (num_conv ):
@@ -161,15 +124,15 @@ def Convolute(self,data,convs,w_convs,thre_convs,conv_step):
161124 featuremap = np .asmatrix (featuremap ).reshape (Size_FeatureMap , Size_FeatureMap )
162125 data_featuremap .append (featuremap )
163126
164- #将data_focus中的focus展开为一维
127+ #expanding the data slice to One dimenssion
165128 focus1_list = []
166129 for each_focus in data_focus :
167130 focus1_list .extend (self .Expand_Mat (each_focus ))
168131 focus_list = np .asarray (focus1_list )
169132 return focus_list ,data_featuremap
170133
171- # 池化
172- def Pooling ( self , featuremaps , size_pooling ):
134+ def pooling ( self , featuremaps , size_pooling , type = 'average_pool' ):
135+ #pooling process
173136 size_map = len (featuremaps [0 ])
174137 size_pooled = int (size_map / size_pooling )
175138 featuremap_pooled = []
@@ -179,39 +142,40 @@ def Pooling(self,featuremaps,size_pooling):
179142 for i_focus in range (0 ,size_map ,size_pooling ):
180143 for j_focus in range (0 , size_map , size_pooling ):
181144 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 ))
186151 map_pooled = np .asmatrix (map_pooled ).reshape (size_pooled ,size_pooled )
187152 featuremap_pooled .append (map_pooled )
188153 return featuremap_pooled
189154
190- def Expand (self ,datas ):
191- #将三元的数据展开为1为的list
155+ def _expand (self ,datas ):
156+ #expanding three dimension data to one dimension list
192157 data_expanded = []
193158 for i in range (len (datas )):
194159 shapes = np .shape (datas [i ])
195160 data_listed = datas [i ].reshape (1 ,shapes [0 ]* shapes [1 ])
196161 data_listed = data_listed .getA ().tolist ()[0 ]
197162 data_expanded .extend (data_listed )
198- #连接所有数据
199163 data_expanded = np .asarray (data_expanded )
200164 return data_expanded
201165
202- def Expand_Mat (self ,data_mat ):
203- #用来展开矩阵为一维的list
166+ def _expand_mat (self ,data_mat ):
167+ #expanding matrix to one dimension list
204168 data_mat = np .asarray (data_mat )
205169 shapes = np .shape (data_mat )
206170 data_expanded = data_mat .reshape (1 ,shapes [0 ]* shapes [1 ])
207171 return data_expanded
208172
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 ):
210174 '''
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]
215179 '''
216180 pd_all = []
217181 i_pool = 0
@@ -226,6 +190,7 @@ def Getpd_From_Pool(self,out_map,pd_pool,num_map,size_map,size_pooling):
226190 return pd_all
227191
228192 def trian (self ,patterns ,datas_train , datas_teach , n_repeat , error_accuracy ,draw_e = bool ):
193+ #model traning
229194 print ('----------------------Start Training-------------------------' )
230195 print (' - - Shape: Train_Data ' ,np .shape (datas_train ))
231196 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_
234199 mse = 10000
235200 while rp < n_repeat and mse >= error_accuracy :
236201 alle = 0
237- print ('-------------进行第%d次学习 --------------' % rp )
202+ print ('-------------Learning Time %d --------------' % rp )
238203 for p in range (len (datas_train )):
239- #print('------------学习第%d个图像 --------------'%p)
204+ #print('------------Learning Image: %d --------------'%p)
240205 data_train = np .asmatrix (datas_train [p ])
241206 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 ,
243208 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 )
245210 shape_featuremap1 = np .shape (data_conved1 )
246211 '''
247212 print(' -----original shape ', np.shape(data_train))
248213 print(' ---- after convolution ',np.shape(data_conv1))
249214 print(' -----after pooling ',np.shape(data_pooled1))
250215 '''
251- data_bp_input = self .Expand (data_pooled1 )
252- # 计算第一层输入输出
216+ data_bp_input = self ._expand (data_pooled1 )
253217 bp_out1 = data_bp_input
254- # 计算第二层输入输出
218+
255219 bp_net_j = np .dot (bp_out1 ,self .vji .T ) - self .thre_bp2
256220 bp_out2 = self .sig (bp_net_j )
257- # 计算第三层输入输出
258221 bp_net_k = np .dot (bp_out2 ,self .wkj .T ) - self .thre_bp3
259222 bp_out3 = self .sig (bp_net_k )
260223
261- # 计算一般化误差
224+ #--------------Model Leaning ------------------------
225+ # calcluate error and gradient---------------
262226 pd_k_all = np .multiply ((data_teach - bp_out3 ), np .multiply (bp_out3 , (1 - bp_out3 )))
263227 pd_j_all = np .multiply (np .dot (pd_k_all ,self .wkj ), np .multiply (bp_out2 , (1 - bp_out2 )))
264228 pd_i_all = np .dot (pd_j_all ,self .vji )
265229
266230 pd_conv1_pooled = pd_i_all / (self .size_pooling1 * self .size_pooling1 )
267231 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 ],
269233 shape_featuremap1 [1 ],self .size_pooling1 )
270-
271- #卷积层1的权重和阈值修正,每个卷积核的权重需要修正 12*12(map) 次
272- #修正量为featuremap中点的偏导值 乘以 前一层图像focus, 整个权重模板一起更新
234+ #weight and threshold learning process---------
235+ #convolution layer
273236 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 ])
275238 delta_w = self .rate_weight * np .dot (pd_conv_list ,data_focus1 )
276239
277240 self .w_conv1 [k_conv ] = self .w_conv1 [k_conv ] + delta_w .reshape ((self .conv1 [0 ],self .conv1 [0 ]))
278241
279242 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
282244 self .wkj = self .wkj + pd_k_all .T * bp_out2 * self .rate_weight
283- # 更新ji层的权重
284245 self .vji = self .vji + pd_j_all .T * bp_out1 * self .rate_weight
285- # 更新阈值
286246 self .thre_bp3 = self .thre_bp3 - pd_k_all * self .rate_thre
287247 self .thre_bp2 = self .thre_bp2 - pd_j_all * self .rate_thre
288- # 计算总误差
248+ # calculate the sum error of all single image
289249 errors = np .sum (abs ((data_teach - bp_out3 )))
290250 alle = alle + errors
291251 #print(' ----Teach ',data_teach)
@@ -307,37 +267,39 @@ def draw_error():
307267 draw_error ()
308268 return mse
309269
310- def produce (self ,datas_test ):
311- #对验证和测试数据集进行输出
270+ def predict (self ,datas_test ):
271+ #model predict
312272 produce_out = []
313273 print ('-------------------Start Testing-------------------------' )
314274 print (' - - Shape: Test_Data ' ,np .shape (datas_test ))
315275 for p in range (len (datas_test )):
316- print ('--------测试第%d个图像----------' % p )
317276 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 ,
319278 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+
323282 bp_out1 = data_bp_input
324- # 计算第二层输入输出
325283 bp_net_j = bp_out1 * self .vji .T - self .thre_bp2
326284 bp_out2 = self .sig (bp_net_j )
327- # 计算第三层输入输出
328285 bp_net_k = bp_out2 * self .wkj .T - self .thre_bp3
329286 bp_out3 = self .sig (bp_net_k )
330287 produce_out .extend (bp_out3 .getA ().tolist ())
331288 res = [list (map (self .do_round ,each )) for each in produce_out ]
332289 return np .asarray (res )
333290
334291 def convolution (self ,data ):
335- #返回卷积和池化后的数据,用于查看图像
292+ #return the data of image after convoluting process so we can check it out
336293 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 ,
338295 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 )
340297
341298 return data_conved1 ,data_pooled1
342299
343300
301+ if __name__ == '__main__' :
302+ pass
303+ '''
304+ I will put the example on other file
305+ '''
0 commit comments