多臂老虎机介绍【Multi-armed Bandits】

强化学习笔记

主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程,个人觉得赵老师的课件深入浅出,很适合入门.

第一章 强化学习基本概念
第二章 贝尔曼方程
第三章 贝尔曼最优方程
第四章 值迭代和策略迭代
第五章 强化学习实践—GridWorld
第六章 蒙特卡洛方法
第七章 Robbins-Monro算法
第八章 多臂老虎机


文章目录

  • 强化学习笔记
  • 一、问题描述
  • 二、动作值函数的估计
  • 三、 ϵ \epsilon ϵ-greedy策略
  • 四、UCB算法
  • 五、 非平稳老虎机
  • 六、总结
  • 七、参考文献


Bandit(老虎机、赌博机)问题是强化学习领域中的一个经典问题,老虎机是一种用于赌博的机器,下拉老虎机的机械手臂,我们可以随机获得一个奖励。在赌场中,我们常常能看见很多老虎机被摆在一排,我们可以选择去下拉其中任何一只手臂,在强化学习中我们称为多臂老虎机(Multi-armed Bandits)问题,后面缩写为abd

一、问题描述

在abd问题中,每个老虎机的奖励值 r 的分布 P ( r ∣ a ) P(r|a) P(ra)​,它对于不同的老虎机来说是不同的,但是对某一台老虎机来说是固定的。比如是10-armed bandits,那么我们知道:

  • 动作空间 A \mathcal{A} A 0 , 1 , 2 , ⋯   , 9. 0,1,2,\cdots,9. 0,1,2,,9.
  • 奖励:通常设置为正太分布 r i ∼ N ( q i , 1 ) , i = 0 , 1 , 2 , ⋯   , 9. r_i\sim \mathcal{N}(q_i, 1),i=0,1,2,\cdots,9. riN(qi,1)i=0,1,2,,9.
  • 状态空间:显然这个问题是一个简化的MDP,可以视为没有状态空间.

如下图所示,10个老虎机的奖励分布都是方差为1的正太分布,但是均值不同。

截屏2024-04-23 19.16.20

我们在一开始是不知道每台老虎机的奖励分布 P ( r ∣ a ) P(r|a) P(ra)(模型未知),而只能通过不断的实验和尝试来增进对分布的了解。假设我们实验n次,在每一次选择一个动作 A t ∈ A A_t\in\mathcal{A} AtA,然后得到一个奖励 R t ∼ r i R_t\sim r_i Rtri,得到如下的序列:
A 1 , R 1 , A 2 , ⋯   , A n , R n . A_1,R_1,A_2,\cdots,A_n,R_n. A1,R1,A2,,An,Rn.我们的目标是最大化累积回报:
G n = ∑ t = 1 n R t . G_n=\sum_{t=1}^{n}R_t. Gn=t=1nRt.所以关键的问题是如何学习一个策略,使得尽量多的选择回报值更高的bandit,而这里就又涉及到ExplorationExploitation的问题了。因为当n给定时,想要获得最大累积回报,是尽可能多的利用当前信息选择最优动作,还是多探索了解更多的信息呢,这也是不同算法所关心的问题。

二、动作值函数的估计

