python实现简单的神经网络 - Go语言中文社区

python实现简单的神经网络


写在前面:

我一直是一个非常懒散的人,没有计划,得过且过,所以导致学很多东西都非常浅显,当然我本来也不是一个很深刻的人。说来惭愧,title是算法工程师却一直不懂深度学习,这一直是我心中的痛,想最近抽空学习深度学习。作为最近的大热,深度学习的入门门槛非常低,因为现在的框架已经做得非常完整了,而且很多开源代码下下来跑跑数据就可以说我跑过模型了,但是我一直对深度学习的内部机理感到迷茫,所以这个领域对我来说像是一个刚炖熟没有切开的猪脚,无从下手。也跟着视频看了几集,总是觉得没有参透,但又不知道是哪里的问题。所以我有个大胆的想法,我希望用一些非常基础的库去实现一些深度学习中常见的算法和网络,这可能是一个系列,也可能只有这一篇。

正文:

本文主要针对前后向传播算法,实现了一个3层的全连接网络,代码我放在了github上。

本文的神经网络结构如下图所示:

网络共有3层,输入层,隐藏层和输出层,每两层之间的节点是全连接的,输入层和隐藏层之间的各个连接的权重由矩阵wi表示,隐藏层和输出层之间的权重关系由wo表示,激活函数采用sigmoid函数。那么对于隐藏层第j个节点可以表示为

输出层表示相同。通过这样的方式我们可以根据输入,一层一层的计算,将结果传导给输出层,这就是前向传播。

实现代码如下:

 def feed_propagation(self, inputs):
        """
        Feed forward nerual network
        Args:
            inputs: input matrix
        """
        if len(inputs) != self._input - 1:
            raise ValueError("Input matrix does not fit the network!")
        for i in xrange(len(inputs)):
            self._ai[i] = inputs[i]
        for j in xrange(self._hidden):
            sum = 0.0
            for i in xrange(self._input):
                sum += self._wi[i][j] * self._ai[i]
            self._ah[j] = self._sigmoid(sum)
        for j in xrange(self._output):
            sum = 0.0
            for i in xrange(self._hidden):
                sum += self._wo[i][j] * self._ah[i]
            self._ao[j] = self._sigmoid(sum)
        return self._ao[:]

 得到输出结果之后我们需要将输出结果和目标结果进行对比,所以我们需要定一个损失函数,来降低损失函数,为简化问题,我们使用MSE作为损失函数。

 那么我们如何将偏导数传递到输入层呢,和前向反馈的机制一样,首先我们对输出层求导,那么输出层的输入部分的偏导为:

 据此我们可以再讲隐藏层的偏导传递到输入层。这就是后向传播算法,代码如下:

 def back_propagation(self, targets, N):
        """
        Back propagation algorithm.
        Args:
            targets: target number, lists
        """
        if len(targets) != self._output:
            raise ValueError("Target does not match the output matrix!")
        # Caluculate the derivative of each layer's input
        out_delta = [0.0] * self._output
        print out_delta
        for i in xrange(self._output):
            out_delta[i] = -(targets[i] - self._ao[i]) * self._dsigmoid(self._ao[i])
        hidden_delta = [0.0] * self._hidden
        for i in xrange(self._hidden):
            error = 0.0
            for j in xrange(self._output):
                error += out_delta[j] * self._wo[i][j]
            hidden_delta[i] = self._dsigmoid(self._ah[i]) * error
        # Update the parameter of each layer's weight
        for j in range(self._hidden):
            for k in range(self._output):
                change = out_delta[k] * self._ah[j]
                self._wo[j][k] -= N * change
        for i in range(self._input):
            for j in range(self._hidden):
                change = hidden_delta[j] * self._ai[i]
                self._wi[i][j] -= N * change
        # loss function is MSE
        error = 0.0
        for k in range(len(targets)):
            error += 0.5 * (targets[k] - self._ao[k]) ** 2
        return error

此处我们的优化方法采用梯度下降。未来的工作是采用其他方法对参数进行优化。 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/lion19930924/article/details/82838350
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 20:30:20
  • 阅读 ( 763 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