神经网络简介
目前最广泛使用的定义是Kohonen于1988年的描述,神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所做出的交互反应。
概述
在生物神经网络中,每个神经元与其他神经元相连,当它兴奋时,就会向相连的神经元发送化学物质,从而改变这些神经元内的电位;如果某神经元的电位超过了一个阈值,那么它就会激活,即兴奋起来并向其他神经元发送化学物质。
在深度学习中也借鉴了这样的结构,每一个神经元(上面说到的简单单元)接受输入x,通过带权重w的连接进行传递,将总输入信号与神经元的阈值进行比较,最后通过激活函数处理确定是否激活,并将激活后的计算结果y输出,而我们所说的训练,所训练的就是这里面的权重w。
每一个神经元的结构如下:
概述
在生物神经网络中,每个神经元与其他神经元相连,当它兴奋时,就会向相连的神经元发送化学物质,从而改变这些神经元内的电位;如果某神经元的电位超过了一个阈值,那么它就会激活,即兴奋起来并向其他神经元发送化学物质。
在深度学习中也借鉴了这样的结构,每一个神经元(上面说到的简单单元)接受输入x,通过带权重w的连接进行传递,将总输入信号与神经元的阈值进行比较,最后通过激活函数处理确定是否激活,并将激活后的计算结果y输出,而我们所说的训练,所训练的就是这里面的权重w。
每一个神经元的结构如下:
神经网络的表示
我们可以将神经元拼接起来,两层神经元,即输入层+输出层(M-P神经元),构成感知机。
而多层功能神经元相连构成神经网络,输入层与输出层之间的所有层神经元,称为隐藏层:
如上图所示,输入层和输出层只有一个,中间的隐藏层可以有很多层(输出层也可以多个,例如经典的GoogleNet,后面会详细介绍)
激活函数
介绍神经网络的时候已经说到,神经元会对化学物质的刺激进行,当达到一定程度的时候,神经元才会兴奋,并向其他神经元发送信息。神经网络中的激活函数就是用来判断我们所计算的信息是否达到了往后面传输的条件。
为什么激活函数都是非线性的
在神经网络的计算过程中,每层都相当于矩阵相乘,无论神经网络有多少层输出都是输入的线性组合,就算我们有几千层的计算,无非还是个矩阵相乘,和一层矩阵相乘所获得的信息差距不大,所以需要激活函数来引入非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中,增加了神经网络模型泛化的特性。
早期研究神经网络主要采用sigmoid函数或者tanh函数,输出有界,很容易充当下一层的输入。
近些年Relu函数及其改进型(如Leaky-ReLU、P-ReLU、R-ReLU等),由于计算简单、效果好所以在多层神经网络中应用比较多。
下面来总结下较常见的激活函数:
初始化一些信息
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
import numpy as np
x= torch.linspace(-10,10,60)
sigmoid 函数
a=11+e−za=\frac{1}{1+e^{-z}}a=1+e−z1 导数 :a′=a(1−a)a^\prime =a(1 - a)a′=a(1−a)
在sigmoid函数中我们可以看到,其输出是在(0,1)这个开区间,它能够把输入的连续实值变换为0和1之间的输出,如果是非常大的负数,那么输出就是0;如果是非常大的正数输出就是1,起到了抑制的作用。
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.ylim((0, 1))
sigmod=torch.sigmoid(x)
plt.plot(x.numpy(),sigmod.numpy())
但是sigmod由于需要进行指数运算(这个对于计算机来说是比较慢,相比relu),再加上函数输