从零开始学习深度学习库-1:前馈网络

你好!欢迎来到这个系列的第一篇文章,我们将尝试用Python构建自己的深度学习库。在这篇文章中,我们将开始编写一个简单的前馈神经网络。我们将仅在这篇文章中处理前向传播,并在下一篇文章中处理网络的训练。这篇文章将介绍基本的前馈神经网络如何接收输入并从中产生输出。

首先,什么是神经网络?

神经网络是一种机器学习技术,它大致模仿了大脑的模型。和所有机器学习技术一样,它通过包含输入及其对应输出的数据集来学习。神经网络由层组成。每一层都通过权重和偏置与下一层相连。这些权重和偏置被网络用来计算它将给出的输出。在网络训练时,这些权重和偏置会被调整,以便网络根据其训练的数据产生最优输出。
在这里插入图片描述
这张图展示了一个三层的神经网络。连接节点的线条用于表示网络的权重和偏置。

它们是如何工作的?(数学原理)

每一层都有自己的权重和偏置。
权重和偏置最初开始时是一个随机值矩阵。
一个基本的前馈神经网络只包含线性层。
线性层使用以下公式产生它们的输出。

x @ w + b

其中...
x 是输入到该层的数据
w 是该层的权重
b 是该层的偏置
(@ 表示矩阵乘法)

每层的输出作为下一层的输入。
注意
如果你不了解矩阵乘法是如何工作的,这个网站很好地解释了这一点。
我们现在只讨论到这里 - 下一篇文章我们将深入研究这些权重和偏置在训练中是如何被纠正的!

激活函数

神经网络的层由节点组成。
激活函数应用于层,以确定哪些节点应该“触发”/“激活”。这种“触发”在人类大脑中也可以观察到,因此在神经网络中引入了激活函数,因为它们大致基于大脑的模型。
激活函数还允许网络模拟非线性数据。没有激活函数,神经网络只会是一个线性回归模型,这意味着它无法模拟大多数现实世界的数据。
有多种激活函数,但以下是最常用的几种…

Sigmoid

Sigmoid函数将输入映射到0到1之间的值,如下图所示。
在这里插入图片描述
在这里插入图片描述
x是输入向量

Relu(修正线性单元)

Relu函数只允许输入向量的正值通过。负值被映射为0。
例如,

[[-5, 10]  
 [15, -10] --> relu --> [[0, 10]
                         [15, 0]]

在这里插入图片描述
在这里插入图片描述

Tanh

Tanh与Sigmoid类似,不同之处在于它将输入映射到-1到1之间的值。
在这里插入图片描述

Softmax

Softmax接收一个输入,并将其映射为概率分布(这意味着输出中的所有值之和为1)。
在这里插入图片描述
(z是输入向量,K是输入向量的长度)

编写代码

我们的矩阵操作需要numpy…

import numpy as np

首先,让我们写我们的线性层类

class Linear:
    def __init__(self, units):
        # units指定层中有多少节点
        self.units = units
        self.initialized = False

    def __call__(self, x):
        # 如果层之前没有被调用过,初始化权重和偏置
        if not self.initialized:
            self.w = np.random.randn(self.input.shape[-1], self.units)
            self.b = np.random.randn(self.units)
            self.initialized = True

        return self.input @ self.w + self.b

示例用法

x = np.array([[0, 1]])
layer = Linear(5)
print (layer(x))

# => [[-2.63399933 -1.18289984  0.32129587  0.2903246  -0.2602642 ]]

现在,让我们按照之前给出的公式编写我们所有的激活函数类

class Sigmoid:
    def __call__(self, x):
        return 1 / (1 + np.exp(-x))

class Relu:
    def __call__(self, x):
        return np.maximum(0, x)   

class Softmax:
    def __call__(self, x):
        return np.exp(x) / np.sum(np.exp(x))   

class Tanh:
    def __call__(self, x):
        return np.tanh(x)

现在让我们编写一个“model”类,它将作为我们所有层的容器/实际的神经网络类。

class Model:
    def __init__(self, layers):
        self.layers = layers

    def __call__(self, x):
        output = x
        for layer in self.layers:
            output = layer(x)

        return output

将所有这些类保存到layer.py(或您喜欢的任何名称)中。
现在我们可以使用我们迄今为止的小型库来构建一个简单的神经网络。

import layers
import numpy as np

# 输入数组
x = np.array([[0, 1], [0, 0], [1, 1], [0, 1]])

# 网络使用我们迄今为止设计的所有层
net = layers.Model([
    layers.Linear(32),
    layers.Sigmoid(),
    layers.Linear(16),
    layers.Softmax(),
    layers.Linear(8),
    layers.Tanh(),
    layers.Linear(4),
    layers.Relu(),
])

print (net(x))
Output:
[[0.         3.87770361 0.17602662 0.        ]
 [0.         3.85640582 0.22373699 0.        ]
 [0.         3.77290517 0.2469388  0.        ]
 [0.         3.87770361 0.17602662 0.        ]]
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第欧根尼的酒桶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值