显然在abd问题中,我们需要估计 q ( s , a ) q(s,a) q(s,a),但这个问题没有 s s s,所以可以简记为 q ( a ) q(a) q(a)。通过前面介绍的Monte-calro方法(蒙特卡洛方法),我们自然地可以想到用均值 Q n ( a ) Q_n(a) Qn(a)来近似期望 q ( a ) q(a) q(a)
Q n ( a ) ≐ 在时间 n 前选择动作 a 的奖励值的总和 在时间 n 前动作 a 被选择的次数 = ∑ i = 1 n − 1 R i ⋅ 1 A i = a ∑ i = 1 n − 1 1 A i = a , Q_n(a)\doteq\frac{\text{在时间 n 前选择动作 a 的奖励值的总和}}{\text{在时间 n 前动作 a 被选择的次数}}=\frac{\sum_{i=1}^{n-1}R_i\cdot\mathbb{1}_{A_i=a}}{\sum_{i=1}^{n-1}\mathbb{1}_{A_i=a}}, Qn(a)在时间 n 前动作 a 被选择的次数在时间 n 前选择动作 a 的奖励值的总和=i=1n11Ai=ai=1n1Ri1Ai=a,其中 1 x \mathbb{1}_x 1x 的值在 x x x 为真时为 1, 否则为 0。我们来看单个老虎机的 Q n ( a ) Q_n(a) Qn(a)怎么计算:
Q n + 1 ( a ) ≐ R 1 + R 2 + ⋯ + R n n . Q_{n+1}(a)\doteq\frac{R_1+R_2+\cdots+R_{n}}{n}. Qn+1(a)nR1+R2++Rn.
由前面介绍的Robbins-Monro算法,我们知道上式可以写成迭代的格式:
Q n + 1 ( a ) = Q n ( a ) − 1 n ( Q n ( a ) − R n ) ( 1 ) Q_{n+1}(a)=Q_n(a)-\frac1n(Q_n(a)-R_n) \qquad(1) Qn+1(a)=Qn(a)n1(Qn(a)Rn)(1)其中 Q 1 Q_1 Q1是初始给定的,迭代的形式可以减少内存和计算的消耗。由RM算法我们知道,如果我们有无限的时间步长,那么就可以保证 Q n ( a ) Q_n(a) Qn(a) 收敛为 q ( a ) q(a) q(a)。我们知道(1)式更一般的形式如下:
Q n + 1 = Q n − α n ( Q n − R n ) , ( 2 ) Q_{n+1}=Q_n-\alpha_n(Q_n-R_n),\qquad(2) Qn+1=Qnαn(QnRn),(2)其中 a n a_n an为步长参数,由RM算法我们知道,要使算法收敛 a n a_n an需要满足:
∑ 1 ∞ α n = ∞ , ∑ 1 ∞ α n 2 < ∞ . ( 3 ) \sum_1^\infty\alpha_n=\infty, \qquad\sum_1^\infty\alpha_n^2<\infty.\qquad(3) 1αn=,1αn2<∞.(3) α n = 1 n \alpha_n=\frac1n αn=n1是满足上述条件的,但是这种取法是比较适合平稳的abd问题,也就是说每个老虎机的奖励分布不随时间改变。但是我们经常会遇到非平稳的强化学习问题,在这种情况下,给予近期奖励比过往奖励更大的权重是更合适的,最流行的方法之一是使用恒定的步长参数,即:
Q n + 1 = Q n − α ( Q n − R n ) , ( 4 ) Q_{n+1}=Q_n-\alpha(Q_n-R_n),\qquad(4) Qn+1=Qnα(QnRn),(4)通过递推,可以得到:
Q n + 1 = Q n + α ( R n − Q n ) = α R n + ( 1 − α ) Q n = α R n + ( 1 − α ) [ α R n − 1 + ( 1 − α ) Q n − 1 ] = α R n + ( 1 − α ) α R n − 1 + ( 1 − α ) 2 Q n − 1 = α R n + ( 1 − α ) α R n − 1 + ( 1 − α ) 2 α R n − 2 + ⋯ + ( 1 − α ) n − 1 α R 1 + ( 1 − α ) n Q 1 = ( 1 − α ) n Q 1 + ∑ i = 1 n α ( 1 − α ) n − i R i . \begin{aligned} Q_{n+1} &= Q_{n}+\alpha(R_{n}-Q_{n}) \\ &=\alpha R_n+(1-\alpha)Q_n \\ &=\alpha R_n+(1-\alpha)\left[\alpha R_{n-1}+(1-\alpha)Q_{n-1}\right] \\ & =\alpha R_{n}+(1-\alpha)\alpha R_{n-1}+(1-\alpha)^{2}Q_{n-1} \\ &=\alpha R_n+(1-\alpha)\alpha R_{n-1}+(1-\alpha)^2\alpha R_{n-2}+ \\ &\qquad\cdots+(1-\alpha)^{n-1}\alpha R_1+(1-\alpha)^nQ_1 \\ &=(1-\alpha)^nQ_1+\sum_{i=1}^n\alpha(1-\alpha)^{n-i}R_i. \end{aligned} Qn+1=Qn+α(RnQn)=αRn+(1α)Qn=αRn+(1α)[αRn1+(1α)Qn1]=αRn+(1α)αRn1+(1α)2Qn1=αRn+(1α)αRn1+(1α)2αRn2++(1α)n1αR1+(1α)nQ1=(1α)nQ1+i=1nα(1α)niRi.注意到 ( 1 − α ) n + ∑ i = 1 n α ( 1 − α ) n − i = 1 (1-\alpha)^n+\sum_{i=1}^n\alpha(1-\alpha)^{n-i}=1 (1α)n+i=1nα(1α)ni=1,所以 Q n + 1 Q_{n+1} Qn+1可以看作 Q 1 , R 1 , ⋯   , R n Q_1,R_1,\cdots,R_n Q1,R1,,Rn的加权和,距离最近的 R n R_n Rn有更大的权值,时间过去较久的 Q 1 , R 1 Q_1,R_1 Q1,R1等权值越来越小。(4)式不满足(3)的条件,所以 Q n Q_n Qn不会严格收敛到 q ( a ) q(a) q(a),但是我们可以证明 E [ Q n ] = q ( a ) \mathbb{E}[Q_n]=q(a) E[Qn]=q(a),对(4)两边取期望,可得:
E [ Q n + 1 ] = ( 1 − α ) E [ Q n ] + α E [ R n ] . \mathbb{E}[Q_{n+1}]=(1-\alpha)\mathbb{E}[Q_n]+\alpha\mathbb{E}[R_n]. E[Qn+1]=(1α)E[Qn]+αE[Rn]. R 1 , ⋯   , R n R_1,\cdots,R_n R1,,Rn是关于同一个老虎机采样得到的独立同分布样本,不妨设 E [ R n ] = r \mathbb{E}[R_n]=r E[Rn]=r,并记 q n = E [ Q n + 1 ] q_n=\mathbb{E}[Q_{n+1}] qn=E[Qn+1],那么我们有:
∣ q n + 1 − r ∣ = ∣ α r + ( 1 − α ) q n − r ∣ = ∣ ( 1 − α ) ( q n − r ) ∣ ⋮ = ∣ ( 1 − α ) n ( q 1 − r ) ∣ ≤ ∣ 1 − α ∣ n ∣ q 1 − r ∣ \begin{aligned} |q_{n+1}-r|&=|\alpha r+(1-\alpha)q_n-r|\\ &=|(1-\alpha)(q_n-r)|\\ &\quad\vdots\\ &=|(1-\alpha)^n(q_1-r)|\\ &\leq|1-\alpha|^n|q_1-r| \end{aligned} qn+1r=αr+(1α)qnr=(1α)(qnr)=(1α)n(q1r)∣1αnq1r显然如果当 ∣ 1 − α ∣ < 1 |1-\alpha|<1 ∣1α<1时,上式右端会趋于0,也就是说当 0 < α < 2 0<\alpha<2 0<α<2时,我们有:
E [ Q n ] = r . \mathbb{E}[Q_n]=r. E[Qn]=r.所以我们用迭代法进行估计仍然是可行的。当然上面这个推导是针对Stationary的情况,Nonstationary的情况更复杂,这里就不展开了。第五节我们通过实验可以发现在非平稳情况下, α \alpha α取固定值的效果确实更好!

