神经网络和深度学习(一)

来源:互联网 发布:刷qq会员软件 编辑:程序博客网 时间:2024/05/29 14:20

   这两天看了 Neural Networks and Deep Learning  网上在线书目的第一章的内容 和 斯坦福大学 《机器学习》的公开课,学习了两种主要的神经网络结构和机器学习中重要的算法——随机梯度下降算法。现在总结如下:

        一个计算模型要划分为神经网络,通常需要大量彼此连接的节点(神经元),具有两个特特性:

               1.每个神经元通过某种特定的输出函数(或称 激励函数 activation function)计算处理来自其他相邻神经元的加权输入值

                2.神经元之间的信息传递的强度,用所谓加权值来定义,算法不断自我学习,调整权值weights

      在此基础上,神经网络的计算模型,依靠大量的数据来训练。

    几个概念:

  cost function(成本函数) : 用来定量评估根据特定输入值计算出来的输出结果,离正确值的偏差

  learning algorithm       :   根据cost function的结果,自我纠正,最快找到神经元之间的最优化的weights权重


    神经元Perceptron :

  

图1 Perceptron neuron


        其中x1, x2, x3 为inputs ,且必须为二进制数字(0 or 1),outputs 也是只有二进制输出。w 为计算权重,这个w设计是重点也是难点。其中计算公式如下:


简化公式, ,其中w 和 x 分别代表权重和输入向量 ,用 偏置 b= -threshold,



 

    神经元Sigmoid :

      
图2 Sigmoid neurons

      比较percrptron 神经元和 Sigmoid神经元,发现他们的结构是一样的,但是对于inputs取值不同,Sigmoid 神经元的Inputs 可以取0~1中的任意值,而且输出值不是0 or 1, 而是 ,这里σ 被称为 sigmoid 函数,定义如下:

     所以,inputs为x1, x2, ..., weights w1, w2,..., bias b 所对应的sigmoid neuron 的输出为:
    
       根据公式,可以得到sigmoid 函数的响应曲线,如下


         


      神经网络的架构




          如上图所示,神经网络架构包括输入层、输出层和隐藏层。这种多层网络被称为  multilayer  perceptrons or MLPs  


   梯度下降算法(gradient descent):

       为了能够检验对于所有的训练输入值x,我们选择的weihts权重 和 biases偏置 使得输出值都近似和 y(x) 相等,使用了一个cost function(成本函数 or loss or objective function):

其中,w 代表网络中所有权重的集合,b 代表所有的偏置,n 是训练输入的总数目,a 是输出向量(依赖于x 、w、b)
如果C(w,b) ≈ 0 , 那么 对于所有的training inputs x, y(x) 约等于output a .非常好
如果 C(w,b) 非常大,那么说明 对于很多inputs ,y(x)不收敛到outputs a。
我们训练算法的目的是minimize 函数C(w,b),换句话说,我们想要找到一系列的w(权重)和b(偏置),使得 C(w,b) 尽可能的小。
我们使用的算法 就是 梯度下降算法



        我们要找到上图中的最低值,使用的方法是高数中的【梯度】,就是用来求变化率最大的地方,也即是沿着哪个方向,C(w,b)的值下降最快,这就是梯度下降算法的核心思想。(此处用v1, v2来代表w 和 b)
      ∆v1 和∆v2 分别代表在v1方向和v2方向上的变化量, ∆C表示C(v1,v2)的变化量
    
       我们现在的想法是 找到合适的∆v1 、∆v2 使得∆C为负值,这样 C就向着变小的方向变化了。
       定义 梯度向量:
  
      此时,公式(7)可以重新表示如下:

        我们令 
                                 其中η 是一个小的正参数(被称为 学习率)
   可以得到新公式:
                           
    然后 我们可以不断更新:
                             
      如何将梯度下降算法应用在神经网络中呢?就是用梯度下降算法来不断寻找、纠正权重w 和 偏置b 来使得等式(6)取得最小值。公式如下:
      
     

     随机梯度下降算法(Stochastic Gradient Descent)

       为了解决梯度下降算法训练样本输入数据太大,学习速度太慢的问题,来加速学习,产生了一种新的算法是随机梯度下降算法。这个算法通过随机选择一定的训练输入样本来计算出一个  来代表梯度

         其中,m为随机选取的输入样本数量。 标记X1, X2,...,Xm 称作 mini-batch。
             可以得到:
                    

         
           


      应用如上网络 进行 简单的手写数字识别 的代码实现

