深度学习导论(4)神经网络基础

深度学习导论(4)神经网络基础

  • 一. 训练深度学习模型的步骤
  • 二. 线性层(或叫全链接层)(Linear layer(dense or fully connected layers))
    • 1. 定义一个层
    • 2. 定义多个层
    • 3. 堆叠线性Layers(层)没有意义
  • 三. 激活函数
    • 1. 再谈激活函数
    • 2. Sigmoid
    • 3. Tanh
    • 4. ReLU
    • 5. 如何在PyTorch上实现激活函数的调用
  • 四. 搭建神经网络模型
    • 1. torch.nn module
    • 2. 基于PyTorch搭建神经网络模型
    • 3. 针对不同机器学习问题的模型结构
  • 五. Loss function(损失函数)
  • 六. Optimizer(优化方法)
  • 七. 训练(学习)过程(Training(learning)procedure)
  • 八. MNIST-PyTorch实现
      • (1) 代码
      • (2) 改变batch并输出input.size
      • (3) 改变batch并输出out.size
      • (4) 深度学习的本质思想
  • 九. 计算损失函数
  • 十. 更新权重
  • 十一. 手写数字识别分类问题具体步骤(Training an handwritten digit classification)

一. 训练深度学习模型的步骤

  • 建立数据通道。即把手里的数据预处理成模型输入的形式;
  • 搭建神经网络结构模型。即神经网络有几层,每层中有几个神经元,神经元之间是如何连接的;
  • 利用损失函数评估模型。输入模型的数据Input经过训练后(例如: 模型中的参数权重矩阵为 w 1 w_1 w1 w 2 w_2 w2,其中 w 1 w_1 w1为第一层与第二层之间连接的权重矩阵, w 2 w_2 w2为第二层与第三层之间连接的权重矩阵,)输出的预测值Output,与输入数据的真实值(即标签Lable)之间的误差,误差的结果就是损失,然后根据误差的值反过来去调整模型中的参数 w 1 w_1 w1 w 2 w_2 w2,如此反复地进行迭代,一直到找到一组最优(或局部最优)的参数 w 1 w_1 w1 w 2 w_2 w2
  • 使用优化算法优化神经网络模型权重。在反复迭代的过程中,需要不断地更新 w 1 w_1 w1 w 2 w_2 w2,这两个矩阵如何更新,就是优化算法。优化算法一般都是基于梯度下降法来更新 w 1 w_1 w1 w 2 w_2 w2(神经网络有很多优化方法)。
    深度学习导论(4)神经网络基础_第1张图片

二. 线性层(或叫全链接层)(Linear layer(dense or fully connected layers))

1. 定义一个层

深度学习导论(4)神经网络基础_第2张图片
(1) 所有的层的模块都在torch.nn中;
(2) 输入是10个神经元,输出是5个神经元,“bias为指定是否加入偏置项b”;
(3) “inp = torch.randn(1, 10)”表示输入的神经元。其中“1”表示的是batch,即每个批次送入的样本数,“10”表示的是每个batch中每个元素有10个维度;
(4) “out = mylayer(inp)”表示输入层。实际上就相当于一个函数,将输入inp送入到模型中去;
(5) “mylayer.weight”表示权重w。w的矩阵Size为[5, 10]。
注: w为权重矩阵。这里以输入为3个神经元,输出为2个神经元为例。
深度学习导论(4)神经网络基础_第3张图片

如上图所示,则权重矩阵 w = [ w 11 w 12 w 13 w 21 w 22 w 23 ] w=\begin{bmatrix} w_{11} & w_{12} & w_{13}\\ w_{21} & w_{22} & w_{23}\end{bmatrix} w=[w11w21w12w22w13w23] w w w的维度就是两行三列。
以batch = 3举例,如下:
深度学习导论(4)神经网络基础_第4张图片

可以发现, w w w权重矩阵并没有改变,这是因为我们没有去更新它。

2. 定义多个层

深度学习导论(4)神经网络基础_第5张图片

(1) 第一层输入神经元数量为10,输出神经元数量为5;
(2) 第二层输入神经元数量为5,输出神经元数量为2;
(3) 把第一层作为第二层的输入,这样两个层就串起来了。
神经网络就是这样串起来的,把前一个层的输出作为后一个层的输入。

3. 堆叠线性Layers(层)没有意义

如图所示:
深度学习导论(4)神经网络基础_第6张图片

堆叠完后还是相当于一层,只不过权重值由3变为了6,所以堆叠线性层是没有任何意义的,因为权重Weight( w w w)是学习出来的,用两层堆叠起来和直接用一层的效果是一样的。所以我们需要考虑如何将线性层变为非线性层,这就需要引出激活函数。

三. 激活函数

