Skip to content

构建神经网络

构建神经网络

  • 神经网络的应用场景
  • 初识神经网络
  • 网络模型的层
  • 构建神经网络
  • 神经网络模型的参数

神经网络的应用场景

  • 神经网络是一门重要的机器学习技术,是目前十分火热的研究方向——深度学习的基础。
  • 学习神经网络不仅可以掌握一门强大的机器学习方法,同时也可以更好地理解深度学习技术。
  • 神经网络获得迅速发展,应用来领域越来越广,解决实际问题的能力也越来越强。

神经网络的应用场景——语音识别

  • 自2006年Hinton等提出深度学习的概念,语音识别是第1个取得突破的领域。
  • 历经数十年的发展,传统语音识别任务的错误率改进却停滞不前。
  • 2013 年,Hinton利用神经网络改进语音识别中的特征提取方法,将错误率降低至17.7%。
  • 至2016年,同声速记产品准确率已经突破95%,超过人类速记员的水平。

神经网络的应用场景——计算机视觉

  • 计算机视觉一直以来都是一个热门的研究领域。计算机视觉任务包括图像分类、图像聚类、图像分割、目标检测、目标追踪等。
  • 2012 年,在大规模图像数据集ImageNet 上,神经网络方法取得了重大突破,准确率达到84.7%。
  • 基于深度神经网络的人脸识别方法DeepID 在2014、2015 年分别达到准确率99.15% 和99.53%。

神经网络的应用场景——医学医疗

  • 随着神经网络各类应用的成功和成熟,在医学和医疗领域也出现了新的突破。
  • 2016年1月,美国Enlitic公司开发的基于深度神经网络的癌症检测系统,采用基于神经网络的无监督深度特征学习方法学习病人的深度特征表达,并借助这一表达进行自动临床决策,其准确率超过92%。

神经网络的应用场景——智能博弈

  • 自从国际象棋世界冠军被深蓝电脑击败后,围棋也成为了“人类智慧最后堡垒”。
  • AlphaGo对战围棋世界冠军李世乭,引起热切关注。
  • 标志了增强学习与神经网络的成功结合,也是“大数据+神经网络”的成功应用。

初识神经网络——起源

  • 1904年生物学家就已知晓人脑中神经元的组成结构。
  • 一个神经元通常具有一条轴突和多个树突,树突用来接受传入信息;轴突用来传递信息。轴突末梢跟其他神经元的树突连接的位置叫突触。
  • 1943年,专家参考了生物神经元的结构,发表了抽象的神经元模型MP。

初识神经网络——结构

  • 神经元模型是一个包含输入,输出与计算功能的模型。
  • 连接是神经元中最重要的东西。每一个连接上都有一个权重。
  • 一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。

初识神经网络——计算

  • 所有变量用符号表示,并且写出输出的计算公式
  • 函数g是sgn函数,即符号函数。该函数当输入大于0时,输出1,否则输出0。

初识神经网络——经典网络解析

  • 一个经典的神经网络,包含输入层、输出层、隐藏层。
  • 多节点输出常用于分类问题。
  • 任何多层网络可以用三层网络近似地表示。
  • 隐藏层用都是用Sigmoid作激活函数,而输出层用的是Purelin。
  • 起初输入层的数值通过网络计算分别传播到隐藏层,再以相同的方式传播到输出层,这个过程叫前向传播。

网络模型的层

  • 神经网络由对数据执行操作的层/模块组成。torch.nn命名空间提供了构建自己的神经网络所需的所有构件。PyTorch中的每个模块都是nn.Module的子类。神经网络是由其他模块(层)组成的模块,其本身也是一个模块。这种嵌套结构允许轻松地构建和管理复杂的体系结构。接下来,我们将构建一个神经网络来对FashionMNIST数据集中的图像进行分类。

网络模型的层

import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

class NeuralNetwork(nn.Module):
    """
    在__init__中初始化神经网络层
    """
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        """
       首先找到NeuralNetwork的父类即类nn.Module
       然后把类NeuralNetwork的对象self转换为类nn.Module的对象
       然后“被转换”的类nn.Module对象调用自己的init函数
        """
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )
    """
    在__forword__中实现操作的逻辑
    """
    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits     

网络模型的层

  • 我们接下来将分解FashionMNIST模型中的层,并采用一个由3张大小为28x28的图像组成的小型批次的样本进行举例说明,并查看当这三张样本通过网络时会发生什么情况。
input_image = torch.rand(3,28,28)
print(input_image.size())