三、 ϵ \epsilon ϵ-greedy策略

通过前面几章的学习我们知道,贪心策略可以写成:
A t = arg ⁡ max ⁡ a Q t ( a ) A_t=\arg\max_aQ_t(a) At=argamaxQt(a)然而,我们也可以把这个贪心策略转化成有一定探索性的策略,即让它以 ϵ \epsilon ϵ 的概率去探索其他动作,也就是 ϵ \epsilon ϵ-greedy策略:
A t = { a random action with probability  ϵ , arg ⁡ max ⁡ a Q t ( a ) with probability  1 − ϵ . A_t=\begin{cases} \text{a random action}& \text{with probability $\epsilon$} , \\ \arg\max_aQ_t(a) & \text{with probability $1-\epsilon$} . \end{cases} At={a random actionargmaxaQt(a)with probability ϵ,with probability 1ϵ.

下面我们实现 ϵ \epsilon ϵ-greedy策略,并看看不同的 ϵ \epsilon ϵ值有什么影响.

import numpy as np
import matplotlib.pyplot as plt

# create k-armed bandit
def k_abd(k):
    q_mean = np.random.normal(0, 1, k)
    return q_mean

def play(epsilon,q_mean):

    k = len(q_mean) # number of bandits
    
    reward = []
    total_reward = 0
    optimal_action_percentage = []
    N = np.zeros(k) # number of times each bandit was chosen
    Q = np.zeros(k) # estimated value
    optimal_action = 0
    optimal_index = np.argmax(q_mean)  # calculate optimal index once
    for i in range(2000):
        
        # epsilon greedy
        if np.random.rand() < epsilon:
            A = np.random.randint(k)
        else:
            A = np.argmax(Q)
        if A == optimal_index:
            optimal_action += 1
        R = np.random.normal(q_mean[A], 1)
        N[A] += 1
        Q[A] += (R - Q[A]) / N[A]
        total_reward += R
        reward.append(total_reward/(i+1))
        optimal_action_percentage.append(optimal_action/(i+1))
    return reward, optimal_action_percentage

k = 10
armed_bandit_10 = k_abd(k)
r1,qap1 = play(0,armed_bandit_10)
r2,qap2 = play(0.01,armed_bandit_10)
r3,qap3 = play(0.1,armed_bandit_10)

# plot
plt.figure(figsize=(10,5),dpi = 150)
plt.plot(r1,label='ε=0')
plt.plot(r2,label='ε=0.01')
plt.plot(r3,label='ε=0.1')
plt.legend()
plt.xlabel('Steps')
plt.ylabel('Average Reward')
plt.title('10-armed bandit problem')
plt.show()

plt.figure(figsize=(10,5),dpi = 150)
plt.plot(qap1,label='ε=0')
plt.plot(qap2,label='ε=0.01')
plt.plot(qap3,label='ε=0.1')
plt.legend()
plt.xlabel('Steps')
plt.ylabel('% Optimal Action')
plt.title('10-armed bandit problem')
plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(1)) 
plt.show()

下图显示了 ϵ \epsilon ϵ分别等于0,0.01,0.1时探索2000次的平均reward,我们可以看到贪心策略 ( ϵ = 0 ) (\epsilon=0) (ϵ=0)的平均奖励最低, ϵ = 0.01 \epsilon=0.01 ϵ=0.01时的平均奖励比 ϵ = 0.1 \epsilon=0.1 ϵ=0.1时高。因为 ϵ \epsilon ϵ-greedy策略理论上最后都能找到最优动作,当找到最优动作后, ϵ = 0.01 \epsilon=0.01 ϵ=0.01时,选择最优动作的概率为 p = 1 − ϵ ≈ 0.99 p=1-\epsilon\approx0.99 p=1ϵ0.99,而 ϵ = 0.1 \epsilon=0.1 ϵ=0.1时,选择最优动作的概率为 p ≈ 0.9 p\approx0.9 p0.9,所以 ϵ = 0.01 \epsilon=0.01 ϵ=0.01时的平均奖励更高。

10abd

下图则是在实验中每种情况下选择最优动作的概率,我们可以看到 ϵ = 0.01 \epsilon=0.01 ϵ=0.01时, p → 0.99 p\to0.99 p0.99,而 ϵ = 0.1 \epsilon=0.1 ϵ=0.1时, p → 0.9 p\to0.9 p0.9.

10abd_p

四、UCB算法

由于动作价值估计的准确性总是存在不确定性,因此需要进行Exploration。贪心算法总是利用当前信息选择最优动作的算法,但实际上其他动作可能更好。 ϵ \epsilon ϵ-greedy策略有一定概率尝试其他动作,但不加区分,对那些接近贪婪或特别不确定的行动没有偏好。最好根据它们实际成为最优动作的潜力在非贪婪行动中进行选择,同时考虑它们的估计与最大值的接近程度以及这些估计中的不确定性。一个有效的方法是UCB算法,这里我们直接给出其策略更新公式(推导可以参考文献2):
A t ≐ arg ⁡ max ⁡ a [ Q t ( a ) + c ln ⁡ t N t ( a ) ] , A_t\doteq\arg\max_a\left[Q_t(a)+c\sqrt{\frac{\ln t}{N_t(a)}}\right], Atargamax[Qt(a)+cNt(a)lnt ],
Python实现如下:

def play_ucb(c, q_mean):
    k = len(q_mean)  # number of bandits
    reward = []
    total_reward = 0
    N = np.zeros(k)  # number of times each bandit was chosen
    Q = np.zeros(k)  # estimated value

    for i in range(1, 2001):  # start from 1 to avoid division by zero in UCB calculation
        if np.min(N) == 0:
            # If any action has not been taken yet, take it to initialize all actions
            A = np.argmin(N)
        else:
            ucb_values = Q + c * np.sqrt(np.log(i) / N)
            A = np.argmax(ucb_values)
        
        R = np.random.normal(q_mean[A], 1)
        N[A] += 1
        Q[A] += (R - Q[A]) / N[A]
        total_reward += R
        reward.append(total_reward / i)

    return reward
rewards = play_ucb(2, armed_bandit_10)  # Example usage with c = 2
# plot reward
plt.figure(figsize=(10,5),dpi = 200)
plt.plot(rewards,label='UCB c=2')
plt.plot(r3,label='ε=0.1')
plt.xlabel('Steps')
plt.ylabel('Average Reward')
plt.title('10-armed bandit problem')
plt.legend()
plt.show()

下图展示了采用UCB算法和采用 ϵ = 0.1 \epsilon=0.1 ϵ=0.1 ϵ \epsilon ϵ-greedy算法的对比,可以看到UCB算的表现更好。

ucb

五、 非平稳老虎机

在上面我们提到对 Q n Q_n Qn迭代更新时, α n = 1 n \alpha_n=\frac1n αn=n1是比较适合平稳的abd问题,也就是说每个老虎机的奖励分布不随时间改变。但是我们经常会遇到非平稳的强化学习问题,在这种情况下,给予近期奖励比过往奖励更大的权重是更合适的,最流行的方法之一是使用恒定的步长参数。下面我们来验证一下是否是这样,我们考虑每个老虎机的 q q q每一步会有一个 N ( 0 , 0.01 ) \mathcal{N}(0,0.01) N(0,0.01)的噪声,代码如下:

import numpy as np
import matplotlib.pyplot as plt

# all bandits have the same initial q value
def initialize_q_means(k):
    return np.zeros(k)

# update q values with random noise
def update_q_means(q_means):
    return q_means + np.random.normal(0, 0.01, size=q_means.shape)

def simulate_bandit(k, steps, epsilon, alpha=None):
    q_means = initialize_q_means(k)
    rewards = {'sample_average': [], 'constant_step': []}
    optimal_action_counts = {'sample_average': [], 'constant_step': []}
    Q_sa = np.zeros(k)  # Q values for sample average
    Q_cs = np.zeros(k)  # Q values for constant step
    N = np.zeros(k)  
    
    total_rewards = {'sample_average': 0, 'constant_step': 0}
    optimal_actions = {'sample_average': 0, 'constant_step': 0}

    for step in range(steps):
        q_means = update_q_means(q_means)
        optimal_action = np.argmax(q_means)
        
        for strategy in ['sample_average', 'constant_step']:
            if np.random.rand() < epsilon:
                action = np.random.randint(k)
            else:
                if strategy == 'sample_average':
                    action = np.argmax(Q_sa)
                else:
                    action = np.argmax(Q_cs)
            
            reward = np.random.normal(q_means[action], 1)
            total_rewards[strategy] += reward
            if action == optimal_action:
                optimal_actions[strategy] += 1
            
            if strategy == 'sample_average':
                N[action] += 1
                Q_sa[action] += (reward - Q_sa[action]) / N[action]
            else:
                # constant step size, alpha = 0.1
                Q_cs[action] += alpha * (reward - Q_cs[action])

            rewards[strategy].append(total_rewards[strategy] / (step + 1))
            optimal_action_counts[strategy].append(optimal_actions[strategy] / (step + 1))
    
    return rewards, optimal_action_counts

# parameters
k = 10  
steps = 10000
epsilon = 0.1
alpha = 0.1

# simulate
rewards, optimal_action_counts = simulate_bandit(k, steps, epsilon, alpha)

# plot
plt.figure(figsize=(10, 8), dpi=150)
plt.subplot(2, 1, 1)
plt.plot(rewards['sample_average'], label='Sample Average')
plt.plot(rewards['constant_step'], label='Constant Step (alpha=0.1)')
plt.title('Average Rewards')
plt.xlabel('Steps')
plt.ylabel('Average Reward')
plt.legend()

plt.subplot(2, 1, 2)
plt.plot(optimal_action_counts['sample_average'], label='Sample Average')
plt.plot(optimal_action_counts['constant_step'], label='Constant Step (alpha=0.1)')
plt.title('Optimal Action Percentage')
plt.xlabel('Steps')
plt.ylabel('Optimal Action %')
plt.legend()

plt.tight_layout()
plt.show()

我们可以得到如下的结果,我们发现确实 α \alpha α取固定步长,比取 α n = 1 n \alpha_n=\frac1n αn=n1效果要好。

output

以下是固定步长参数 α \alpha α 效果更好的原因:

  1. 非静态问题的特点是环境的行为(或潜在的奖励分布)随时间改变。当使用固定的 α \alpha α 时,每次估计给予最新的奖励更大的权重,并逐渐忘记旧的奖励信息。这意味着估计的值能够快速适应环境的变化。而取平均值,则会随着时间逐渐给予历史奖励更多的权重,导致对环境变化的反应迟缓。
  2. 数学上的偏差-方差权衡
    固定的 α \alpha α为估计带来了更高的偏差,但在变化的环境中减少了方差,使得估计更稳定。采样平均方法虽然理论上在静态问题中可以收敛到真实值,但在非静态问题中可能会由于累积了太多过时的信息而导致高方差,使得算法性能下降。

总之,固定的步长 α \alpha α在处理需要快速反应的非静态环境中通常更为适合,因为它允许模型更快地适应最新的环境变化,而不是在老旧数据上花费太多计算资源。这在设计强化学习算法时是一个重要的考量,特别是在那些环境状态快速变化的应用场景中。

六、总结

本节我们介绍了强化学习中的老虎机问题,并介绍了解决老虎机问题的两种经典算法: ϵ \epsilon ϵ-greedy算法和UCB算法,前者是我们在Monte-Carlo方法中介绍过的。同时通过Python实现了这两种算法,实现这两个算法可以加深我们对蒙特卡洛思想以及RM算法在强化学习中的应用的理解,在这个问题中,我们用蒙特卡洛的思想以及RM算法来估计 q ( a ) q(a) q(a),进而进行策略优化。

同时我们还探讨了RM算法中步长 α \alpha α取值对与平稳问题和平稳问题的影响,验证了对与非平稳问题 α \alpha α取固定值更好的结论。

当然关于老虎机问题研究和具体应用还有非常多,具体可以参考文献2.

七、参考文献

  1. Sutton, Richard S., and Andrew G. Barto. Reinforcement learning: An introduction. MIT press, 2018.
  2. Lattimore, Tor, and Csaba Szepesvári. Bandit algorithms. Cambridge University Press, 2020.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基础05-数学运算与排列组合生成

在Python中进行数学运算和生成排列组合是数据科学、机器学习和日常编程中常见的任务。本文将介绍如何在Python中执行基本的数学运算、处理复数、使用数学函数、生成排列和组合、随机数生成、处理分数、统计函数以及处理无穷大和NaN值。 1. 基本算术运算 Python支持传统的四则…

26版SPSS操作教程(高级教程第十三章)

前言 #今日世界读书日&#xff0c;宝子你&#xff0c;读书了嘛~ #本期内容&#xff1a;主成分分析、因子分析、多维偏好分析 #由于导师最近布置了学习SPSS这款软件的任务&#xff0c;因此想来平台和大家一起交流下学习经验&#xff0c;这期推送内容接上一次高级教程第十二章…

【剪映专业版】05文字重叠

【剪映专业版】05文字重叠 1.在素材库中搜索纯黑背景&#xff0c;添加文本&#xff0c;设置合适的字体、字号等&#xff0c;导出备用。 2.返回窗口&#xff0c;设置字体颜色为纯黑&#xff0c;勾选描边设置描边为纯白&#xff0c;描边粗细值为8。导出备用。 3.将视频素材导入。…

SpringCloud系列(11)--将微服务注册进Eureka集群

前言&#xff1a;在上一章节中我们介绍并成功搭建了Eureka集群&#xff0c;本章节则介绍如何把微服务注册进Eureka集群&#xff0c;使服务达到高可用的目的 Eureka架构原理图 1、分别修改consumer-order80模块和provider-payment8001模块的application.yml文件&#xff0c;使这…

Win10 打开有些软件主界面会白屏不显示,其他软件都正常

环境&#xff1a; Win10专业版 英伟达4070 显卡 问题描述&#xff1a; Win10 打开有些软件主界面会白屏不显示,打开远程协助软件AIRMdesk,白色&#xff0c;其他软件都正常 解决方案&#xff1a; 网上说电脑没有接显示器独立显卡的关系导致 我是只有一台主机&#xff0c;没…

VUE3 ref,props,生命周期

1.--ref属性 1.1代码 1.1.1子表 <template><div class"person"><h1>中国</h1><h2 ref"title2">北京</h2><h3>尚硅谷</h3><button click"showLog">点我输出h2这个元素</button>&l…

海康智能相机FTP本地存图流程

背景&#xff1a;近期一个新项目需要使用到智能相机&#xff0c;借助智能相机算法直接输出检测结果并将相机图像进行本地化保存和展示。由于申购目标智能相机未到&#xff0c;暂时使用测试智能相机。 目标智能相机型号&#xff1a;海康智能相机MV-SC3050XC 当前测试相机型号…

MySQL主要内容

1&#xff0c;在表中插入数据 插入值的类型&#xff0c;必须和字段的类型保持一致 - 如果数据类型是字符串&#xff0c;必须引号引起来&#xff0c;数字的话&#xff0c;可以不加 - 插入的数据顺序和字段的顺序必须保持一致 格式一&#xff1a;向表中插入数据 insert in…

python爬虫学习第二十八天-------了解scrapy(二十八天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

【k8s】Kubernetes 1.29.4离线安装部署(总)

&#xff08;一&#xff09;kubernetes1.29.4离线部署之-安装文件准备 &#xff08;二&#xff09;kubernetes1.29.4离线部署之-镜像文件准备 &#xff08;三&#xff09;kubernetes1.29.4离线部署之-环境初始化 &#xff08;四&#xff09;kubernetes1.29.4离线部署之-组件安装…

网工学习云计算HCIE感受如何?

作为一名网工&#xff0c;我经常会在各种网络论坛里查询搜索一些网络技术资料&#xff0c;以及跟论坛里的网友交流讨论平时在工作、学习中遇到的问题、故障&#xff0c;因此也经常能在论坛的首页看到誉天的宣传信息。机缘巧合之下关注了誉天的B站号&#xff0c;自从关注了誉天的…

真实世界的密码学(一)

原文&#xff1a;annas-archive.org/md5/655c944001312f47533514408a1a919a 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 序言 当你拿起这本书时&#xff0c;你可能会想&#xff0c;为什么又一本关于密码学的书&#xff1f;甚至&#xff0c;为什么我要读这本…

【DDD领域驱动设计】战术设计--核心概念介绍

目录 前言 战术设计 基本概念 领域内&#xff1a; 实体 值对象 领域服务 模块 对象生命周期&#xff1a; 聚合 工厂 仓库 其他&#xff1a; 领域事件 事件溯源 实例介绍 前言 上一篇文章 DDD-事件风暴 属于领域驱动设计中的战略设计&#xff0c;战略设计主要从…

数据中台工具的选型要点_光点科技

数据中台工具扮演着举足轻重的角色。想要全面理解数据中台工具的意义、作用以及应用方式&#xff0c;就必须深入探讨这一概念以及相关实践。 数据中台工具概述 数据中台&#xff0c;是一个支持数据集成、管理、分析和服务的平台&#xff0c;它能够帮助企业统一数据资源&#xf…

GreatSQL统计信息相关知识点

相关知识点&#xff1a; INNODB_STATS_PERSISTON或用STATS_PERSIST1定义单个表时&#xff0c;优化器统计信息将持久化到磁盘。默认情况下&#xff0c;innodb_stats_persistent是启用的。 持久统计信息存储在mysql.innodb_table_stats和mysql.innodb_index_stats表中。 默认情…

梦境绘师:揭秘生成对抗网络(GAN)的魔法

梦境绘师&#xff1a;揭秘生成对抗网络&#xff08;GAN&#xff09;的魔法 1 引言 在今日的深度学习领域&#xff0c;生成对抗网络&#xff08;GAN&#xff09;已成为一项无人能外的技术&#xff0c;以其独特的数据生成能力俘获了无数研究者和工程师的心。这项技术不仅在理论上…

CSS3新增特性(二)

四、2D 转换 • 属性名&#xff1a;transform &#xff08;可用于制作2D转换&#xff0c;也可用于制作3D转转换&#xff1b;2D转换是平面上的转换&#xff0c;3D转换是在三维立体空间的转换&#xff09; • 作用&#xff1a;对元素进行水平或垂直方向的移动、缩放、旋转、拉长…

【GitHub】2FA认证(双重身份验证)

GitHub 2FA认证&#xff08;双重身份验证&#xff09; 写在最前面一、使用 TOTP 应用程序配置双2FA&#xff08;双因素身份验证&#xff09;1. 介绍2. github3. 认证 官网介绍小结 & 补充 &#xff1a;权限不足or验证码错误问题 &#x1f308;你好呀&#xff01;我是 是Yu欸…

增加PyQt5界面的交通流量预测(模型为CNN_GRU,CNN_BiGRU_ATTENTION,LSTM,Python代码)

1.效果视频&#xff1a;增加PyQt5界面的交通流量预测&#xff08;模型为CNN_GRU&#xff0c;CNN_BiGRU_ATTENTION&#xff0c;LSTM&#xff09;_哔哩哔哩_bilibili&#xff09; 2.三个模型和数据集的介绍 交通流量预测(python代码&#xff0c;压缩包中带有数据&#xff0c;CN…

又发现一个超好用的youtube字幕翻译插件!!!

最近有了梯子&#xff0c;所以热衷于去youtube、Facebook、Twitter等网站浏览。但英语不好是硬伤&#xff0c;不懈努力之下&#xff0c;让我发现了一个超超超超好用的翻译插件——Relingo。 1.支持Youtube字幕翻译 官网下载安装后&#xff0c;打开youtube视频&#xff0c;右侧…