从零开始学Pytorch(三)之多层感知机的实现
多层感知机的基本知识
我们将以多层感知机(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=XWhWo+bhWo+bo.
从联立后的式子可以看出,虽然神经网络引入了隐藏层,却依然等价于一个单层神经网络:其中输出层权重参数为WhWo\boldsymbol{W}_h\boldsymbol{W}_oWhWo,偏差参数为bhWo+bo\boldsymbol{b}_h \boldsymbol{W}_o + \boldsymbol{b}_obhWo+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(三)之多层感知机的实现相关推荐
- 从零开始学架构三 高性能
从零开始学架构三 高性能 读写分离 读写分离的基本实现是: 数据库服务器搭建主从集群,一主一从.一主多从都可以. 数据库主机负责读写操作,从机只负责读操作. 数据库主机通过复制将数据同步到从机,每台数 ...
- 从零开始学Pytorch(零)之安装Pytorch
本文首发于公众号"计算机视觉cv" Pytorch优势 聊聊为什么使用Pytorch,个人觉得Pytorch比Tensorflow对新手更为友善,而且现在Pytorch在学术界 ...
- 从零开始学Pytorch(第5天)
从零开始学Pytorch(第5天) 前言 一.模块类的构建 1. nn.Module 2.构建一个线性回归类 二.计算图和自动求导机制 1.计算图 2.自动求导 总结 前言 今天主要了解和学习Pyto ...
- 《动手实现深度学习》笔记(三)多层感知机
四. 多层感知机 4.1 简介及实现 4.1.1 简介 1. [线性模型可能出错] 仿射变换中的线性是一个很强的假设,但实际上线性模型是可能会出错的,线性意味着单调,任何特征的增大都会导致模型输出 ...
- 动手学深度学习(PyTorch实现)(五)--多层感知机
多层感知机 1. 基本知识 2. 激活函数 2.1 ReLU函数 2.2 Sigmoid函数 2.3 tanh函数 2.4 关于激活函数的选择 3. PyTorch实现 3.1 导入相应的包 3.2 ...
- 三、多层感知机及模型优化
文章目录 前言 一.多层感知机 1.1 隐藏层 1.1.1 什么叫隐藏层 1.1.2 为什么需要隐藏层 1.2 激活函数 1.2.1 ReLU函数 1.2.2 Sigmoid函数 1.2.3 tanh ...
- 从零开始学Pytorch(五)之欠拟合和过拟合
本文首发于微信公众号"计算机视觉cv" 模型选择.过拟合和欠拟合 训练误差和泛化误差 训练误差(training error)指模型在训练数据集上表现出的误差,泛化误差(gener ...
- 【动手学深度学习】多层感知机(MLP)
1 多层感知机的从零开始实现 torch.nn 继续使用Fashion-MNIST图像分类数据集 导入需要的包 import torch from torch import nn from d2l i ...
- 动手学深度学习之多层感知机
多层感知机 多层感知机的基本知识 深度学习主要关注多层模型.本节将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念. 隐藏层 下图展示了一个多层感知机的神 ...
最新文章
- as3回调方法模拟事件监听
- 关于outlook2010帐户设置
- C/C++:sizeof('a')的值为什么不一样?
- SpringMVC+Hibernate+Junit4+json基本框架近乎0配置
- app 崩溃测试 (转:CSDN 我去热饭)
- Python连接SQL Server数据库 - pymssql使用基础
- php7 提示500错误解决,升级php7出现500错误怎么办
- Freeswitch NAT问题
- react-native相机
- qscoj:喵哈哈村的卢西奥
- python调用 ole:win32com用法详解
- Vue 快速原型开发
- 百度程序员开发避坑指南(前端篇)
- Win8 RP微软原版光盘镜像下载大全(含中文版)
- 音乐格式怎么转换,音频格式转换的方法
- HCIP 综合实验(一)
- 2022还不知道登陆邮箱账号怎么填写?个人邮箱登录注册流程看详解
- Unity 优化贴图模型
- 2020年交通运输区块链白皮书
- 大头贴制作大师 v6.9.5 简体中文绿色特别版
热门文章
- linux rabbitmq 远程登录
- [JoyOI] 1035 棋盘覆盖 (二分图匹配)
- 编译JDK源代码【转】
- 数据库-MySQL-JDBC-execute、executeUpdate、executeQuery
- html实现平面地图效果,HTML5 光点组成的平面和立体世界地图
- datax 不识别字段过滤_静电式空气过滤器有什么特点 静电式空气过滤器特点介绍【详解】...
- 树莓派 python_树莓派笔记08—Python流水灯
- 计算机主板用塑料做的好吗,电脑主板包装的塑料袋为什么是用透明胶封的,这样...-卓优商学问答...
- java运用ascii实现动画效果_安卓开发20:动画之Animation 详细使用-主要通过java代码实现动画效果...
- 2021年11月国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发