《动手学深度学习》笔记2.1——神经网络从基础→进阶 (层和块 - 自定义块)

目录

0. 前言

原书正文(第五章)

第五章 - 第一节 - 层和块 - 自定义块

1. Sequential() PyTorch高级API

2. MLP() 无传入参数

3. MySequential() 传入任意层(块)

4. FixedHiddenMLP() 无传入参数-固定隐藏层

5. NestMLP() 传入嵌套块-多次嵌套

6. 效率问题

7. 小结


0. 前言

  • 课程全部代码(pytorch版)已上传到附件
  • 本章节为原书第5章,共分为6节,本篇是第1节:层和块(自定义块)
    • 第2-3节:《动手学深度学习》笔记2.2——神经网络从基础→进阶 (参数管理-每层的权重/偏置)-CSDN博客
    • 第4节:《动手学深度学习》笔记2.3——神经网络从基础→进阶 (自定义层)-CSDN博客
    • 第5节:《动手学深度学习》笔记2.4——神经网络从基础→进阶 (文件读写-保存参数和模型)-CSDN博客
    • 第6节:《动手学深度学习》笔记2.5——神经网络从基础→使用GPU (CUDA-单卡-多卡-张量操作)-CSDN博客
  • 本章的代码位置:chapter_deep-learning-computation/index.ipynb
  • 本章的视频链接:
    • 16 PyTorch 神经网络基础【动手学深度学习v2】_哔哩哔哩_bilibili
    • 17 使用和购买 GPU【动手学深度学习v2】_哔哩哔哩_bilibili
  • 本章核心内容:深入探索深度学习计算的关键组件, 即模型构建、参数访问与初始化、设计自定义层和块、将模型读写到磁盘, 以及利用GPU实现显著的加速
  • 从基础到进阶:本章知识将使读者从深度学习“基础用户”变为“高级用户”
  • 与后面高级模型的关系:虽然本章不介绍任何新的模型或数据集, 但后面的高级模型章节在很大程度上依赖于本章的知识
  • 同学反馈:本章的学习解开了前后章节的很多困惑,对打牢基础非常有帮助
  • 想完全读懂本章节,需要有线性回归、softmax回归、多层感知机等相关基础,主要的前置知识可参考
    • https://blog.csdn.net/weixin_57972634/category_12776752.html
    • 还非常需要python基础,得学到面向对象:https://download.csdn.net/download/weixin_57972634/89738887?spm=1001.2014.3001.5503

原书正文(第五章)

除了庞大的数据集和强大的硬件, 优秀的软件工具在深度学习的快速发展中发挥了不可或缺的作用。 从2007年发布的开创性的Theano库开始, 灵活的开源工具使研究人员能够快速开发模型原型, 避免了我们使用标准组件时的重复工作, 同时仍然保持了我们进行底层修改的能力。 随着时间的推移,深度学习库已经演变成提供越来越粗糙的抽象。 就像半导体设计师从指定晶体管到逻辑电路再到编写代码一样, 神经网络研究人员已经从考虑单个人工神经元的行为转变为从层的角度构思网络, 通常在设计架构时考虑的是更粗糙的块(block)。

之前我们已经介绍了一些基本的机器学习概念, 并慢慢介绍了功能齐全的深度学习模型。 在上一章中,我们从零开始实现了多层感知机的每个组件, 然后展示了如何利用高级API轻松地实现相同的模型。 为了易于学习,我们调用了深度学习库,但是跳过了它们工作的细节。 在本章中,我们将深入探索深度学习计算的关键组件, 即模型构建、参数访问与初始化、设计自定义层和块、将模型读写到磁盘, 以及利用GPU实现显著的加速。 这些知识将使读者从深度学习“基础用户”变为“高级用户”。 虽然本章不介绍任何新的模型或数据集, 但后面的高级模型章节在很大程度上依赖于本章的知识。

第五章 - 第一节 - 层和块 - 自定义块

之前首次介绍神经网络时,我们关注的是具有单一输出的线性模型。 在这里,整个模型只有一个输出。

注意,单个神经网络:

(1)接受一些输入;

(2)生成相应的标量输出;

