计算图 Compute Graph 和自动求导 Autograd | PyTorch 深度学习实战
前一篇文章,Tensor 基本操作5 device 管理,使用 GPU 设备 | PyTorch 深度学习实战
本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started
PyTorch 计算图和 Autograd
- 微积分之于机器学习
- Computational Graphs 计算图
- Autograd 自动求导
- 一个训练过程及 no_grad 的使用
- 示例代码
- 执行结果
- 生成数据
- 第一轮后
- 第二轮后
- 第十轮后
- 更多计算图的知识
- 更为复杂点的计算图的样子
- 自动求导有关的参数
- Links
微积分之于机器学习
机器学习的主要工作原理,就是万事万物存在规律,而我们使用机器来完成参数评估。参数评估的过程是随机梯度下降,也就是任意选择起点,然后使用微积分技术指导我们调优,找到一组最优参数值。
这就像我们爬山,面对众多的山峰,我们从不同的出发点出发,不断的朝着山顶前进,最终,我们即便起点不同,都可以达到山顶 - 通向山顶的路有多条。另外一方面,我们可能来到了不同的山顶。
在我们爬山的过程中,如何选择下一步呢?这时,就是微积分大显身手的时候了。
在机器学习中,对参数优化的过程,使用了大量微积分的运算,PyTorch 能成为通用性的机器学习框架,就在于不同的机器学习任务底层的数学原理是一致的,而 PyTorch 内置了这些标准化的数学运算,在 PyTorch 中,除了 Tensor 外,还有两个关键的概念:
- 计算图
- 自动求导
Computational Graphs 计算图
神经网络是由很多神经元组成的网络,最简单的神经网络就是只包含一个线性神经元的神经网络,理解这个最简单的神经网络,有助于理解任何复杂的神经网络。
z = x ∗ w + b z = x * w + b z=x∗w+b
注意:这里没有添加激活函数,这个神经元是一个简单的线性神经元。
计算过程:
- 加权输出 z 与理想输出 y 之间,使用交叉熵(CE)计算出损失(loss)
- 然后基于 loss 计算梯度 grad
- 基于梯度更新 w 和 b
这个计算过程,可以用一张图表达,一个图就是由节点以及边组成,边上定义操作符。同时,这个计算过程会在训练中发生多次,因为梯度下降算法是 SGD 迭代运算。
PyTorch 为了让每次运算可以更灵活,比如使用 Dropout 随机丢弃一些神经元,PyTorch 实现了每次运算动态的生成这张图 - 动态计算图1。也就是说,对于每次运算,PyTorch 会生成一个计算图并附着计算状态。
Autograd 自动求导
附着状态,最主要的目的就是实现自动求导。因为每个节点都是一个变量,变量和变量之间通过操作符相互依赖,而操作符和变量构成的函数式,就可以实现求导,根据链式法则,实现计算图中,每个变量的导数的计算。
在上图,只有一个线性神经元的情况下,PyTorch 的自动求导是如何工作的呢?参考下面的代码。
import torch# 定义输入和理想输出
x = torch.ones(5) # input tensor
y = torch.zeros(3) # expected output# 定义参数
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)# 定义模型,并进行一次运算
z = torch.matmul(x, w)+b# 定义损失函数,并得到单次的损失
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)# 进行反向传播,并得到梯度
loss.backward()
print(w.grad)
print(b.grad)
如此一来,参数更新将变得非常简单。计算图允许每次迭代传入不同的操作符等,实现训练过程更灵活的配置。计算图保留了运算过程中的 Tensor、操作符、操作符对应的导函数。当 loss.backward() 调用时,顺序的调用自动求导变量的导函数,得到 .grad
梯度值。
一个训练过程及 no_grad 的使用
现在我们看一个例子,通过一个简单的模型,了解训练中,自动求导机制是如何工作的。
示例代码
'''
autograd
'''
import plotly.graph_objects as go
import plotly.express as px
from torch import nn
import numpy as np
import torch
import math# 输入变量 x,理想输出 yt(生成 y 的函数就是要拟合的模型)
X = torch.tensor(np.linspace(-10, 10, 1000))
y = 1.5 * torch.sin(X) + 1.2 * torch.cos(X/4) # 真实的模型
yt = y + np.random.normal(0, 1, 1000)# vis
def plotter(X, y, yhat=None, title=None):with torch.no_grad():fig = go.Figure()fig.add_trace(go.Scatter(x=X, y=y, mode='lines', name='y'))fig.add_trace(go.Scatter(x=X, y=yt, mode='markers', marker=dict(size=4), name='yt'))if yhat is not None: fig.add_trace(go.Scatter(x=X, y=yhat, mode='lines', name='yhat'))fig.update_layout(template='none', title=title)fig.show()plotter(X, y, title='Data Generating Process')# 计算模型的实际输出,这里前提是假设知道变量 X 和函数 sin|cos, 而不知道参数 theta
def fit_model(theta:torch.tensor=torch.rand(3, requires_grad=True)):return theta[0] * X + theta[1] * torch.sin(X) + theta[2] * torch.cos(X/4)# 随机初始化参数,开启自动求导
theta = torch.randn(3, requires_grad=True)# 损失函数和优化器
loss_fn = nn.MSELoss() # MSE loss
optimizer = torch.optim.SGD([theta], lr=0.01) # build optimizer # 迭代训练
epochs = 500
for i in range(epochs):yhat = fit_model(theta) # 计算实际输出loss = loss_fn(y, yhat) # 将实际输出和理想输出传入损失函数,得到损失 lossloss.backward() # 反向传播,完成 .grad 梯度的计算optimizer.step() # 基于梯度完成参数更新 optimizer.zero_grad() # 本轮计算完成,将梯度值归零,否则下次计算损失并调用 backward 导致梯度累计 if i % (epochs/10) == 0: # 验证及输出调试信息 msg = f"loss: {loss.item():>7f} theta: {theta.detach().numpy()}"yhat = fit_model(theta)plotter(X, y, yhat.detach(), title=f"loss: {loss.item():>7f} theta: {theta.detach().numpy().round(3)}")
执行结果
生成数据
创建了一个假数据:
- 分布在象限中的点就是 x,y
- 象限中的曲线,就是符合设想的模型,我们看最终的机器学习的模型,能否拟合这条曲线
第一轮后
初始化后,实际模型和理想模型差距很大。注意,此时 theta 和目标参数差距很大。
第二轮后
经过两次迭代,差距在缩小。
第十轮后
又经过了几轮训练,此时,我们发现图中已经分辨不出来,但是从 theta 的值,我们还可以看到一点差距,这已经证明,机器学习拟合上了目标空间。
更多计算图的知识
更为复杂点的计算图的样子
在训练中,生成的 DAG 类似如下。
自动求导有关的参数
# 做一个计算图
x = torch.rand(1)
b = torch.rand(1, requires_grad=True)
w = torch.rand(1, requires_grad=True)
y = w * x # y 是一个新的 tensor# 检查 y 是否是叶子节点,这里 y 是输出,也就是 root 节点而不是 leaf 节点
print(y.is_leaf)# 反向传播
y.backward(retain_graph=True) # retain_graph=True,保留计算图中的状态,https://discuss.pytorch.org/t/use-of-retain-graph-true/179658
print(w.grad) # 查看梯度
Links
- How Computational Graphs are Constructed in PyTorch
- How Computational Graphs are Executed in PyTorch
- PyTorch’s Dynamic Graphs (Autograd)
- Automatic Differentiation with torch.autograd
- Autograd mechanics
PyTorch 使用 DAG 有向无环图这种格式存储计算图,其中输入的 Tensor 称为叶子节点(leaves),输出的 Tensor 称为根节点(roots)。 ↩︎
相关文章:
计算图 Compute Graph 和自动求导 Autograd | PyTorch 深度学习实战
前一篇文章,Tensor 基本操作5 device 管理,使用 GPU 设备 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started PyTorch 计算图和 Autograd 微积分之于机器学习Computational Graphs 计算图Autograd…...
Vue 图片引用方式详解:静态资源与动态路径访问
目录 前言1. 引用 public/ 目录2. assets/ 目录3. 远程服务器4. Vue Router 动态访问5. 总结6. 扩展(图片不显示) 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 在 Vue 开发中&#x…...
熟练掌握Http协议
目录 基本概念请求数据Get请求方式和Post请求方式 响应数据响应状态码 基本概念 Http协议全称超文本传输协议(HyperText Transfer Protocol),是网络通信中应用层的协议,规定了浏览器和web服务器数据传输的格式和规则 Http应用层协议具有以下特点&#…...
爬虫学习笔记之Robots协议相关整理
定义 Robots协议也称作爬虫协议、机器人协议,全名为网络爬虫排除标准,用来告诉爬虫和搜索引擎哪些页面可以爬取、哪些不可以。它通常是一个叫做robots.txt的文本文件,一般放在网站的根目录下。 robots.txt文件的样例 对有所爬虫均生效&#…...
血压计OCR文字检测数据集VOC+YOLO格式2147张11类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2147 标注数量(xml文件个数):2147 标注数量(txt文件个数):2147 …...
正则表达式详细介绍
目录 正则表达式详细介绍什么是正则表达式?元字符转义字符字符类限定字符字符分枝字符分组懒惰匹配和贪婪匹配零宽断言 正则表达式详细介绍 什么是正则表达式? 正则表达式是一组由字母和符号组成的特殊文本,它可以用来从文本中找出满足你想…...
初识ArkTS语言
文章目录 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。 从…...
Go语言并发之美:构建高性能键值存储系统
摘要 本文介绍了基于Go语言实现的高性能并发键值存储系统。通过深入探讨Go语言在并发编程中的优势,文章详细阐述了系统的锁机制、分片优化、内存管理和持久化设计等关键环节。这些设计展示了如何在系统开发中进行有效的权衡,以确保最优性能。该系统不仅充…...
6. k8s二进制集群之各节点部署
获取kubernetes源码安装主节点(分别执行以下各节点命令)安装工作节点(同步kebelet和kube-proxy到各工作节点)总结 继续上一篇文章《k8s二进制集群之ETCD集群部署》下面介绍一下各节点的部署与配置。 获取kubernetes源码 https:/…...
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架
目录 前言 环境介绍 代码与动机 架构设计,优缺点 博客系列指引 前言 笔者前段时间花费了一周,整理了一下自从TM1637开始打算的,使用OLED来搭建一个通用的显示库的一个工程。笔者的OLED库已经开源到Github上了,地址在…...
spring基础总结
先修知识:依赖注入,反转控制,生命周期 IDEA快捷键 Ctrl Altm:提取方法,设置trycatch 通用快捷键: Ctrl F:在当前文件中查找文本。Ctrl R:在当前文件中替换文本。Ctrl Z:撤销…...
基础相对薄弱怎么考研
复习总体规划 明确目标 选择专业和院校:根据你的兴趣、职业规划和自身实力,选择适合自己的专业和院校。可以参考往年的分数线、报录比、复试难度等。了解考试科目:不同专业考试科目不同,一般包括: 公共课:…...
代码随想录36 动态规划
leetcode 343.整数拆分 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 1…...
p5r预告信生成器API
p5r预告信生成器API 本人将js生成的p5r预告信使用go语言进行了重写和部署,并开放了其api,可以直接通过get方法获取预告信的png。 快速开始 http://api.viogami.tech/p5cc/:text eg: http://api.viogami.tech/p5cc/persona5 感谢p5r风格字体的制作者和…...
React图标库: 使用React Icons实现定制化图标效果
React图标库: 使用React Icons实现定制化图标效果 图标库介绍 是一个专门为React应用设计的图标库,它包含了丰富的图标集合,覆盖了常用的图标类型,如FontAwesome、Material Design等。React Icons可以让开发者在React应用中轻松地添加、定制各…...
说说Redis的内存淘汰策略?
大家好,我是锋哥。今天分享关于【说说Redis的内存淘汰策略?】面试题。希望对大家有帮助; 说说Redis的内存淘汰策略? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 提供了多种内存淘汰策略,用于在内存达到限制时决定如何…...
【C语言】自定义类型讲解
文章目录 一、前言二、结构体2.1 概念2.2 定义2.2.1 通常情况下的定义2.2.2 匿名结构体 2.3 结构体的自引用和嵌套2.4 结构体变量的定义与初始化2.5 结构体的内存对齐2.6 结构体传参2.7 结构体实现位段 三、枚举3.1 概念3.2 定义3.3 枚举的优点3.3.1 提高代码的可读性3.3.2 防止…...
机器学习8-卷积和卷积核1
机器学习8-卷积和卷积核1 卷积与图像去噪卷积的定义与性质定义性质卷积的原理卷积步骤卷积的示例与应用卷积的优缺点优点缺点 总结 高斯卷积核卷积核尺寸的设置依据任务类型考虑数据特性实验与调优 高斯函数标准差的设置依据平滑需求结合卷积核尺寸实际应用场景 总结 图像噪声与…...
3、C#基于.net framework的应用开发实战编程 - 实现(三、三) - 编程手把手系列文章...
三、 实现; 三.三、编写应用程序; 此文主要是实现应用的主要编码工作。 1、 分层; 此例子主要分为UI、Helper、DAL等层。UI负责便签的界面显示;Helper主要是链接UI和数据库操作的中间层;DAL为对数据库的操…...
PHP 中 `foreach` 循环结合引用使用时可能出现的问题
问题背景 假设你有如下 PHP 代码: <?php $arr array(1, 2, 3, 4);// 使用引用遍历并修改数组元素 foreach ($arr as &$value) {$value $value * 2; } // 此时 $arr 变为 array(2, 4, 6, 8)// 再使用非引用方式遍历数组 foreach ($arr as $key > $val…...
go gin配置air
一、依赖下载 安装最新,且在你工作区下进行安装,我的是D:/GO是我的工作区,所有项目都在目录下的src, go install github.com/air-verse/airlatest 如果出现类似报错: 将图中第三行 github.com/air-verse/air 替换最…...
在 Spring Boot 项目中,bootstrap.yml 和 application.yml文件区别
在 Spring Boot 项目中,bootstrap.yml 和 application.yml 是两个常用的配置文件,它们的作用和加载顺序有所不同。以下是它们的详细说明: 1. bootstrap.yml 作用: bootstrap.yml 是 Spring Cloud 项目中的配置文件,用于…...
Excel中Address函数的用法
Excel中Address函数的用法 1. 函数详细讲解1.1 函数解释1.2 使用格式1.3 参数定义1.4 要点 2. 实用演示示例2.1 函数需求2.2 公式编写2.3 计算过程 3. 注意事项4. 文档下载5. 其他文章6. 获取全部Excel练习素材快来试试吧🥰 函数练习素材👈点击即可进行下…...
游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文
Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…...
智能家居监控系统数据收集积压优化
亮点:RocketMQ 消息大量积压问题的解决 假设我们正在开发一个智能家居监控系统。该系统从数百万个智能设备(如温度传感器、安全摄像头、烟雾探测器等)收集数据,并通过 RocketMQ 将这些数据传输到后端进行处理和分析。 在某些情况下…...
Zabbix7.0安装(Ubuntu24.04+LNMP)
1.选择版本 下载Zabbix 2.安装虚拟机 这里选择在Ubuntu24.04上安装Zabbix. 安装链接https://blog.csdn.net/weixin_58189050/article/details/145446065 配置源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ubuntu/ noble main restricted universe multive…...
SpringBoot+Dubbo+zookeeper 急速入门案例
项目目录结构: 第一步:创建一个SpringBoot项目,这里选择Maven项目或者Spring Initializer都可以,这里创建了一个Maven项目(SpringBoot-Dubbo),pom.xml文件如下: <?xml versio…...
6种MySQL高可用方案对比分析
大家好,我是 V 哥,关于 MySQL 高可用方案,在面试中频频出现,有同学在字节面试就遇到过,主要考察你在高可用项目中是如何应用的,V 哥整理了6种方案,供你参考。 V 哥推荐:2024 最适合入…...
CLK敏感源和完整GND平面
SPI Flash芯片辐射发射(RE)问题: 某款产品在3米法电波暗室进行辐射(RE)发射测试时,发现多个频点余量不满足6dB管控要求. 通过频谱分析仪近场探头分析定位到干扰频点来自于SPI Flash时钟信号的高次谐波干扰,深入分析发…...
团体程序设计天梯赛-练习集——L1-034 点赞
前言 20分的题目题目不难,理解也不难,做起来有点问题 L1-034 点赞 微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本…...
独立成分分析 (ICA):用于信号分离或降维
人工智能例子汇总:AI常见的算法和例子-CSDN博客 独立成分分析 (Independent Component Analysis, ICA) 是一种用于信号分离和降维的统计方法,常用于盲源分离 (Blind Source Separation, BSS) 问题,例如音频信号分离或脑电信号 (EEG) 处理。…...
【EdgeAI实战】(2)STM32 AI 扩展包的安装与使用
【EdgeAI实战】(1)STM32 边缘 AI 生态系统 【EdgeAI实战】(2)STM32 AI 扩展包的安装与使用 【EdgeAI实战】(2)STM32 AI 扩展包的安装与使用 1. STM32Cube.AI 简介1.1 STM32Cube.AI 简介1.2 X-CUBE-AI 内核引…...
【Java】MyBatis动态SQL
在MyBatis中使用动态SQL语句。 动态SQL是指根据参数数据动态组织SQL的技术。 生活中的案例: 在京东上买东西时,用户搜索商品,可以选择筛选条件,比如品牌,价格,材质等,也可以不使用筛选条件。这时…...
Spring Boot篇
为什么要用Spring Boot Spring Boot 优点非常多,如: 独立运行 Spring Boot 而且内嵌了各种 servlet 容器,Tomcat、Jetty 等,现在不再需要打成 war 包部署到 容器 中,Spring Boot 只要打成一个可执行的 jar 包就能独…...
深入理解Node.js_架构与最佳实践
1. 引言 1.1 什么是Node.js Node.js简介:Node.js是一个基于Chrome V8引擎的JavaScript运行时,用于构建快速、可扩展的网络应用。Node.js的历史背景和发展:Node.js最初由Ryan Dahl在2009年发布,旨在解决I/O密集型应用的性能问题。随着时间的推移,Node.js社区不断壮大,提供…...
使用mockttp库模拟HTTP服务器和客户端进行单元测试
简介 mockttp 是一个用于在 Node.js 中模拟 HTTP 服务器和客户端的库。它可以帮助我们进行单元测试和集成测试,而不需要实际发送 HTTP 请求。 安装 npm install mockttp types/mockttp模拟http服务测试 首先导入并创建一个本地服务器实例 import { getLocal } …...
响应式编程_02基本概念:背压机制 Backpressure
文章目录 Pre流流的处理模型拉模式推模式 流量控制产者生产数据的速率小于消费者的场景生产者生产数据的速率大于消费者消费数据无界队列有界丢弃队列有界阻塞队列 背压机制响应式流规范响应式流的核心接口PublisherSubscriberSubscription 响应式流的技术生态圈 小结 Pre 响应…...
Jason配置环境变量
jason官网 https://jason-lang.github.io/ https://github.com/jason-lang/jason/releases 步骤 安装 Java 21 或更高版本 安装 Visual Studio Code 根据操作系统,请按照以下具体步骤操作 视窗 下载 Jason 的最新版本,选择“jason-bin-3.3.0.zip”…...
[ESP32:Vscode+PlatformIO]新建工程 常用配置与设置
2025-1-29 一、新建工程 选择一个要创建工程文件夹的地方,在空白处鼠标右键选择通过Code打开 打开Vscode,点击platformIO图标,选择PIO Home下的open,最后点击new project 按照下图进行设置 第一个是工程文件夹的名称 第二个是…...
java开发面试自我介绍模板_java面试自我介绍3篇
java 面试自我介绍 3 篇 java 面试自我介绍篇一: 我叫赵,我的同学更都喜欢称呼我的英文名字,叫,六月的 意思,是君的谐音。我来自安徽的市,在 21 年我以市全市第一名 的成绩考上了大学,…...
intra-mart实现简易登录页面笔记
一、前言 最近在学习intra-mart框架,在此总结下笔记。 intra-mart是一个前后端不分离的框架,开发时主要用的就是xml、html、js这几个文件; xml文件当做配置文件,html当做前端页面文件,js当做后端文件(js里…...
2025最新软件测试面试大全
前面看到了一些面试题,总感觉会用得到,但是看一遍又记不住,所以我把面试题都整合在一起,都是来自各路大佬的分享,为了方便以后自己需要的时候刷一刷,不用再到处找题,今天把自己整理的这些面试题…...
JDK17主要特性
JDK 17,也被称为Java 17或Java Platform, Standard Edition 17,是Java编程语言的第十七个主要版本,由Oracle公司在2021年9月发布。Java 17是一个长期支持(LTS,Long-Term Support)版本,这意味着它…...
基于SpringBoot的在线远程考试系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
Android Studio:Application 和 Activity的区别
Application 和 Activity 是 Android 中非常重要的两个组件,它们分别负责不同的生命周期管理和应用的不同层次的操作。 Application 是应用级别的生命周期管理,它在整个应用运行时只有一个实例,负责应用的全局初始化和资源管理。Activity 是…...
GAN(生成对抗网络,Generative Adversarial Network)
https://www.bilibili.com/video/BV1mp4y187dm/?spm_id_from333.788.recommend_more_video.2&vd_source35b06c13f470dff84c947fa3045bafc3...
大模型Dense、MoE 与 Hybrid-MoE 架构的比较
在大模型架构设计中,Dense(全连接)、MoE(混合专家)和Hybrid-MoE(混合式MoE)是三种主流的参数组织方式,它们在模型容量、计算效率和应用场景上存在显著差异。以下从核心原理、技术特点…...
Java进阶学习之路
Java进阶之路 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 Java进阶之路前言一、Java入门 Java基础 1、Java概述 1.1 什…...
Django 多数据库
django 支持项目连接多个数据库 DATABASES = {default: {ENGINE: django.db.backends.mysql,NAME: xxx,USER: root,"PASSWORD": xxxxx,HOST: xxxx,PORT: 3306,},bak: {ENGINE: django.db.backends.mysql,NAME: xxx,USER: root,"PASSWORD": xxxx,HOST: xxx…...
Vue 中如何嵌入可浮动的第三方网页窗口(附Demo)
目录 前言1. 思路Demo2. 实战Demo 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 1. 思路Demo 以下Demo提供思路参考,需要结合实际自身应用代码 下述URL的链接使用百度替代! 方式 1…...