• python 实现简单卷积网络框架


    第一步定义卷积核类:

    class Filter(object):
        # 滤波器类 对卷积核进行初始化
        def __init__(self,width,height,depth):
            # initialize the filter parameter
            self.weights=np.random.uniform(-1e-4,1e-4,(depth,height,width))
            self.bias=0
            self.weights_grad=np.zeros(self.weights.shape)
            self.bias_grad=0
        def get_weights(self):
            return self.weights
        def get_bias(self):
            return self.bias
        def update_weight(self,learning_rate):
            self.weights-=self.weights_grad*learning_rate
            self.bias-=self.bias_grad*learning_rate
    

      定义卷积层

    def conv(input_array,kernel_array,output_array,stride,bias):
        channel_number=input_array.ndim
        output_width=output_array.shape[1]
        output_height=output_array.shape[0]
        kernel_width=kernel_array.shape[-1]
        kernel_height=kernel_array.shape[-2]
        for i in range(output_height):
            for j in range(output_width):
    # get_patch 得到i,j位置对应的图像的块 output_array[i][j]=(get_patch(input_array,i,j,kernel_width,kernel_height,stride)*kernel_array).sum()+bias

      定义padding 函数:根据扩展的大小进行0填充

    def padding(input_array, zero_padding):
        if zero_padding == 0:
            return input_array
        else:
            if input_array.ndim == 3:
                input_width = input_array.shape[2]
                input_height = input_array.shape[1]
                input_depth = input_array.shape[0]
                padded_array = np.zeros((input_depth, input_height + 2 * zero_padding,
                                             input_width + 2 * zero_padding))
                padded_array[:, zero_padding:zero_padding + input_height,
                zero_padding:zero_padding + input_width] = input_array
    
            elif input_array.ndim == 2:
                input_width = input_array.shape[1]
                input_height = input_array.shape[0]
                padded_array = np.zeros((input_height + 2 * zero_padding, input_width + 2 * zero_padding))
                padded_array[zero_padding:zero_padding + input_width,
                zero_padding:zero_padding + input_height] = input_array
            return padded_array
    

      定义卷积类:

        def calculate_output_size(input_size,filter_size,zero_padding,stride):
            return (input_size-filter_size+2*zero_padding)/stride+1
    

      

    class ConvLayer(object):
        def __init__(self,input_width,input_height,channel_number,
                     filter_width,filter_height,filter_number,zero_padding,stride,
                     activator,learning_rate):
            self.input_width=input_width
            self.input_height=input_height
            self.channel_number=channel_number
            self.filter_width=filter_width
            self.filter_height=filter_height
            self.filter_number=filter_number
            self.zero_padding=zero_padding
            self.stride=stride
    # 根据(f-w+2p)/2+1 self.outpu_width=ConvLayer.calculate_output_size(self.input_width, filter_width,zero_padding,stride) self.output_height=ConvLayer.calculate_output_size(self.input_height, filter_height,zero_padding, stride)
    # 得到padding 后的图像 self.output_array=np.zeros(self.filter_number,self.output_width,self.output_height) # the output of the convolution
    # 初始化filters
    self.filters=[] # initialize filters for i in range(filter_number): self.filters.append(Filter(filter_width,filter_height,self.channel_number)) self.activator=activator self.learning_rate=learning_rate # 对 灵敏度图进行扩充 def expand_sentivity_map(self,sensitivity_array): depth=sensitivity_array.shape[0] expanded_width=(self.input_width-self.filter_width+2*self.zero_padding+1) expanded_height=(self.input_height-self.filter_height+2*self.zero_padding+1) expand_array=np.zeros((depth,expanded_height,expanded_width)) for i in range(self.output_height): for j in range(self.output_width):
    i_pos=i*self.stride j_pos=j*self.stride expand_array[:,i_pos,j_pos]=sensitivity_array[:,i,j] return expand_array
    # 创建灵敏度矩阵 def create_delta_array(self): return np.zeros((self.channnel_number,self.input_height,self.input_width)) # 前向传递 def forward(self,input_array): self.input_array=input_array # first pad image to the size needed self.padded_input_array=padding(input_array,self.zero_padding) for f in range(self.filter_number): filter=self.filters[f] conv(self.paded_input_array,filter.get_weights(),filter.get_bias()) element_wise_op(self.output_array,self.acitator.forward) # 反向传递
    def bp_sensitivity_map(self, sensitivity_array,activator): # padding sensitivity map expanded_array=self.expand_sentivity_map(sensitivity_array) expanded_width=expanded_array.shape[2] zp=(self.input_width+self.filter_width-1-expanded_width)/2 padded_array=padding(expanded_array,zp) self.delta_array=self.create_delta_array() for f in range(self.filter_number): filter=self.filter[f] filpped_weights=np.array(map(lambda i: np.rot90(i,2),filter.get_weights())) delta_array=self.create_delta_array() for d in range(delta_array.shape[0]) conv(padded_array[f],filpped_weights[d],delta_array[d],1,0) self.delta_array+=delta_array derivative_array=np.array(self.input_array) element_wise_op(derivative_array,activator.backward) self.delta_array*=derivative_array
    # 参数的梯度是 输入乘以灵敏度矩阵 def bp_gradient(self,sensitivity_array): expanded_array=self.expand_sensitivity_map(sensitivity_array) for f in range(self.filter_number): filter=self.filter[f] for d in range(filter.weights.shape[0]): conv(self.padded_input_array[d],expanded_array[f],filter.weights_grad[d],1,0) filter.bias_grad=expanded_array[f].sum()
    # 对参数进行update def update(self): for filter in self.filters: filter.update(self.learning_rate)

      

  • 相关阅读:
    再谈Dilworth定理
    区间动态规划
    单调队列优化动态规划
    暑假集训考试R2 konomi 慕
    NOIP 2000 计算器的改良
    2007 Simulation message
    COCI 2003 LIFTOVI 电梯 SPFA
    NOIP 2003 数字游戏
    USACO 2014 DEC Guard Mark 状态压缩
    使用HttpClient发送GET请求
  • 原文地址:https://www.cnblogs.com/fanhaha/p/7793462.html
Copyright © 2020-2023  润新知