强化学习 DQN 速成

2023-10-26

强化学习 DQN 速成

这是对 《深度强化学习》 王树森 张志华 中 DQN 部分的缩写以及部分内容的个人解读

书中的 DQN 是一个相对终极版本的存在,相信体量会比网络上其他资料要大很多

基本概念

我们通过贪吃蛇来引入几个基本概念

符号 中文 说明
S , s S,s S,s 状态 贪吃蛇和食物的位置,空间的大小等
A , a A,a A,a 动作 贪吃蛇当前时刻要做出的行为,如前进和左转
R , r R,r R,r 奖励 贪吃蛇当前时刻做出行为会获得的奖励,如吃到食物奖励100分
U , u U,u U,u 回报 每一步奖励累加到游戏结束为止的和,或者说总奖励,我们的目标是最大化总奖励
γ \gamma γ 折扣率 每一步奖励的权重不同,这是衰减率,即越往后权重越小,一般可以取 γ = 0.95 \gamma=0.95 γ=0.95
π ( a ∣ s ) \pi (a | s) π(as) 随机策略函数 条件概率密度函数,在 s s s 状态下,执行 a a a 动作的概率,是待学习的
p ( s t + 1 ∣ s t , a t ) p(s_{t+1}|s_{t},a_{t}) p(st+1st,at) 状态转移函数 见下
Q π ( s t , a t ) Q_{\pi}(s_{t},a_{t}) Qπ(st,at) 动作价值函数 见下
Q ⋆ ( s , a ) Q_{\star}(s,a) Q(s,a) 最优动作价值函数 最好的随机策略函数 π \pi π对应的动作价值函数

状态转移函数:

条件概率密度函数,在 s t s_{t} st 状态下执行 a t a_{t} at 操作,转移到 s t + 1 s_{t+1} st+1 的概率,对于贪吃蛇来说,随机性来自于可能吃掉了食物,出现新的食物,换言之如果没有吃掉食物,在给定条件下下一个状态是确定的,也就是只有一个 s t + 1 s_{t+1} st+1 的值为 1 1 1,其他都为 0 0 0

动作价值函数:

完成 t t t 时刻决策后,我们希望估计局势,也就是接下来回报的期望,显然当我们确定了该时刻的状态和动作后,之后的行为可以唯一确认之后的回报,而之后的行为只与随机策略函数 π \pi π有关(我们认为状态转移函数 p p p是固定的)

符号说明:
若下文出现花体字符,他们的意义是对应的全体可行集合

策略学习与价值学习

策略学习

直接学习策略函数 π \pi π,然后让智能体概率采样地执行。

价值学习

我们越过策略函数直接学习最优价值函数,然后让智能体每一步都执行最优价值函数最高的动作。例如在 s s s 状态下

Q ⋆ ( s , 上 ) = 100 , Q ⋆ ( s , 左 ) = 200 , . . . = 100 , . . . = 0 Q_{\star}(s,\text{上})=100,Q_{\star}(s,\text{左})=200,...=100,...=0 Q(s,)=100,Q(s,)=200,...=100,...=0

那么我们令其执行“左”。

DQN 与 Q 学习

我们接下来只涉及价值学习的原理和方法

首先让我们快速回顾一下深度神经网络,它可以抽象成一组输入,一组参数,一组预测输出,一组事实输出,它的学习是对参数执行梯度下降以最小化预测输出和实时输出的差距,而接下来我们要介绍深度强化学习网络DQN,和对应的学习算法 TD 算法(事实上本文中只提及 TD 算法中的 Q 学习算法,所以有时候我混为一谈,但本章中仍称之为 TD 算法)

TD算法和传统神经网络最大不同就是强化学习网络不存在一个事实输出,所以它将事实输出替换为部分事实输出,下面会展示这一点

上文我们提到,价值学习是越过策略函数直接学习最优价值函数,也就是“策略”其实是一个黑箱,我们不用知道是什么,我们这里直接给出蒙特卡罗近似和最优贝尔曼方程结合的一个关键结果(下简称最优贝尔曼方程,因为多次用到)