(3)具有一组相关 参数(parameters),更新这些参数可以优化某目标函数。

然后,当考虑具有多个输出的网络时, 我们利用矢量化算法来描述整层神经元。

像单个神经元一样,层:

(1)接受一组输入,

(2)生成相应的输出,

(3)由一组可调整参数描述。

当我们使用softmax回归时,一个单层本身就是模型。 然而,即使我们随后引入了多层感知机,我们仍然可以认为该模型保留了上面所说的基本架构。

对于多层感知机而言,整个模型及其组成层都是这种架构。 整个模型接受原始输入(特征),生成输出(预测), 并包含一些参数(所有组成层的参数集合)。 同样,每个单独的层接收输入(由前一层提供), 生成输出(到下一层的输入),并且具有一组可调参数, 这些参数根据从下一层反向传播的信号进行更新。

事实证明,研究讨论 “比单个层大” 但 “比整个模型小” 的组件更有价值。 例如,在计算机视觉中广泛流行的ResNet-152架构就有数百层, 这些层是由层组(groups of layers)的重复模式组成。 这个ResNet架构赢得了2015年ImageNet和COCO计算机视觉比赛 的识别和检测任务 :cite:He.Zhang.Ren.ea.2016。 目前ResNet架构仍然是许多视觉任务的首选架构。 在其他的领域,如自然语言处理和语音, 层组以各种重复模式排列的类似架构现在也是普遍存在。

为了实现这些复杂的网络,我们引入了神经网络的概念。 (block)可以描述单个层、由多个层组成的组件或整个模型本身。 使用块进行抽象的一个好处是可以将一些块组合成更大的组件, 这一过程通常是递归的,如 :numref:fig_blocks所示。 通过定义代码来按需生成任意复杂度的块, 我们可以通过简洁的代码实现复杂的神经网络。

从编程的角度来看,块由(class)表示。 它的任何子类都必须定义一个将其输入转换为输出的前向传播函数, 并且必须存储任何必需的参数。 注意,有些块不需要任何参数。 最后,为了计算梯度,块必须具有反向传播函数。 在定义我们自己的块时,由于自动微分(在 《动手学深度学习》笔记1.3——矩阵求导_方向导数与梯度的关系-CSDN博客 中引入自动求导) 提供了一些后端实现,我们只需要考虑前向传播函数和必需的参数。

在构造自定义块之前,(我们先回顾一下多层感知机) (《动手学深度学习》笔记1.6——多层感知机→代码实现_两层感知机代码函数实现-CSDN博客)的代码。 下面的代码生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接隐藏层, 然后是一个具有10个隐藏单元且不带激活函数的全连接输出层。

1. Sequential() PyTorch高级API

import torch
from torch import nn
from torch.nn import functional as F  # functional Module包括了一些没有参数的函数,下面会看到具体用法net = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))  # 单隐藏层(256个神经元), 输入20→输出10X = torch.rand(2, 20)  # 权重X,初始化成2行20列的、均值为0方差为1的随机矩阵
# 2是批量大小,20是输入的维度,10是输出的大小
net(X)

在这个例子中,我们通过实例化nn.Sequential来构建我们的模型, 层的执行顺序是作为参数传递的。 简而言之,(nn.Sequential定义了一种特殊的 Module), 即在PyTorch中表示一个块的类, 它维护了一个由Module组成的有序列表。 注意,两个全连接层都是Linear类的实例, Linear类本身就是Module的子类。 另外,到目前为止,我们一直在通过net(X)调用我们的模型来获得模型的输出。 这实际上是net.__call__(X)的简写

这个前向传播函数非常简单: 它将列表中的每个块连接在一起,将每个块的输出作为下一个块的输入

2. MLP() 无传入参数

要想直观地了解块是如何工作的,最简单的方法就是自己实现一个块 ,进而从零定义和执行块。 在实现我们自定义块之前,我们简要总结一下每个块必须提供的基本功能。

  1. 将输入数据作为其前向传播函数的参数。
  2. 通过前向传播函数来生成输出。请注意,输出的形状可能与输入的形状不同。例如,我们上面模型中的第一个全连接的层接收一个20维的输入,但是返回一个维度为256的输出。
  3. 计算其输出关于输入的梯度,可通过其反向传播函数进行访问。通常这是自动发生的。
  4. 存储和访问前向传播计算所需的参数。
  5. 根据需要初始化模型参数。

在下面的代码片段中,我们从零开始编写一个块。 它包含一个多层感知机,其具有256个隐藏单元的隐藏层和一个10维输出层。 注意,下面的MLP类继承了表示块的类。 我们的实现只需要提供我们自己的构造函数(Python中的__init__函数)和前向传播函数。

class MLP(nn.Module):  # 定义MLP是nn.Module的一个子类(涉及到python面向对象编程的相关知识)# 用模型参数声明层。这里,我们声明两个全连接的层def __init__(self):  # 创建对象(实例)时,__init__会自动执行# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样,在类实例化时也可以指定其他函数参数,例如模型参数params(稍后将介绍)super().__init__()  # super() 调用父类nn.Module的构造函数__init__(),初始化模型(必要)的参数和子模块self.hidden = nn.Linear(20, 256)  # 隐藏层:存在类的成员变量hidden里面self.out = nn.Linear(256, 10)  # 输出层:存在类的成员变量hidden里面# 定义模型的前向传播,即如何根据输入X返回所需的模型输出def forward(self, X):  # 前向传播:逐层运算;更新参数在反向传播过程中# 注意,这里我们使用ReLU的函数版本,其在nn.functional模块中定义。return self.out(F.relu(self.hidden(X))) # 先把输入X存到hidden层里面,得到隐藏层的输出# 用ReLU激活后放入out层里

我们首先看一下前向传播函数,它以X作为输入, 计算带有激活函数的隐藏表示,并输出其未规范化的输出值。 在这个MLP实现中,两个层都是实例变量。 要了解这为什么是合理的,可以想象实例化两个多层感知机(net1net2), 并根据不同的数据对它们进行训练。 当然,我们希望它们学到两种不同的模型。

实例化多层感知机的层,然后在每次调用前向传播函数时调用这些层

注意一些关键细节: 首先,我们定制的__init__函数通过super().__init__() 调用父类的__init__函数, 省去了重复编写模版代码的痛苦。 然后,我们实例化两个全连接层, 分别为self.hiddenself.out。 注意,除非我们用到一个新的运算符, 否则我们不必担心反向传播基础的函数或参数初始化, 系统将调用父类nn.Module的__init__()函数自动初始化。

我们来试一下这个MLP()函数:

net = MLP()
net(X)

的一个主要优点是它的多功能性。 我们可以子类化块以创建层(如全连接层的类)、 整个模型(如上面的MLP类)或具有中等复杂度的各种组件。 我们在接下来的章节中充分利用了这种多功能性, 比如在处理卷积神经网络时。

3. MySequential() 传入任意层(块)

现在我们可以更仔细地看看Sequential类是如何工作的, 回想一下Sequential的设计是为了把其他模块串起来。 为了构建我们自己的简化的MySequential, 我们只需要定义两个关键函数:

  1. 一种将块逐个追加到列表中的函数;
  2. 一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”。

下面的MySequential类提供了与默认Sequential类相同的功能。

class MySequential(nn.Module):def __init__(self, *args):  # *args是可变参数列表, 在实例化 MySequential 类时传入任意数量的参数# *args 是一个元组(tuple),可以传入多个 nn.Module 子类实例(层,块),它们会被打包成一个元组super().__init__()  # 和上面MLP()一样,调用父类nn.Module中的__init__()来初始化基本的模型和参数for idx, module in enumerate(args):  # enumerate()是内置函数,可同时获取可迭代对象的索引和对应的元素# 可以这样理解: 下方MySequential()传入的3个成员nn.Linear(20, 256),nn.ReLU(),nn.Linear(256, 10)# 放到了*args元组里,为每个成员(层,块)生成一个顺序idx,按顺序放进成员变量_module里self._modules[str(idx)] = module  # 成员变量_module的类型是OrderedDict(顺序字典)def forward(self, X):# OrderedDict保证了按照成员(层,块)添加的顺序遍历(调用)它们for block in self._modules.values():  # 按顺序每次用values()拿一个成员(层,块),放到block里,传入XX = block(X)  # 这里的X可看作中间变量,不断按顺序在成员(层,块)间塑性非线性变换return X  # 返回最后输出的X

__init__函数将每个模块逐个添加到有序字典_modules中。 读者可能会好奇为什么每个Module都有一个_modules属性? 以及为什么我们使用它而不是自己定义一个Python列表? 简而言之,_modules的主要优点是: 在模块的参数初始化过程中, 系统知道在_modules字典中查找需要初始化参数的子块。

  • MySequential的前向传播函数被调用时, 每个添加的块都按照它们被添加的顺序执行。

现在可以使用我们的 MySequential类 重新实现多层感知机

net = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
net(X)

请注意,MySequential的用法与之前为Sequential类编写的代码相同(咱的MySequential算是基础版的Sequential

拓展:可参考/回顾 《动手学深度学习》笔记1.6——多层感知机→代码实现_两层感知机代码函数实现-CSDN博客 )

4. FixedHiddenMLP() 无传入参数-固定隐藏层

Sequential类使模型构造变得简单, 允许我们组合新的架构,而不必定义自己的类。 然而,并不是所有的架构都是简单的顺序架构。 当需要更强的灵活性时,我们需要定义自己的块。 例如,我们可能希望在前向传播函数中执行Python的控制流。 此外,我们可能希望执行任意的数学运算, 而不是简单地依赖预定义的神经网络层。

class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 不计算梯度的随机权重参数。因此其在训练期间保持不变self.rand_weight = torch.rand((20, 20), requires_grad=False)self.linear = nn.Linear(20, 20)def forward(self, X):X = self.linear(X)# 使用创建的常量参数以及relu和mm函数X = F.relu(torch.mm(X, self.rand_weight) + 1)# 复用全连接层。这相当于两个全连接层共享参数X = self.linear(X)# 控制流while X.abs().sum() > 1:X /= 2return X.sum()

在这个FixedHiddenMLP模型中,我们实现了一个隐藏层, 其权重(self.rand_weight)在实例化时被随机初始化,之后为常量。 这个权重不是一个模型参数,因此它永远不会被反向传播更新。 然后,神经网络将这个固定层的输出通过一个全连接层。

注意,在返回输出之前,模型做了一些不寻常的事情: 它运行了一个while循环,在L1范数大于1的条件下, 将输出向量除以2,直到它满足条件为止。 最后,模型返回了 X 中所有项的和。 注意,此操作可能不会常用于在任何实际任务中, 我们只展示如何将任意代码集成到神经网络计算的流程中。

net = FixedHiddenMLP()
net(X)

输出:

5. NestMLP() 传入嵌套块-多次嵌套

我们可以[混合搭配各种组合块的方法]。 在下面的例子中,我们以一些想到的方法嵌套块,嵌套了用 nn.Sequential() 合并好的块。

class NestMLP(nn.Module):def __init__(self):super().__init__()self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),  # 隐藏层1nn.Linear(64, 32), nn.ReLU())  # 隐藏层2self.linear = nn.Linear(32, 16)  # 输出层def forward(self, X):return self.linear(self.net(X))  # 一次嵌套chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())  # 二次嵌套,两个块夹一层拼在一起
chimera(X)

输出:

6. 效率问题

读者可能会开始担心操作效率的问题。 毕竟,我们在一个高性能的深度学习库中进行了大量的字典查找、 代码执行和许多其他的Python代码。 Python的问题全局解释器锁 是众所周知的。 在深度学习环境中,我们担心速度极快的GPU可能要等到CPU运行Python代码后才能运行另一个作业。

7. 小结

  • 一个块可以由许多层组成;一个块可以由许多块组成。
  • 块可以包含代码。
  • 块负责大量的内部处理,包括参数初始化和反向传播。
  • 层和块的顺序连接由Sequential块处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/434234.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue之axios请求