1. 再谈激活函数

  • 激活函数可以将线性模型的输出限定在一定的范围内。
  • 通过堆叠经过激活函数非线性化后的线性模型,可以高度逼近非线性过程。
  • 我们不需要关心用来表示数据的确切的函数类型,只是把深度神经网络模型看做一个通用逼近器或参数估计方法。
  • 常用激活函数:
    • Sigmoid
    • Tanh
    • ReLU
    • LeakyReLU

2. Sigmoid

深度学习导论(4)神经网络基础_第7张图片

当输入趋近于无穷小时,函数的值就趋近于0; 当输入趋近于无穷大时,函数的值就趋近于1。所以经过Sigmoid激活函数后,输出就压缩到了(0, 1)之间。

3. Tanh

深度学习导论(4)神经网络基础_第8张图片

4. ReLU

深度学习导论(4)神经网络基础_第9张图片

当输入小于0时,输出等于0; 当输入大于0时,输出等于输入本身。

5. 如何在PyTorch上实现激活函数的调用

深度学习导论(4)神经网络基础_第10张图片

四. 搭建神经网络模型

1. torch.nn module

  • torch.nn module专门用来构建神经网络,其包含了构建所有神经网络结构的模块,在PyTorch中将这些模块成为module(在其他框架中一般成为layers)。
  • 所有PyTorch module均继承自torch.nn基类。

2. 基于PyTorch搭建神经网络模型

深度学习导论(4)神经网络基础_第11张图片

3. 针对不同机器学习问题的模型结构

  • Linear layer: 线性层(一般用于输出层、输入层或中间层)
  • Long Short-Term Memory(LSTM): 长短时网络,一种RNN网络(一般用于输入层或中间层)
  • CNN: 卷积神经网络(一般用于输入层或中间层)
  • The last layer: 输出层
    • Linear layer: for regression problem
      对于回归问题,一般采用线性层。
    • Sigmoid activation function: for binary classification problem
      对于二分类问题,一般采用Sigmoid激活函数。
    • Softmax layer: for multi-class classification problem
      对于多分类问题,一般采用Softmax层。

举例: 非线性网络可以这样理解: 首先是一些线性层(Linear layer),线性层后边加上非线性层(如ReLU函数),然后ReLU的输出又传送到线性层当中,然后在线性层的后边又加上非线性层(如ReLU函数),…… ,最后加入输出层,输出层要根据任务来决定。

五. Loss function(损失函数)

常用的损失函数:

  • L1 loss: Mostly used as a regularizer.(一般用于正则化或规格化)

  • MSE loss(均方差误差): used as loss function for regression problems(一般用于回归问题中): 1 n ∑ ( Y ^ − Y ) 2 \frac{1}{n}\displaystyle \sum{(\hat{Y}-Y)^2} n1(Y^Y)2其中 Y ^ \hat{Y} Y^为模型预测值, Y Y Y 为真实值。

  • Cross-entropy loss: used for binary and multi-class classfication problems(一般用于二分类或者多分类问题)

    对于神经网络模型来说,就是像搭积木一样搭建一个网络模型,再根据具体的任务指定一个损失函数,然后根据损失函数的值去更新模型的权重( w w w b b b),这样就能找到一组最优(或者局部最优)的 w w w b b b。在搭建神经网络结构的时候,中间到底用几个隐藏层,每一层当中用几个神经元,这些问题就是模型的超参数。
    常用的超参数有Learing rate、层数、每层神经元数量等,超参数的设定没有具体原则,就是根据自己数据集的特点或者分布多尝试。

六. Optimizer(优化方法)

如何去更新模型的权重 w w w b b b,向左或者向右,每次走多远,怎么去走,这就是优化问题,这也是一种类型的超参数。
常用的优化方法:

  • SGD
  • Adagrad
  • Adam
  • RMSProp

一般来说认为Adam比较好用,但是有些问题使用最原始的SGD效果反而更好,需要具体问题具体分析。

七. 训练(学习)过程(Training(learning)procedure)

  • Define the neural network that has some learnable parameters(or weights)
  • Iterate over a dataset of inputs
  • Process input though the network
  • Compute the loss(how far is the output from being correct)
  • Propagate gradients back into the network’s parameters
  • Update the weights of the network,typically using a simple update rule: w e i g h t = w e i g h t − l e a r n i n g _ r a t e ∗ g r a d i e n t weight=weight-learning\_rate*gradient weight=weightlearning_rategradient
  • 定义一个神经网络,里边有一些可学习的参数( w w w b b b)。可学习的意思就是不需要人为的计算,只需要机器去学习自动帮我们找到最优(或者局部最优)的参数;
  • 将数据集作为输入,反复地进行迭代;
  • 通过模型进行输入;
  • 计算损失值Loss(预测值与真实值之间的误差到底有多大);
  • 将梯度传播回模型的参数中(梯度下降法),即根据Loss值去反向的更新模型的权重 w w w b b b;
  • 一般情况下,使用如下规则去更新 w w w b b b: w e i g h t = w e i g h t − l e a r n i n g _ r a t e ∗ g r a d i e n t weight=weight-learning\_rate*gradient weight=weightlearning_rategradient