Q ⋆ ( s t , a t ) ≈ r t + γ ⋅ max ⁡ a ∈ A Q ⋆ ( s t + 1 , a ) Q_{\star}\left(s_{t}, a_{t}\right) \approx r_{t}+\gamma \cdot \max _{a \in \mathcal{A}} Q_{\star}\left(s_{t+1}, a\right) Q(st,at)rt+γaAmaxQ(st+1,a)

它的意义是显然的,类似动态规划,当前最优显然是当前行为的奖励加上之后的最优得到的

TD算法

敲黑板,重点来了:我们假设目前学习中的 Q ⋆ Q_{\star} Q函数是一个效果很差的 Q ⋆ Q_{\star} Q函数,通过这个函数我们得到了等号左边的预测值,我们希望用等号右边作为事实输出学习,但是等号右边仍然包含我们待学习的 Q 函数

如果是过去的神经网络,这样的学习是没有意义的,相当于用错误的方法求两遍,自己和自己对照

然而等号右边还包含了一个确定的事实值 r t r_t rt,所以等号右边的事实程度要更高一些,于是我们把右侧全体看作一个部分事实输出去做学习,这就是TD算法,这是一种自举算法(自己更新自己)

训练过程

与环境交互得到四元组 ( s t , a t , r t , s t + 1 ) (s_t,a_t,r_t,s_{t+1}) (st,at,rt,st+1),每个四元组就是一个样本,也是最优贝尔曼方程中所有与环境相关的值,对于每一个样本就是代入 Q 函数中,(右侧需要枚举多个 Q 函数取最大值),然后执行梯度下降

值得注意的是,如何采样,强化学习中叫行为策略。一种方法是随机采样,随便玩,随便采,但是这显然不是我们想要的,我们希望我们的AI是一个聪明的AI,所以我们应该给它对应的问题。

常见的行为策略是 ϵ − g r e e d y \epsilon-greedy ϵgreedy 策略,我们以一定概率选择最优的行动,而剩下的概率随机行动,我的理解中这是基于高分更难遇见,而且更难学习这个共识,人为去平衡样本,和机器学习中偏采样相关的内容是一致的。

一些概念

Q学习是学习 Q ⋆ Q_{\star} Q,对应的又有SARSA学习的是 Q π Q_{\pi} Qπ,二者都归属于TD算法,目前前者是托管更主流的算法,后者则用于动作好坏的评估,因为 Q π Q_{\pi} Qπ 才和具体的动作有关

DQN是用深度神经网络来作为Q学习中 Q ⋆ Q_{\star} Q的表达形式,过去是用表格

下文中 DQN 和 Q ⋆ Q_{\star} Q 函数混为一谈,但实际上 Q ⋆ Q_{\star} Q 函数可以有多种表达形式

DQN 的高级技巧

DQN 最初不带任何优化的实现取得的效果是有限的,下面会介绍实际应用场合中被广泛采用的技巧

经验回放

将四元组 ( s t , a t , r t , s t + 1 ) (s_t,a_t,r_t,s_{t+1}) (st,at,rt,st+1)储存在一个经验回放数组中,当记忆填满时再开始更新参数(学习),何时填满是超参数,填满后以随机抽样的方式进行学习。

优点
  1. 打破序列相关性,相当于 random_shuffle,如果不这样做我们的样本大概率是相邻的两个局面被采集到了一起
  2. 可样本重复利用,如其名,经验自然是多次回放的

优先经验回放

对经验回放进行改进,优先经验回放以一定的规则对记忆赋权,加权抽样

它的权重定义为 δ + ϵ \delta + \epsilon δ+ϵ,其中 δ \delta δ 即上文提到的TD算法中的预测值和部分事实值的差

δ = Q ⋆ ( s t , a t ) − [ r t + γ ⋅ max ⁡ a ∈ A Q ⋆ ( s t + 1 , a ) ] \delta = Q_{\star}\left(s_{t}, a_{t}\right) - [r_{t}+\gamma \cdot \max _{a \in \mathcal{A}} Q_{\star}\left(s_{t+1}, a\right)] δ=Q(st,at)[rt+γaAmaxQ(st+1,a)]

ϵ \epsilon ϵ 是一个极小的正数

相当于多做错题

训练过程