网络模型的层 - nn.Flatten

  • 我们初始化神经网络的nn.Flatten层,随后将每个2D的28x28图像转换为784像素值的连续向量(minibatch的维度在dim=0被保留)。
    flatten = nn.Flatten()
    flat_image = flatten(input_image)
    print(flat_image.size())
    

网络模型的层 - nn.Linear

  • 线性图层是一个模块,它使用存储的权重和偏置对输入应用线性变换。
    layer1 = nn.Linear(in_features=28*28, out_features=20)
    hidden1 = layer1(flat_image)
    print(hidden1.size())
    

网络模型的层 - nn.ReLU

  • 神经网络模型的输入和输出之间之所以能够创建复杂映射,就是非线性激活即nn.ReLU在发挥作用。在线性变换之后应用它们来引入非线性,帮助神经网络学习各种各样的场景。
  • 在基础的模型中,我们使用nn.ReLU在线性层之间构建非线性激活,但是还有其他的激活方式可以在的模型中引入非线性(如nn.Sigmoid)。

网络模型的层 - nn.ReLU

print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")

网络模型的层 - nn.Sequential

  • nn.Sequential is an ordered container of modules. The data is passed through all the modules in the same order as defined. You can use sequential containers to put together a quick network like seq_modules.
  • nn.Sequential是模块的有序容器。数据按照定义的顺序通过nn.Sequential中所包含的所有模块。因此,可以使用Sequential容器来构建一个类似seq_modules的快速网络。

网络模型的层 - nn.Sequential

seq_modules = nn.Sequential(
    flatten,
    layer1,
    nn.ReLU(),
    nn.Linear(20, 10)
)
input_image = torch.rand(3,28,28)
logits = seq_modules(input_image)

网络模型的层 - nn.Softmax

  • 神经网络的最后一个线性层的输出logits,它的原始值范围应该在[-infty,infty]之间。然后将logits的值返回传递给nn.Softmax模块。logits的值被缩放为[0,1]之间,这表示每个类的模型预测概率。其中,dim参数指示值的总和必须等于1。

网络模型的层 - nn.Softmax

softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)

构建神经网络

构建神经网络

  • 神经网络由对数据执行操作的层/模块组成。torch.nn命名空间提供了构建自己的神经网络所需的所有构件。PyTorch中的每个模块都是nn.Module的子类。神经网络是由其他模块(层)组成的模块,其本身也是一个模块。这种嵌套结构允许轻松地构建和管理复杂的体系结构。接下来,我们将构建一个神经网络来对FashionMNIST数据集中的图像进行分类。

构建神经网络-定义类

  • 我们通过对nn.Module进行子类化来定义我们的神经网络,并在__init__中初始化神经网络层。每个nn.Module子类实现forward方法中对输入数据的操作。
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

class NeuralNetwork(nn.Module):
    """
    在__init__中初始化神经网络层
    """
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        """
       首先找到NeuralNetwork的父类即类nn.Module
       然后把类NeuralNetwork的对象self转换为类nn.Module的对象
       然后“被转换”的类nn.Module对象调用自己的init函数
        """
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )
    """
    在__forword__中实现操作的逻辑
    """
    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits     

构建神经网络-定义类

  • 我们学习构建一个NeuralNetwork的实例,将其移动到设备上,随后打印其结构进行观察。
model = NeuralNetwork().to(device)
print(model)

构建神经网络-定义类

  • 为了使用模型,我们向它传递输入数据。随后数据在模型中进行前向传播,以及一些后台操作。
  • 对输入数据调用模型后,会返回一个10维张量(其中包含每个类别的原始预测值)。最后,我们通过神经网络的nn.Softmax模块来获得预测概率。
X = torch.rand(1, 28, 28, device=device)
logits = model(X)#获得模型的输出
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)#根据输出进行概率预测
print(f"Predicted class: {y_pred}")

构建神经网络——要点总结

  • 必须继承 nn.Module 类。nn.Module 是所有神经网络模块的基类。 Torchvison 中的那些模型都是通过继承 nn.Module 模块来构建网络模型的。
  • 重写 __init__() 方法。通常来说要把有需要学习的参数的层放到构造函数中。
  • forward() 是必须重写的方法。它是用来定义这个模型是如何计算输出的。

神经网络模型的参数

神经网络模型的参数

  • 神经网络内的许多层是参数化的,即各自具有在训练期间优化的相关权重和偏置。通过子类化nn.Module可以自动跟踪模型对象中定义的所有字段,并使用模型的parameters()或named_parameters()方法来访问所有参数。在这个例子中,我们迭代每个参数,并打印其大小及其值的预览。

神经网络模型的参数

model = NN()
print(f"Model structure: {model}\n\n")

for name, param in model.named_parameters():
    print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")#打印限制