【深度学习(deep learning)】花书第10章 序列建模:循环和递归网络 读书笔记
【深度学习(deep learning)】花书第10章 序列建模:循环和递归网络 读书笔记
第10章 序列建模:循环和递归网络
- 【深度学习(deep learning)】花书第10章 序列建模:循环和递归网络 读书笔记
- 前言
- 一、序列模型
- 1.1 序列模型中的参数共享
- 1.时延神经网络(卷积)
- 2.循环神经网络
- 1.2 计算图展开
- 二、循环神经网络 RNN
- 2.1 多对多,隐藏到隐藏
- **反向传播:通过时间反向传播(BPTT)**
- 2.2 多对多,输出到隐藏
- 训练算法:导师驱动过程(teacher forcing)
- 2.3 多对一,隐藏到隐藏
- 2.4 基于上下文的RNN序列建模
- 2.4.1 一对多 隐藏到隐藏 标记到隐藏
- 2.4.2 多对多 隐藏到隐藏 标记到隐藏
- 2.5 双向RNN
- 2.6 基于编码-解码的 序列到序列(seq to seq)
- 2.7 深度循环网络
- 三、循环神经网络的优化问题
- 3.1 长期依赖的问题
- 3.2 回声状态网络 ESN
- 3.3 多时间尺度策略
- 3.3.1 时间维度的跳跃连接
- 3.3.2 渗漏单元
- 3.3.3 删除连接
- 3.4 优化长期依赖
- 3.4.1 截断梯度
- 3.4.2 引导信息流的正则化
- 四、门控RNN
- 4.1 长短期记忆网络 LSTM
- 4.2 门控循环单元 GRU
- 参考资料
前言
打基础,阅读花书,感觉一次性啃不动。看一点算一点,写一点笔记留作纪念。以便日后查看与回顾。大名鼎鼎RNN。2020.12.3-2020.12.4
以下是正式内容。除了特殊标注外,其他配图都来自花书。
一、序列模型
处理序列数据:
x(1),⋯,x(t),⋯,x(τ)\boldsymbol{x}^{\left( 1 \right)},\cdots ,\boldsymbol{x}^{\left( t \right)},\cdots ,\boldsymbol{x}^{\left( \tau \right)} x(1),⋯,x(t),⋯,x(τ)
1.1 序列模型中的参数共享
1.时延神经网络(卷积)
在一维时间序列上使用卷积,输出的每一项是相邻几项输入的函数。在每个时间步中使用相同的卷积核。最终效果是读入一个序列,输出一个卷积后的序列。
2.循环神经网络
输出的每一项是前一项输出的函数。由前一项输出得到后一项输出的规则是公用的,因此参数是共享的。
1.2 计算图展开
递归表达式:
s(t)=f(s(t−1);θ)\boldsymbol{s}^{\left( t \right)}=f\left( \boldsymbol{s}^{\left( t-1 \right)};\boldsymbol{\theta } \right) s(t)=f(s(t−1);θ)展开成非递归:
含外部信号的递归表达式:h(t)=f(h(t−1),x(t);θ)\boldsymbol{h}^{\left( t \right)}=f\left( \boldsymbol{h}^{\left( t-1 \right)},\boldsymbol{x}^{\left( t \right)};\boldsymbol{\theta } \right) h(t)=f(h(t−1),x(t);θ)展开的计算图:
h(t)作为过去序列信息的一个有损表示。可以用另一个函数表达这种关系:
h(t)=f(h(t−1),x(t);θ)\boldsymbol{h}^{\left( t \right)}=f\left( \boldsymbol{h}^{\left( t-1 \right)},\boldsymbol{x}^{\left( t \right)};\boldsymbol{\theta } \right) h(t)=f(h(t−1),x(t);θ)=g(t)(x(t),x(t−1),x(t−2),...,x(2),x(1))=g^{\left( t \right)}\left( \boldsymbol{x}^{\left( t \right)},\boldsymbol{x}^{\left( t-1 \right)},\boldsymbol{x}^{\left( t-2 \right)},...,\boldsymbol{x}^{\left( 2 \right)},\boldsymbol{x}^{\left( 1 \right)} \right) =g(t)(x(t),x(t−1),x(t−2),...,x(2),x(1))展开带来的好处:
- 可以处理任意长度的序列。因为函数处理的是每个时刻中固定的大小,与序列长度就无关了。
- f函数是共享的,也就是参数共享。
二、循环神经网络 RNN
循环神经网络有多种模式。
2.1 多对多,隐藏到隐藏
每个时间步都产生一个输出,隐藏单元之间有循环连接。
将一个长度的输入序列映射到等长的输出序列,且y相互间无关(条件独立的假设)
x是输入,h是隐层表示,o是隐层输出,y只真实标记,L是根据输出与标记计算的损失。
前向传播过程:t=1 到 t=τ(tanh softmax 分别代表激活函数和输出函数)
a(t)=b+Wh(t−1)+Ux(t)\boldsymbol{a}^{\left( t \right)}=\boldsymbol{b}+\boldsymbol{Wh}^{\left( t-1 \right)}+\boldsymbol{Ux}^{\left( t \right)} a(t)=b+Wh(t−1)+Ux(t)h(t)=tanh(a(t))\boldsymbol{h}^{\left( t \right)}=\tan\text{h}\left( \boldsymbol{a}^{\left( t \right)} \right) h(t)=tanh(a(t))o(t)=c+Vh(t)\boldsymbol{o}^{\left( t \right)}=\boldsymbol{c}+\boldsymbol{Vh}^{\left( t \right)} o(t)=c+Vh(t)y^(t)=softmax(o(t))\boldsymbol{\hat{y}}^{\left( t \right)}=softmax\left( \boldsymbol{o}^{\left( t \right)} \right) y^(t)=softmax(o(t))
总的L 就是序列上损失L(t)的总和。每一个损失都是y的预测的负对数似然。
L=∑tL(t)L=\sum_t{L^{\left( t \right)}} L=t∑L(t)L(t)=−logpmodel(y(t)∣{x(1),...,x(t)})L^{\left( t \right)}=-\log\text{\ }p_{model}\left( \boldsymbol{y}^{\left( t \right)}|\left\{ \boldsymbol{x}^{\left( 1 \right)},...,\boldsymbol{x}^{\left( t \right)} \right\} \right) L(t)=−log pmodel(y(t)∣{x(1),...,x(t)})
反向传播:通过时间反向传播(BPTT)
只能串行,且前向传播各状态必须保存,一般训练方法的时空代价都很大。
1.L→L(t)∂L∂L(t)=1\frac{\partial L}{\partial L^{\left( t \right)}}\ =\ 1 ∂L(t)∂L = 1
2.L(t)→o(t)(y是o输入到softmax后产生的概率向量)
3.计算h
t = τ: o → h
t = τ-1 到 t = 1:h(t+1) → h(t) , o(t) → h(t)
4.计算每一时间步对共享权重的梯度影响,再计算完全的权重梯度。
2.2 多对多,输出到隐藏
每个时间步都产生一个输出,当前的输出到下一时刻的隐藏之间有循环连接。
牺牲了一些循环连接,模型的表示能力有所削减,但是可以进行并行化。h(t)可以同时计算。
训练算法:导师驱动过程(teacher forcing)
在训练时,用真实标记y去替代隐层输出o。
但是y并不能完全代替o,更不能代替h中的信息。因此完全使用导师驱动过程,会导致训练和预测时的差异太大,可以混合使用导师驱动过程和隐层输出o以缓解这个问题。
2.3 多对一,隐藏到隐藏
隐藏单元之间有循环连接,但是只有最后产生一个输出。
2.4 基于上下文的RNN序列建模
上下文:RNN的输入
2.4.1 一对多 隐藏到隐藏 标记到隐藏
接受一个向量x当作输入,映射到一个序列y。
适用任务如图注,给定一个图片(一个向量),得到一个文字序列(一个序列)。
2.4.2 多对多 隐藏到隐藏 标记到隐藏
将一个长度的输入序列映射到等长的输出序列,且y之间相关
2.5 双向RNN
序列中的一个时间步不仅与过去的时间步(以及其输出/标记)有关,还和其未来的时间步(及其输出/标记)相关。
在语音序列/文字序列中相当常见这种相关性。
x 同时输入 到一个序列前向前进的表示h与一个序列后向递进的表示g中,且这 两个表示同时输入产生输出 o。
2.6 基于编码-解码的 序列到序列(seq to seq)
将一个可变长度序列映射到一个长度任意的序列。
编码器(读取器、输入):一个多对一RNN,将输入序列映射到一个上下文表示(一个向量) 。通常取最后一个表示h当作上下文表示C。
解码器(写入器、输出):一个一对多RNN,将上下文表示映射到输出序列。
两个子网络共同训练以最大化目标:
logP(y(1),...,y(ny)∣x(1),...,x(nx))\log\text{\ }P\left( \boldsymbol{y}^{\left( 1 \right)},...,\boldsymbol{y}^{\left( n_y \right)}|\boldsymbol{x}^{\left( 1 \right)},...,\boldsymbol{x}^{\left( n_x \right)} \right) log P(y(1),...,y(ny)∣x(1),...,x(nx))
在解码器部分,一对多 有多种输入方式:
1.如2.4.1所示,将输入向量作为各隐层的共同输入
2.将输入向量作为起始状态 h0
3.两者的结合
2.7 深度循环网络
增加RNN中的隐层数目。 当隐层数目变多时,循环连接的连接方式更为多种多样。
(a):添加隐层,各隐层内部分别包含循环连接。
(b):在输入-隐层,隐层-隐层,隐层到输出中,插入MLP(起到提取特征等等多种多样的效果),延长循环连接的路径(但是会难以优化)。
(c):增加跳跃链接,缓解路径延长。
三、循环神经网络的优化问题
3.1 长期依赖的问题
- 梯度爆炸:梯度变得很大。
- 梯度消失:梯度趋于0,指数级缩小。
- 激活函数在多次叠加后 极端非线性。
原因:循环网络参数共享,导致了同一矩阵的高维幂运算。简化表示为:
h(t)=QTΛtQh(0)\boldsymbol{h}^{\left( t \right)}=\boldsymbol{Q}^T\boldsymbol{\Lambda }^t\boldsymbol{Q}h^{\left( 0 \right)} h(t)=QTΛtQh(0) t很大时:小于一的特征值会衰减到0,大于一的会激增。到最后,除特征最大值方向外的所有信息都会被丢弃。
梯度爆炸比较容易解决,可以进行梯度截断。
梯度消失则会导致网络丧失学习长期联系的能力。序列越深,序列初期的信息对应权重越是指数级衰减,越容易被短期信息所扰动,甚至覆盖。
解决办法:
1.直接优化长期依赖,比如梯度截断/正则化等。
2.设置隐藏单元,增强其学习历史的能力,比如回声状态网络
3.多时间尺度策略:设计在多个时间尺度上工作的模型,如渗漏单元
4.门控网络,如LSTM
3.2 回声状态网络 ESN
基本思想:设置隐藏单元,使其捕捉过去的输入历史,并且只学习输出权重。
回声状态网络与流体状态机都基于这种想法,并称为储层计算。
ESN使用连续输出的隐藏单元,流行状态机使用脉冲神经元(二值输出)。
在隐藏单元内形成了可能捕获输入历史不同方面的临时特征池。
将循环网络视为动态系统,并设定让 动态系统 接近 稳定边缘的输入与循环权重,以使输入与权重可以表达丰富的历史信息。
jacobian矩阵的谱半径:特征值的最大绝对值。
谱半径在线性网络中的作用:
假设刚开始的梯度向量为g,反向传播jacobian矩阵为J,在n步之后,得到:Jng\boldsymbol{J}^n\boldsymbol{g} Jng则带有扰动的反向传播会得到:Jn(g+δv)\boldsymbol{J}^n\left( \boldsymbol{g}+\delta \boldsymbol{v} \right) Jn(g+δv)偏离了Jnδv\boldsymbol{J}^n\delta \boldsymbol{v} Jnδv如果v是特征向量对应的单位特征向量,则每一步只是对jacobian矩阵进行简单的缩放。偏离的距离是:δ∣λ∣n\delta \left| \lambda \right|^n δ∣λ∣n当v是最大特征值对应的特征向量,则代表扰动可能达到的最宽量。
∣λ∣ >1,偏差指数增长,反之则指数缩小。
回声状态网络的策略是固定权重,使其具有一定的谱半径,比如3。这样会使信息在传播的过程中会逐步放大,但是又会因为非线性单元的饱和而带来一定的稳定作用,从而不会爆炸。
3.3 多时间尺度策略
模型的一部分处理细粒度时间尺度,学习细节;另一部分在粗时间粒度上学习过去的长期信息。
3.3.1 时间维度的跳跃连接
跨时间维度增加连接。
3.3.2 渗漏单元
渗漏单元:使用线性自连接的隐藏单元,可以模拟滑动平均
对于要更新的v值,维护一个滑动平均值:μ(t)←αμ(t−1)+(1−α)v(t)\mu ^{\left( t \right)}\gets \alpha \mu ^{\left( t-1 \right)}+\left( 1-\alpha \right) v^{\left( t \right)} μ(t)←αμ(t−1)+(1−α)v(t)α是 μ (t-1) 到 μ (t) 的线性自连接。
调整连接系数α和时间步数d,可以实现多种方式的平滑地读取过去的信息。
3.3.3 删除连接
删除长度为1的连接。
3.4 优化长期依赖
3.4.1 截断梯度
有多种方案:
1.在参数更新前,逐元素截断参数梯度ifgi>v,gi=vif\ g_i>v\ ,\ g_i=v if gi>v , gi=v2.在参数更新前,截断梯度g的范数if∥g∥>v,g=g∥g∥vif\ \lVert \boldsymbol{g} \rVert >v\ ,\ \boldsymbol{g}=\frac{\boldsymbol{g}}{\lVert \boldsymbol{g} \rVert}v if ∥g∥>v , g=∥g∥gv方案2可以保证方向是不变的,仍然沿着梯度方向,但是大小缩小了。
3.4.2 引导信息流的正则化
在展开的计算图中,希望路径上的梯度乘积接近1(不消失,也不爆炸). 一种办法是门控单元,另一种办法是施加正则化或约束参数。
形式上,希望
(∇h(t)L)∂h(t)∂h(t−1)=∇h(t)L\left( \nabla _{\boldsymbol{h}^{\left( t \right)}}L \right) \frac{\partial \boldsymbol{h}^{\left( t \right)}}{\partial \boldsymbol{h}^{\left( t-1 \right)}}\ =\ \nabla _{\boldsymbol{h}^{\left( t \right)}}L (∇h(t)L)∂h(t−1)∂h(t) = ∇h(t)L提出以下正则项:Ω=∑t(∥(∇h(t)L)∂h(t)∂h(t−1)∥∥∇h(t)L∥−1)2\varOmega =\sum_t{\left( \frac{\lVert \left( \nabla _{\boldsymbol{h}^{\left( t \right)}}L \right) \frac{\partial \boldsymbol{h}^{\left( t \right)}}{\partial \boldsymbol{h}^{\left( t-1 \right)}}\ \rVert} {\lVert \nabla _{\boldsymbol{h}^{\left( t \right)}}L \rVert}-1 \right)}^2 Ω=t∑(∥∇h(t)L∥∥(∇h(t)L)∂h(t−1)∂h(t) ∥−1)2
这一正则化的优缺点:
1.计算梯度比较困难,但是可以改造后向传播,用恒值近似表示变量。与截断梯度配合,可以显著增加RNN学习的依赖跨度。
2.在处理冗余数据的任务,如语言模型,不如LSTM有效。
四、门控RNN
门控RNN使用门控循环单元,扩展渗漏单元。渗漏单元对于过去信息的读取是基于一个常量系数的,是固定的,学习到的过去信息会一直保存,不能忘记。门控单元允许动态地修改这些权重,网络能自主地进行清除无用的历史信息。
4.1 长短期记忆网络 LSTM
核心贡献:引入自循环,以产生梯度长时间持续流动的路径。自循环的权重视上下文而定,并不固定。由门控制自循环的权重,累积的时间尺度可以动态地改变。
LSTM除了外部RNN循坏外,还有内部的LSTM细胞循环(这一个细胞相当于一个隐藏单元):
状态单元 s:线性单元,维护与渗漏单元类似的线性自环。代表着网络的长期状态信息。s(t)=f(t)∘s(t−1)+g(t)∘i(t)\boldsymbol{s}^{\left( t \right)}=\boldsymbol{f}^{\left( t \right)}\circ \boldsymbol{s}^{\left( t-1 \right)}+\boldsymbol{g}^{\left( t \right)}\circ \boldsymbol{i}^{\left( t \right)} s(t)=f(t)∘s(t−1)+g(t)∘i(t)
遗忘门:sigmoid单元,控制状态单元线性自环的权重。控制保存长期状态,决定上一代长期状态多少写入这一代。
f(t)=σ(bf+Wfhh(t−1)+Wfxx(t))f^{\left( t \right)}=\sigma \left( \boldsymbol{b}^{f}+\boldsymbol{W}_{fh}\boldsymbol{h}^{\left( t-1 \right)}+\boldsymbol{W}_{fx}\boldsymbol{x}^{\left( t \right)} \right) f(t)=σ(bf+Wfhh(t−1)+Wfxx(t))
输入门:sigmoid单元,决定一个输入能否累积到状态。控制当前信息写入到长期状态中,决定当前输入多少能写入到长期状态。
g(t)=σ(bg+Wghh(t−1)+Wgxx(t))g^{\left( t \right)}=\sigma \left( \boldsymbol{b}^{g}+\boldsymbol{W}_{gh}\boldsymbol{h}^{\left( t-1 \right)}+\boldsymbol{W}_{gx}\boldsymbol{x}^{\left( t \right)} \right) g(t)=σ(bg+Wghh(t−1)+Wgxx(t))
输入单元:常规的神经元,计算当前输入特征,允许非线性。
i(t)=σ/tanh(b+Whh(t−1)+Wxx(t))i^{\left( t \right)}=\sigma /\tan\text{h}\left( \boldsymbol{b}+\boldsymbol{W}_h\boldsymbol{h}^{\left( t-1 \right)}+\boldsymbol{W}_x\boldsymbol{x}^{\left( t \right)} \right) i(t)=σ/tanh(b+Whh(t−1)+Wxx(t))
输出门:sigmoid单元,决定细胞能否进行输出。控制是否要将长期状态写出到输出。o(t)=σ(bo+Wohh(t−1)+Woxx(t))o^{\left( t \right)}=\sigma \left( \boldsymbol{b}^{o}+\boldsymbol{W}_{oh}\boldsymbol{h}^{\left( t-1 \right)}+\boldsymbol{W}_{ox}\boldsymbol{x}^{\left( t \right)} \right) o(t)=σ(bo+Wohh(t−1)+Woxx(t))
最终输出:h(t)=tanh(s(t))∘o(t)\boldsymbol{h}^{\left( t \right)}=\tan\text{h}\left( \boldsymbol{s}^{\left( t \right)} \right) \circ \boldsymbol{o}^{\left( t \right)} h(t)=tanh(s(t))∘o(t)
4.2 门控循环单元 GRU
单个门控单元更新门同时控制遗忘因子和更新状态单元。
更新门:遗忘门与输入门的合并。
u(t)=σ(bu+Wuhh(t−1)+Wuxx(t))u^{\left( t \right)}=\sigma \left( \boldsymbol{b}^{u}+\boldsymbol{W}_{uh}\boldsymbol{h}^{\left( t -1\right)}+\boldsymbol{W}_{ux}\boldsymbol{x}^{\left( t \right)} \right) u(t)=σ(bu+Wuhh(t−1)+Wuxx(t))
复位门:
r(t)=σ(br+Wrhh(t−1)+Wrxx(t))r^{\left( t \right)}=\sigma \left( \boldsymbol{b}^{r}+\boldsymbol{W}_{rh}\boldsymbol{h}^{\left( t -1\right)}+\boldsymbol{W}_{rx}\boldsymbol{x}^{\left( t \right)} \right) r(t)=σ(br+Wrhh(t−1)+Wrxx(t))
输入单元:i(t)=σ/tanh(b+Wh[h(t−1)∘r(t)]+Wxx(t))i^{\left( t \right)}=\sigma /\tan\text{h}\left( \boldsymbol{b}+\boldsymbol{W}_h\left[ \boldsymbol{h}^{\left( t-1 \right)}\circ \boldsymbol{r}^{\left( t \right)} \right] +\boldsymbol{W}_x\boldsymbol{x}^{\left( t \right)} \right) i(t)=σ/tanh(b+Wh[h(t−1)∘r(t)]+Wxx(t))
输出:h(t)=(1−u(t))∘h(t−1)+u(t)∘i(t)\boldsymbol{h}^{\left( t \right)}=\left( 1-\boldsymbol{u}^{\left( t \right)} \right) \circ \boldsymbol{h}^{\left( t-1 \right)}+\boldsymbol{u}^{\left( t \right)}\circ \boldsymbol{i}^{\left( t \right)} h(t)=(1−u(t))∘h(t−1)+u(t)∘i(t)
参考资料
1.机器学习,周志华
2.统计学习方法,第二版,李航
3.https://zhuanlan.zhihu.com/p/38431213
4.https://github.com/MingchaoZhu/DeepLearning
5.https://www.bilibili.com/video/BV1kE4119726?p=5&t=1340
6.cs231n
7.https://zybuluo.com/hanbingtao/note/541458
8.https://zhuanlan.zhihu.com/p/30844905
9.https://blog.csdn.net/weixin_42555985/article/details/104422343
10.https://blog.csdn.net/weixin_42555985/article/details/104471711
11.https://zybuluo.com/hanbingtao/note/581764
12.https://blog.csdn.net/weixin_42555985/article/details/104490326
【深度学习(deep learning)】花书第10章 序列建模:循环和递归网络 读书笔记相关推荐
- 真的!最难啃的《深度学习》圣经花书,居然新出版了视频课!
[翻到文末免费学习<机器学习实战>,还能让你看尽CV和NLP完整技术路径以及前沿+经典论文篇目,助你构建深度学习知识框架] 在AI领域内,关于深度学习的课程资料有很多很多,而<深度学 ...
- 最难啃的《深度学习》圣经花书,居然新出版了视频课!
[翻到文末免费学习<机器学习实战>,还能让你看尽CV和NLP完整技术路径以及前沿+经典论文篇目,助你构建深度学习知识框架] 在AI领域内,关于深度学习的课程资料有很多很多,而<深度学 ...
- OMG!最难啃的《深度学习》圣经花书,居然新出版了视频课!
[翻到文末免费学习<机器学习实战>,还能让你看尽CV和NLP完整技术路径以及前沿+经典论文篇目,助你构建深度学习知识框架] 在AI领域内,关于深度学习的课程资料有很多很多,而<深度学 ...
- 机器学习(Machine Learning)深度学习(Deep Learning)资料汇总
本文来源:https://github.com/ty4z2008/Qix/blob/master/dl.md 机器学习(Machine Learning)&深度学习(Deep Learning ...
- 机器学习(Machine Learning)深度学习(Deep Learning)资料【转】
转自:机器学习(Machine Learning)&深度学习(Deep Learning)资料 <Brief History of Machine Learning> 介绍:这是一 ...
- 机器学习(Machine Learning)深度学习(Deep Learning)资料集合
机器学习(Machine Learning)&深度学习(Deep Learning)资料 原文链接:https://github.com/ty4z2008/Qix/blob/master/dl ...
- 机器学习 Machine Learning 深度学习 Deep Learning 资料
机器学习(Machine Learning)&深度学习(Deep Learning)资料 機器學習.深度學習方面不錯的資料,轉載. 原作:https://github.com/ty4z2008 ...
- 大量机器学习(Machine Learning)深度学习(Deep Learning)资料
机器学习目前比较热,网上也散落着很多相关的公开课和学习资源,这里基于课程图谱的机器学习公开课标签做一个汇总整理,便于大家参考对比. 1.Coursera上斯坦福大学Andrew Ng教授的" ...
- 机器学习(Machine Learning)amp;深度学习(Deep Learning)资料
机器学习(Machine Learning)&深度学习(Deep Learning)资料 機器學習.深度學習方面不錯的資料,轉載. 原作:https://github.com/ty4z2008 ...
最新文章
- ios c语言头文件,iOS开发 -- C语言基础12(预处理指令)
- 让人迷茫的三十岁,从专业技能、行业知识和软实力的人才三角谈起
- Linux下安装并破解StarUML
- 数据结构-查找-总结归纳知识点
- WPF多线程UI更新——两种方法
- 高阶函数(Higher-order function)
- 山东大学计算机应用基础期中测试,山东大学期末考试计算机应用基础模拟题三套题.pdf...
- MySql Connector-Java下载
- 【OpenCV】图片对比度和亮度
- python与excel-超简单:用Python让Excel飞起来
- ImportError: No module named MySQLdb
- 基于STM32的PWM电机驱动TB6612、A4950
- UiPath Excel内容去重操作(21.10现代设计体验)
- LeetCode 3:Longest Substring Without Repeating Charact
- cortana在哪里打开_Windows 10开启Cortana的方法步骤
- 使用纯JavaCV实现颜色分割 / 轮廓提取 / 离焦 / 线性旋转变焦模糊 / 灰度化 / 标注等处理
- Spring学习(二)—— 对象创建方式及依赖注入
- 全国计算机软考网络管理员考试大纲(2012)
- KNN算法(二) sklearn KNN实践
- CodeForces 1216CodeForces 1221 A~D
热门文章
- 软硬件学习记录2——通道速率中比特率bps、Bps、波特率含义及换算
- 论文写作-如何提高英语论文写作水平
- 投影变换--透视投影和正交投影
- springboot(九)--统一异常处理(500)、错误页处理(404)
- 多场景支付融合,刷脸支付入驻新华书店
- PHP正则验证手机号
- 【GMS认证】MBA政策解读
- 9.1 多元微分学及应用——多元函数的基本概念
- 【数据库】主键,超键,候选键,外键区别与联系?
- 计算机从图灵到冯诺依曼,电脑是谁发明的 冯·诺依曼和图灵(两人都起到了重要作用)...