非均匀采样需要对应地调整学习率,一种可行的办法是这样
α j = α ( b ⋅ p j ) β \alpha_{j}=\frac{\alpha}{\left(b \cdot p_{j}\right)^{\beta}} αj=(bpj)βα
其中 β \beta β 是超参数

另外我们采样时计算得到的 δ \delta δ 是旧参数下的,我们学习时要用新的参数重新计算

目标网络

原始的 Q 学习算法会导致 Q ⋆ Q_{\star} Q 函数非均匀地被高估,因为 TD 是一种自举算法,即自己更新自己,而估计中的噪声,即高估(低估)就会自己传给自己,导致整体和谐地被高估(低估)。这里因为算法中是取max,所以会把高估的噪音过滤出来,总体来看就是 Q 函数最后一定是被高估的。

然而高估本身没有问题,问题出在不平衡地高估,因为我们的决策是取最优决策,均匀高估不会影响确定最优决策,但是实验发现它往往是不均匀地,如因为采样很难均匀的缘故。

有两种方法来解决这个问题,目标网络和双Q学习

目标网络的想法是通过两个网络来切断自举

具体地,上文我们一直在用的网络我们称为DQN,我们另外定义一个网络结构一模一样的网络称为目标网络

训练过程

我们要学习的DQN仍然是最优贝尔曼方程的左式,但是右式我们用新定义的网络目标网络去计算,两个网络的差为新定义的误差,用这个误差去更新DQN,再用 DQN 和 目标网络 加权平均去更新 目标网络,这个权重是一个超参数

双Q学习

双Q学习和目标网络很像,我们可以这样引入双Q学习


r t + γ ⋅ max ⁡ a ∈ A Q ⋆ ( s t + 1 , a ) r_{t}+\gamma \cdot \max _{a \in \mathcal{A}} Q_{\star}\left(s_{t+1}, a\right) rt+γaAmaxQ(st+1,a)

拆分成选择(选择出估值最大的行为)和求值(计算最大行为对应的估值)

如果不拆分,这两步对于原始 Q 学习和目标网络来说是统一的,因为选择最大值行为本身就计算完对应最大值了

双Q学习可以解读为用DQN网络做行为选择,但是用"目标网络"求值,这时前者选择出来的行为不一定对应后者的最大行为了。但我们用这个不一定最大的估值去学习,结果就是

y ~ t ⏟ 双  Q  学习  ≤ y ^ t − ⏟ 用目标网络的  Q  学习  \underbrace{\tilde{y}_{t}}_{\text {双 } \mathrm{Q} \text { 学习 }} \leq \underbrace{\widehat{y}_{t}^{-}}_{\text {用目标网络的 } \mathrm{Q} \text { 学习 }}  Q 学习  y~t用目标网络的 Q 学习  y t

而这恰恰就是我们想要的,缓解最大化造成的高估

训练过程

和目标网络是基本一致的,最后仍然是一个加权平均

另外以上方法中,双Q算法是效果最好的

对决网络

以上是学习方法,接下来介绍两种对神经网络结构的改进

对决网络将 DQN 拆分成两部分 最优优势函数 D ⋆ ( s , a ) D_{\star}(s,a) D(s,a) 和 最优状态价值函数 V ⋆ ( s ) V_{\star}(s) V(s)

先给出直观的理解:

最优状态价值函数 V ⋆ ( s ) V_{\star}(s) V(s) 描述的是一个状态本身的优劣,它对所有动作取平均

V π ( s ) V_{\pi}(s) Vπ(s) Q π ( s , a ) Q_{\pi}(s, a) Qπ(s,a) 其中当步 a a a 按照 π \pi π 决策的期望,最优就是选取最优的 π \pi π,类似 Q ⋆ Q_{\star} Q Q π 的差别 Q_{\pi} 的差别 Qπ的差别

优势函数则是 a a a 动作较期望动作的优势,最优则是最优相对最优的优势

D ⋆ ( s , a ) = Q ⋆ ( s , a ) − V ⋆ ( s ) D_{\star}(s,a) = Q_{\star}\left(s, a\right) - V_{\star}(s) D(s,a)=Q(s,a)V(s)

容易证明

