《动手学深度学习》Day3:多层感知机


文章目录

  • 一、多层感知机的基本知识
    • 1.1 隐藏层
    • 1.2 表达公式
    • 1.3 激活函数
    • 1.4 多层感知机
  • 二、多层感知机从零开始的实现
    • 2.1 获取训练集
    • 2.2 定义模型参数
    • 2.3 定义激活函数
    • 2.4 定义网络
    • 2.5 定义损失函数
    • 2.6 训练
  • 三、多层感知机pytorch实现
    • 3.1 初始化模型和各个参数
    • 3.2 训练


一、多层感知机的基本知识

深度学习主要关注多层模型。在这里,我们将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念。

1.1 隐藏层

下图展示了一个多层感知机的神经网络图,它含有一个隐藏层,该层中有5个隐藏单元。
《动手学深度学习》Day3:多层感知机_第1张图片

1.2 表达公式

具体来说,给定一个小批量样本 X ∈ R n × d \textbf{X}\in R^{n\times d} XRn×d其批量大小为n,输入个数为d。假设多层感知机只有一个隐藏层,其中隐藏单元个数为h。记隐藏层的输出(也称为隐藏层变量或隐藏变量)为 H \textbf{H} H,有 H ∈ R n × h \textbf{H}\in R^{n\times h} HRn×h。因为隐藏层和输出层均是全连接层,可以设隐藏层的权重参数和偏差参数分别为 W h ∈ R d × h \textbf{W}_{h}\in R^{d\times h} WhRd×h b h ∈ R 1 × h \textbf{b}_{h}\in R^{1\times h} bhR1×h,输出层的权重和偏差参数分别为 W o ∈ R h × q \textbf{W}_{o}\in R^{h\times q} WoRh×q b o ∈ R 1 × q \textbf{b}_{o}\in R^{1\times q} boR1×q.

我们先来看一种含单隐藏层的多层感知机的设计。其输出 O ∈ R n × q \textbf{O}\in R^{n\times q} ORn×q的计算为
在这里插入图片描述
也就是将隐藏层的输出直接作为输出层的输入。如果将以上两个式子联立起来,可以得到
在这里插入图片描述
从联立后的式子可以看出,虽然神经网络引入了隐藏层,却依然等价于一个单层神经网络:其中输出层权重参数为 W h W o \textbf{W}_{h}\textbf{W}_{o} WhWo,偏差参数为 b h W o + b o \textbf{b}_{h}\textbf{W}_{o}+\textbf{b}_{o} bhWo+bo。不难发现,即便再添加更多的隐藏层,以上设计依然只能与仅含输出层的单层神经网络等价。

1.3 激活函数

上述问题的根源在于全连接层只是对数据做仿射变换(affine transformation),而多个仿射变换的叠加仍然是一个仿射变换。解决问题的一个方法是引入非线性变换,例如对隐藏变量使用按元素运算的非线性函数进行变换,然后再作为下一个全连接层的输入。这个非线性函数被称为激活函数(activation function)。

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

1、ReLU函数

ReLU(rectified linear unit)函数提供了一个很简单的非线性变换。给定元素 x x x,该函数定义为
在这里插入图片描述
可以看出,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')

《动手学深度学习》Day3:多层感知机_第2张图片

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

《动手学深度学习》Day3:多层感知机_第3张图片
2、Sigmoid函数

sigmoid函数可以将元素的值变换到0和1之间:
在这里插入图片描述

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

《动手学深度学习》Day3:多层感知机_第4张图片
依据链式法则,sigmoid函数的导数
在这里插入图片描述
下面绘制了sigmoid函数的导数。当输入为0时,sigmoid函数的导数达到最大值0.25;当输入越偏离0时,sigmoid函数的导数越接近0。

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

《动手学深度学习》Day3:多层感知机_第5张图片

1.4 多层感知机

多层感知机就是含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。多层感知机的层数和各隐藏层中隐藏单元个数都是超参数。以单隐藏层为例并沿用本节之前定义的符号,多层感知机按以下方式计算输出:
在这里插入图片描述
其中 ϕ \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

2.1 获取训练集

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/kesci/input/FashionMNIST2065')

2.2 定义模型参数

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)

2.3 定义激活函数

def relu(X):
    return torch.max(input=X, other=torch.tensor(0.0))

2.4 定义网络

def net(X):
    X = X.view((-1, num_inputs))
    H = relu(torch.matmul(X, W1) + b1)
    return torch.matmul(H, W2) + b2

2.5 定义损失函数

loss = torch.nn.CrossEntropyLoss()

2.6 训练

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实现

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__)

3.1 初始化模型和各个参数

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)

3.2 训练

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

你可能感兴趣的:(深度学习框架实战,深度学习)