zoukankan      html  css  js  c++  java
  • 深度学习---手写字体识别程序分析(python)

    我想大部分程序员的第一个程序应该都是“hello world”,在深度学习领域,这个“hello world”程序就是手写字体识别程序。

    这次我们详细的分析下手写字体识别程序,从而可以对深度学习建立一个基本的概念。

    1.初始化权重和偏置矩阵,构建神经网络的架构

    import numpy as np

    class network():

      def __init__(self, sizes):

        self.num_layers = len(sizes) 

        self.sizes = sizes

        self.biases = [ np.random.randn(y,1) for y in sizes[1:] ]

        self.weights = [ np.random.randn(y,x) for x,y in zip(sizes(:-1), sizes(1:)) ]

    在实例化一个神经网络时,去初始化权重和偏置的矩阵,例如

      network0 = network([784, 30, 10])

    可以初始化一个3层的神经网络, 各层神经元的个数分别为 784, 30 , 10

    2. 如何去反向传播计算代价函数的梯度?

    这个过程可以大概概括如下:

    (1)正向传播,获得每个神经元的带权输出和激活因子(a)

    (2)计算输出层的误差

    (3)反向传播计算每一层的误差和梯度

    用python实现的代码如下:

    def backprop(self, x, y):

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

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

           

           #计算每个神经元的带权输入z及激活值

      zs = []

           activation = x

           activations = [x]

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

        z = np.dot(w, activation) + b

        zs.append(z)

        activation = sigmod(z)

        activations.append(activation)

          #计算输出层误差(这里采用的是二次代价函数)

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

      delta_w[-1] = np.dot(delta, activations[-2].transpose())

      delta_b[-1] = delta

      #反向传播

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

        delta = np.dot(delta_w[-l+1].transpose(),delta)*sigmod_prime(zs[-l])

        delta_w[-l] = np.dot(delta, activations[-l-1].transpose())

        delta_b[-l] = delta

      return delta_w, delta_b

    3.如何梯度下降,更新权重和偏置?

    通过反向传播获得了更新权重和偏置的增量,进一步进行更新,梯度下降。

    def update_mini_batch(self, mini_batch, eta):

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

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

      for x,y in mini_batch:

        (这里针对一个小批量内所有样本,应用反向传播,积累权重和偏置的变化)

        delta_w_p, delta_b_p = self.backprop(x,y)

        delta_w = [ dt_w + dt_w_p for dt_w,dt_w_p in zip(delta_w, delta_w_p)]

        delta_b = [ dt_b + dt_b_p for dt_b,dt_b_p in zip(delta_b, delta_b_p)]

      self.weights = [ w-(eta/len(mini_batch)*nw) for w,nw in zip(self.weights, delta_w)]

      self.biases = [ b-(eta/len(mini_batch)*nb) for b,nb in zip(self.biases, delta_b)]

    def SGD(self, epochs, training_data,  mini_batch_size,eta, test_data=None):

      if test_data:

        n_tests = len(tast_data)

      n_training_data = len(training_data)

      for i in xrange(0, epochs):

        random.shuffle(training_data)

        mini_batches = [  training_data[k:k+mini_batch_size]

                for k in xrange(0, n_training_data, mini_batch_size)

                ]

        for mini_batch in mini_batches:

          self.update_mini_batch(mini_batch, eta)

      

  • 相关阅读:
    TCP和UDP的一些区别: TCP提供可靠传输的机制:
    rpc和 http的区别
    熔断原理与实现Golang版
    源码解读 Golang 的 sync.Map 实现原理
    mysql底层为啥用b 树不用红黑树_MySQL索引底层数据结构
    一条sql 查询语句是如何执行的
    网络相关知识
    为什么遍历 Go map 是无序的?
    Go语言 参数传递究竟是值传递还是引用传递的问题分析
    解决goland debug 调试问题 Version of Delve is too old for this version of Go
  • 原文地址:https://www.cnblogs.com/jen104/p/7593339.html
Copyright © 2011-2022 走看看