Q ⋆ ( s , a ) = V ⋆ ( s ) + D ⋆ ( s , a ) − max ⁡ a ∈ A D ⋆ ( s , a ) ⏟ 恒等于零  , ∀ s ∈ S , a ∈ A Q_{\star}(s, a)=V_{\star}(s)+D_{\star}(s, a)-\underbrace{\max _{a \in \mathcal{A}} D_{\star}(s, a)}_{\text {恒等于零 }}, \quad \forall s \in \mathcal{S}, a \in \mathcal{A} Q(s,a)=V(s)+D(s,a)恒等于零  aAmaxD(s,a),sS,aA

因为最优的时候, π \pi π 一定能正确地唯一选到期望最大的动作,此时 D D D 也必须选到那个 a a a 才能让这个“优势”为0,否则就是负数

我们的网络就可以定义为
Q ( s , a ; w ) ≜ V ( s ; w V ) + D ( s , a ; w D ) − max ⁡ a ∈ A D ( s , a ; w D ) Q(s, a ; \boldsymbol{w}) \triangleq V\left(s ; \boldsymbol{w}^{V}\right)+D\left(s, a ; \boldsymbol{w}^{D}\right)-\max _{a \in \mathcal{A}} D\left(s, a ; \boldsymbol{w}^{D}\right) Q(s,a;w)V(s;wV)+D(s,a;wD)aAmaxD(s,a;wD)

之所以要把一件事拆成两部分,我的理解中这可以和残差神经网络统一地解释,即人为地用外界知识精细化网络结构,省去了让他自己进化出这样的框架的时间

其中我们预期的结果中 max ⁡ a ∈ A D ( s , a ; w D ) \max _{a \in \mathcal{A}} D\left(s, a ; \boldsymbol{w}^{D}\right) maxaAD(s,a;wD) 应该是 0 0 0,所以这个 max 看似可以删除,但其实不可以

直接说结论就是它可以让结果唯一,若去掉这一项,存在这样一种情况, V V V D D D 相对应地增大减少,总结果是不变的,结果就是这两个网络很难收敛,比如两个锯齿状的网络,和两个平滑的网络,都可以使得结果正确,没有一个可以稳定收敛的位置

而加上 max 我的理解是它可以过滤掉这种波动,因为 max 的存在,在学习过程中,这种对应性的相消是很难同步的,为了互相迁就,它会趋向某一个由初值决定的固定的偏差,网络就会收敛到一个固定的位置了

更高的层次来说,我们硬生生拆开成两个网络其实丢失了一些信息,max 相当于给网络结构注入了更多信息(这里信息的表现形式就是性质),有类似剪枝的效果

值得注意的是:实际上这两者这样训练,最后单独看必然是不准确的,例如我事后同加同减,对于输入输出来说一定还是正确的。但是我学习的本来就是他们的和,所以没有关系

训练过程
  1. 我们发现,实际上用 mean 替代 max 效果更好,因为这一项的目标本来就是引入全体的信息降低网络波动的可能,而平均值显然包含了更多的全体信息
  2. 显然我们可以让这两个网络共享部分开始时候的卷积层用来提取特征,然后再用全连接层输出各自的信息,最后相加

噪声网络

和对决网络独立,这是第二种优化网络的方法

这是神经网络的通法,即给每个参数加上一个正态分布的随机扰动,使得每个参数实际上是从一个正态分布中产生的。其中正态分布的平均值实际上是没有扰动时的参数,正态分布的方差也是需要梯度下降学习的参数,值得注意的是,这两者往往采用不同的学习率

这样做的优点是显而易见的,即增加鲁棒性,同时鼓励网络进行探索

另外这样可以免去采用 ϵ − g r e e d y \epsilon-greedy ϵgreedy 行动策略,而直接固定选择期望最大的动作行动,因为噪音本身就会鼓励探索,事实证明效果更好

另外在训练结束后,实际决策时把方差设为 0 使之退化回原来的 DQN 就可以了

总结

在实际训练时,我们往往采用以上所有方法的总和,以下摘抄原书

