L3 多层感知机
**本小节用到的数据下载
1、涉及语句 import d2lzh1981 as d2l
数据1 :
d2lzh1981
链接:https://pan.baidu.com/s/1LyaZ84Q4M75GLOO-ZPvPoA
提取码:cf8s
2、涉及语句
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root=’/home/kesci/input/FashionMNIST2065’)
数据2 : 为方便,可把数据直接下载下来。
为使用需
1)保持数据文件夹的路径把数据拷贝到jupyter notebook路径下
2)修改 home路径前加点 ,即’./home/kesci/input/FashionMNIST2065’)。
3)修改d2lzh1981文件下的utils.py 的load_data_fashion_mnist() 方法。为
torchvision.datasets.FashionMNIST(root=root, train=True, download=False, transform=transform)
FashionMNIST2065
链接:https://pan.baidu.com/s/1MLhOsusr5hqPn8sik1bUqw
提取码:v0l8**
多层感知机
- 多层感知机的基本知识
- 使用多层感知机图像分类的从零开始的实现
- 使用pytorch的简洁实现
多层感知机的基本知识
深度学习主要关注多层模型。在这里,我们将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念。
隐藏层
下图展示了一个多层感知机的神经网络图,它含有一个隐藏层,该层中有5个隐藏单元。
表达公式
具体来说,给定一个小批量样本X∈Rn×d\boldsymbol{X} \in \mathbb{R}^{n \times d}X∈Rn×d,其批量大小为nnn,输入个数为ddd。假设多层感知机只有一个隐藏层,其中隐藏单元个数为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函数只保留正数元素,并将负数元素清零。为了直观地观察这一非线性变换,我们先定义一个绘图函数xyplot。
%matplotlib inline
import torch
import numpy as np
import matplotlib.pyplot as plt
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l
print(torch.__version__)
1.3.0
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)).
下面绘制了sigmoid函数的导数。当输入为0时,sigmoid函数的导数达到最大值0.25;当输入越偏离0时,sigmoid函数的导数越接近0。
x.grad.zero_()
y.sum().backward()
xyplot(x, x.grad, 'grad of sigmoid')

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).
我们接着绘制tanh函数。当输入接近0时,tanh函数接近线性变换。虽然该函数的形状和sigmoid函数的形状很像,但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).
下面绘制了tanh函数的导数。当输入为0时,tanh函数的导数达到最大值1;当输入越偏离0时,tanh函数的导数越接近0。
x.grad.zero_()
y.sum().backward()
xyplot(x, x.grad, 'grad of tanh')

