2

太天才了,把感知机组装在一起是不是就是神经网络了?

 3 years ago
source link: https://www.daqianduan.com/17948.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

大家好,今天来继续聊聊深度学习。

有同学跟我说很久没有更新深度学习的模型了,倒不是不愿意更新,主要是一次想把一个技术专题写完。但是纯技术文章观众老爷们不太爱看,所以我一般都把纯技术文章放在次条。不过既然有同学催更,那么我还是响应一下需求,来更新一篇。

神经网络与感知机的不同

上一篇文章当中我们讲了感知机,由于文章比较久了,估计很多同学没有看过,没有关系,可以点击下方传送门回去补课。

深度学习开篇,来聊聊感知机的原理

我们当时在文章里放了一张图,这张图是一个多层感知机的图,大家看一下,就是下面这张图。

eqI7ny.jpg

这张图乍一看没什么问题,但是细想会觉得有点奇怪,好像我们印象里看到的神经网络的图片也是这样的,既然如此,那么它们之间有什么区别呢?

表面上最明显的区别就是名字不同,这是一张神经网络的图片。我们发现同样是三层,但是它每一层的名字分别是输入层、中间层(隐藏层)和输出层。我们一般把输入层和输出层单独命名, 中间的若干层都叫做隐藏层 或者是中间层。当然像是感知机一样,以数字来命名层数也是可以的,比如下图当中的输入层叫做第0层,中间层叫做第一层,最后输出层叫做第2层。

我们一般不把输出层看作是有效的神经网络,所以 下图的网络被称为二层神经网络 ,而不是三层神经网络。

vmAbiq.jpg

除了名字的叫法不同之外,还有一个最关键的区别就是激活函数,为了说明白这点,我们先来看看神经网络当中的信号传递。

信号传递

下图是一张我随便找来的神经网络图,我们可以看到输入的第一个节点被置为了1。这样做是为了 方便引入偏移量 ,只是我们一般情况下画图的时候,不会特意把偏移量画出来。我们以下图为例子来看下神经网络当中信号的传递方式。

mmErMz.jpg

我们以为例,可以来试着写出的表达式,它一共有三个input,分别是1,,,然后我们也可以看到每一个input对应的权重,所以最后可以写成:

到这里还没有结束,神经网络当中 每一层都会有对应的激活函数 。一般情况下同一层网络当中的激活函数相同,我们把它叫做h,所以最终这个节点的输出并不是刚刚得到的,而是。

EVvyei.jpg

激活函数我们已经比较熟悉了,之前介绍过很多次,常用的大概有以下几种:Relu、Sigmoid、tanh、softmax,以及一些衍生出的变种。一般情况下, 在输出层之前我们通常使用Relu ,如果模型是一个分类模型,我们会在最后使用Sigmoid或者是softmax,如果是回归模型则不使用任何激活函数。

Sigmoid我们已经很熟悉了,如果我们把LR模型也看成是一个单层的神经网络的话,那么Sigmoid就是它的激活函数。 Sigmoid应用在二分类场景当中单个的输出节点上 ,输出的值如果大于0.5表示为真,否则为假。在一些概率预估场景当中,也可以认为输出值就代表了事件发生的概率。

与之对应的是softmax函数,它应用在多分类问题当中,它应用的节点数量不是1个,而是k个。这里的k表示多分类场景当中的类别数量。我们以k=3举例,看下图:

eYNne2.jpg

在图中一共有三个节点,对于每一个节点来说,它的公式可以写成:

其实和Sigmoid的计算方式是一样的,只不过最后计算了一个权重。最后我们会在这k个节点当中选择最大的作为最终的分类结果。

代码实现

最后,我们来试着写一下神经网络的代码,由于现在我们还没有介绍神经网络的训练方法,所以我们只能实现它预测的部分。等我们介绍完了反向传播算法之后,再来补上模型训练的过程。

如果不考虑反向传播的话,其实整个算法的代码非常简单,只要熟悉Python语法的同学都能看懂。

import numpy as np

def relu(x):
return np.where(x > 0, x, 0)


def sigmoid(x):
return 1 / (1 + np.exp(-x))


class NeuralNetwork():
def __init__(self):
self.params = {}
self.params['W1'] = np.random.rand(2, 3)
self.params['b1'] = np.random.rand(1, 3)
self.params['W2'] = np.random.rand(3, 2)
self.params['b2'] = np.random.rand(1, 2)
self.params['W3'] = np.random.rand(2, 1)
self.params['b3'] = np.random.rand(1, 1)

def forward(self, x):
a1 = np.dot(x, self.params['W1']) + self.params['b1']
z1 = relu(a1)

a2 = np.dot(z1, self.params['W2']) + self.params['b2']
z2 = relu(a2)

a3 = np.dot(z2, self.params['W3']) + self.params['b3']
return np.where(sigmoid(a3) > 0.5, 1, 0)


if __name__ == "__main__":
nn = NeuralNetwork()
print(nn.forward(np.array([3, 2])))

在下一篇文章当中我们将会来探讨神经网络的训练方法,也就是大名鼎鼎的反向传播算法,看看它是在神经网络当中如何运作的。

今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个 三连支持 吧~( 点赞、关注、转发


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK