多层感知机的基本知识

我们将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念。

隐藏层

下图展示了一个多层感知机的神经网络图,它含有一个隐藏层,该层中有5个隐藏单元。

表达公式

设小批量样本X∈Rn×d\boldsymbol{X} \in \mathbb{R}^{n \times d}X∈Rn×d,nnn为批量大小,ddd为1输入个数。假设多层感知机只有一个隐藏层,其中隐藏单元个数为hhh。记隐藏层的输出(也称为隐藏层变量或隐藏变量)为H\boldsymbol{H}H,有H∈Rn×h\boldsymbol{H} \in \mathbb{R}^{n \times h}H∈Rn×h。设隐藏层的权重参数和偏差参数分别为Wh∈Rd×h\boldsymbol{W}_h \in \mathbb{R}^{d \times h}Wh​∈Rd×h和 bh∈R1×h\boldsymbol{b}_h \in \mathbb{R}^{1 \times h}bh​∈R1×h,输出层的权重和偏差参数分别为Wo∈Rh×q\boldsymbol{W}_o \in \mathbb{R}^{h \times q}Wo​∈Rh×q和bo∈R1×q\boldsymbol{b}_o \in \mathbb{R}^{1 \times q}bo​∈R1×q。

下面是单隐藏层的多层感知机的设计。其输出O∈Rn×q\boldsymbol{O} \in \mathbb{R}^{n \times q}O∈Rn×q的计算为

H=XWh+bh,O=HWo+bo,\begin{aligned} \boldsymbol{H} &= \boldsymbol{X} \boldsymbol{W}_h + \boldsymbol{b}_h,\\ \boldsymbol{O} &= \boldsymbol{H} \boldsymbol{W}_o + \boldsymbol{b}_o, \end{aligned} HO​=XWh​+bh​,=HWo​+bo​,​

将以上两个式子联立起来,得:

O=(XWh+bh)Wo+bo=XWhWo+bhWo+bo.\boldsymbol{O} = (\boldsymbol{X} \boldsymbol{W}_h + \boldsymbol{b}_h)\boldsymbol{W}_o + \boldsymbol{b}_o = \boldsymbol{X} \boldsymbol{W}_h\boldsymbol{W}_o + \boldsymbol{b}_h \boldsymbol{W}_o + \boldsymbol{b}_o. O=(XWh​+bh​)Wo​+bo​=XWh​Wo​+bh​Wo​+bo​.

从联立后的式子可以看出,虽然神经网络引入了隐藏层,却依然等价于一个单层神经网络:其中输出层权重参数为WhWo\boldsymbol{W}_h\boldsymbol{W}_oWh​Wo​,偏差参数为bhWo+bo\boldsymbol{b}_h \boldsymbol{W}_o + \boldsymbol{b}_obh​Wo​+bo​。所以即便再添加更多的隐藏层,依然只与仅含输出层的单层神经网络等价。

激活函数

以上问题在于全连接层只是对数据做仿射变换(affine transformation),而多个仿射变换的叠加仍然是一个仿射变换。所以需要一个非线性函数来进行变换,打破这种仿射变换,然后输出再作为下一个全连接层的输入。这个非线性函数被称为激活函数(activation function)。

下面我们介绍几个常用的激活函数:

ReLU函数

ReLU(rectified linear unit)函数提供了一个简单的非线性变换。给定元素xxx,该函数定义为

ReLU(x)=max⁡(x,0).\text{ReLU}(x) = \max(x, 0). ReLU(x)=max(x,0).

由上述可得,ReLU函数只保留正数元素,并将负数元素清零。下面我们把ReLU函数画出来。先定义一个绘图函数xyplot。

注:d2lzh1981为一个包名,先封装好然后可以直接调用;具体代码在下面Github页面上:https://github.com/d2l-ai/d2l-zh/tree/master/d2lzh

%matplotlib inline
import torch
import numpy as np
import matplotlib.pyplot as plt
import sys
sys.path.append("/home/input") #文件夹路径
import d2lzh1981 as d2l
def xyplot(x_vals, y_vals, name):# d2l.set_figsize(figsize=(5, 2.5))plt.plot(x_vals.detach().numpy(), y_vals.detach().numpy())plt.xlabel('x')plt.ylabel(name + '(x)')
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = x.relu()
xyplot(x, y, 'relu')

y.sum().backward()
xyplot(x, x.grad, 'grad of relu')

Sigmoid函数

sigmoid函数将元素的值变换到0和1之间:

sigmoid(x)=11+exp⁡(−x).\text{sigmoid}(x) = \frac{1}{1 + \exp(-x)}. sigmoid(x)=1+exp(−x)1​.

y = x.sigmoid()
xyplot(x, y, 'sigmoid')


对sigmoid函数求导,其导数为:
sigmoid′(x)=sigmoid(x)(1−sigmoid(x)).\text{sigmoid}'(x) = \text{sigmoid}(x)\left(1-\text{sigmoid}(x)\right). sigmoid′(x)=sigmoid(x)(1−sigmoid(x)).

tanh函数

tanh(双曲正切)函数可以将元素的值变换到-1和1之间:

tanh(x)=1−exp⁡(−2x)1+exp⁡(−2x).\text{tanh}(x) = \frac{1 - \exp(-2x)}{1 + \exp(-2x)}. tanh(x)=1+exp(−2x)1−exp(−2x)​.

当输入接近0时,tanh函数接近线性变换。tanh函数在坐标系的原点上对称。

y = x.tanh()
xyplot(x, y, 'tanh')


tanh的导数为:
tanh′(x)=1−tanh2(x).\text{tanh}'(x) = 1 - \text{tanh}^2(x). tanh′(x)=1−tanh2(x).

x.grad.zero_()
y.sum().backward()
xyplot(x, x.grad, 'grad of tanh')

激活函数的选择

ReLu函数是一个通用的激活函数,一般都用ReLu。但是,ReLU函数只能在隐藏层中使用。
用于分类器时,sigmoid函数及其组合通常效果更好。由于梯度消失问题,有时要避免使用sigmoid和tanh函数。

多层感知机

多层感知机含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。
H=ϕ(XWh+bh),O=HWo+bo,\begin{aligned} \boldsymbol{H} &= \phi(\boldsymbol{X} \boldsymbol{W}_h + \boldsymbol{b}_h),\\ \boldsymbol{O} &= \boldsymbol{H} \boldsymbol{W}_o + \boldsymbol{b}_o, \end{aligned} HO​=ϕ(XWh​+bh​),=HWo​+bo​,​

多层感知机从零开始的实现

import torch
import numpy as np
import sys
sys.path.append("/home/input") #文件夹路径
import d2lzh1981 as d2l
#获取数据集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/input/FashionMNIST2065')
#自定义模型参数
num_inputs, num_outputs, num_hiddens = 784, 10, 256W1 = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_hiddens)), dtype=torch.float)
b1 = torch.zeros(num_hiddens, dtype=torch.float)
W2 = torch.tensor(np.random.normal(0, 0.01, (num_hiddens, num_outputs)), dtype=torch.float)
b2 = torch.zeros(num_outputs, dtype=torch.float)params = [W1, b1, W2, b2]
for param in params:param.requires_grad_(requires_grad=True)
#定义激活函数
def relu(X):return torch.max(input=X, other=torch.tensor(0.0))
#定义网络
def net(X):X = X.view((-1, num_inputs))H = relu(torch.matmul(X, W1) + b1)return torch.matmul(H, W2) + b2
#定义损失函数
loss = torch.nn.CrossEntropyLoss()
#训练
num_epochs, lr = 5, 100.0def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,params=None, lr=None, optimizer=None):for epoch in range(num_epochs):train_l_sum, train_acc_sum, n = 0.0, 0.0, 0for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y).sum()# 梯度清零if optimizer is not None:optimizer.zero_grad()elif params is not None and params[0].grad is not None:for param in params:param.grad.data.zero_()l.backward()if optimizer is None:d2l.sgd(params, lr, batch_size)else:optimizer.step()  # “softmax回归的简洁实现”一节将用到train_l_sum += l.item()train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = evaluate_accuracy(test_iter, net)print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

多层感知机pytorch简洁实现

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("/home/input")
import d2lzh1981 as d2l
num_inputs, num_outputs, num_hiddens = 784, 10, 256net = nn.Sequential(d2l.FlattenLayer(),nn.Linear(num_inputs, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_outputs), )for params in net.parameters():init.normal_(params, mean=0, std=0.01)
num_inputs, num_outputs, num_hiddens = 784, 10, 256net = nn.Sequential(d2l.FlattenLayer(),nn.Linear(num_inputs, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_outputs), )for params in net.parameters():init.normal_(params, mean=0, std=0.01)

