参考文章:
1.动手学深度学习——多层感知机(原理解释+代码详解)_多层感知机 代码-CSDN博客
2.4.1. 多层感知机 — 动手学深度学习 2.0.0 documentation
3.深度理解多层感知机(MLP) | 米奇妙妙屋
1. 神经网络由来
神经网络的灵感取自于生物上的神经元细胞。希望仿照人类神经网络的结构,搭建一种人为的神经网络结构,从而使其能够完成一些计算任务。
神经网络中计算的基本单元是神经元,一般称作节点(node)或者单元(unit)。每个节点可以从其他节点接收输入,或者从外部源接收输入,然后计算输出。每个输入都各自的权重(weight,即 w),用于调节该输入对输出影响的大小,节点的结构如下图。
其中:
- 输入:x1,x2
- 权重:x1的权重为w1,x2的权重为w2
- 偏置:b (偏置的主要功能是为每一个节点提供可训练的常量值)
- 激活函数:f
注意:一般采用非线性函数,其作用是将非线性引入神经元的输出。因为大多数现实世界的数据都是非线性的,我们希望神经元能够学习非线性的函数表示,如果激活函数仍然是线性的,那么根据线性可叠加的原理,整个函数模型仍然是线性的,那么就无法解决我们遇到的问题(例如异或),因此激活函数非线性这一点非常重要。
2. 激活函数
几种激活函数:
-
Sigmoid(S 型激活函数):输入一个实值,输出一个 0 至 1 间的值 σ(x) = 1 / (1 + exp(−x))
-
tanh(双曲正切函数):输入一个实值,输出一个 [-1,1] 间的值 tanh(x) = 2σ(2x) − 1
-
ReLU:ReLU 代表修正线性单元。输出一个实值,并设定 0 的阈值(函数会将负值变为零)f(x) = max(0, x)
-
第一种Sigmoid就是逻辑回归使用的激活函数,往往应用于二分类;在神经网络中,我们往往更倾向于使用最后一种relu函数作为激活函数。
import torch
from d2l import torch as d2l
# Relu
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = torch.relu(x)
d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize=(5, 2.5))
d2l.plt.show()
# Relu的导数
y.backward(torch.ones_like(x), retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of relu', figsize=(5, 2.5))
d2l.plt.show()
# sigmoid
y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize=(5, 2.5))
d2l.plt.show()
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of sigmoid', figsize=(5, 2.5))
d2l.plt.show()
# tanh
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize=(5, 2.5))
d2l.plt.show()
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of tanh', figsize=(5, 2.5))
d2l.plt.show()
2.1 ReLU函数
2.2 sigmoid函数
2.3 tanh函数
3.MLP结构
-
输入节点(Input Nodes):输入节点从外部世界提供信息,总称为输入层。在输入节点中,不进行任何的计算,仅向隐藏节点传递信息。
-
隐藏节点(Hidden Nodes):隐藏节点和外部世界没有直接联系(由此得名)。这些节点进行计算,并将信息从输入节点传递到输出节点。隐藏节点总称为隐藏层。尽管一个前馈神经网络只有一个输入层和一个输出层,但网络里可以没有隐藏层(如果没有隐藏层,激活函数选择sigmod,那么就变成逻辑回归了),也可以有多个隐藏层。
-
输出节点(Output Nodes):输出节点总称为输出层,负责计算,并从网络向外部世界传递信息。