美文网首页收藏夹程序员充电站深度学习实战与源码解读
零基础入门深度学习(3) - 神经网络和反向传播算法

零基础入门深度学习(3) - 神经网络和反向传播算法

作者: 韩炳涛 | 来源:发表于2016-08-24 21:40 被阅读4463次

    由于简书不支持数学公式,请移步零基础入门深度学习(3) - 神经网络和反向传播算法。为了保证最佳阅读效果,请尽量在电脑上阅读。

    相关文章

    零基础入门深度学习(1) - 感知器
    零基础入门深度学习(2) - 线性单元和梯度下降

    相关文章

      网友评论

      • 周俊_420f:老师您好,我是一名学生,我在学习您bp.py中的Node类中的calc_output()方法时,不明白reduce函数中的ret为什么能参与运算,我的理解是它是一个Connection对象,就像conn。期待您的解答,感谢。
        def calc_output(self):
        output = reduce(lambda ret, conn: ret + conn.upstream_node.output * conn.weight,
        self.upstream, 0)
        self.output = sigmoid(output)
      • WEIYAFEI:您好,我是一名大学生。在学习您的bp.py中的Node类的代码时,不明白 ‘conn.upstream_node.output * conn.weigh’中的‘conn.upstream_node.output’和‘conn.weigh’是何时被定义过的。非常想解决这个问题,希望您能抽出时间为我解答,感谢。
        def calc_output(self):
        output = reduce(lambda ret, conn: ret + conn.upstream_node.output * conn.weight, self.upstream, 0)
        self.output = sigmoid(output)
        周俊_420f:同学你好,我正好也在看这篇文档,也许能回答一下你的问题。
        conn.upstream_node.output中,conn是一个Connection对象,它在初始化的时候会有upstream_node和weight这两个属性。不知道这样能不能解答你的问题。
        我在同样一行的代码也遇到了问题,我的问题是reduce函数中的ret为什么能参与运算,我的理解是它是一个Connection对象,怎么会与数值进行计算呢。如果你知道,请你帮忙解答一下,谢谢!
      • 十一Dreamer:def backward(self, delta_array):
        '''
        反向计算W和b的梯度
        delta_array: 从上一层传递过来的误差项
        '''
        # 式8
        self.delta = self.activator.backward(self.input) * np.dot(
        self.W.T, delta_array)
        self.W_grad = np.dot(delta_array, self.input.T)
        self.b_grad = delta_array
        您好,在计算delta的时候,传入的参数为self.activator.backward(self.input),按照推导的公式,这儿不是self.output吗?不知道理解的对不对,还麻烦讲解一下,非常感谢。
      • 8ecf6f4b97c0:bp.py中,ConstNode的隐藏层计算函数calc_hidden_layer_delta,由于self.ouput=1, 而计算结果应该恒为0。从ConstNode存在的意义来看,应该不需要存在计算的函数,是否相关函数都可以使用空函数,还是由其他考虑?
      • eb1edeba7214:ef backward(self, delta_array):
        '''
        反向计算W和b的梯度
        delta_array: 从上一层传递过来的误差项
        '''
        # 式8
        self.delta = self.activator.backward(self.input) * np.dot(
        self.W.T, delta_array)
        self.W_grad = np.dot(delta_array, self.input.T)
        self.b_grad = delta_array
        根据公式 b_grad 不应该等于self.delta么
        韩炳涛: @nk_lwang 上一层传过来的误差项是用来计算本层的权重和bias,本层的误差项是用来计算下一层的权重和bias。这个是为了方便代码实现,也就是每一层计算出来的self.delta都是为了给下面的层来用的。
      • 3b814f22610b:冒昧问下, bp的推导是不是有问题, 公式(30-31), 公式(38-39).
        麻烦check下, 谢谢!
        3b814f22610b:a_j = f(net_j), 求导应该是f'(net_j), 是不是这样?
      • 豌豆的号角:教程很好,已收藏,但是我跑了一下神经网络的程序,跑出来错误率有0.6,也就是识别正确率才0.4,请问预期的是多少?
      • 北静王:首先,非常感谢作者能够提供这么好的学习笔记。
        我在学习您的教程的过程中,遇到了一些问题,现写下来和您探讨一下。
        1. 教程三中,向量化推导中,式8误差在反向传播中,是从后面的层向前传播的,所以应该是(l+1)而不是(l-1)
        2. 教程三中,代码中FullConnectedLayer初始化的时候b和output都是使用的numpy的二维方式初始化的(其中第二维大小是1),在forward的计算中,wx+b这里就会出错,由于np.dot(self.W, input_array) 计算出来的是一个一维的向量,但是b是个二维的,所以有bug。
        3. sigmod函数的溢出问题。

        最后想知道您是否还有其他的教程可以学习,近期有出新教程的计划没有。谢谢!
        韩炳涛:1. 原文写错了,已改正
        2. 文章中的代码可能不是最新的,我把代码放到GitHub上了https://github.com/hanbt/learn_dl,是可以运行的版本。
        3. 有时候会这样,不过可以忽略,最终仍然能够收敛。
      • 81bc38e348aa:专门注册来评论。非常感谢您的教程,非常好,原理讲的很详细,然后也有代码实践和注意事项。
        刚刚看到第3讲,“向量化编程”这里的关于W更新的地方,(式8),有两处我觉得可能写错了,您看一下

        1. 第l层的误差项,应该是由第l+1层的误差项反向传播过来计算的吧,这样的话式子右边delta的上标不是应该是l+1吗
        2. 还是关于式8,W的更新,应该是第l层更新时候用的W矩阵应该是l+1层的W矩阵吧?
        我看你代码中 FullConnectedLayer类 第39行直接是用到当前层W转置,应该是下一层的W矩阵的转置吧?

        上面是我的两个疑问点,还请不吝赐教。
        韩炳涛:1. 原文写错了,已改正
        2. delta_array保存的是误差函数E当对于第l层的加权输入的导数,因此,按照式8计算的是l-1层的δ。
      • c320fc7c09e6:按写法定义了
        def sigmoid(output):
        return 1.0 / (1.0 + np.exp(-output))

        跑出来:
        C:/work/dp/bp.py:103: RuntimeWarning: overflow encountered in exp
        return 1.0 / (1.0 + np.exp(-output))

        楼主有遇到么?请问有完成可以跑的代码下载测试么
        韩炳涛: @太平洋的风在转 有时候会这样,不影响收敛。
      • c320fc7c09e6:看了第一遍,是个好教程。请问现在做什么工作呢
      • 来个芒果:写的很好,赞一个,我有两个疑问。
        1 为什么δ要这样取值,有什么说法吗?
        2 为什么δ中求偏导时,要对加权值netj求骗到,对j的输出值aj求偏导不是更方便吗?
        望指导,谢谢
        韩炳涛: @asdfcxz 韩炳涛: @asdfcxz 没什么特别的道理,就是为了实现方便。因为加权输入正好是wx的计算结果,对加权输入求偏导,得到的值点乘w的转置就是向前一层传递的残差,叉乘x就是w的梯度,把这个值保存起来写代码最方便。如果你保存对aj的偏导,那么你向上传递残差时需要计算一次激活函数的导数,等你计算w的梯度时还得重新再算一次激活函数的偏导。
      • 晴天雨_fa54:写的很详细~
      • 晴天雨_fa54:老师您好,在向量化编程部分的Network类里,第12行有个SigmoidActivator()函数,运行出错,并没有这个函数的定义啊。
        韩炳涛:@Thunder_54a5 https://github.com/hanbt/learn_dl
        0f5ec7e78236:请问在github上有完整的代码下载吗?
        韩炳涛: @晴天雨_fa54 多谢指出,回头我把这个函数加上
      • a5c9650ee2e4:想问一下老师,对于变分自编码器原理能不能讲一下
      • 0dbee5d5d1da:Network中train_one_sample缺少calc_gradient
        该为 get_gradient然后update_weight吧
        0dbee5d5d1da:@韩炳涛 是我看得不仔细,哈哈!by the way,教程写得很赞!!!期待后续~
        韩炳涛:@BlackKing_S 程序本身是没有错的,我把calc_gradient放在update_weight里面了。虽然本身没错,不过这种写法确实可读性不好,谢谢你指出这个问题,后续我会重构一下。
      • 665f7f4215d9:讲的很透彻,赞! 另外,公式里面的式(6)和(24)好像有笔误
        韩炳涛:@青青021 确实写错了。已经改过来了,多谢多谢 :smile:
      • 轀墨:学习了
      • 木马木马木:先关注,洗完澡再来磕。
        韩炳涛:@鄞姐姐 其实洗完澡睡一觉再来磕更好:P

      本文标题:零基础入门深度学习(3) - 神经网络和反向传播算法

      本文链接:https://www.haomeiwen.com/subject/jgimsttx.html