强化学习的数学原理(十)actor-critic 方法
由于全文太长,只好分开发了。(已完结!在专栏查看本系列其他文章)
个人博客可以直接看全文~
本系列为在学习赵世钰老师的“强化学习的数学原理” 课程后所作笔记。
课堂视频链接https://www.bilibili.com/video/BV1sd4y167NS/
第十章 actor-critic 方法
actor-critic本身就是policy gradient
The simplest actor-critic
也称QAC(这里的Q是公式中的q,也就是action value)
policy gradient算法:
θ t + 1 = θ + α ∇ θ J ( θ t ) = θ t + α E S ∼ η , A ∼ π [ ∇ θ l n π ( A ∣ S , θ t ) q π ( S , A ) ] θ t + 1 = θ t + α ∇ θ l n π ( a t ∣ s t , θ t ) q t ( s t , a t ) \begin{aligned} \theta_{t + 1} &= \theta + \alpha \nabla_\theta J(\theta_t) \\ &= \theta _t + \alpha \mathbb E_{S \sim \eta,A \sim \pi}[\nabla _\theta ln \pi(A|S,\theta_t)q_\pi(S,A)] \\ \theta_{t+1} &= \theta_t + \alpha \nabla_\theta ln \pi(a_t|s_t,\theta_t) q_t(s_t,a_t) \end{aligned} θt+1θt+1=θ+α∇θJ(θt)=θt+αES∼η,A∼π[∇θlnπ(A∣S,θt)qπ(S,A)]=θt+α∇θlnπ(at∣st,θt)qt(st,at)
这个更新策略的算法就是actor, critic则用来估计 q t ( s t , a t ) q_t(s_t,a_t) qt(st,at)
如何得到 q t ( s t , a t ) q_t(s_t,a_t) qt(st,at) ?
两种方法:
- MC learning:这样结合就得到了REINFORCE算法。
- Temporal-difference learning: actor-critic算法。
优化目标函数 J ( θ ) J(\theta) J(θ) ,使其最大化。
对于每个episode的第t步,执行如下:
-
遵循 π ( a ∣ s t , θ t ) \pi(a|s_t,\theta_t) π(a∣st,θt) 生成 a t a_t at ,得到( r t + 1 , s t + 1 r_{t+1},s_{t+1} rt+1,st+1) ,然后遵循 π ( a ∣ s t + 1 , θ t ) \pi (a|s_{t+1},\theta_t) π(a∣st+1,θt) 生成 a t + 1 a_{t+1} at+1
-
Critic(value update):
w t + 1 = w t + α w [ r t + 1 + γ q ( s t + 1 , a t + 1 ) , w t ] − q ( s t , a t , w t ) ∇ w q ( s t , a t , w t ) w_{t+1} = w_t + \alpha_w [r_{t+1} + \gamma q(s_{t+1},a_{t+1}),w_t] - q(s_t,a_t,w_t) \nabla_w q(s_t,a_t,w_t) wt+1=wt+αw[rt+1+γq(st+1,at+1),wt]−q(st,at,wt)∇wq(st,at,wt)
Actor (policy update):
θ t + 1 = θ t + α θ ∇ θ l n π ( a t ∣ s t , θ t ) q ( s t , a t , w t + 1 ) \theta_{t+1} = \theta_t + \alpha_\theta \nabla_{\theta} ln \pi (a_t|s_t,\theta_t) q(s_t,a_t,w_{t+1}) θt+1=θt+αθ∇θlnπ(at∣st,θt)q(st,at,wt+1)
这个算法是on-policy 的。
The simplest actor-critic实际上就是 SARSA + value function approximation
advantage actor-critic
也叫AAC ,A2C
首先我们为policy gradient 引入一个新的baseline(b函数)
KaTeX parse error: Invalid color: ' #0000FF' at position 238: …A) - \textcolor{̲ ̲#̲0̲0̲0̲0̲F̲F̲}̲{b(S)})] \end{…
为什么引入新的b 函数,等式依然成立?
因为如下公式成立:
E S ∼ η , A ∼ π [ ∇ θ ln π ( A ∣ S , θ t ) b ( S ) ] = 0 \mathbb E_{S \sim \eta ,A \sim \pi } [\nabla_\theta \ln \pi (A|S,\theta_t)b(S)] = 0 ES∼η,A∼π[∇θlnπ(A∣S,θt)b(S)]=0
详细地说:
E S ∼ η , A ∼ π [ ∇ θ ln π ( A ∣ S , θ t ) b ( S ) ] = ∑ s ∈ S η ( s ) ∑ a ∈ A π ( a ∣ s , θ t ) ∇ θ ln π ( a ∣ s , θ t ) b ( s ) = ∑ s ∈ S η ( s ) ∑ a ∈ A ∇ θ π ( a ∣ s , θ t ) b ( s ) = ∑ s ∈ S η ( s ) b ( s ) ∑ a ∈ A ∇ θ π ( a ∣ s , θ t ) = ∑ s ∈ S η ( s ) b ( s ) ∇ θ ∑ a ∈ A π ( a ∣ s , θ t ) = ∑ s ∈ S η ( s ) b ( s ) ∇ θ 1 = 0 \begin{aligned} \mathbb E_{S \sim \eta ,A \sim \pi } [\nabla_\theta \ln \pi (A|S,\theta_t)b(S)] &= \underset{s \in S}{\sum} \eta(s) \underset{a \in \mathcal A}{\sum} \pi(a|s,\theta_t) \nabla_\theta \ln\pi(a|s,\theta_t) b(s) \\ &= \underset{s \in S}{\sum} \eta(s) \underset{a \in \mathcal A}{\sum} \nabla_\theta \pi (a|s,\theta_t) b(s) \\ &= \underset{s \in S}{\sum} \eta(s) b(s) \underset{a \in \mathcal A}{\sum} \nabla_\theta \pi(a|s,\theta_t) \\ &=\underset{s \in S}{\sum} \eta(s) b(s) \nabla_\theta \underset{a \in \mathcal A}{\sum} \pi(a|s,\theta_t) \\ &= \underset{s \in S}{\sum} \eta(s) b(s) \nabla_\theta 1 =0 \end{aligned} ES∼η,A∼π[∇θlnπ(A∣S,θt)b(S)]=s∈S∑η(s)a∈A∑π(a∣s,θt)∇θlnπ(a∣s,θt)b(s)=s∈S∑η(s)a∈A∑∇θπ(a∣s,θt)b(s)=s∈S∑η(s)b(s)a∈A∑∇θπ(a∣s,θt)=s∈S∑η(s)b(s)∇θa∈A∑π(a∣s,θt)=s∈S∑η(s)b(s)∇θ1=0
引入这个b函数有什么用?
我们说 ∇ θ J ( θ ) = E [ X ] \nabla_\theta J(\theta) = \mathbb E[X] ∇θJ(θ)=E[X]
那么我们知道
- E [ X ] \mathbb E[X] E[X] 和b(S) 无关。
- X的方差和b有关。
所以我们可以通过设置b函数来减小方差。
设置b函数为如下值时,能使得方差最小:
b ∗ ( s ) = E A ∼ π [ ∣ ∣ ∇ θ ln π ( A ∣ s , θ t ) ∣ ∣ 2 q ( s , A ) ∣ ∣ ] E A ∼ π [ ∣ ∣ ∇ θ ln π ( A ∣ s , θ t ) ∣ ∣ 2 ∣ ∣ ] b^* (s) = \frac{\mathbb E_{A\sim \pi }[||\nabla_\theta \ln \pi (A|s,\theta_t)||^2 q(s,A)||]}{\mathbb E_{A\sim \pi }[||\nabla_\theta \ln \pi (A|s,\theta_t)||^2||]} b∗(s)=EA∼π[∣∣∇θlnπ(A∣s,θt)∣∣2∣∣]EA∼π[∣∣∇θlnπ(A∣s,θt)∣∣2q(s,A)∣∣]
其中 ∣ ∣ ∇ θ ln π ( A ∣ s , θ t ) ∣ ∣ 2 ||\nabla_\theta \ln \pi (A|s,\theta_t)||^2 ∣∣∇θlnπ(A∣s,θt)∣∣2 可以被认为是一个权重。
但是这个公式太复杂了。我们一般直接用
b ( s ) = E A ∼ π [ q ( s , A ) ] = v π ( s ) b(s) = \mathbb E_{A \sim \pi}[q(s,A)] = v_\pi(s) b(s)=EA∼π[q(s,A)]=vπ(s)
把上式带入公式中,我们可以得到gradient-ascent算法:
KaTeX parse error: Invalid color: ' #0000FF' at position 111: …t) ( \textcolor{̲ ̲#̲0̲0̲0̲0̲F̲F̲}̲{q_\pi(S,A) - v…
我们叫 δ π ( S , A ) = q π ( S , A ) − v π ( S ) \delta_\pi(S,A) = q_\pi(S,A) - v_\pi(S) δπ(S,A)=qπ(S,A)−vπ(S) 为advantage funciton(优势函数)
v π ( S ) v_\pi(S) vπ(S) 是某个状态下的action的平均值, 所以 δ π ( S , A ) \delta_\pi(S,A) δπ(S,A) 描述了当前的action和同状态的其他action相比的优劣。
公式还可以写成下面:
θ t + 1 = θ t + α ∇ θ ln π ( a t ∣ s t , θ t ) δ t ( s t , a t ) = θ t + α ∇ θ π ( a t ∣ s t , θ t ) π ( a t ∣ s t , θ t ) δ t ( s t , a t ) = θ t + α δ t ( s t , a t ) π ( a t ∣ s t , θ t ) ∇ θ π ( a t ∣ s t , θ t ) \theta_{t+1} = \theta _t + \alpha \nabla_\theta \ln \pi (a_t|s_t,\theta_t) \delta_t(s_t,a_t) \\ = \theta _t + \alpha \frac{\nabla_\theta\pi (a_t|s_t,\theta_t)}{\pi(a_t|s_t,\theta_t)} \delta_t(s_t,a_t) \\ = \theta _t + \alpha \frac{\delta_t(s_t,a_t) }{\pi(a_t|s_t,\theta_t)} \nabla_\theta\pi (a_t|s_t,\theta_t) θt+1=θt+α∇θlnπ(at∣st,θt)δt(st,at)=θt+απ(at∣st,θt)∇θπ(at∣st,θt)δt(st,at)=θt+απ(at∣st,θt)δt(st,at)∇θπ(at∣st,θt)
于是我们公式中的 δ t ( s t , a t ) π ( a t ∣ s t , θ t ) \frac{\delta_t(s_t,a_t) }{\pi(a_t|s_t,\theta_t)} π(at∣st,θt)δt(st,at) 决定了step-size(和第9讲REINFORCE中的 β t \beta_t βt 一样能够很好地平衡 e x p l o r a t i o n exploration exploration 和 e x p l o i t a t i o n exploitation exploitation
A2C ,或者TD actor-critic 的过程:
目标是寻找最大的 J ( θ ) J(\theta) J(θ)
在每个episode的第t时刻,我们执行如下:
-
遵循 π ( a ∣ s t , θ t ) \pi(a|s_t,\theta_t) π(a∣st,θt)生成 a t a_t at 然后得到 r t + 1 , s t + 1 r_{t+1},s_{t+1} rt+1,st+1
-
TD error(advantage function):
δ t = r t + 1 + γ v ( s t + 1 , w t ) − v ( s t , w t ) \delta_t = r_{t+1} + \gamma v(s_{t+1},w_t) - v(s_t,w_t) δt=rt+1+γv(st+1,wt)−v(st,wt)
-
Critic (value update):
w t + 1 = w t + α w δ t ∇ w v ( s t , w t ) w_{t+1} = w_t + \alpha_w \delta_t \nabla_w v(s_t,w_t) wt+1=wt+αwδt∇wv(st,wt)
-
Actor(plicy update):
θ t + 1 = θ t + α θ δ t ∇ θ ln π ( a t ∣ s t , θ t ) \theta_{t+1} = \theta_t + \alpha_\theta \delta_t \nabla_\theta \ln \pi (a_t|s_t,\theta_t) θt+1=θt+αθδt∇θlnπ(at∣st,θt)
这是一个on-policy 的。
off-policy actor-critic
Policy gradient是on-policy的原因是梯度必须服从 π \pi π 策略,这里的 π \pi π 既是behavior policy ,同时这个 π \pi π 也是我们要更新的target policy。
可以使用importance sampling 来把on-policy转为off-policy。
E X ∼ p 0 [ X ] = ∑ x p 0 ( x ) x = ∑ x p 1 ( x ) p 0 ( x ) p 1 ( x ) x = E X ∼ p 1 [ f ( X ) ] \mathbb E_{X \sim p_0} [X] = \underset{x}{\sum}p_0(x)x = \underset{x}{\sum} p_1(x) \frac{p_0(x)}{p_1(x)}x = \mathbb E_{X\sim p_1} [f(X)] EX∼p0[X]=x∑p0(x)x=x∑p1(x)p1(x)p0(x)x=EX∼p1[f(X)]
于是我们就可以通过 p 1 p_1 p1 进行采样,然后估计 p 0 p_0 p0 采样下的均值。 那么热和计算$ \mathbb E_{X\sim p_1} [f(X)]$ ?
令f为如下函数:
f = 1 n ∑ n i = 1 f ( x i ) , where x i ∼ p i f = \frac{1}{n} \underset{i = 1}{\overset{n}{\sum}} f(x_i) , \text{where } x_i \sim p_i f=n1i=1∑nf(xi),where xi∼pi
那么就有
E X ∼ p 1 [ f ‾ ] = E X ∼ p 1 [ f ( X ) ] v a r X ∼ p 1 [ f ‾ ] = 1 n v a r X ∼ p 1 [ f ( X ) ] \begin{aligned} \mathbb E_{X \sim p_1}[\overline f] &= \mathbb E _{X \sim p_1} [f(X)] \\ var_{X \sim p _ 1} [\overline f] &= \frac{1}{n} var_{X \sim p _1}[f(X)] \end{aligned} EX∼p1[f]varX∼p1[f]=EX∼p1[f(X)]=n1varX∼p1[f(X)]
所以 f ‾ \overline f f (f的平均数)就可以用来估计 E X ∼ p 1 [ f ‾ ] = E X ∼ p 0 [ X ] \mathbb E_{X \sim p_1}[\overline f] = \mathbb E _{X \sim p_0} [X] EX∼p1[f]=EX∼p0[X]
E X ∼ p 0 [ X ] ≈ f ‾ = 1 n ∑ n i = 1 f ( x i ) = 1 n ∑ n i = 1 p 0 ( x i ) p 1 ( x i ) x i \mathbb E_{X \sim p_0} [X] \approx \overline f = \frac{1}{n}\underset{i = 1}{\overset{n}{\sum}} f(x_i) = \frac{1}{n} \underset{i = 1}{\overset{n}{\sum}}\frac{p_0(x_i)}{p_1(x_i) }x_i EX∼p0[X]≈f=n1i=1∑nf(xi)=n1i=1∑np1(xi)p0(xi)xi
这里的 p 0 ( x i ) p 1 ( x i ) \frac{p_0(x_i)}{p_1(x_i) } p1(xi)p0(xi) 可以被认为是权重,那么直观地看就是对于 p 0 p_0 p0 相对难取的样本,赋予更高的权重。
这个权重叫做 importance权重。
就是因为我们只能知道 p 0 ( x ) p_0(x) p0(x) ,但求不出 E X ∼ o 0 [ X ] \mathbb E_{X \sim o_0}[X] EX∼o0[X] , 所以才需要importance sampling。
假设 β \beta β 是behavior policy生成的经验采样。
我们的目标是更新target policy π \pi π 来最大化 J ( θ ) J(\theta) J(θ)
J ( θ ) = ∑ s ∈ S d β ( s ) v π ( s ) = E S ∼ d β [ v π ( S ) ] J(\theta) = \underset{s \in S}{\sum} d_\beta(s) v_\pi(s) = \mathbb E _{S \sim d_\beta} [v_\pi (S)] J(θ)=s∈S∑dβ(s)vπ(s)=ES∼dβ[vπ(S)]
他的梯度如下:
∇ θ J ( θ ) = E S ∼ ρ , A ∼ β [ π ( A ∣ S , θ ) β ( A ∣ S ) ∇ θ ln π ( A ∣ S , θ ) q π ( S , A ) ] \nabla _\theta J(\theta) = \mathbb E_{S \sim \rho,A \sim \beta} [\frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla_\theta \ln \pi(A|S,\theta)q_\pi(S,A)] ∇θJ(θ)=ES∼ρ,A∼β[β(A∣S)π(A∣S,θ)∇θlnπ(A∣S,θ)qπ(S,A)]
这里的 β \beta β 是behavior policy , ρ \rho ρ 是state distribution。
优化:
我们仍然可以通过加上baseline来进行优化:$\delta \pi(S,A) = q\pi(S,A) - v_\pi(S) $ 。
θ t + 1 = θ t + α θ π ( a t ∣ s t , θ t ) β ( a t ∣ s t ) ∇ θ ln π ( a t ∣ s t , θ t ) ( q t ( s t , a t ) − v t ( s t ) ) \theta_{t+1} = \theta_t + \alpha_\theta \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \nabla_\theta \ln \pi(a_t|s_t,\theta_t) (q_t(s_t,a_t) - v_t (s_t)) θt+1=θt+αθβ(at∣st)π(at∣st,θt)∇θlnπ(at∣st,θt)(qt(st,at)−vt(st))
在这之中
q t ( s t , a t ) − v t ( s t ) ≈ r t + 1 + γ v t ( s t + 1 ) − v t ( s t ) = δ t ( s t , a t ) q_t (s_t,a_t) - v_t(s_t) \approx r_{t+1} + \gamma v_t(s_{t+1}) - v_t(s_t) = \delta_t(s_t,a_t) qt(st,at)−vt(st)≈rt+1+γvt(st+1)−vt(st)=δt(st,at)
于是最终的算法就是
θ t + 1 = θ t + α θ δ t ( s t , a t ) β ( a t ∣ s t ) ∇ θ ln π ( a t ∣ s t , θ t ) π ( a t ∣ s t , θ t ) \theta_{t+1} = \theta_t + \alpha_\theta \frac{\delta_t (s_t,a_t)}{\beta(a_t|s_t)} \nabla_\theta \ln \pi(a_t|s_t,\theta_t) \pi(a_t|s_t,\theta_t) θt+1=θt+αθβ(at∣st)δt(st,at)∇θlnπ(at∣st,θt)π(at∣st,θt)
Deterministic actor-critic
DPG和之前的(QAC,A2C、off-policy的actor-critic)相比的一大特点就是他的策略 π ( a ∣ s , θ ) \pi(a|s,\theta) π(a∣s,θ) 可以是负数。
于是我们用deterministic policies来解决continuous action(无限个的、连续的action)
之前我们是通过策略 π ( a ∣ s , θ ) ∈ [ 0 , 1 ] \pi(a|s,\theta) \in [0,1] π(a∣s,θ)∈[0,1] 来决定要采取哪个动作a。
而现在我们改成下面这样:
a = μ ( s , θ ) a = \mu (s,\theta) a=μ(s,θ)
意味着我们直接通过s得到a的值,而不是借助每一个action的概率来决定选择哪个a。
J ( θ ) = E [ v μ ( s ) ] = ∑ s ∈ S d 0 ( s ) v μ ( s ) J(\theta) = \mathbb E [v_\mu (s)] = \underset{s \in S}{\sum} d_0 (s)v_\mu (s) J(θ)=E[vμ(s)]=s∈S∑d0(s)vμ(s)
d 0 d_0 d0 的选择和 μ \mu μ 无关。
选择 d 0 d_0 d0的两种特殊的情况:
- d 0 ( s 0 ) − 1 d_0(s_0) - 1 d0(s0)−1 , d 0 ( s ≠ s 0 ) = 0 d_0(s \not = s_0) = 0 d0(s=s0)=0 . 在这里 s 0 s_0 s0 是一个特殊的开始状态。
- d 0 d_0 d0 取决于behavior policy 在 μ \mu μ 上的内容。
∇ θ J ( θ ) = ρ μ ( s ) ∇ θ μ ( s ) ( ∇ a q μ ( s , a ) ) ∣ a = μ ( s ) s ∈ S = E S ∼ ρ μ [ ∇ θ μ ( s ) ( ∇ a q μ ( s , a ) ) ∣ a = μ ( s ) ] \begin{aligned} \nabla_\theta J(\theta) &= \underset{s \in S}{\rho_\mu(s) \nabla_\theta \mu(s)(\nabla_a q_\mu(s,a))|_{a = \mu(s)}} \\ &= \mathbb E_{S \sim \rho_\mu} [\nabla_\theta \mu(s)(\nabla_a q_\mu(s,a))|_{a = \mu(s)}] \end{aligned} ∇θJ(θ)=s∈Sρμ(s)∇θμ(s)(∇aqμ(s,a))∣a=μ(s)=ES∼ρμ[∇θμ(s)(∇aqμ(s,a))∣a=μ(s)]
这里面的梯度没有action A。
所以这个deterministic policy gradient 是一个off-policy的方法。(因为我们不需要关心这个a是通过哪个策略得到的)
梯度上升:
θ t + 1 = θ t + α θ E S ∼ ρ μ [ ∇ θ μ ( s ) ( ∇ a q μ ( s , a ) ) ∣ a = μ ( s ) ] θ t + 1 = θ t + α θ ∇ θ μ ( s t ) ( ∇ a q μ ( s t , a ) ) ∣ a = μ ( s ) \theta_{t+1} = \theta_t + \alpha_\theta \mathbb E_{S \sim \rho_\mu} [\nabla_\theta \mu(s)(\nabla_a q_\mu(s,a))|_{a = \mu(s)}] \\ \theta_{t+1} = \theta_t + \alpha_\theta \nabla_\theta \mu(s_t) (\nabla _a q_\mu (s_t,a))|_{a = \mu(s)} θt+1=θt+αθES∼ρμ[∇θμ(s)(∇aqμ(s,a))∣a=μ(s)]θt+1=θt+αθ∇θμ(st)(∇aqμ(st,a))∣a=μ(s)
注意:
-
β \beta β 和 μ \mu μ 是不同的。
-
β \beta β 也可以设置为 μ + n o i s e \mu + noise μ+noise.
如何选取 q ( s , a , w ) q(s,a,w) q(s,a,w) ?
- 线性函数: q ( s , a , w ) = ϕ T ( s , a ) w q(s,a,w) = \phi^T(s,a)w q(s,a,w)=ϕT(s,a)w
- 神经网络:DDPG
相关文章:
强化学习的数学原理(十)actor-critic 方法
由于全文太长,只好分开发了。(已完结!在专栏查看本系列其他文章) 个人博客可以直接看全文~ 本系列为在学习赵世钰老师的“强化学习的数学原理” 课程后所作笔记。 课堂视频链接https://www.bilibili.com/video/BV1sd4y167NS/ 第十章 acto…...
多个定时器同时工作时,会出现哪些常见的bug ,如何解决??(定时任务未实时更新但刷新后正常的问题分析)
1. 定时器冲突与覆盖 问题:后设置的定时器可能覆盖先前的定时器,导致前一个定时器失效 原因:未正确管理定时器ID或未清除前一个定时器 2. 性能问题 内存泄漏:未清除不再需要的定时器会导致内存占用不断增加 CPU过载:…...
代码随想录算法训练营day5(哈希表)
华子目录 有效的字母异位词思路 有效的字母异位词 https://leetcode.cn/problems/valid-anagram/description/ 思路 使用哈希表,这里哈希表使用数组先申请一个26空间的大小的数组遍历第一个字符串,记录每个字符出现的次数1遍历第二个字符串,…...
Python(17)Python字符编码完全指南:从存储原理到乱码终结实战
目录 背景介绍一、字符编码核心原理1. 计算机存储本质2. Python3的编码革命3. 主流编码格式对比 二、编码转换核心方法1. 编码(Encode)过程2. 解码(Decode)过程3. 错误处理策略 三、文件操作编码实战1. 文本文件读写2. 二进制模式…...
Node.js 文件读取与复制相关内容
Node.js 文件读取与复制相关内容的系统总结,包括 同步读取、异步读取、流式读取、复制操作、两者对比及内存测试。 🧩 一、Node.js 文件读取方式总结 Node.js 使用 fs(文件系统)模块进行文件操作: 1. 同步读取&#…...
大数据面试问答-HBase/ClickHouse
1. HBase 1.1 概念 HBase是构建在Hadoop HDFS之上的分布式NoSQL数据库,采用列式存储模型,支持海量数据的实时读写和随机访问。适用于高吞吐、低延迟的场景,如实时日志处理、在线交易等。 RowKey(行键) 定义…...
jupyter 文件浏览器,加强版,超好用,免费exe
第一步:github搜索 lukairui的 jupyter-viewer-plus 仓库 第二步: git clone 到本地。 解压zip包 第三步: 进入压缩包,第一次双击打开jupyter-viewer-plus.exe运行,第一次运行后,界面上有一个“设为…...
【AI工具】用大模型生成脑图初试
刚试用了一下通过大模型生成脑图,非常简单,记录一下 一、用大模型生成脑图文件 关键:存在markdown文件 举例:使用Deepseek,输入问题:“针对大模型的后训练,生成一个开发计划,用ma…...
数据结构-树与二叉树
一、树的定义与基本术语 1.1 树的定义 树(Tree)是一种非线性的数据结构,它是由 n(n ≥ 0)个有限节点组成的集合。如果 n 0,称为空树;如果 n > 0,则: 有一个特定的节…...
STL_unordered_map_01_基本用法
👋 Hi, I’m liubo👀 I’m interested in harmony🌱 I’m currently learning harmony💞️ I’m looking to collaborate on …📫 How to reach me …📇 sssssdsdsdsdsdsdasd🎃 dsdsdsdsdsddfsg…...
ARCGIS国土超级工具集1.5更新说明
ARCGIS国土超级工具集V1.5版本更新说明:因作者近段时间工作比较忙及正在编写ARCGISPro国土超级工具集(截图附后)的原因,故本次更新为小更新(没有增加新功能,只更新了已有的工具)。本次更新主要修…...
主流物理仿真引擎和机器人/强化学习仿真平台对比
以下是当前主流的物理仿真引擎和机器人/强化学习仿真平台的特点和适用场景,方便根据需求选择: 🧠 NVIDIA 系列 ✅ Isaac Lab v1.4 / v2 特点: 基于 Omniverse Isaac Sim,属于高端视觉机器人仿真框架v2 更加模块化&a…...
STM32 HAL库内部 Flash 读写实现
一、STM32F407 内部 Flash 概述 1.1 Flash 存储器的基本概念 Flash 存储器是一种非易失性存储器,它可以在掉电的情况下保持数据。STM32F407 系列微控制器内部集成了一定容量的 Flash 存储器,用于存储程序代码和数据。Flash 存储器具有擦除和编程次数的…...
C++学习:六个月从基础到就业——面向对象编程:构造函数与析构函数
C学习:六个月从基础到就业——面向对象编程:构造函数与析构函数 本文是我C学习之旅系列的第十篇技术文章,主要讨论C中构造函数与析构函数的概念、特点和使用技巧。这些是C对象生命周期管理的关键组成部分。查看完整系列目录了解更多内容。 引…...
dfs二叉树中的深搜(回溯、剪枝)--力扣129、814、230、257
目录 1.1题目链接:129.求根节点到叶结点数字之和 1.2题目描述:给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。 1.3解法(dfs-前序遍历): 2.1题目链接:814.二叉树剪枝 2.2题目描述&…...
Python Selenium 一小时速通教程
Python Selenium 一小时速通教程 实战案例 一、环境配置(10分钟) 安装Python 确保已安装Python 3.x(官网下载)。 安装Selenium 在终端运行: pip install selenium下载浏览器驱动 Chrome:访问 ChromeDriv…...
通过GO后端项目实践理解DDD架构
最近在工作过程中重构的项目要求使用DDD架构,在网上查询资料发现教程五花八门,并且大部分内容都是长篇的概念讲解,晦涩难懂,笔者看了一些github上入门的使用DDD的GO项目,并结合自己开发中的经验,谈谈自己对…...
MybatisPlus最新版分页无法使用
在使用分页的时候发现分页拦截器关键API会报错,其实根本原因是在之前只需要导入一个mybatisplus依赖,而现在分页似乎被单独分离出来了,需要额外导入新依赖使其支持 <dependency><groupId>com.baomidou</groupId><art…...
【Android学习记录】工具使用
文章目录 一. 精准找视图资源ID1. 准备工作2. 使用 uiautomator 工具2.1. 获取设备的窗口内容2.2. Pull XML 文件2.3. 查看 XML 文件 3. 直接使用 ADB 命令4. 使用 Android Studio 的 Layout Inspector总结 二. adb shell dumpsys activity1. 如何使用 ADB 命令2. 输出内容解析…...
youtube视频和telegram视频加载原理差异分析
1. 客户侧缓存与流式播放机制 流式视频应用(如 Netflix、YouTube)通过边下载边播放实现流畅体验,其核心依赖以下技术: 缓存预加载:客户端在后台持续下载视频片段(如 DASH/HLS 协议的…...
在机器视觉检测中为何选择线阵工业相机?
线阵工业相机,顾名思义是成像传感器呈“线”状的。虽然也是二维图像,但极宽,几千个像素的宽度,而高度却只有几个像素的而已。一般在两种情况下使用这种相机: 1. 被测视野为细长的带状,多用于滚筒上检测的问…...
lwip记录
Index of /releases/lwip/ (gnu.org) 以太网(Ethernet)是互联网技术的一种,由于它是在组网技术中占的比例最高,很多人 直接把以太网理解为互联网。 以太网是指遵守 IEEE 802.3 标准组成的局域网,由 IEEE 802.3 标准规定的主要是位于 参考模…...
Redis清空缓存
尽管redis可以设置ttl过期时间进行指定key的定时删除,但是在某些场景下,比如: 测试时需要批量删除指定库下所有库下所有的数据,则会涉及到缓存清除的话题。 如下为具体的操作及说明: 场景类型操作指令清空当前库下所有…...
WPF 依赖注入启动的问题
原因是在App.xaml 设置了 StartupUri“MainWindow.xaml” 1.依赖注入后启动的主窗体存在无参构造 程序正常启动,但是主窗体界面会弹出2个窗体。 2.依赖注入后启动的主窗体存在有参构造 报错...
Arcgis经纬线标注设置(英文、刻度显示)
在arcgis软件中绘制地图边框,添加经纬度度时常常面临经纬度出现中文,如下图所示: 解决方法,设置一下Arcgis的语言 点击高级--确认 这样Arcgis就转为英文版了,此时在来看经纬线刻度的标注,自动变成英文...
【电子通识】案例:电缆的安装方式也会影响设备的可靠性?
背景 在日常生活中,我们常常会忽略一些看似微不足道的细节,但这些细节有时却能决定设备的寿命和安全性。比如,你知道吗?一根电缆的布置方式,可能会决定你的设备是否会因为冷凝水而损坏。 今天,我们就来聊聊…...
房屋装修费用预算表:45594 =未付14509 + 付清31085【时间:20250416】
文章目录 引言I 房屋装修费用预算表II 市场价参考防水搬运3000III 装修计划整体流程进度细节国补IV 付款凭证(销售单)伟星 PPR +PVC+太阳线+地漏=6500入户门设计通铺大板瓷砖 | 湿贴 3408(地)+3600(加)+5209(墙)=12217元门头铁空调引言 关注我,发送【装修记账】获取预…...
Python文件操作完全指南:从基础到高级应用
目录 一、文件基础概念 1.1 什么是文件? 1.2 文件的存储方式 文本文件 二进制文件 二、Python文件操作基础 2.1 文件操作三步曲 2.2 核心函数与方法 2.3 文件读取详解 基本读取示例 文件指针机制 2.4 文件打开模式 写入文件示例 2.5 高效读取大文件 三…...
03(总)-docker篇 Dockerfile镜像制作(jdk,jar)与jar包制作成docker容器方式
全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.2 上文传送门 2. docker镜像制作一: jdk2.1 制作jdk镜像2.1.1 准备工作2.1.2 jdk镜像的Dockerfile2.1.3 基于Dockerfile构建镜像2.1.4 docker使用镜像运行容器2.1.5 进入jdk1.8容器内测试 3. docker镜像制作二: java镜像(jar包)…...
CUDA的安装
打开nvidia控制面板 找到组件 打开 CUDA Toolkit Archive | NVIDIA Developer 下载CUDA...
四六级听力调频广播有线传输无线覆盖系统:弥补单一发射系统安全缺陷,构建稳定可靠听力系统平台
四六级听力调频广播有线传输无线覆盖系统:弥补单一发射系统安全缺陷,构建稳定可靠听力系统平台 北京海特伟业科技有限公司任洪卓发布于2025年4月16日 随着英语四六级考试的规模不断扩大,听力考试部分的设备可靠性问题日益凸显。传统的无线发射系统存在…...
信创服务器-大国崛起,信创当道!
信创产业是数据安全、网络安全的基础,也是新基建的重要组成部分。在政策的推动下,2020-2022 年,中国信创服务器出货量整体呈现出快速增长的趋势,其中党政、电信、金融等领域采购频次高,单次采购量大,是中国…...
【仿Mudou库one thread per loop式并发服务器实现】SERVER服务器模块实现
SERVER服务器模块实现 1. Buffer模块2. Socket模块3. Channel模块4. Poller模块5. EventLoop模块5.1 TimerQueue模块5.2 TimeWheel整合到EventLoop5.1 EventLoop与线程结合5.2 EventLoop线程池 6. Connection模块7. Acceptor模块8. TcpServer模块 1. Buffer模块 Buffer模块&…...
冒泡与 qsort 排序策略集
今天我们要学习两种排序方法,分别是冒泡排序和qsort函数排序,冒泡排序相对qsort函数排序要简单一点,更易于理解。 1.冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复遍历元素列并比较相邻元素来实现排…...
【Linux】第七章 控制对文件的访问
目录 1. 什么是文件系统权限?它是如何工作的?如何查看文件的权限? 2. 解释‘-rw-r--r--’这个字符串。 3. 使用什么命令可以更改文件和目录的权限?写出分别使用符号法和数值法将权限从 754 修改为 775 的命令。 4. 如何修改文…...
网站301搬家后谷歌一直不收录新页面怎么办?
当网站因更换域名或架构调整启用301重定向后,许多站长发现谷歌迟迟不收录新页面,甚至流量大幅下滑。 例如,301跳转设置错误可能导致权重传递失效,而新站内容与原站高度重复则可能被谷歌判定为“低价值页面”。 即使技术层面无误&a…...
socket 客户端和服务器通信
服务器 using BarrageGrab; using System; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace Lyx {class Server{private TcpListener listener;private Concurre…...
C实现md5功能
md5在线验证: 在线MD5计算_ip33.com 代码如下: #include "md5.h" #include <string.h> #include "stdio.h"/** 32-bit integer manipulation macros (little endian)*/ #ifndef GET_ULONG_LE #define GET_ULONG_LE(n,b,i) …...
【项目】CherrySudio配置MCP服务器
CherrySudio配置MCP服务器 (一)Cherry Studio介绍(二)MCP服务环境搭建(1)环境准备(2)依赖组件安装<1> Bun和UV安装 (3)MCP服务器使用<1> 搜索MCP…...
第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能
反模式:滥用导致的内存开销React 19编译器自动Memoization原理 React Hooks 性能优化进阶:从手动到自动 Memoization (基于 React 18 及以下版本,结合 React 19 新特性分析) 一、useMemo/useCallback 的正确使用场景…...
【Qt】QWidget 核⼼属性详解
🍑个人主页:Jupiter. 🚀 所属专栏:QT 欢迎大家点赞收藏评论😊 目录 🏝 一.相关概念🎨二. 核⼼属性概览🍄2.1 enabled🥭2.2geometry🌸 2.3 windowTitle&#…...
如何知道raid 有问题了
在 Rocky Linux 8 上,你的服务器使用了 RAID5(根据 lsblk 输出,/dev/sda3、/dev/sdb1 和 /dev/sdc1 组成 md127 RAID5 阵列)。为了监控 RAID5 阵列中磁盘的健康状态,并及时发现某块磁盘损坏,可以通过以下方…...
操作系统之shell实现(上)
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
精益数据分析(3/126):用数据驱动企业发展的深度解析
精益数据分析(3/126):用数据驱动企业发展的深度解析 大家好!一直以来,我都坚信在当今竞争激烈的商业环境中,数据是企业获得竞争优势的关键。最近深入研究《精益数据分析》这本书,收获颇丰&…...
React 18/19 使用Ant Design全局弹窗message
react 18 及以上,拥有并发模式,不允许在渲染过程中直接触发副作用(如弹窗、网络请求等),应将其放至 useEffect 中,确保其在渲染完成后调用 useEffect(() > {message.success(操作成功!);}, …...
【spark3.2.4】--完全分布式集群搭建
一、spark-env.sh 文件配置(操作路径:$SPARK_HOME/conf/spark-env.sh) 如果还没创建: cp $SPARK_HOME/conf/spark-env.sh.template $SPARK_HOME/conf/spark-env.sh然后编辑(比如用 vim): vim…...
Web3技术下数字资产数据保护的实践探索
在这个信息爆炸的时代,数字资产已经成为我们生活中不可或缺的一部分。随着Web3技术的兴起,它以其去中心化、透明性和安全性的特点,为数字资产的管理和保护提供了新的解决方案。本文将探讨Web3技术在数字资产数据保护方面的实践探索࿰…...
灰度共生矩阵(GLCM)简介
灰度共生矩阵(GLCM)简介 1. 基本概念 灰度共生矩阵(Gray-level Co-occurrence Matrix, GLCM)是一种用于分析图像纹理特征的统计方法。它通过计算图像中特定空间关系的像素对出现的频率,来描述纹理的规律性1。 核心思想:统计图像中相距为d、方向为θ的两个像素点,分别具…...
基于javaEE+jqueryEasyUi+eclipseLink+MySQL的课程设计客房管理信息系统
1. 系统概述 1.1 系统功能概述 1)客户管理。能够增加一个客户,包括:身份证号、客户名称、出生年月、性别、联系电话、邮箱、会员类别等信息,默认会员类别为空;能够修改和删除客户信息;能够根据客户名称、联系电话查询…...
3款本周高潜力开源AI工具(多模态集成_隐私本地化)
本周聚焦 AI 技术领域,为开发者精选 3 款兼具创新性与实用性的开源项目。这些项目覆盖图像生成、智能助手、大语言模型框架等方向,通过技术突破解决开发痛点,助力开发者高效构建智能应用。 更多精彩科技推荐请点击->:更多精彩科…...