实际编程实现 DQN 的时候, 应该将本章的四种技巧一优先经验回放、双 Q 学习、 对决网络、噪声 DQN一全部用到。应该用对决网络的神经网络结构, 而不是简单的 D Q N \mathrm{DQN} DQN 结构。往对决网络中的参数 w \boldsymbol{w} w 中加人噪声, 得到噪声 D Q N \mathrm{DQN} DQN, 记作 Q ~ ( s , a , ξ ; μ , σ ) \widetilde{Q}(s, a, \boldsymbol{\xi} ; \boldsymbol{\mu}, \boldsymbol{\sigma}) Q (s,a,ξ;μ,σ) 。 训练要用双 Q \mathrm{Q} Q 学习、优先经验回放, 而不是原始的 Q \mathrm{Q} Q 学习。双 Q \mathrm{Q} Q 学习需要目标网络 Q ~ ( s , a , ξ ; μ − , σ − ) \widetilde{Q}\left(s, a, \boldsymbol{\xi} ; \boldsymbol{\mu}^{-}, \boldsymbol{\sigma}^{-}\right) Q (s,a,ξ;μ,σ)计算 TD 目标。它跟噪声 D Q N \mathrm{DQN} DQN 的结构相同, 但是参数不同。
初始的时候, 随机初始化 μ 、 σ \mu 、 \sigma μσ, 并且把它们赋值给目标网络参数: μ − ← μ 、 σ − ← σ 。  \mu^{-} \leftarrow \boldsymbol{\mu} 、 \boldsymbol{\sigma}^{-} \leftarrow \boldsymbol{\sigma}_{\text {。 }} μμσσ  然后重复下面的步骤更新参数。把当前的参数记作 μ now  、 σ now  、 μ now  − 、 σ now  − \boldsymbol{\mu}_{\text {now }} 、 \sigma_{\text {now }} 、 \boldsymbol{\mu}_{\text {now }}^{-} 、 \sigma_{\text {now }}^{-} μnow σnow μnow σnow 

  1. 用优先经验回放, 从数组中抽取一个四元组, 记作 ( s j , a j , r j , s j + 1 ) \left(s_{j}, a_{j}, r_{j}, s_{j+1}\right) (sj,aj,rj,sj+1)
  2. 用标准正态分布生成 ξ \boldsymbol{\xi} ξ 。对噪声 D Q N \mathrm{DQN} DQN 做正向传播, 得到:
    q ^ j = Q ~ ( s j , a j , ξ ; μ now  , σ now  ) . \widehat{q}_{j}=\widetilde{Q}\left(s_{j}, a_{j}, \boldsymbol{\xi} ; \boldsymbol{\mu}_{\text {now }}, \boldsymbol{\sigma}_{\text {now }}\right) . q j=Q (sj,aj,ξ;μnow ,σnow ).
  3. 根据噪声 D Q N \mathrm{DQN} DQN 选出最优动作:
    a ~ j + 1 = argmax ⁡ a ∈ A Q ~ ( s j + 1 , a , ξ ; μ now  , σ now  ) . \tilde{a}_{j+1}=\underset{a \in \mathcal{A}}{\operatorname{argmax}} \widetilde{Q}\left(s_{j+1}, a, \boldsymbol{\xi} ; \boldsymbol{\mu}_{\text {now }}, \boldsymbol{\sigma}_{\text {now }}\right) . a~j+1=aAargmaxQ (sj+1,a,ξ;μnow ,σnow ).
  4. 用标准正态分布生成 ξ ′ \boldsymbol{\xi}^{\prime} ξ 。根据目标网络计算价值:
    q j + 1 ^ = Q ~ ( s j + 1 , a ~ j + 1 , ξ ′ ; μ now  − , σ now  − ) . \widehat{q_{j+1}}=\widetilde{Q}\left(s_{j+1}, \tilde{a}_{j+1}, \boldsymbol{\xi}^{\prime} ; \boldsymbol{\mu}_{\text {now }}^{-}, \boldsymbol{\sigma}_{\text {now }}^{-}\right) . qj+1 =Q (sj+1,a~j+1,ξ;μnow ,σnow ).
  5. 计算 TD 目标和 TD 误差:
    y ^ j − = r j + γ ⋅ q ^ j + 1  和  δ j = q ^ j − y ^ j . \widehat{y}_{j}^{-}=r_{j}+\gamma \cdot \widehat{q}_{j+1} \quad \text { 和 } \quad \delta_{j}=\widehat{q}_{j}-\widehat{y}_{j} . y j=rj+γq j+1  δj=q jy j.
  6. α μ \alpha_{\mu} αμ α σ \alpha_{\sigma} ασ 为学习率。做梯度下降更新噪声 D Q N \mathrm{DQN} DQN 的参数:
    μ new  ← μ now  − α μ ⋅ δ j ⋅ ∇ μ Q ~ ( s j , a j , ξ ; μ now  , σ now  ) σ new  ← σ now  − α σ ⋅ δ j ⋅ ∇ σ Q ~ ( s j , a j , ξ ; μ now  , σ now  ) \begin{aligned} &\boldsymbol{\mu}_{\text {new }} \leftarrow \boldsymbol{\mu}_{\text {now }}-\alpha_{\mu} \cdot \delta_{j} \cdot \nabla_{\mu} \widetilde{Q}\left(s_{j}, a_{j}, \boldsymbol{\xi} ; \boldsymbol{\mu}_{\text {now }}, \boldsymbol{\sigma}_{\text {now }}\right) \\ &\boldsymbol{\sigma}_{\text {new }} \leftarrow \boldsymbol{\sigma}_{\text {now }}-\alpha_{\sigma} \cdot \delta_{j} \cdot \nabla_{\sigma} \widetilde{Q}\left(s_{j}, a_{j}, \boldsymbol{\xi} ; \boldsymbol{\mu}_{\text {now }}, \boldsymbol{\sigma}_{\text {now }}\right) \end{aligned} μnew μnow αμδjμQ (sj,aj,ξ;μnow ,σnow )σnew σnow ασδjσQ (sj,aj,ξ;μnow ,σnow )
  7. τ ∈ ( 0 , 1 ) \tau \in(0,1) τ(0,1) 是需要手动调的超参数。做加权平均更新目标网络的参数:
    μ new  − ← τ ⋅ μ new  + ( 1 − τ ) ⋅ μ now  − , σ new  − ← τ ⋅ σ new  + ( 1 − τ ) ⋅ σ now  − . \begin{aligned} &\boldsymbol{\mu}_{\text {new }}^{-} \leftarrow \tau \cdot \boldsymbol{\mu}_{\text {new }}+(1-\tau) \cdot \boldsymbol{\mu}_{\text {now }}^{-}, \\ &\boldsymbol{\sigma}_{\text {new }}^{-} \leftarrow \tau \cdot \boldsymbol{\sigma}_{\text {new }}+(1-\tau) \cdot \boldsymbol{\sigma}_{\text {now }}^{-} . \end{aligned} μnew τμnew +(1τ)μnow ,σnew τσnew +(1τ)σnow .
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