关于激活函数的选择
ReLu函数是一个通用的激活函数,目前在大多数情况下使用。但是,ReLU函数只能在隐藏层中使用。
用于分类器时,sigmoid函数及其组合通常效果更好。由于梯度消失问题,有时要避免使用sigmoid和tanh函数。
在神经网络层数较多的时候,最好使用ReLu函数,ReLu函数比较简单计算量少,而sigmoid和tanh函数计算量大很多。
在选择激活函数的时候可以先选用ReLu函数如果效果不理想可以尝试其他激活函数。
多层感知机
多层感知机就是含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。多层感知机的层数和各隐藏层中隐藏单元个数都是超参数。以单隐藏层为例并沿用本节之前定义的符号,多层感知机按以下方式计算输出:
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,
其中ϕ\phiϕ表示激活函数。
多层感知机从零开始的实现
import torch
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l
print(torch.__version__)
1.3.0
获取训练集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/kesci/input/FashionMNIST2065')
定义模型参数
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = 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.0
# def 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, 0
# for 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)
epoch 1, loss 0.0030, train acc 0.712, test acc 0.806
epoch 2, loss 0.0019, train acc 0.821, test acc 0.806
epoch 3, loss 0.0017, train acc 0.847, test acc 0.825
epoch 4, loss 0.0015, train acc 0.856, test acc 0.834
epoch 5, loss 0.0015, train acc 0.863, test acc 0.847
多层感知机pytorch nn.Sequential实现
import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l
print(torch.__version__)
1.3.0
初始化模型和各个参数
num_inputs, num_outputs, num_hiddens = 784, 10, 256
net = 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)
对x的形状转换的这个功能已经自定义一个FlattenLayer类中,放在d2lzh_pytorch中方便后面使用
class FlattenLayer(nn.Module):
def __init__(self):
super(FlattenLayer, self).__init__()
def forward(self, x): # x 的形状: (batch, *, *, ...)
return x.view(x.shape[0], -1)
#若x是包含batchsize维度为4的tensor,即(batchsize,channels,x,y),x.size(0)指batchsize的值
#x = x.view(x.size(0), -1) 等同x = x.view(batchsize, -1)。
torch x = x.view(x.size(0),-1)的理解
训练
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/kesci/input/FashionMNIST2065')
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)
epoch 1, loss 0.0031, train acc 0.701, test acc 0.774
epoch 2, loss 0.0019, train acc 0.821, test acc 0.806
epoch 3, loss 0.0017, train acc 0.841, test acc 0.805
epoch 4, loss 0.0015, train acc 0.855, test acc 0.834
epoch 5, loss 0.0014, train acc 0.866, test acc 0.840
L3 多层感知机的更多相关文章
- DeepLearning学习(1)--多层感知机
想直接学习卷积神经网络,结果发现因为神经网络的基础较弱,学习起来比较困难,所以准备一步步学.并记录下来,其中会有很多摘抄. (一)什么是多层感知器和反向传播 1,单个神经元 神经网络的基本单元就是神经 ...
- Theano3.4-练习之多层感知机
来自http://deeplearning.net/tutorial/mlp.html#mlp Multilayer Perceptron note:这部分假设读者已经通读之前的一个练习 Classi ...
- 学习笔记TF026:多层感知机
隐含层,指除输入.输出层外,的中间层.输入.输出层对外可见.隐含层对外不可见.理论上,只要隐含层节点足够多,只有一个隐含层,神经网络可以拟合任意函数.隐含层越多,越容易拟合复杂函数.拟合复杂函数,所需 ...
- 『TensorFlow』读书笔记_多层感知机
多层感知机 输入->线性变换->Relu激活->线性变换->Softmax分类 多层感知机将mnist的结果提升到了98%左右的水平 知识点 过拟合:采用dropout解决,本 ...
- MXNET:多层感知机
从零开始 前面了解了多层感知机的原理,我们来实现一个多层感知机. # -*- coding: utf-8 -*- from mxnet import init from mxnet import nd ...
- 基于theano的多层感知机的实现
1.引言 一个多层感知机(Multi-Layer Perceptron,MLP)可以看做是,在逻辑回归分类器的中间加了非线性转换的隐层,这种转换把数据映射到一个线性可分的空间.一个单隐层的MLP就可以 ...
- (数据科学学习手札44)在Keras中训练多层感知机
一.简介 Keras是有着自主的一套前端控制语法,后端基于tensorflow和theano的深度学习框架,因为其搭建神经网络简单快捷明了的语法风格,可以帮助使用者更快捷的搭建自己的神经网络,堪称深度 ...
- (数据科学学习手札34)多层感知机原理详解&Python与R实现
一.简介 机器学习分为很多个领域,其中的连接主义指的就是以神经元(neuron)为基本结构的各式各样的神经网络,规范的定义是:由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系 ...
- DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解
本文介绍多层感知机算法,特别是详细解读其代码实现,基于python theano,代码来自:Multilayer Perceptron,如果你想详细了解多层感知机算法,可以参考:UFLDL教程,或者参 ...
随机推荐
- PTA 创建计算机类
6-5创建计算机 (10分) 定义一个简单的Computer类,有数据成员芯片(cpu).内存(ram).光驱(cdrom)等等,有两个公有成员函数run.stop.cpu为CPU类的一个对象,ram ...
- Effective python(五):内置模块
1,考虑使用contextlib和with语句改写可复用的try/finally代码 with lock:print('lock is held')相当于try:print('lock is held ...
- 力软敏捷框架7.0.6 葡萄城报表升级到ar14版本
忙了两天终于搞定升级到ar14版本,坑无数,终于算全部解决,在这里做一个小结. 1.第一步去掉框架中原本集成的ar13部分(吐槽一下应该是对12的集成). 首先去掉licenses.licx文件. 然 ...
- CSS样式的4种写法 | 以及选择器的几种用法
CSS样式: 1.内部样式表 <style type="text/css"> 样式表写法 </style> 2.使用link标签,在文档中声明使用 ...
- Python第三方包之pretty-errors
Python第三方包之pretty-errors 发现了一个第三方好用的python包,这个包可以让我们在面对冗长的错误时候能够一眼看到重点 安装方式 pip install pretty-error ...
- Java并发基础07. ThreadLocal类以及应用技巧
在前面的文章(6. 线程范围内共享数据)总结了一下,线程范围内的数据共享问题,即定义一个 Map,将当前线程名称和线程中的数据以键值对的形式存到 Map 中,然后在当前线程中使用数据的时候就可以根据当 ...
- Vertica的这些事(十二)——-vertica备份与恢复
最近在使用vertica,上网找了很多资料都没有,只有自己看官方文档动手搞一下了,今天搞了vertica的备份与恢复 以下是整理的过程,分享给大家,如有问题欢迎大家指正~ 可加QQ群交流:412191 ...
- 三角函数在Three.js中的点的移动轨迹应用
在学习2D文字的时候,看到官网有这样一个示例: https://threejs.org/examples/#css2d_label (贪心)
Given a collection of number segments, you are supposed to recover the smallest number from them. Fo ...
- Jenkins中管道案例脚本(生命式语法)
pipeline { agent any parameters { choice( choices: 'feature\nmaster\npercent10', description: '选择要发布 ...