[python] view plain copy
  1. """ 
  2. network.py 
  3. ~~~~~~~~~~ 
  4.  
  5. A module to implement the stochastic gradient descent learning 
  6. algorithm for a feedforward neural network.  Gradients are calculated 
  7. using backpropagation.  Note that I have focused on making the code 
  8. simple, easily readable, and easily modifiable.  It is not optimized, 
  9. and omits many desirable features. 
  10. """  
  11.   
  12. #### Libraries  
  13. # Standard library  
  14. import random  
  15.   
  16. # Third-party libraries  
  17. import numpy as np  
  18.   
  19. class Network(object):  
  20.   
  21.     def __init__(self, sizes):  
  22.         """The list ``sizes`` contains the number of neurons in the 
  23.         respective layers of the network.  For example, if the list 
  24.         was [2, 3, 1] then it would be a three-layer network, with the 
  25.         first layer containing 2 neurons, the second layer 3 neurons, 
  26.         and the third layer 1 neuron.  The biases and weights for the 
  27.         network are initialized randomly, using a Gaussian 
  28.         distribution with mean 0, and variance 1.  Note that the first 
  29.         layer is assumed to be an input layer, and by convention we 
  30.         won't set any biases for those neurons, since biases are only 
  31.         ever used in computing the outputs from later layers."""  
  32.         self.num_layers = len(sizes)  
  33.         self.sizes = sizes  
  34.         self.biases = [np.random.randn(y, 1for y in sizes[1:]]  
  35.         self.weights = [np.random.randn(y, x)  
  36.                         for x, y in zip(sizes[:-1], sizes[1:])]  
  37.   
  38.     def feedforward(self, a):  
  39.         """Return the output of the network if ``a`` is input."""  
  40.         for b, w in zip(self.biases, self.weights):  
  41.             a = sigmoid(np.dot(w, a)+b)  
  42.         return a  
  43.   
  44.     def SGD(self, training_data, epochs, mini_batch_size, eta,  
  45.             test_data=None):  
  46.         """Train the neural network using mini-batch stochastic 
  47.         gradient descent.  The ``training_data`` is a list of tuples 
  48.         ``(x, y)`` representing the training inputs and the desired 
  49.         outputs.  The other non-optional parameters are 
  50.         self-explanatory.  If ``test_data`` is provided then the 
  51.         network will be evaluated against the test data after each 
  52.         epoch, and partial progress printed out.  This is useful for 
  53.         tracking progress, but slows things down substantially."""  
  54.         if test_data: n_test = len(test_data)  
  55.         n = len(training_data)  
  56.         for j in xrange(epochs):  
  57.             random.shuffle(training_data)  
  58.             mini_batches = [  
  59.                 training_data[k:k+mini_batch_size]  
  60.                 for k in xrange(0, n, mini_batch_size)]  
  61.             for mini_batch in mini_batches:  
  62.                 self.update_mini_batch(mini_batch, eta)  
  63.             if test_data:  
  64.                 print "Epoch {0}: {1} / {2}".format(  
  65.                     j, self.evaluate(test_data), n_test)  
  66.             else:  
  67.                 print "Epoch {0} complete".format(j)  
  68.   
  69.     def update_mini_batch(self, mini_batch, eta):  
  70.         """Update the network's weights and biases by applying 
  71.         gradient descent using backpropagation to a single mini batch. 
  72.         The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta`` 
  73.         is the learning rate."""  
  74.         nabla_b = [np.zeros(b.shape) for b in self.biases]  
  75.         nabla_w = [np.zeros(w.shape) for w in self.weights]  
  76.         for x, y in mini_batch:  
  77.             delta_nabla_b, delta_nabla_w = self.backprop(x, y)  
  78.             nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]  
  79.             nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]  
  80.         self.weights = [w-(eta/len(mini_batch))*nw  
  81.                         for w, nw in zip(self.weights, nabla_w)]  
  82.         self.biases = [b-(eta/len(mini_batch))*nb  
  83.                        for b, nb in zip(self.biases, nabla_b)]  
  84.   
  85.     def backprop(self, x, y):  
  86.         """Return a tuple ``(nabla_b, nabla_w)`` representing the 
  87.         gradient for the cost function C_x.  ``nabla_b`` and 
  88.         ``nabla_w`` are layer-by-layer lists of numpy arrays, similar 
  89.         to ``self.biases`` and ``self.weights``."""  
  90.         nabla_b = [np.zeros(b.shape) for b in self.biases]  
  91.         nabla_w = [np.zeros(w.shape) for w in self.weights]  
  92.         # feedforward  
  93.         activation = x  
  94.         activations = [x] # list to store all the activations, layer by layer  
  95.         zs = [] # list to store all the z vectors, layer by layer  
  96.         for b, w in zip(self.biases, self.weights):  
  97.             z = np.dot(w, activation)+b  
  98.             zs.append(z)  
  99.             activation = sigmoid(z)  
  100.             activations.append(activation)  
  101.         # backward pass  
  102.         delta = self.cost_derivative(activations[-1], y) * \  
  103.             sigmoid_prime(zs[-1])  
  104.         nabla_b[-1] = delta  
  105.         nabla_w[-1] = np.dot(delta, activations[-2].transpose())  
  106.         # Note that the variable l in the loop below is used a little  
  107.         # differently to the notation in Chapter 2 of the book.  Here,  
  108.         # l = 1 means the last layer of neurons, l = 2 is the  
  109.         # second-last layer, and so on.  It's a renumbering of the  
  110.         # scheme in the book, used here to take advantage of the fact  
  111.         # that Python can use negative indices in lists.  
  112.         for l in xrange(2self.num_layers):  
  113.             z = zs[-l]  
  114.             sp = sigmoid_prime(z)  
  115.             delta = np.dot(self.weights[-l+1].transpose(), delta) * sp  
  116.             nabla_b[-l] = delta  
  117.             nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())  
  118.         return (nabla_b, nabla_w)  
  119.   
  120.     def evaluate(self, test_data):  
  121.         """Return the number of test inputs for which the neural 
  122.         network outputs the correct result. Note that the neural 
  123.         network's output is assumed to be the index of whichever 
  124.         neuron in the final layer has the highest activation."""  
  125.         test_results = [(np.argmax(self.feedforward(x)), y)  
  126.                         for (x, y) in test_data]  
  127.         return sum(int(x == y) for (x, y) in test_results)  
  128.   
  129.     def cost_derivative(self, output_activations, y):  
  130.         """Return the vector of partial derivatives \partial C_x / 
  131.         \partial a for the output activations."""  
  132.         return (output_activations-y)  
  133.   
  134. #### Miscellaneous functions  
  135. def sigmoid(z):  
  136.     """The sigmoid function."""  
  137.     return 1.0/(1.0+np.exp(-z))  
  138.   
  139. def sigmoid_prime(z):  
  140.     """Derivative of the sigmoid function."""  
  141.     return sigmoid(z)*(1-sigmoid(z))  


     抓紧时间充电——面向对象的编程C++ / Python、神经网络知识体系架构!
原创粉丝点击