Vue之axios请求 axios请求, 是Vue前端框架非常重要的一部分, 今天我们就讲解axios请求, 到底有什么作用, 以及会告诉大家axios的常见用法。 axios请求, 是网页向后端发起请求, 后端吧数据给我们网页, 这是一个前后端交互的过程。当我们学会了axios, 我们可以实现前端和后端练…

【算法篇】二叉树类(2)(笔记)

目录 一、Leetcode 题目 1. 左叶子之和 (1)迭代法 (2)递归法 2. 找树左下角的值 (1)广度优先算法 (2)递归法 3. 路径总和 (1)递归法 (2…

H. Sakurako‘s Test

H. Sakurakos Test 原题 本题通过前缀和和二分可以解决, 原理并不是很困难, 但是比较难想到 我们只需要对每一个 x, 二分求出中位数, 预处理好即可, 二分的检查通过求k倍的x可以在调和级数的时间内实现 代码 #include <bits/stdc.h> #define int long longusing name…

mysql索引 -- 聚簇索引,非聚簇索引,如何查看linux下的数据库文件,普通/辅助索引(回表查询)

目录 聚簇索引和非聚簇索引 聚簇索引 介绍 示例 查看当前的数据库数据目录 表文件 非聚簇索引 介绍 myisam 示例 普通(辅助)索引 引入(回表查询) mysql索引结构详细介绍 -- mysql索引 -- 索引的硬件理解(磁盘,磁盘与系统),软件理解(mysql,与系统io,buffer pool),索…

基于SpringBoot的新冠检测信息管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 国内外在该方向的研究现状及分析 新型冠状病毒肺炎疫情发生以来&#xff0c;中国政府采取积极的防控策略和措施&#xff0c;经过两个多月的不懈努力&#xff0c;有效控制了新发病例的増长&#xff0c;本地传播已经趋于完全控制…

【Java】六大设计原则和23种设计模式

目录 一、JAVA六大设计原则 二、JAVA23种设计模式 1. 创建型模式 2. 结构型模式 3. 行为型模式 三、设计原则与设计模式 1. 设计原则 2. 设计模式 四、单例模式 1. 饿汉式 2. 懒汉式 四、代理模式 1. 什么是代理模式 2. 为什么要用代理模式 3. 有哪几种代理模式 …

并发面试合集

1.创建线程的方式 区分线程和线程体的概念&#xff0c;线程体通俗点说就是任务。创建线程体的方式&#xff1a;像实现Runnable、Callable接口、继承Thread类、创建线程池等等&#xff0c;这些方式并没有真正创建出线程&#xff0c;严格来说&#xff0c;Java就只有一种方式可以…

MySQl查询分析工具 EXPLAIN ANALYZE

文章目录 EXPLAIN ANALYZE是什么Iterator 输出内容解读EXPLAIN ANALYZE和EXPLAIN FORMATTREE的区别单个 Iterator 内容解读 案例分析案例1 文件排序案例2 简单的JOIN查询 参考资料&#xff1a;https://hackmysql.com/book-2/ EXPLAIN ANALYZE是什么 EXPLAIN ANALYZE是MySQL8.…

有问题未解决(9.28)

#include <stdio.h> int main() {int a 1;int b 2;int c 3;int arr[] { a,b,c };arr[0] 10;printf("%d\n", a);//打印结果为1&#xff1b;return 0; } 颠覆认知了&#xff0c;或许也没有颠覆 arr是一个int类型的数组&#xff0c;他存的就是一个数&…

Arch - 架构安全性_保密(Confidentiality)

文章目录 OverView导图保密保密强度与成本客户端加密密码存储与验证 Code总结 OverView 即使只限定在“软件架构设计”这个语境下&#xff0c;系统安全仍然是一个很大的话题。 接下来我们将对系统安全架构的各个方面进行详细分析&#xff0c;包括认证、授权、凭证、保密、传输…

JSP(Java Server Pages)基础使用二

简单练习在jsp页面上输出出乘法口诀表 既然大家都是来看这种代码的人了&#xff0c;那么这种输出乘法口诀表的这种简单算法肯定是难不住大家了&#xff0c;所以这次主要是来说jsp的使用格式问题。 <%--Created by IntelliJ IDEA.User: ***Date: 2024/7/18Time: 11:26To ch…

大厂AI必备数据结构与算法——链表(三)详细文档

冲冲冲&#xff01;开干 神马&#xff01;神马&#xff01;神马&#xff0c;一向让我们学习起来抓耳挠腮的数据结构课程竟然也有教程&#xff1f;还那么详细&#xff1f;&#xff1f;真的假的&#xff1f; 那么好&#xff0c;胡广告诉你是假的&#xff0c;哈哈哈哈哈哈哈哈哈…

走进上海郭培高定会馆:以冠珠华脉、华珍筑就至臻至性的艺术空间

“我热爱高级时装&#xff0c;因为她是一种生命的停驻。我希望我的高级时装成为馆藏级的精品&#xff0c;殿堂级的珍宝&#xff0c;成为传世杰作。” ——郭培 中国唯一一位法国高定公会受邀会员&#xff0c;曾荣登《TIME》时代周刊全球100位最具影响力人物榜单。纽约时报评价…

opencv学习:通过图像透视进行发票识别完整代码流程

概念&#xff1a; 使用OpenCV库实现图像的透视变换处理&#xff0c;以矫正图像中的透视失真。通过本实验&#xff0c;学习者将掌握图像处理的基本操作&#xff0c;包括图像的读取、显示、大小调整、灰度转换、二值化、轮廓检测、轮廓近似以及透视变换。 步骤&#xff1a; 1. …

vue3 通过 axios + jsonp 实现根据公网 ip, 查询天气信息

前提 安装 axios 的 jsonp 适配器。 pnpm install pingtou/axios-jsonp 简单使用说明&#xff1a;当与后端约定的请求 callback 参数名称不为为 callback 时&#xff0c;可修改。一般无需添加。 1. 获取当前电脑 ip 和城市信息 请求地址&#xff1a; https://whois.pconl…

【质优价廉】GAP9 AI算力处理器赋能智能可听耳机,超低功耗畅享未来音频体验!

当今世界&#xff0c;智能可听设备已经成为了流行趋势。随后耳机市场的不断成长起来&#xff0c;消费者又对AI-ANC&#xff0c;AI-ENC&#xff08;环境噪音消除&#xff09;降噪的需求逐年增加&#xff0c;但是&#xff0c;用户对于产品体验的需求也从简单的需求&#xff0c;升…

isilon存储node节点更换你必须知道的知识

最近一直想要写一篇文章是关于EMC Isilon 存储控制器方面的&#xff0c;是什么力量促使我要写这个文章呢&#xff1f;作为一个卖存储备件的资深搬运工&#xff0c;最近遇到了一些关于控制器方面的备件询价、备件更换方面的问题&#xff0c;每次都要花大量的时间给客户解释。解释…

【JVM】JVM执行流程和内存区域划分

文章目录 是什么JVM 执行流程内存区域划分堆栈程序计数器元数据区经典笔试题 是什么 Java 虚拟机 JDK&#xff0c;Java 开发工具包JRE&#xff0c;Java 运行时环境JVM&#xff0c;Java 虚拟机 JVM 就是 Java 虚拟机&#xff0c;解释执行 Java 字节码 JVM 执行流程 编程语言…

24年下重庆事业单位考试报名超详细流程

&#x1f388;提交报考申请 考生通过重庆市人力资源和社会保障局官网&#xff08;rlsbj.cq.gov.cn&#xff09;“热点服务”中“人事考试网上报名”栏进行报名。报名时间为2024年8月12日9:00—8月17日9:00。 &#x1f388;网上缴费 资格初审合格后&#xff0c;考生应在2024年8…

奇瑞汽车—经纬恒润 供应链技术共创交流日 成功举办

2024年9月12日&#xff0c;奇瑞汽车—经纬恒润技术交流日在安徽省芜湖市奇瑞总部成功举办。此次盛会标志着经纬恒润与奇瑞汽车再次携手&#xff0c;深入探索汽车智能化新技术的前沿趋势&#xff0c;共同开启面向未来的价值服务与产品新篇章。 面对全球汽车智能化浪潮与产业变革…