多层感知机
0. 环境介绍
环境使用 Kaggle 里免费建立的 Notebook
教程使用李沐老师的 动手学深度学习 网站和 视频讲解
小技巧:当遇到函数看不懂的时候可以按 Shift+Tab 查看函数详解。
1. 多层感知机概述
1.0 感知机
感知机是一个二分类模型。
 感知机训练过程:
 
感知机模型不能拟合 XOR 函数,它只能产生线性分割面。
 
1.1 多层感知机
1.1.1 学习 XOR
学习两条线:
 
 得到结果:
 
 结构示意图:
 
1.1.2 隐藏层
单隐藏层单分类:
 
 单隐藏层多分类:
 
 多隐藏层:
 
1.1.3 MLP 结构

 怎么设计网络比较好?
 李沐老师说:更深且瘦的网络效果可能要比浅而胖的网络效果要好,浅而胖的网络容易过拟合。但是老师也说这个没有理论依据,但效果上确实要好😂。
1.1.4 激活函数
并且激活函数必须是非线性的。若激活函数是线性的话,即使经过多层感知机,运算结果还是 W i j W_{ij} Wij 的线性组合,即还是线性的,无法解决非线性问题。
为方便理解:
 浙江大学 胡浩基老师的机器学习课程 6:50 左右有例子。
1.1.4.1 ReLU
ReLU 激活函数公式:
 
     
      
       
        
         ReLU
        
        
         
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         max
        
        
         
        
        
         (
        
        
         x
        
        
         ,
        
        
         0
        
        
         )
        
       
       
         \operatorname{ReLU}(x) = \max(x, 0) 
       
      
     ReLU(x)=max(x,0)
 
1.1.4.2 Sigmoid
将输入投影到 
    
     
      
       
        (
       
       
        0
       
       
        ,
       
       
        1
       
       
        )
       
      
      
       (0, 1)
      
     
    (0,1)。
 Sigmoid激活函数的公式:
 
     
      
       
        
         sigmoid
        
        
         
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         
          1
         
         
          
           1
          
          
           +
          
          
           exp
          
          
           
          
          
           (
          
          
           −
          
          
           x
          
          
           )
          
         
        
        
         .
        
       
       
         \operatorname{sigmoid}(x) = \frac{1}{1 + \exp(-x)}. 
       
      
     sigmoid(x)=1+exp(−x)1.
 
1.1.4.3 tanh
与 sigmoid 函数类似, tanh (双曲正切)函数能将其输入压缩转换到区间 
    
     
      
       
        (
       
       
        −
       
       
        1
       
       
        ,
       
       
        1
       
       
        )
       
      
      
       (-1, 1)
      
     
    (−1,1) 上。
 tanh 激活函数的公式:
 
     
      
       
        
         tanh
        
        
         
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         
          
           1
          
          
           −
          
          
           exp
          
          
           
          
          
           (
          
          
           −
          
          
           2
          
          
           x
          
          
           )
          
         
         
          
           1
          
          
           +
          
          
           exp
          
          
           
          
          
           (
          
          
           −
          
          
           2
          
          
           x
          
          
           )
          
         
        
        
         .
        
       
       
         \operatorname{tanh}(x) = \frac{1 - \exp(-2x)}{1 + \exp(-2x)}. 
       
      
     tanh(x)=1+exp(−2x)1−exp(−2x).
 
1.1.5 超参数
- 隐藏层数
- 每层隐藏层的大小(神经元个数)
2. 从零实现
2.0 导入模块
!pip install -U d2l # install d2l 模块
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
2.1 初始化模型参数
实现一个具有单隐藏层的多层感知机, 它包含 256 256 256 个隐藏单元。
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 第一层
W1 = nn.Parameter(torch.randn(
    num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
# 第二层
W2 = nn.Parameter(torch.randn(
    num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
2.2 激活函数(ReLU)
def relu(X):
    a = torch.zeros_like(X)
    return torch.max(X, a)
2.3 模型
def net(X):
    X = X.reshape((-1, num_inputs))
    H = relu(X@W1 + b1)  # 这里“@”代表矩阵乘法
    return (H@W2 + b2)
2.4 损失函数
loss = nn.CrossEntropyLoss(reduction='none')
2.5 训练
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)

2.6 预测
d2l.predict_ch3(net, test_iter)

3. 简洁实现
3.0 导入模块
import torch
from torch import nn
from d2l import torch as d2l
3.1 模型
net = nn.Sequential(nn.Flatten(),
                    nn.Linear(784, 256),
                    nn.ReLU(),
                    nn.Linear(256, 10))
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights);
3.2 损失函数,优化器
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=lr)
3.3 训练
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)