从零开始学Pytorch(三)之多层感知机的实现相关推荐

  1. 从零开始学架构三 高性能

    从零开始学架构三 高性能 读写分离 读写分离的基本实现是: 数据库服务器搭建主从集群,一主一从.一主多从都可以. 数据库主机负责读写操作,从机只负责读操作. 数据库主机通过复制将数据同步到从机,每台数 ...

  2. 从零开始学Pytorch(零)之安装Pytorch

    本文首发于公众号"计算机视觉cv" Pytorch优势   聊聊为什么使用Pytorch,个人觉得Pytorch比Tensorflow对新手更为友善,而且现在Pytorch在学术界 ...

  3. 从零开始学Pytorch(第5天)

    从零开始学Pytorch(第5天) 前言 一.模块类的构建 1. nn.Module 2.构建一个线性回归类 二.计算图和自动求导机制 1.计算图 2.自动求导 总结 前言 今天主要了解和学习Pyto ...

  4. 《动手实现深度学习》笔记(三)多层感知机

    四. 多层感知机 4.1 简介及实现 4.1.1 简介   1. [线性模型可能出错] 仿射变换中的线性是一个很强的假设,但实际上线性模型是可能会出错的,线性意味着单调,任何特征的增大都会导致模型输出 ...

  5. 动手学深度学习(PyTorch实现)(五)--多层感知机

    多层感知机 1. 基本知识 2. 激活函数 2.1 ReLU函数 2.2 Sigmoid函数 2.3 tanh函数 2.4 关于激活函数的选择 3. PyTorch实现 3.1 导入相应的包 3.2 ...

  6. 三、多层感知机及模型优化

    文章目录 前言 一.多层感知机 1.1 隐藏层 1.1.1 什么叫隐藏层 1.1.2 为什么需要隐藏层 1.2 激活函数 1.2.1 ReLU函数 1.2.2 Sigmoid函数 1.2.3 tanh ...

  7. 从零开始学Pytorch(五)之欠拟合和过拟合

    本文首发于微信公众号"计算机视觉cv" 模型选择.过拟合和欠拟合 训练误差和泛化误差 训练误差(training error)指模型在训练数据集上表现出的误差,泛化误差(gener ...

  8. 【动手学深度学习】多层感知机(MLP)

    1 多层感知机的从零开始实现 torch.nn 继续使用Fashion-MNIST图像分类数据集 导入需要的包 import torch from torch import nn from d2l i ...

  9. 动手学深度学习之多层感知机

    多层感知机 多层感知机的基本知识 深度学习主要关注多层模型.本节将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念. 隐藏层 下图展示了一个多层感知机的神 ...

最新文章

  1. as3回调方法模拟事件监听
  2. 关于outlook2010帐户设置
  3. C/C++:sizeof('a')的值为什么不一样?
  4. SpringMVC+Hibernate+Junit4+json基本框架近乎0配置
  5. app 崩溃测试 (转:CSDN 我去热饭)
  6. Python连接SQL Server数据库 - pymssql使用基础
  7. php7 提示500错误解决,升级php7出现500错误怎么办
  8. Freeswitch NAT问题
  9. react-native相机
  10. qscoj:喵哈哈村的卢西奥
  11. python调用 ole:win32com用法详解
  12. Vue 快速原型开发
  13. 百度程序员开发避坑指南(前端篇)
  14. Win8 RP微软原版光盘镜像下载大全(含中文版)
  15. 音乐格式怎么转换,音频格式转换的方法
  16. HCIP 综合实验(一)
  17. 2022还不知道登陆邮箱账号怎么填写?个人邮箱登录注册流程看详解
  18. Unity 优化贴图模型
  19. 2020年交通运输区块链白皮书
  20. 大头贴制作大师 v6.9.5 简体中文绿色特别版

热门文章

  1. linux rabbitmq 远程登录
  2. [JoyOI] 1035 棋盘覆盖 (二分图匹配)
  3. 编译JDK源代码【转】
  4. 数据库-MySQL-JDBC-execute、executeUpdate、executeQuery
  5. html实现平面地图效果,HTML5 光点组成的平面和立体世界地图
  6. datax 不识别字段过滤_静电式空气过滤器有什么特点 静电式空气过滤器特点介绍【详解】...
  7. 树莓派 python_树莓派笔记08—Python流水灯
  8. 计算机主板用塑料做的好吗,电脑主板包装的塑料袋为什么是用透明胶封的,这样...-卓优商学问答...
  9. java运用ascii实现动画效果_安卓开发20:动画之Animation 详细使用-主要通过java代码实现动画效果...
  10. 2021年11月国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发