强化学习 DQN 速成 的相关文章

随机推荐

  • Qt实现2D绘图

    一 介绍 Qt中提供了强大的2D绘图系统 可以使用相同的API在屏幕和绘图设备上进行绘制 它主要基于QPainter QPaintDevice和QPaintEngine这三个类 其中QPainter用来执行绘图操作 QPaintDevice
  • 科技抗老新突破,香港美容仪品牌内地重磅上市

    近年来 新消费时代 颜值经济 的火热促使美容行业市场规模增长迅速 越来越多的人愿意为 美 买单 对美的需求也随之增长 美容行业已经成为成长最快的新锐产业 随着经济和科技的发展 快捷 也成为了当今社会的时代特征 美容行业也从传统的美容院向家用
  • 竞赛选题 opencv 图像识别 指纹识别 - python

    0 前言 优质竞赛项目系列 今天要分享的是 基于机器视觉的指纹识别系统 学长这里给一个题目综合评分 每项满分5分 难度系数 3分 工作量 3分 创新点 4分 该项目较为新颖 适合作为竞赛课题方向 学长非常推荐 更多资料 项目分享 https
  • 前端安装vue-cli报错:npm ERR! notarget No matching version found for vue@cli.

    安装vue cli的版本3以上的内容 命令中 在最前 不在中间 对的命令是npm install g vue cli C Users 15232 gt npm install g vue cli npm ERR code ETARGET n
  • Linux 安装Mysql 详细教程(图文教程)

    首先通过xshell或者 putty 远程进入Linux 命令行操作界面 Xshell 的安装 1 去XShell Download下载需要的版本 XShell免费版 解决官网打不开的问题 百度网盘 https pan baidu com
  • 用6个实例,8段代码,详解Python中的for循环

    目录 前言 01 使用tryexcept的for循环 02 指数运算 03 嵌套的循环 04 在for循环中使用split 函数 1 使用split 函数做单词比较 2 使用split 函数打印指定格式的文本 3 使用split 函数打印固
  • windows 7Z命令行与安装

    7z 全称7 Zip 是一款开源软件 是目前公认的压缩比例最大的压缩解压软件 7z exe在CMD窗口的使用说明如下 7 Zip A 4 57 Copyright c 1999 2007 Igor Pavlov 2007 12 06 Usa
  • colmap代码解读

    clomap是作者在ECCV2016年发表的基于两个概率的深度值和法线估计的论文 开源 下面就开源代码Patch match cuda cu文件做简单的介绍 产生随机法向量和随机深度值 扰动法向量 产生随机三个方位角度 和扰动深度值 根据像
  • 多线程案例(2) - 阻塞队列

    目录 一 阻塞队列 1 1 什么是阻塞队列 1 2 生产者消费者模型 1 3 标准库中的阻塞队列 1 4 阻塞队列的实现 一 阻塞队列 1 1 什么是阻塞队列 阻塞队列 BlockingQueue 是一种特殊的队列 遵循 先进先出 的原则
  • Deep-Learning-YOLOV4实践:ScaledYOLOv4模型训练自己的数据集调试问题总结

    error error1 CUDA out of memory error2 TypeError can t convert cuda error Deep Learning YOLOV4实践 ScaledYOLOv4 数据集制作 Deep
  • 知识库-kafka shell脚本用法

    脚本名称 用途描述 connect distributed sh 连接kafka集群模式 connect standalone sh 连接kafka单机模式 kafka acls sh todo kafka broker api versi
  • 一篇搞定dockerfile定制镜像过程

    一 定制镜像的两种方法 1 docker commit 通过已有容器创建镜像 提交容器快照作为镜像 不推荐 2 docker build 就是本文着重讲的dockerfile创建镜像方式 推荐 docker commit无法还原镜像制作过程
  • 【Linux学习】epoll详解

    什么是epoll epoll是什么 按照man手册的说法 是为处理大批量句柄而作了改进的poll 当然 这不是2 6内核才有的 它是在2 5 44内核中被引进的 epoll 4 is a new API introduced in Linu
  • centos7运行vue项目问题汇总

    一 node踩坑之This is probably not a problem with npm There is likely additional logging output above 错误 解决步骤 1 可能由于种种版本更新的原因
  • windbg 常用命令详解

    一 1 address eax 查看对应内存页的属性 2 vertarget 显示当前进程的大致信息 3 peb 显示process Environment Block 4 lmvm 可以查看任意一个dll的详细信息 例如 我们查看cyus
  • java中List按照指定字段排序工具类

    文章标题 java中List按照指定字段排序工具类 文章地址 http blog csdn net 5iasp article details 17717179 包括如下几个类 1 实体类 package com newyear wish
  • 【C语言】螺旋数组

    螺旋数组的打印 程序C语言代码 更改宏定义的数值即可实现螺旋数组行列的变化 include stdio h define ROW 5 宏定义行 define COL 5 宏定义列 void main int arr ROW COL 0 in
  • Python Decorators(二):Decorator参数

    Python Decorators II Decorator Arguments October 19 2008 本文是Python 3 Patterns Idioms Python3之模式和用法 一书的章节节选第二部分 点击这里阅读第一部
  • Kotlin数据类型(一:数据类型)

    一 Boolean Boolean类型有两种类型的 true flase val a Boolean true val b Boolean false 二 Number数据类型 package net println kotlin auth
  • 强化学习 DQN 速成

    强化学习 DQN 速成 这是对 深度强化学习 王树森 张志华 中 DQN 部分的缩写以及部分内容的个人解读 书中的 DQN 是一个相对终极版本的存在 相信体量会比网络上其他资料要大很多 基本概念 我们通过贪吃蛇来引入几个基本概念 符号 中文