八. MNIST-PyTorch实现

深度学习导论(4)神经网络基础_第12张图片

在输入层前边是没有权重的,即就是原始的输入数据,在输入层和隐藏层之间有权重,在隐藏层和输出层之间有权重,所以对于这个模型,我们需要定义两个层次,而且是两个线性层。
注:

  • 在__init__函数中定义模型中的“层”。其中fc1为隐藏层,fc2为输出层。对于fc1层来说,输入就是输入层直接送入模型的数据,即28*28=784维的向量,共有512个神经元; 对于fc2层来说,输入就是前一个层的神经元个数,即512维向量,因为是手写数字识别,共有数字0~9,使用one-hot向量表示lable,所以,输出的神经元有10个。(例如: 0123456789,如果只有“0”上有输出,其它没有,那么输出就是“1000000000”,同理,如果只有“1”上有输出,那么就是“0100000000”)。 在输入层的神经元后有一个SoftMax函数,目的是将神经元的输出概率范围压缩在(0, 1)之间,且所有概率值加起来的和等于1。看概率哪个最大,那么就属于哪一类。(例如,在手写数字识别中,“0”的概率比其他数字都大,那么认为手写数字属于“0”这一类,所以,输出就是“1000000000”)。然后再和样本的真实值作对比得到损失值(例如,这个样本的标签就是“1000000000”,那么这个样本的损失值Loss=0)。
  • bias默认为True。
  • 一个神经层网络的手写数字识别,其识别正确率就能达到80%~90%,这就是神经网络结构的厉害之处。
  • 如果出现“NameError: name ‘nn’ is not defined”,那么需要添加“import torch.nn as nn”。

(1) 代码

代码如下:

import torch
from torch.nn import Linear
import torch.nn as nn
import torch.nn.functional as F
from torch.nn import ReLU


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 512)
        self.fc2 = nn.Linear(512, 10)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.softmax(self.fc2(x), dim=1)
        return x


net = Net()
print(net)

input = torch.randn(1, 28*28)

out = net(input)
print(input)
print(out)

结果如下:
深度学习导论(4)神经网络基础_第13张图片
深度学习导论(4)神经网络基础_第14张图片

其中结果图中上面的tensor为输入,下面的tensor为输出。
注: 在定义forword函数时,如果不加上SoftMax函数,那么输出结果就会有正数也有负数,加上SoftMax函数后,输出结果全部在(0, 1)之间。

(2) 改变batch并输出input.size

input = torch.randn(1, 28*28)
改为input = torch.randn(2, 28*28)并输出input的size
输出结果如下:
深度学习导论(4)神经网络基础_第15张图片

可以看到输入数据的size为(2, 784),其中“2”表示batch,即每一批(batch)将2个样本送进模型; “784”表示每个样本的维度。

(3) 改变batch并输出out.size

将代码改为:

input = torch.randn(200, 28*28)

out = net(input)
print(input.size())
print(out.size())
print(input)
print(out)

输出结果如下:
深度学习导论(4)神经网络基础_第16张图片
可以看到输入数据的size为(200, 784),输出数据的size为(200, 10)。

(4) 深度学习的本质思想

通过以上实验可以看出: 深度学习的本质思想就是在做映射,输入到输出之间的映射关系。

九. 计算损失函数

深度学习导论(4)神经网络基础_第17张图片

注: “out”就是模型中的输出,“target”就是模型中的“label”。

十. 更新权重

深度学习导论(4)神经网络基础_第18张图片

模型参数(以MNIST-PyTorch实现中的代码为例):

print(net.parameters())

输出结果如下:
在这里插入图片描述

要查看 w w w b b b的具体值,需要添加一个迭代器。

十一. 手写数字识别分类问题具体步骤(Training an handwritten digit classification)

  • Load and normalizing the MNIST training and test datasets using torchvision;
    使用torchvision加载并对MNIST数据集规格化;
  • Define a Convolution Neural Network
    定义卷积神经网络;
  • Define a loss function
    定义损失函数;
  • Train the network on the training data
    利用数据经过反复迭代(多轮epoch),训练网络,得到一组最优的(或者局部最优的)网络参数( w w w b b b);
  • Test the network on the test data
    得到网络参数( w w w b b b)后,模型就有了,就可以利用测试集数据去测试网络模型。

你可能感兴趣的:(深度学习,深度学习,神经网络,pytorch)