2.搭建一个神经网络模型训练MNIST手写体数字数据集中遇到的问题及解决方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.搭建一个神经网络模型训练MNIST手写体数字数据集中遇到的问题及解决方法相关的知识,希望对你有一定的参考价值。

参考技术A

批量输入后,如何使用numpy矩阵计算的方法计算各权值梯度,提高计算速度

   def backprop(self, x, y):  #x为多维矩阵。每列为一个x值。 y为多维矩阵。每列为一个y值。 

        batch_num=x.shape[1]

        #print(x.shape)

        #print(y.shape)

        

        """创建两个变量,用来存储所有b值和所有w值对应的梯度值。初始化为0.nabla_b为一个list,形状与biases的形状完全一致。nabla_w 为一个list,形状与weights的形状完全一致。        

        """

        nabla_b = [np.zeros(b.shape) for b in self.biases]

        nabla_w = [np.zeros(w.shape) for w in self.weights]

        # feedforward

        """activations,用来所有中间层和输出层在一次前向计算过程中的最终输出值,即a值。该值记录下来,以供后期使用BP算法求每个b和w的梯度。    

        """     

        activation = x  #x为本批多个x为列组成的矩阵。 

        activations = [x] # list to store all the activations, layer by layer

        """zs,用来所有中间层和输出层在一次前向计算过程中的线性输出值,即z值。该值记录下来,以供后期使用BP算法求每个b和w的梯度。    

        """

        zs = [] # list to store all the z vectors, layer by layer ,zs的每个元素为本batch的x对应的z为列构成的矩阵。


        """   

                通过一次正向计算,将中间层和输出层所有的z值和a值全部计算出来,并存储起来。供接下来求梯度使用。

        """     

        for b, w in zip(self.biases, self.weights):

            #print(w.shape)

            #print(np.dot(w, activation).shape)

            #print(b.shape)

            z = np.dot(w, activation)+b   #z为本batch的x对应的z为列构成的矩阵。

            zs.append(z)

            activation = sigmoid(z)

            activations.append(activation)


        """   

                以下部分是采用BP算法求解每个可训练参数的计算方法。是权重更新过程中的关键。

        """ 

        # backward pass

        # 求出输出层的delta值

        delta = ((activations[-1]-y) * sigmoid_prime(zs[-1]))

        nabla_b[-1] = delta.mean(axis=1).reshape(-1, 1)        

        nabla_w[-1] =np.dot(delta,activations[-2].transpose())/batch_num

        

        

        # Note that the variable l in the loop below is used a little

        # differently to the notation in Chapter 2 of the book.  Here,

        # l = 1 means the last layer of neurons, l = 2 is the

        # second-last layer, and so on.  It's a renumbering of the

        # scheme in the book, used here to take advantage of the fact

        # that Python can use negative indices in lists.

        for l in range(2, self.num_layers):

            z = zs[-l]

            sp = sigmoid_prime(z)

            delta = (np.dot(self.weights[-l+1].transpose(), delta) * sp)

            nabla_b[-l] = delta.mean(axis=1).reshape(-1, 1)

            nabla_w[-l] =np.dot(delta,activations[-l-1].transpose())/batch_num

        return (nabla_b, nabla_w)


##梯度计算后,如何更新各权值


    def update_mini_batch(self, mini_batch, eta):

        """Update the network's weights and biases by applying

        gradient descent using backpropagation to a single mini batch.

        The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta``

        is the learning rate."""

        """ 初始化变量,去存储各训练参数的微分和。

        """

        nabla_b = [np.zeros(b.shape) for b in self.biases]

        nabla_w = [np.zeros(w.shape) for w in self.weights]

        """ 循环获取batch中的每个数据,获取各训练参数的微分,相加后获得各训练参数的微分和。

        """

        x_batch=None

        y_batch=None

        for x, y in mini_batch:

            if( x_batch is None):

                x_batch=x

            else:

                x_batch=np.append(x_batch,x,axis=1)    

            if( y_batch is None):

                y_batch=y

            else:

                y_batch=np.append(y_batch,y,axis=1)    

        

        

        delta_nabla_b, delta_nabla_w = self.backprop(x_batch, y_batch)

            

        nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]

        nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]

        

        """ 使用各训练参数的平均微分和与步长的乘积,去更新每个训练参数

        """

        self.weights = [w-eta*nw

                        for w, nw in zip(self.weights, nabla_w)]

        self.biases = [b-eta*nb

                       for b, nb in zip(self.biases, nabla_b)]

以上是关于2.搭建一个神经网络模型训练MNIST手写体数字数据集中遇到的问题及解决方法的主要内容,如果未能解决你的问题,请参考以下文章

深度学习笔记:基于Keras库的MNIST手写数字识别

联邦学习实战基于FATE框架的MNIST手写数字识别——卷积神经网络

基于 Tensorflow 2.x 实现多层卷积神经网络,实践 MNIST 手写数字识别

基于 Tensorflow 2.x 实现多层卷积神经网络,实践 MNIST 手写数字识别

基于 Tensorflow 2.x 实现多层卷积神经网络,实践 MNIST 手写数字识别

在PaddlePaddle上实现MNIST手写体数字识别