精华内容
下载资源
问答
  • 反向传播算法代码 MachineLearning-DeepLearning-NLP-LeetCode-StatisticalLearningMethod 最近在学习机器学习,深度学习,自然语言处理,统计学习方法等知识,所以决定自己将学习的相关算法用Python实现一遍,并...
  • 吴恩达机器学习课程反向传播算法的数学推导 Proof of Back Propagation Algorithm.pdf 【本文旨在给出吴恩达机器学习课程反向传播算法的数学推导】
  • 反向传播算法python实现.
  • 反向传播算法代码笔记)

    千次阅读 2018-12-11 17:44:58
    #反向传播算法定义损失函数和激活函数 def loss(network_y, real_y): ''' 返回函数的编导,损失函数使用 MSE L = 1/2 (netowork_y - real_y)^2 delta_L = network_y - real_y 损失函数使用了均方误差作为该...
    import numpy as np
    #反向传播算法定义损失函数和激活函数
    
    def loss(network_y, real_y):
        '''
        返回函数的编导,损失函数使用 MSE
        L = 1/2 (netowork_y - real_y)^2
        delta_L = network_y - real_y
        损失函数使用了均方误差作为该神经网络的损失函数,因此求导后的输入分别为网络的预测值和真实输出值,
        输出为两者的差。激活函数采用 Sigmoid 函数
        '''
        return (network_y - real_y)
    def sigmoid(z):
        """
        激活函数使用 sigmoid
        :param z:
        :return:
        """
        return 1.0 / (1.0 + np.exp(-z))
    
    def sigmoid_der(z):
        """digmoid 函数的导数 dervation of sigmoid"""
        return sigmoid(z) * (1 - sigmoid(z))
    
    #反向传播算法的具体实现
    """backprop() 函数的输入为 x 和 y ,其中x 为(3,1)的矩阵, y 为(2,1)的矩阵。
    根据反向传播算法的四个基本公式(BP1 —BP4)的计算中需要知道每一层的神经元的激活值和加权输入值,因此在进行向前椽传播时,
    使用activation 记录每一层的激活值和 zs 记录每一层的加权输入值
    首先从L 层进行计算,因此先计算输出层的误差,然后计算损失函数关于输出层L 中的偏置和权值参数的偏导。
    最后循环为range(2,num_laylwes), 意思时从网络的倒数第二层开始,往前计算第 l 层的损失值
    以及损失函数关于第 l 层的偏置和权值的偏导。最后输出一次反向传播后, 得到关于损失函数的所有参数的偏导
    """
    def backprop(x, y):
        """反向传播算法的实现"""
        """初始化网网络参数的导数,权值 w  的偏导和偏置 b 的偏导"""
        delta_w = [np.zeros(w.shape) for w  in weights]
        delta_b = [np.zeros(b.shape) for b in biases]
        """向前传播 feed forward"""
        activation = x # 把输入的数据作为第一次激活值
        activations = [x] #存储网络的激活值
        zs = []     #存储网络的加权输入值 ( z = wx +b)
        for w,b in zip(weights, biases):
            z = np.dot(w, activation) + b
            activation = sigmoid(z)
            activations.append(activation)
            zs.append(z)
    
        """反向传播 back propagation"""
        #BP1 计算输出层误差
    
        delta_L = loss(activation[-1], y)*sigmoid_der(zs[-1])
        #BP3 损失函数在输出层关于偏置的偏导
        delta_b[-1] = delta_L
        #BP4 损失函数在输出层关于权值的偏导
    
        delta_w[-1] = np.dot(delta_L, activations [-2].transpose())
    
        delta_l = delta_L
        for l in range(2, num_layers):
            # BP2 计算第1层误差
            z = zs [-1]
            sp = sigmoid_der(z)
            delta_l = np.dot(weights[-l + 1].transpose(), delta_l) *sp
            # BP3 损失函数在 l 层关于偏置的偏导
            delta_b[-1] = delta_l
            # BP4 损失函数 在 l 层关于权值的偏导
            delta_w[-1] = np.dot(delta_l, activations[-l-1].transpose())
        return (delta_w, delta_b)
    """ 定义神经网络的模型架构[ input , hidden, output ] 
    根据网络模型的大小,利用高斯分布函数的权值参数 weights 和 偏置参数 biases 产生 均值为 0 , 方差为1 
    的随机值。
    
    """
    network_sizes = [3, 4, 2]
    #初始化该神经网络的参数
    sizes = network_sizes
    num_layers = len (sizes)
    biases = [np.random.randn(h, 1) for h in sizes[1:]]
    weights = [np.random.randn(y, x) for y, x in zip(sizes[:-1], sizes[1:])]
    
    # 产生训练的数据
    
    training_x = np.random.rand(3).reshape(3, 1)
    training_y = np.array([0, 1]).reshape(2, 1)
    print("training data x :{},training data y :{}".format(training_x,training_y))
    backprop(training_x, training_y)
    

     

    展开全文
  • 训练输入向量和目标向量分别从... 这个想法是从 AliReza KashaniPour 和 Phil Brierley 创建的算法中挑选出来的。 隐藏层的激活函数是logsig,输出层是线性的! 只需按 F5 就可以了! anshuman0387[at]yahoo[dot]com :)
  • 原文链接:CHAPTER 2 How...反向传播算法最初在 1970 年代被提及,但是人们直到 David Rumelhart、Geoffrey Hinton 和 Ronald Williams 的著名的 1986 年的论文中才认识到这个算法的重要性。 反向传播的核心是一个对...

    原文链接:CHAPTER 2 How the backpropagation algorithm works

    神经网络与机器学习系列文章链接

    反向传播概述

    反向传播算法最初在 1970 年代被提及,但是人们直到 David Rumelhart、Geoffrey Hinton 和 Ronald Williams 的著名的 1986 年的论文中才认识到这个算法的重要性。

    反向传播的核心是一个对代价函数 C 关于任何权重 w 和 偏置 b 的偏导数 \partial{C}/\partial{w} 的表达式。

    这个表达式告诉我们在改变权重和偏置时,代价函数变化的快慢。

    关于代价函数的两个假设

    1. 代价函数可以被写成在每一个训练样本 x 上的代价函数 C_x 的均值 C=\frac{1}{n}\sum_{x} C_x

    2. 代价函数可以写成神经网络输出的函数。

    需要假设1的原因是,反向传播实际上是对一个独立的训练样本计算了 \partial{C_x}/\partial{w}\partial{C_x}/\partial{b}。然后通过在所有训练样本上进行平均化获得 \partial{C}/\partial{w}\partial{C}/\partial{w}

    需要假设2的原因是,要把代价函数与神经网络输出联系起来,进而与神经网络的参数联系起来。

    符号定义

    W_{jk}^{l} 是从 l-1 层的第 k 个神经元到 l 层的第 j 个神经元的权重。

    b_j^l 是第 l 层的第 j 个神经元的偏置。

    a_j^l 是第 l 层的第 j 个神经元的激活值。

    \sigma 是激活函数。

    把上面的符号向量化

    W^{l} 是权重矩阵,第 jk 列的元素是 W_{jk}^{l}

    例如第二层与第三层之间的权重矩阵是

    w^3 = { \left[      \begin{matrix}        w_{11}^3 & w_{12}^3 & w_{13}^3 & w_{14}^3\\        w_{21}^3 & w_{22}^3 & w_{23}^3 & w_{24}^3       \end{matrix} \right] }

    b^l 是偏置向量。第 j 行的元素是 b_j^l

    例如第二层的偏置向量是

    b^2 = { \left[      \begin{matrix}        b_{1}^2  \\        \\        b_{2}^2\\        \\        b_{3}^2\\        \\        b_{4}^2       \end{matrix}       \right] }

    有了这些表示 l 层的第 j 个神经元的激活值 a_j^l 就和 l-1 层的激活值通过方程关联起来了

    a^{l}_j = \sigma \left( \sum_k w^{l}_{jk} a^{l-1}_k + b^l_j \right)

    把上面式子向量化

    a^{l} = \sigma(w^l a^{l-1}+b^l)

    例如第三层的激活向量是

    { \left[  \begin{matrix}    a_{1}^3  \\    \\    a_{2}^3 \\   \end{matrix}   \right] }   =\sigma\left(   { \left[    \begin{matrix}      w_{11}^3 & w_{12}^3 & w_{13}^3 & w_{14}^3\\      w_{21}^3 & w_{22}^3 & w_{23}^3 & w_{24}^3     \end{matrix}     \right] }     { \left[     \begin{matrix}       a_{1}^2  \\       \\       a_{2}^2 \\       \\       a_{3}^2  \\       \\       a_{4}^2 \\      \end{matrix}      \right] }+      { \left[       \begin{matrix}         b_{1}^3  \\         \\         b_{2}^3 \\         \\        \end{matrix}        \right] }\right)

    a^{l} 是激活向量。第 j 行的元素是 a_j^l

    定义

    z^l \equiv w^l a^{l-1}+b^l

    a^l =\sigma(z^l)

    z^l 表示第第 l 层的带权输入。第 j 个元素是 z_j^l

    z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

    z_j^l 是第 l 层的第 j 个神经元的带权输入。

    反向传播的核心是一个对代价函数 C 关于任何权重 w 和 偏置 b 的偏导数 \partial{C}/\partial{w} 的表达式。为了计算这些值,引入一个中间量 \delta_j^l ,表示在 l 层的第 j 个神经元的误差。

    定义

    \delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

    \delta^l 是误差向量,\delta^l 的第 j 个元素是 \delta_j^l

    反向传播的四个基本方程

    \nabla_a 是求梯度运算符,\nabla_a C 结果是一个向量,其元素是偏导数 \partial C / \partial a^L_j

    \odot 是按元素乘积的运算符,{(s \odot t)}_j = s_j t_j ,例如

    \left[\begin{array}{c} 1 \\ 2 \end{array}\right]   \odot \left[\begin{array}{c} 3 \\ 4\end{array} \right] = \left[ \begin{array}{c} 1 * 3 \\ 2 * 4 \end{array} \right] = \left[ \begin{array}{c} 3 \\ 8 \end{array} \right].

    反向传播算法

    正如我们上面所讲的,反向传播算法对一个训练样本计算代价函数的梯度,C=C_x。在实践 中,通常将反向传播算法和诸如随机梯度下降这样的学习算法进行组合使用,我们会对许多训 练样本计算对应的梯度。特别地,给定一个大小为 m 的小批量数据,下面的算法在这个小批量 数据的基础上应用梯度下降学习算法:

    反向传播算法与小批量随机梯度下降算法结合的一个示意代码,完整代码参看 network.py

    def backprop(self, x, y):
            """Return a tuple ``(nabla_b, nabla_w)`` representing the
            gradient for the cost function C_x.  ``nabla_b`` and
            ``nabla_w`` are layer-by-layer lists of numpy arrays, similar
            to ``self.biases`` and ``self.weights``."""
            nabla_b = [np.zeros(b.shape) for b in self.biases]
            nabla_w = [np.zeros(w.shape) for w in self.weights]
            # feedforward
            activation = x
            activations = [x] # list to store all the activations, layer by layer
            zs = [] # list to store all the z vectors, layer by layer
            for b, w in zip(self.biases, self.weights):
                z = np.dot(w, activation)+b
                zs.append(z)
                activation = sigmoid(z)
                activations.append(activation)
            # backward pass
            delta = self.cost_derivative(activations[-1], y) * \
                sigmoid_prime(zs[-1])
            nabla_b[-1] = delta
            nabla_w[-1] = np.dot(delta, activations[-2].transpose())
            # 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
                nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
            return (nabla_b, nabla_w)
    
    复制代码
    def cost_derivative(self, output_activations, y):
            """Return the vector of partial derivatives \partial C_x /
            \partial a for the output activations."""
            return (output_activations-y)
    
    def sigmoid_prime(z):
        """Derivative of the sigmoid function."""
        return sigmoid(z)*(1-sigmoid(z))
    复制代码

    四个基本方程的证明

    我们现在证明这四个基本的方程(BP)-(BP4)。所有的这些都是多元微积分的链式法则的推论。

    证明\delta^L = \nabla_a C \odot \sigma'(z^L)

    从方程(BP1)开始,它给出了误差 \delta^l 的表达式。根据定义

    \delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

    根据关于代价函数的两个假设2 “代价函数可以写成神经网络输出的函数”,应用链式法测可知可先对神经网络输出求偏导 {\partial C}/{\partial a^L_k} 再对带权输出求偏导 {\partial a^L_k} /  {\partial z^L_j}

    \delta^L_j = \sum_k \frac{\partial C}{\partial a^L_k } \frac{\partial a^L_k}{\partial z^L_j},

    看起来上面式子很复杂,但是由于第 k 个神经元的输出激活值 a_k^l 只依赖于 当下标 k=j 时第 j 个神经元的输入权重 z_j^l。所有当 k\neq {j}\partial a^L_k / \partial z^L_j 消失了。结果我们可以简化上一个式子为

    \delta^L_j = \frac{\partial C}{\partial a^L_j} \frac{\partial a^L_j}{\partial z^L_j}.

    又因为 a^L_j = \sigma(z^L_j) 所以 \frac{\partial a^L_j}{\partial z^L_j} 可以写成 \sigma'(z^L_j),方程变为

    \delta^L_j = \frac{\partial C}{\partial a^L_j} \sigma'(z^L_j)

    这就是分量形式的(BP1),再根据\nabla_a 是求梯度运算符,\nabla_a C 结果是一个向量,其元素是偏导数 \partial C / \partial a^L_j。方程可以写成向量形式

    \delta^L ={\nabla_a {C}} \odot {\sigma'(z^L_j)}

    (BP1) 得到证明。

    证明 \delta^l = ((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l)

    证明(BP2),它个给出以下一层误差 \delta^{l+1} 的形式表示误差 \delta^l。为此,要以 \delta^l_j = \partial C / \partial z^l_j的形式重写 \delta^{l+1}_k = \partial C / \partial z^{l+1}_k,\delta^{l+1}\delta^l 通过 z_k^{l+1}z_j^l 联系起来,应用链式法测

    根据 z_k^{l+1} 的定义有

    z^{l+1}_k = \sum_j w^{l+1}_{kj } a^l_j +b^{l+1}_k = \sum_j w^{l+1}_{kj} \sigma(z^l_j) +b^{l+1}_k

    z_k^{l+1}z_j^{l} 做偏微分,得到

    \frac{\partial z^{l+1}_k}{\partial z^l_j} = w^{l+1}_{kj} \sigma'(z^l_j)

    注意虽然z^{l+1}z^{l} 所在的两层神经元连接错综复杂,但两层之间任意一对神经元(同一层内不连接)只有一条连接,即 z_k^{l+1}z_j^{l} 之间只通过 w_{kj}^{l+1} 连接。所以z_k^{l+1}z_j^{l} 做偏微分的结果很简单,只是 w^{l+1}_{kj} \sigma'(z^l_j)。把这个结果带入 \delta_j^l

    \delta^l_j = \sum_k w^{l+1}_{kj }  \delta^{l+1}_k \sigma'(z^l_j)

    这正是以分量形式写的(BP2)。

    写成向量形式

    \delta^l = ((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l)

    举例

    { \left[  \begin{matrix}    \delta_{1}^l  \\    \\    \delta_{2}^l \\    \\    ...    \\   \delta_{j}^l   \end{matrix}   \right] }   = { \left[      \begin{matrix}        w_{11}^{l+1} & w_{21}^{l+1} & w_{31}^{l+1} & ... &w_{k1}^{l+1} \\        \\        w_{12}^{l+1} & w_{22}^{l+1} & w_{32}^{l+1} & ... & w_{k2}^{l+1} \\        \\        ...        \\        w_{j1}^{l+1} & w_{j2}^{l+1} & w_{j1}^{l+1} & ... & w_{kj}^{l+1}       \end{matrix}       \right] }    { \left[    \begin{matrix}      \delta_{1}^{l+1}  \\      \\      \delta_{2}^{l+1} \\      \\      \delta_{3}^{l+1} \\      \\      ...      \\     \delta_{k}^{l+1}     \end{matrix}     \right] }     \odot     { \left[     \begin{matrix}       \sigma'(z_1^l)  \\       \\       \sigma'(z_2^l) \\       \\       \sigma'(z_3^l) \\       \\       ...       \\      \sigma'(z_k^l)      \end{matrix}      \right] }

    (BP2) 得到证明。

    证明 \frac{\partial C}{\partial b^l_j} =\delta^l_j.

    根据 z_j^l 定义

    z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

    \delta_j^l 定义

    \delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

    因此

    \frac{\partial C}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial b^l_j}

    又因为

    \frac{\partial z^l_j}{\partial b^l_j} = 1

    所以

    \frac{\partial C}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\cdot 1= \frac{\partial C}{\partial z^l_j}=\delta^l_j

    \frac{\partial C}{\partial b^l_j} =\delta^l_j

    写成向量形式

    \frac{\partial C}{\partial b^l} =\delta^l

    (BP3) 得到证明。

    证明 \frac{\partial C}{\partial w^l_{jk}} = a^{l-1}_k \delta^l_j

    根据 z_j^l 定义

    z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

    \delta_j^l 定义

    \delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

    又因为

    \frac{\partial z^l_j}{\partial w^l_{jk}} = a_k^{l-1}

    所以

    \frac{\partial C}{\partial w^l_{jk}} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial w^l_{jk}} = \delta^l_j a_k^{l-1}

    把式子向量化

    \frac{\partial C}{\partial w^l} = \delta^l (a^l)^T

    举例

    \frac{\partial C}{\partial w^l} = { \left[  \begin{matrix}    \delta_{1}^l  \\    \\    \delta_{2}^l \\    \\    ...    \\   \delta_{j}^l   \end{matrix}   \right] }{ \left[      \begin{matrix}        a_{1}^{l-1} & a_{2}^{l-1} & ... &a_{k}^{l-1}       \end{matrix}       \right] }

    (BP4) 得到证明。

    一个直观的图:

    到此关于反向传播的四个方程已经全部证明完毕。

    其他学者反向传播四个方程的证明(他写的更简明扼要些):CSDN: oio328Loio

    反向传播:全局观

    如上图所示,假设我们对 w_{jk}^l 做一点微小的扰动 \Delta w_{jk}^l, 这个扰动会沿着神经网络最终影响到代价函数 C, 代价函数的 \Delta C 改变和 \Delta w_{jk}^l 按照下面公式联系起来

    \Delta C \approx \frac{\partial C}{\partial w^l_{jk}} \Delta w^l_{jk}

    可以想象影响代价函数的一条路径是

    \Delta C \approx \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}} \Delta w^l_{jk}

    为了计算 C 的全部改变,我们需要对所有可能的路径进行求和,即

    \Delta C \approx \sum_{mnp\ldots q} \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}} \Delta w^l_{jk}

    因为

    \frac{\partial C}{\partial w^l_{jk}}=\frac{\Delta C}{\Delta w^l_{jk}}

    根据上面的三个式子可知

    \frac{\partial C}{\partial w^l_{jk} } = \sum_{mnp\ldots q} \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}}

    上面的公式看起来复杂,这里有一个相当好的直觉上的解释。我们用这个公式计算 C 关于网络中一个权重的变化率。而这个公式告诉我们的是:两个神经元之间的连接其实是关联于一个变化率因子,这仅仅是一个神经元的激活值相对于其他神经元的激活值的偏导数。路径的变化率因子就是这条路径上众多因子的乘积。整个变化率 \partial C / \partial w^l_{jk} 就是对于所有可能从初始权重到最终输出的代价函数的路径的变化率因子的和。针对某一路径,这个过程解释如下,

    如果用矩阵运算对上面式子所有的情况求和,然后尽可能化简,最后你会发现,自己就是在做反向传播!可以将反向传播想象成一种计算所有可能路径变化率求和的方式。或者,换句话说,反向传播就是一种巧妙地追踪权重和偏置微小变化的传播,抵达输出层影响代价函数的技术。

    如果你尝试用上面的思路来证明反向传播,会比本文的反向传播四个方程证明复杂许多,因为按上面的思路来证明有许多可以简化的地方。其中可以添加一个巧妙的步骤,上面方程的偏导对象是类似 a_q^{l+1} 的激活值。巧妙之处是改用加权输入,例如 z_q^{l+1} ,作为中间变量。如果没想到这个主意,而是继续使用激活值 a_q^{l+1} ,你得到的证明最后会比前文给出的证明稍稍复杂些。

    其实最早的证明的出现也不是太过神秘的事情。因为那只是对简化证明的艰辛工作的积累!


    参考文献

    [1] Michael Nielsen. CHAPTER 2 How the backpropagation algorithm works[DB/OL]. neuralnetworksanddeeplearning.com/chap2.html, 2018-06-21.

    [2] Zhu Xiaohu. Zhang Freeman.Another Chinese Translation of Neural Networks and Deep Learning[DB/OL]. github.com/zhanggyb/nn…, 2018-06-21.

    [3] oio328Loio. 神经网络学习(三)反向(BP)传播算法(1)[DB/OL]. blog.csdn.net/hoho1151191…, 2018-06-25.

    展开全文
  • 主要介绍了numpy实现神经网络反向传播算法的步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 神经网络算法,是使用计算机模拟生物神经系统,来模拟人类思维方式的算法。它的基本单位就是人工神经元。通过相互连接形成一张神经网络。 生物神经网络中,每个神经元与其他神经元连接,当它“激活”时,会传递...

    一、单个神经元

    神经网络算法,是使用计算机模拟生物神经系统,来模拟人类思维方式的算法。它的基本单位就是人工神经元。通过相互连接形成一张神经网络。

    生物神经网络中,每个神经元与其他神经元连接,当它“激活”时,会传递化学物质到相连的神经元,改变其他神经元的电位,当电位达到一定“阈值”,那么这个神经元也会被激活。

    单个人工神经元的计算公式:

    其中:

     为输入参数向量,表示其他神经元输入的信号。

     为每个输入参数的权重值,表示对应神经元信号的权重。

    θ为阈值或者偏差值,是指该激活神经元的难易程度。

    y为神经元的输出值,表示该神经元是否被激活。

    Act()为激活函数,理想的激活函数是下图(a)中的跃阶函数,“1”为神经元兴奋,“0”为神经元抑制,但由于跃阶函数具有不是连续可导等不好的性质,因此一般采用下图(b)的Sigmoid函数作为激活函数。

     

    二、全连接神经网络结构

    我们来定义一个全连接神经网络:

    全连接神经网络,就是指每一层的每个神经元都和下一层的每个神经元相连接。

    Layer:0为输入层,

    Layer:L为输出层

    其他L-1个Layer为隐层

    输入x

     

    我们称一个输入值x为一个样本

    输出 y

    变量的上标(0)(L),表示该变量处于神经网络的哪一层。

    表示第L层编号为i的神经元。 表示第L层的神经元数量。

    更好的理解神经网络,可观看此视频:https://www.bilibili.com/video/av15532370

     

    三、反向传播算法(BP算法)

    下面来说明如何调整一个神经网络的参数,也就是误差反向传播算法(BP算法)。以得到一个能够根据输入,预测正确输出的模型。

    1、首先我们要了解优化的目标

    根据人工神经元的定义,有以下三个公式:

    其中,Act()是激活函数,之前已经说过。

    根据公式(2)和公式(3),可以得出各个神经元之间的通用计算公式,如下所示:

    公式(4)是人工神经网络正向传播的核心公式。

     

    那么,我们根据什么来调整神经网络的参数,以得到一个能够正确预测结果的模型呢?请看下面的公式:

    公式(5)用来计算我们期望的输出和实际输出的“差别”,其中cost()叫做损失函数。我们的期望是损失值达到最小。

    但是,只根据一次输出的损失值,对参数进行调整,无法使模型适应所有输入样本。我们需要的是,调整参数,使得所有输入样本,得到输出的总损失值最小,而不是只让其中一个样本的损失值最小,导致其他样本损失值增大。因此有如下公式:

    公式(6)表示一个batch的所有样本输出的总损失值的平均值。其中,bn表示一个batch中样本的数量。

    为什么不用所有的样本计算损失值,而将所有样本分成一个个的batch呢?因为所有的训练样本数量太大了,可能有数以百万计,将所有的样本损失值都一起进行运算,计算量过于庞大,大大降低了模型计算的速度。

    公式(6)中计算总的损失值C,其实是一个以所有的连接权值ω和所有的阈值θ未为变量的多元函数。我们想要的模型就是求得C最小时,所有ω和θ的值。直接计算显然是不可能的,因为对于一个大的深度神经网络,所有的参数变量,可能数以万计。

    在这里我们使用梯度下降算法来逐步逼近C的最小值,也就是先随机得到一组参数变量的值,然后计算参数变量当前的梯度,向梯度的反方向,也就是C变小最快的方向,逐步调整参数值,最终得到C的最小值,或者近似最小值。

    而将所有样本,随机分成一个个固定长度的batch,以得到近似的梯度方向,叫做随机梯度下降算法

    更好理解梯度下降算法,逐步求得最优的参数值,可观看此视频:https://www.bilibili.com/video/av16144388

     

    2、开始求梯度

    那么,根据梯度的定义,接下来的任务,就是求取各个参数变量相对于C的偏导数。我们将使用误差反向传播算法来求取各个参数变量的偏导数。

    这里先剧透一下,求取参数偏导数的方法,和神经网络正向传播(根据样本计算输出值)的方式类似,也是逐层求解,只是方向正好相反,从最后一层开始,逐层向前。

    更好的理解误差反向传播算法,可观看此视频:https://www.bilibili.com/video/av16577449

    首先,我们先求神经网络最后一层,也就是输出层的相关参数的偏导数。为了降低推导的复杂性,我们只计算相对于一个样本的损失值函数Cbi的偏导数,因为相对于总损失值函数C的偏导数值,也不过是把某个参数的所有相对于Cbi偏导数值加起来而已。

    根据公式(2)、公式(3)、公式(5),以及“复合函数求导法则”,可以得到输出层(L层)某个神经元的权值参数ω的偏导数,计算公式如下:

    根据公式(5)可以得到:

    根据公式(2)可以得到:

    根据公式(3)可以得到:

    将公式(8)(9)(10),带入公式(7),可以得到:

     

    我们令:

    根据公式(8)(9)则有:

    将公式(13),带入公式(11),可以得到:

    这样我们就得到了输出层L相关的权值参数ω的偏导数计算公式!

    接下来,同理可得输出层L相关的阈值θ的偏导数计算公式为:

    而根据公式(3)可以得到:

    将公式(16)带入公式(15)可以得到:

    这就是输出层L相关的阈值θ的偏导数计算公式!

     

    3、根据L层,求前一层参数的偏导函数

    由公式(3)可知,一个权值参数ω只影响一个L-1层的神经元,因此有:

    根据公式(3)可以得到:

    将公式(19)带入公式(18)可以得到:

    根据公式(12)可以得到:

    将公式(21)带入公式(20)可以得到:

    同理,我们可以得到:

    根据公式(3)可以得到:

    将公式(24)带入公式(23)可以得到:

    这样我们就得到了L-1层神经元相关参数的计算公式!

     

    下面,我们还需要推导一下 之间的关系,根据公式(2)可以得到:

    同样根据公式(2)可以得到:

    将公式(27)带入公式(26)可以得到:

    由公式(3)可知,一个权值参数ω只影响一个L-1层的神经元,但这个L-1层神经元影响了所有L层的神经元。因此,根据“多元复合函数求导法则”有:

    根据公式(12)可以得到:

    将公式(27)带入公式(26)可以得到:

    根据公式(3)可以得到:

    将公式(32)带入到公式(31)可以得到:

    将公式(33)带入公式(28)可以得到:

    这样我们就得到了反向传播,逐层推导的通用公式:

    在这里,ω和z都是正向传播过程中,已经算好的常数,而  可以从L层开始逐层向前推导,直到第1层,第0层是输入层,不需要调整参数。而第L层的   可参考公式(13)。

     

    下面是全连接神经网络的python实现代码:

    #coding=utf-8
    import numpy as np
    import matplotlib.pylab as plt
    import random
    
    class NeuralNetwork(object):
        def __init__(self, sizes, act, act_derivative, cost_derivative):
            #sizes表示神经网络各层的神经元个数,第一层为输入层,最后一层为输出层
            #act为神经元的激活函数
            #act_derivative为激活函数的导数
            #cost_derivative为损失函数的导数
            self.num_layers = len(sizes)
            self.sizes = sizes
            self.biases = [np.random.randn(nueron_num, 1) for nueron_num in sizes[1:]]
            self.weights = [np.random.randn(next_layer_nueron_num, nueron_num)
                for nueron_num, next_layer_nueron_num in zip(sizes[:-1], sizes[1:])]
            self.act=act
            self.act_derivative=act_derivative
            self.cost_derivative=cost_derivative
    
        #前向反馈(正向传播)
        def feedforward(self, a):
            #逐层计算神经元的激活值,公式(4)
            for b, w in zip(self.biases, self.weights):
                a = self.act(np.dot(w, a)+b)
            return a
    
        #随机梯度下降算法
        def SGD(self, training_data, epochs, batch_size, learning_rate):
            #将训练样本training_data随机分为若干个长度为batch_size的batch
            #使用各个batch的数据不断调整参数,学习率为learning_rate
            #迭代epochs次
            n = len(training_data)
            for j in range(epochs):
                random.shuffle(training_data)
                batches = [training_data[k:k+batch_size] for k in range(0, n, batch_size)]
                for batch in batches:
                    self.update_batch(batch, learning_rate)
                print("Epoch {0} complete".format(j))
    
        def update_batch(self, batch, learning_rate):
            #根据一个batch中的训练样本,调整各个参数值
            nabla_b = [np.zeros(b.shape) for b in self.biases]
            nabla_w = [np.zeros(w.shape) for w in self.weights]
            for x, y in batch:
                delta_nabla_b, delta_nabla_w = self.backprop(x, y)
                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-(learning_rate/len(batch))*nw for w, nw in zip(self.weights, nabla_w)]
            self.biases = [b-(learning_rate/len(batch))*nb for b, nb in zip(self.biases, nabla_b)]
    
        #反向传播
        def backprop(self, x, y):
            #保存b和w的偏导数值
            nabla_b = [np.zeros(b.shape) for b in self.biases]
            nabla_w = [np.zeros(w.shape) for w in self.weights]
            #正向传播
            activation = x
            #保存每一层神经元的激活值
            activations = [x]
            #保存每一层神经元的z值
            zs = []
            for b, w in zip(self.biases, self.weights):
                z = np.dot(w, activation)+b
                zs.append(z)
                activation = self.act(z)
                activations.append(activation)
            #反向传播得到各个参数的偏导数值
            #公式(13)
            d = self.cost_derivative(activations[-1], y) * self.act_derivative(zs[-1])
            #公式(17)
            nabla_b[-1] = d
            #公式(14)
            nabla_w[-1] = np.dot(d, activations[-2].transpose())
            #反向逐层计算
            for l in range(2, self.num_layers):
                z = zs[-l]
                sp = self.act_derivative(z)
                #公式(36),反向逐层求参数偏导
                d = np.dot(self.weights[-l+1].transpose(), d) * sp
                #公式(38)
                nabla_b[-l] = d
                #公式(37)
                nabla_w[-l] = np.dot(d, activations[-l-1].transpose())
            return (nabla_b, nabla_w)
    
    #距离函数的偏导数
    def distance_derivative(output_activations, y):
        #损失函数的偏导数
        return 2*(output_activations-y)
    
    # sigmoid函数
    def sigmoid(z):
        return 1.0/(1.0+np.exp(-z))
    
    # sigmoid函数的导数
    def sigmoid_derivative(z):
        return sigmoid(z)*(1-sigmoid(z))
    
    if __name__ == "__main__":
        #创建一个5层的全连接神经网络,每层的神经元个数为1,8,5,3,1
        #其中第一层为输入层,最后一层为输出层
        network=NeuralNetwork([1,8,5,3,1],sigmoid,sigmoid_derivative,distance_derivative)
    
        #训练集样本
        x = np.array([np.linspace(-7, 7, 200)]).T
        #训练集结果,由于使用了sigmoid作为激活函数,需保证其结果落在(0,1)区间内
        y = (np.cos(x)+1)/2
    
        #使用随机梯度下降算法(SGD)对模型进行训练
        #迭代5000次;每次随机抽取40个样本作为一个batch;学习率设为0.1
        training_data=[(np.array([x_value]),np.array([y_value])) for x_value,y_value in zip(x,y)]
        network.SGD(training_data,5000,40,0.1)
    
        #测试集样本
        x_test = np.array([np.linspace(-9, 9, 120)])
        #测试集结果
        y_predict = network.feedforward(x_test)
    
        #图示对比训练集和测试集数据
        plt.plot(x,y,'r',x_test.T,y_predict.T,'*')
        plt.show()

     

    展开全文
  • BP——反向传播算法公式推导及代码

    千次阅读 多人点赞 2019-03-14 23:51:19
    BP——反向传播算法计算过程详解人工神经网络的结构前向传播激活函数反向传播梯度下降具体计算过程 本文主要参考吴恩达和李宏毅的深度学习视频,然后自己做的笔记 反向传播计算部分参考李宏毅的视频讲解,要是有...

    本文主要参考吴恩达和李宏毅的深度学习视频,然后自己做的笔记
    反向传播计算部分参考李宏毅的视频讲解,要是有童鞋也对反向传播这一部分的计算不那么清明,可以考虑选择留下来看看我的笔记,也可以移步李宏毅大神的视频讲解

    人工神经网络的结构

    (注:Markdown敲公式对我来说太困难,后面的公式都用图片的形式展示)
    神经网络的结构包括:输入层(input layer)、隐藏层(hidden layer)、输出层(output layer)。如下图所示:
    神经网络结构
    当然,隐含层可以有无数层,这里我只画了两层。
    输入层输入的数据是训练样本(x1,x2,…,xn,y),训练样本中的x1到xn表示输入的特征值,而y则表示咱们希望输出的预期值。
    隐含层将会进行一系列的计算来缩小训练样本的估计值y’与预期值y之间的误差。
    输出层则会输出训练后得到的估计值y’。

    前向传播

    为了后面的表示方便,我们这里先约定一下每个神经元的表示方法。
    aj[l][i]:第i个样本的第l层上第j个神经元的输入,且有 a[0] = x 。
    z:中间变量
    J:代价函数
    g():激活函数

    前向传播主要完成两个任务:

    1. 计算每一个神经元的激活值a;
    2. 是计算最后的代价函数J(y’, y)(如果我们这里只有一个输入样本的话,那么应该叫做损失函数)。

    即将用到的公式有(这里就以上面给出的人工神经网络结构为例子,即一个样本的表示形式):
    在这里插入图片描述
    我们定义
    前向传播的计算流程:

    1. 输入的准备工作:a[0]、w[1]、b[1]都排排坐,下面准备吃果果啦~
      在这里插入图片描述
    2. 求出a[1]
      在这里插入图片描述
      根据【人工神经网络结构图】可知,咱们的三个输入都连接到了三个神经元上,每个神经元都要有一个输出,因此咱们最后求得的a[1]也是一个3*1的向量。

    咱们将上面的式子扔到神经网络中表示:
    前向传播计算流程
    看到没有,每一个神经元都要进行一次z和a的计算,一直传到输出层,输出层求得的a就是咱们样本的估计值!

    在python中表示求解z、a的式子为:

    z = np.dot(w.T, x)+b
    a = sigmoid(z)    #这里我采用sigmoid()函数作为激活函数,这个函数主要是用来作二分类
    
    1. 损失函数J(y’, y)在python中的表示:

    损失函数:求解单个样本的误差
    代价函数:求解多个样本的误差

    cost = -y * np.log(y') - (1 - y) * np.log(1 - y')   #这里只是单个样本的损失函数,如果咱们有m个样本的话就需要将这m个样本的损失值全部加起来再除以m求得这m个样本的代价函数。
    

    激活函数

    激活函数的作用:加入非线性因素,解决线性不可分问题。(比如说,现在给你一个得用歪七扭八的线来划分两个区域,你用直线肯定是不可能把他俩完美的分开的,但是加入非线性因素以后,你就可以拟合出一条近乎完美的线来划分这两个区域啦~)

    激活函数有很多种,咱在上面使用的是用于二分类的一种常用的激活函数,一般用在输出层。(不同层可以使用不同的激活函数,还有一点很重要的是:激活函数得是可微的!因为咱们在反向传播阶段得对激活函数求导!)

    各种激活函数详情请咨询:千奇百怪的激活函数 来源:wikipedia

    反向传播

    老规矩,先约定一波:
    dw: J对w求偏导
    db: J对b求偏导
    dz: J对z求偏导
    da: J对a求偏导

    步骤:

    1. 求解dw, db
    2. 更新w, b

    方法:梯度下降
    小工具:链式求导

    咱们在计算时一定一定会用到的四个公式:
    反向传播必备公式
    现在看不太明白这几个公式没有关系,咱们先往后走,看看具体是怎么计算的,一会再看这些公式心就明朗啦~ 加油加油,马上就完了!

    梯度下降

    咱们要清楚,方向传播的目的就是为了找到一个最好的w和b,让咱们的损失达到最小,让咱们的结果无限逼近最优解。那么为了让咱们这个值达到最优,咱们就要采用梯度下降的方法来不断优化这个值。当然,学习率的选择也是非常重要的。不然就可能出现两种不太招人待见的情况:1.要训练贼多次才能到达最优解;2.始终到不了最优解。
    梯度下降
    箭头所指的方向就是梯度下降的方向。

    具体计算过程

    step1. 计算隐藏层误差(这里以第一个神经元为例)
    思路:要求解dw[1]和db[1],先要求解出dz[1],要求dz[1],那么先要知道da[1]。因此咱们求解的过程就是da—>dz—>dw,db
    过程如下:
    计算隐藏层误差
    可以看到上面的求解过程就是一个链式求导过程。一层一层的剥开,一层一层的求解。

    step2. 计算输出层误差
    输出层误差的求解过程中间只有一个da[L]这个中间变量。这个就留给大家自己写啦!(其实我最开始的地方都已经给出了)

    step3. 咱们都知道每一层的dw和db是如何得到的了,现在要做的就是更新w和b了!还是用上面更新的那个公式来求解!这里我也不重复写了~

    完结了~
    咱们在实现过程中实际上也是不断迭代求解w和b来训练整个网络结构,使得整个网络的损失达到最小!

    下面是大家最喜欢的部分!不贴代码的博客不是好博客!

    import math
    import random
    import string
    
    random.seed(0)
    
    
    # calculate a random number where:  a <= rand < b
    def rand(a, b):
        return (b - a) * random.random() + a
    
    
    # Make a matrix (we could use NumPy to speed this up)
    def makeMatrix(I, J, fill=0.0):
        m = []
        for i in range(I):
            m.append([fill] * J)
        return m
    
    
    # our sigmoid function, tanh is a little nicer than the standard 1/(1+e^-x)
    def sigmoid(x):
        return math.tanh(x)
    
    
    # derivative of our sigmoid function, in terms of the output (i.e. y)-derivative of tanh
    def dsigmoid(y):
        return 1.0 - y ** 2
    
    
    class CBPNNClass:
        def __init__(self, ni, nh, no):
            # number of input, hidden, and output nodes
            self.ni = ni + 1  # +1 for bias node
            self.nh = nh
            self.no = no
    
            # activations for nodes
            self.ai = [1.0] * self.ni
            self.ah = [1.0] * self.nh
            self.ao = [1.0] * self.no
    
            # create weights
            self.wi = makeMatrix(self.ni, self.nh)
            self.wo = makeMatrix(self.nh, self.no)
            # set them to random vaules
            for i in range(self.ni):
                for j in range(self.nh):
                    self.wi[i][j] = rand(-0.2, 0.2)
            for j in range(self.nh):
                for k in range(self.no):
                    self.wo[j][k] = rand(-2.0, 2.0)
    
            # last change in weights for momentum
            self.ci = makeMatrix(self.ni, self.nh)
            self.co = makeMatrix(self.nh, self.no)
    
        def update(self, inputs):
            if len(inputs) != self.ni - 1:
                raise ValueError('wrong number of inputs')
    
            # input activations
            for i in range(self.ni - 1):
                # self.ai[i] = sigmoid(inputs[i])
                self.ai[i] = inputs[i]
    
            # hidden activations
            for j in range(self.nh):
                sum = 0.0
                for i in range(self.ni):
                    sum = sum + self.ai[i] * self.wi[i][j]
                self.ah[j] = sigmoid(sum)
    
            # output activations
            for k in range(self.no):
                sum = 0.0
                for j in range(self.nh):
                    sum = sum + self.ah[j] * self.wo[j][k]
                self.ao[k] = sigmoid(sum)
    
            return self.ao[:]
    
        def backPropagate(self, targets, N, M):
            if len(targets) != self.no:
                raise ValueError('wrong number of target values')
    
            # calculate error terms for output
            output_deltas = [0.0] * self.no
            for k in range(self.no):
                error = targets[k] - self.ao[k]
                output_deltas[k] = dsigmoid(self.ao[k]) * error
    
            # calculate error terms for hidden
            hidden_deltas = [0.0] * self.nh
            for j in range(self.nh):
                error = 0.0
                for k in range(self.no):
                    error = error + output_deltas[k] * self.wo[j][k]
                hidden_deltas[j] = dsigmoid(self.ah[j]) * error
            # update output weights
            for j in range(self.nh):
                for k in range(self.no):
                    change = output_deltas[k] * self.ah[j]
                    self.wo[j][k] = self.wo[j][k] + N * change + M * self.co[j][k]
                    self.co[j][k] = change
                    # print N*change, M*self.co[j][k]
    
            # update input weights
            for i in range(self.ni):
                for j in range(self.nh):
                    change = hidden_deltas[j] * self.ai[i]
                    self.wi[i][j] = self.wi[i][j] + N * change + M * self.ci[i][j]
                    self.ci[i][j] = change
    
            # calculate error
            error = 0.0
            for k in range(len(targets)):
                error = error + 0.5 * (targets[k] - self.ao[k]) ** 2
            return error
    
        def test(self, patterns):
            for p in patterns:
                print(p[0], '->', self.update(p[0]))
    
        def weights(self):
            print('Input weights:')
            for i in range(self.ni):
                print(self.wi[i])
            print()
            print('Output weights:')
            for j in range(self.nh):
                print(self.wo[j])
    
        def train(self, patterns, iterations=1000, N=0.5, M=0.1):
            # N: learning rate
            # M: momentum factor
            for i in range(iterations):
                error = 0.0
                for p in patterns:
                    inputs = p[0]
                    targets = p[1]
                    self.update(inputs)
                    error = error + self.backPropagate(targets, N, M)
                if i % 100 == 0:
                    print('error %-.5f' % error)
    
    
    def demo():
        # Teach network XOR function
        pat = [
            [[0, 0], [0]],
            [[0, 1], [1]],
            [[1, 0], [1]],
            [[1, 1], [0]]
        ]
        # create a network with two input, two hidden, and one output nodes
        n = CBPNNClass(2, 2, 1)
        # train it with some patterns
        n.train(pat)
        # test it
        n.test(pat)
    
    
    if __name__ == '__main__':
        demo()
    

    代码来源:Andrew Ng的课程!这里并没有使用tensorflow框架,所以很多函数都是自己写的,大家可以将在这个代码上进行改写~

    展开全文
  • 第十章 神经网络参数的反向传播算法代价函数
  • 针对多感知器,梯度下降算法 1.预测一个连续值,我们的做法是,不对他激活,直接输出 2.预测“是”或“否”的分类问题,则对输出层,做sigmoid运算二分类输出 3.多分类softmax运算,输出多个分类在概率上的分别 多层...
  • 前向传播算法和反向传播算法

    千次阅读 2017-12-28 22:22:55
    最近在看神经网络中的前向传播算法(FP)和反向传播算法(BP),特地进行总结一下,方便以后理解。1.基本概念  上图是一张自己画的神经网络的图。假设每一层都添加了偏度单元(即值为1的神经元),用来表示阀值(因为...
  •  《实例》阐述算法,...01—回顾昨天,分析了手写字数据集分类的原理,利用神经网络模型,编写了SGD算法代码,分多个epochs,每个 epoch 又对 mini_batch 样本做多次迭代计算,详细的过程,请参考:深度学习|神经
  • 深度学习(一):DNN前向传播算法和反向传播算法

    万次阅读 多人点赞 2018-11-29 17:32:13
    文章目录一、深度神经网络(DNN)模型1.1 从感知机到神经网络1.2 DNN的基本结构二、DNN前向传播算法2.1 DNN前向传播算法数学原理2.2 DNN前向传播算法2.3 DNN前向传播算法小结三、DNN反向传播算法3.1 DNN反向传播算法...
  • 反向传播示例代码全解析

    千次阅读 2018-07-05 12:29:04
    可以看出该代码充分利用了这4个公式来体现反向传播算法的过程,这个反向我觉得就是先利用公式(1)计算输出层的错误量,再利用公式(3)、(4)计算该层的偏置和权重的改变速率。有了最后一层的各项数据,再利用公式...
  • 主要介绍了Python实现的人工神经网络算法,结合实例形式分析了Python基于反向传播算法实现的人工神经网络相关操作技巧,需要的朋友可以参考下
  • 主要讲解了深度学习将要用到的python的基础知识以及简单介绍了numpy库和matpoltlib库,本书编写深度学习神经网络代码仅使用Python和numpy库,不使用目前流行的各种深度学习框架,适合入门新手学习理论知识。...
  • Python实现一个简单的反向传播算法

    千次阅读 2019-03-25 22:16:11
    # 反向传播计算梯度核心! # 计算过程见上图 grad_y_pred = 2.0 * ( y_pred - y ) grad_w2 = h_relu . T . dot ( grad_y_pred ) grad_h_relu = grad_y_pred . dot ( w2 . T ) grad_h = ...
  • 为了在保证图像质量的前提...实验结果表明,DR-BP算法相比仅适用于单站式成像的快速傅里叶变换算法,重建图像边缘干扰少,相比传统的反向传播算法,重建速度大幅提升,本文实验中获得的图像质量相同时,重建速度可提升60倍。
  • 机器学习(十一)神经网络模型之代价函数及利用反向传播算法实现梯度下降算法 前言 上篇博文已经详细解释了什么是神经网络,以及如何理解一个神经网络模型的计算过程,并利用反向传播算法实现了神经网络模型中预测...
  • 根据反向传播(BP)原理,不调用MATLAB提供的函数,简单实现BP算法反向传播(BP)网络是采用误差反向后传学习算法训练的前馈网络。其实现步骤为: (1) 前向:求出所有神经元的输出2)计算实际输出和期望输出...
  • 反向传播的目的是计算成本函数C对网络中任意w或b的偏导数。...反向传播算法中Sigmoid函数代码演示: # 实现 sigmoid 函数 return 1 / (1 + np.exp(-x)) def sigmoid_derivative(x): # sigmoid 导数的计算 retu
  • 最近在看深度学习的东西,一开始看的吴恩达的...反向传播法其实是神经网络的基础了,但是很多人在学的时候总是会遇到一些问题,或者看到大篇的公式觉得好像很难就退缩了,其实不难,就是一个链式求导法则反复用。如果
  • pytorch的官网上有一段教程,是使用python的numpy工具实现一个简单的神经网络的bp算法。下面先贴上自己的代码: import numpy as np N,D_in,H,D_out = 4,10,8,5 x = np.random.randn(N,D_in)#4x10 y = np.random...
  • 反向传播_学习 使用不列颠哥伦比亚大学EECE592学习系统体系结构的Java Assignment1进行反向传播学习( ) 实现一个多层感知器,并使用错误反向传播算法对其进行训练。 有关详细信息: 反向传播: : 作业: :
  • 神经网络中的反向传播(BackPropagation)介绍及公式推导 神经网络中的激活函数的作用,最常用的两个激活函数Sigmoid 和TanH 代价函数对介绍二次代价函数(Quadratic Cost),交叉熵代价函数(Cross-entropy Cost)
  • 机器学习笔记之反向传播算法

    千次阅读 2019-04-14 00:05:05
    来比较这些已经计算得到的偏导数项,把用反向传播算法得到的偏导数值与用数值方法得到的估计值进行比较,确保两种方法得到相近的值,最重要的一点是停用梯度检验 使用 优化算法 来最小化代价函数
  • 梯度下降和反向传播算法讲解

    千次阅读 2019-10-22 16:19:07
    这里只是包含一层的神经网络,没法体现出反向传播的直观,但是如果是深层结构,我们更新完最内层的w后,其求导结果还可以继续使用,然后再通过内层对外层的结果,算出L对外层w的导数,实现了误差函数的结果反向传播...
  • 反向传播算法(过程及公式推导)

    万次阅读 多人点赞 2016-04-01 21:19:56
    反向传播算法(Backpropagation)是目前用来训练人工神经网络(Artificial Neural Network,ANN)的最常用且最有效的算法。
  • 推导CNN中的BP误差反向传播算法

    千次阅读 2019-07-11 22:21:37
    实际上就是一个:梯度下降反向传播更新 如果熟知高数和懂最优化的梯度下降理论,可以直接跳到 四 一、反向传播的由来 在我们开始DL的研究之前,需要把ANN—人工神经元网络以及bp算法做一个简单解释。 输入层...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,309
精华内容 11,323
关键字:

反向传播算法代码