DL之CNN:自定义SimpleConvNet【3层,im2col优化】利用mnist数据集实现手写数字识别多分类训练来评估模型

输出结

DL之CNN:自定义SimpleConvNet【3层,im2col优化】利用mnist数据集实现手写数字识别多分类训练来评估模型

 

设计思

DL之CNN:自定义SimpleConvNet【3层,im2col优化】利用mnist数据集实现手写数字识别多分类训练来评估模型

 

核心代

class Convolution:

   def __init__(self, W, b, stride=1, pad=0):  

……

   def forward(self, x):  

       FN, C, FH, FW = self.W.shape  

       N, C, H, W = x.shape

       out_h = 1 + int((H + 2*self.pad - FH) / self.stride)

       out_w = 1 + int((W + 2*self.pad - FW) / self.stride)

       col = im2col(x, FH, FW, self.stride, self.pad)    

       col_W = self.W.reshape(FN, -1).T                  

             

       out = np.dot(col, col_W) + self.b                  

       out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

         

       self.x = x

       self.col = col

       self.col_W = col_W

       return out  

   def backward(self, dout):    

       FN, C, FH, FW = self.W.shape                  

       dout = dout.transpose(0,2,3,1).reshape(-1, FN)  

       self.db = np.sum(dout, axis=0)    

       self.dW = np.dot(self.col.T, dout)

       self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)

       dcol = np.dot(dout, self.col_W.T)  

       return dx  

class Pooling:

   def __init__(self, pool_h, pool_w, stride=1, pad=0):

       self.pool_h = pool_h

       self.pool_w = pool_w

       self.stride = stride

       self.pad = pad

       

       self.x = None

       self.arg_max = None

……

class SimpleConvNet:   #

   def __init__(self, input_dim=(1, 28, 28),  

                conv_param={'filter_num':30, 'filter_size':5, 'pad':0, 'stride':1},

                hidden_size=100, output_size=10, weight_init_std=0.01):

 

       filter_num = conv_param['filter_num']

       filter_size = conv_param['filter_size']

       filter_pad = conv_param['pad']

       filter_stride = conv_param['stride']

       input_size = input_dim[1]

       conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1

       pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))

       self.params = {}

       self.params['W1'] = weight_init_std * \

                           np.random.randn(filter_num, input_dim[0], filter_size, filter_size)

       self.params['b1'] = np.zeros(filter_num)

       self.params['W2'] = weight_init_std * \

                           np.random.randn(pool_output_size, hidden_size)

       self.params['b2'] = np.zeros(hidden_size)

       self.params['W3'] = weight_init_std * \

                           np.random.randn(hidden_size, output_size)

       self.params['b3'] = np.zeros(output_size)

       self.layers = OrderedDict()

       self.layers['Conv1'] = Convolution(self.params['W1'], self.params['b1'],

                                          conv_param['stride'], conv_param['pad'])  

       self.layers['Relu1'] = Relu()                                                

       self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2)                

       self.layers['Affine1'] = Affine(self.params['W2'], self.params['b2'])        

       self.layers['Relu2'] = Relu()

       self.layers['Affine2'] = Affine(self.params['W3'], self.params['b3'])

       self.last_layer = SoftmaxWithLoss()  

   

……

   def save_params(self, file_name="params.pkl"):  

       params = {}                            

       for key, val in self.params.items():

           params[key] = val

       with open(file_name, 'wb') as f:    

           pickle.dump(params, f)

   def load_params(self, file_name="params.pkl"):  

       with open(file_name, 'rb') as f:      

           params = pickle.load(f)

       for key, val in params.items():      

           self.params[key] = val

       for i, key in enumerate(['Conv1', 'Affine1', 'Affine2']):

           self.layers[key].W = self.params['W' + str(i+1)]

           self.layers[key].b = self.params['b' + str(i+1)]


上一篇:12月8日云栖精选夜读:智能诊断-人工智能在云平台上的新玩法


下一篇:什么是 JavaConfig?