强化学习入门谈

之前我们见识到很多机器学习大展手脚的任务场景了,但是机器学习依旧有很多软肋。

回忆一下,我们之前做的机器学习(深度学习)策略基本都是类似于"supervised learning"的方法,比如你想用CNN实现一个classificationer,你就必须给每个图片标记label。而所谓unsupervised learning,实质上是把label的过程交给机器完成了。

但对于一些任务,人类自己也不知道最佳答案是什么。例如下围棋,给定某一时刻棋谱,这时候人类也不知道正确答案应该是什么。

在这里插入图片描述

和监督学习的对比

我们可以把强化学习与监督学习做一个对比。以图片分类为例,如图 1.2 所示,**监督学习(supervised learning)**假设我们有大量被标注的数据,比如汽车、飞机、椅子这些被标注的图片,这些图片都要满足独立同分布,即它们之间是没有关联关系的。假设我们训练一个分类器,比如神经网络。为了分辨输入的 图片中是汽车还是飞机,在训练过程中,需要把正确的标签信息传递给神经网络。 当神经网络做出错误的预测时,比如输入汽车的图片,它预测出来是飞机,我们就会直接告诉它,该预测是错误的,正确的标签应该是汽车。最后我们根据类似错误写出一个损失函数(loss function),通过反向传播(back propagation)来训练神经网络。

所以在监督学习过程中,有两个假设:

  • 输入的数据(标注的数据)都应是没有关联的。因为如果输入的数据有关联,学习器(learner)是不好学习的。
  • 需要告诉学习器正确的标签是什么,这样它可以通过正确的标签来修正自己的预测。

通常假设样本空间中全体样本服从一个未知分布,我们获得的每个样本都是独立地从这个分布上采样获得的,即独立同分布(independent and identically distributed,简称 i.i.d.)。

但很多时候情况就不一样了,下面是一个space invader的太空射击游戏。玩家通过左右移动飞船射击歪星人获得分数。在玩游戏的过程中,我们可以发现智能体得到的观测(observation)不是独立同分布的,上一帧与下一帧间其实有非常强的连续性。我们得到的数据是相关的时间序列数据,不满足独立同分布。另外,我们并没有立刻获得反馈,游戏没有告诉我们哪个动作是正确动作。

比如现在把木板往右移,这只会使得球往上或者往左一点儿,我们并不会得到即时的反馈。因此,强化学习之所以困难,是因为智能体不能得到即时的反馈,然而我们依然希望智能体在这个环境中学习。

在这里插入图片描述

强化学习的训练数据就是一个玩游戏的过程。我们从第 1 步开始,采取一个动作,比如我们往右移,第 2 步我们又做出动作,得到的训练数据是一个玩游戏的序列。比如现在是在第 3 步,我们把这个序列放进网络,希望网络可以输出一个动作,即在当前的状态应该输出往右移或 者往左移或者开火。这里有个问题,我们没有标签来说明现在这个动作是正确还是错误的,必须等到游戏结束才可能知道,这个游戏可能 10s 后才结束。现在这个动作到底对最后游戏是否能赢有无帮助,我们其实是不清楚的。这里我们就面临**延迟奖励(delayed reward)**的问题,延迟奖励使得训练网络非常困难。

强化学习和监督学习的区别如下。

(1)强化学习输入的样本是序列数据,而不像监督学习里面样本都是独立的。

(2)学习器并没有告诉我们每一步正确的动作应该是什么,学习器需要自己去发现哪些动作可以带来 最多的奖励,只能通过不停地尝试来发现最有利的动作。

(3)智能体获得自己能力的过程,其实是不断地试错探索(trial-and-error exploration)的过程。探索 (exploration)和利用(exploitation)是强化学习里面非常核心的问题。其中,探索指尝试一些新的动作, 这些新的动作有可能会使我们得到更多的奖励,也有可能使我们“一无所有”;利用指采取已知的可以获得最多奖励的动作,重复执行这个动作,因为我们知道这样做可以获得一定的奖励。因此,我们需要在探索和利用之间进行权衡,这也是在监督学习里面没有的情况。

(4)在强化学习过程中,没有非常强的监督者(supervisor),只有奖励信号(reward signal),并且奖励信号是延迟的,即环境会在很久以后告诉我们之前我们采取的动作到底是不是有效的。因为我们没有得 到即时反馈,所以智能体使用强化学习来学习就非常困难。当我们采取一个动作后,如果我们使用监督学习,我们就可以立刻获得一个指导,比如,我们现在采取了一个错误的动作,正确的动作应该是什么。而在强化学习里面,环境可能会告诉我们这个动作是错误的,但是它并没有告诉我们正确的动作是什么。而且更困难的是,它可能是在一两分钟过后告诉我们这个动作是错误的。所以这也是强化学习和监督学习不同的地方。

通过与监督学习的比较,我们可以总结出强化学习的一些特征。

(1)强化学习会试错探索,它通过探索环境来获取对环境的理解。

(2)强化学习智能体会从环境里面获得延迟的奖励。

(3)在强化学习的训练过程中,时间非常重要。因为我们得到的是有时间关联的数据(sequential data), 而不是独立同分布的数据。在机器学习中,如果观测数据有非常强的关联,会使得训练非常不稳定。这也是为什么在监督学习中,我们希望数据尽量满足独立同分布,这样就可以消除数据之间的相关性。

(4)智能体的动作会影响它随后得到的数据,这一点是非常重要的。在训练智能体的过程中,很多时 候我们也是通过正在学习的智能体与环境交互来得到数据的。所以如果在训练过程中,智能体不能保持稳定,就会使我们采集到的数据非常糟糕。我们通过数据来训练智能体,如果数据有问题,整个训练过程就会失败。所以在强化学习里面一个非常重要的问题就是,怎么让智能体的动作一直稳定地提升。

## 强化学习概述

**强化学习(reinforcement learning,RL)**讨论的问题是智能体(agent)怎么在复杂、不确定的环境(environment)中最大化它能获得的奖励。如图 1.1 所示,强化学习由两部分组成:智能体和环境。在强化学习过程中,智能体与环境一直在交互。智能体在环境中获取某个状态后,它会利用该状态输出一个动作 (action),这个动作也称为决策(decision)。然后这个动作会在环境中被执行,环境会根据智能体采取的动作,输出下一个状态以及当前这个动作带来的奖励。智能体的目的就是尽可能多地从环境中获取奖励。

也就是说,在强化学习中,有一个智能体(Agent,也就是这里的Actor),然后智能体会和环境(Environment)进行互动,环境会给智能体一个观测(Observation,函数的输入)。智能体可以根据这个观测产生一个动作(Action,函数的输出),这个动作反过来也会影响环境,然后环境会给出新的观测,同时也会给出一个奖励(Reward),告诉智能体所采取动作的好坏。智能体看到新的观测后,会继续采取一个新的动作,如此循环往复。

这里的智能体就是我们要找的函数,这个函数的目标是找到一个策略(Policy)去最大化从环境中获取的奖励总和。

比如在射击外星人中,当机器此时选择向右这个动作之后,它会得到奖励值为0,因为我们定义只有击毙外星人才会获得奖励(游戏中也会获得分数)。

当采取一个动作之后游戏的画面也会发生改变,代表我们有了新的观测。此时智能体可以采取新的动作,假设智能体采取的动作是开火,并且击杀了一个外星人,游戏中得到的分数是5分,这里假设我们也将奖励设为5分。

这样我们在玩游戏的过程中会不断的得到奖励(可能为正、可能为零、还可能为负),只要游戏没有终止。强化学习的目标就是想要找到一个能获取到最大奖励总和的智能体。

又比如说下围棋,可以执行某一步,定义获胜reward为1,失败为-1。其他时候都是0.

接下来我们介绍**序列决策(sequential decision making)**过程。强化学习研究的问题是智能体与环境交互的问题。智能体把它的动作输出给环境,环境取得这个动作后会进行下一步,把下一步的观测与这个动作带来的奖励返还给智能体。这样的交互会产生很多观测,智能体的目的是从这些观测之中学到能最大化奖励的策略。

奖励

奖励是由环境给的一种标量的反馈信号(scalar feedback signal),这种信号可显示智能体在某一步采取某个策略的表现如何。强化学习的目的就是最大化智能体可以获得的奖励,智能体在环境里面存在的目 的就是最大化它的期望的累积奖励(expected cumulative reward)。不同的环境中,奖励也是不同的。这里给大家举一些奖励的例子。

(1)比如一个象棋选手,他的目的是赢棋,在最后棋局结束的时候,他就会得到一个正奖励(赢)或者负奖励(输)。

(2)在股票管理里面,奖励由股票获取的奖励与损失决定。

(3)在玩雅达利游戏的时候,奖励就是增加或减少的游戏的分数,奖励本身的稀疏程度决定了游戏的难度。

序列决策

在一个强化学习环境里面,智能体的目的就是选取一系列的动作来最大化奖励,所以这些选取的动作 必须有长期的影响。但在这个过程里面,智能体的奖励其实是被延迟了的,就是我们现在选取的某一步动作,可能要等到很久后才知道这一步到底产生了什么样的影响。如图 1.13 所示,在玩雅达利的 Pong 游戏时,我们可能只有到最后游戏结束时,才知道球到底有没有被击打过去。过程中我们采取的上升(up)或 下降(down)动作,并不会直接产生奖励。强化学习里面一个重要的课题就是近期奖励和远期奖励的权衡 (trade-off),研究怎么让智能体取得更多的远期奖励。

在与环境的交互过程中,智能体会获得很多观测。针对每一个观测,智能体会采取一个动作,也会得到一个奖励。所以历史是观测、动作、奖励的序列:
H t = o 1 , a 1 , r 1 , … , o t , a t , r t H_{t}=o_{1}, a_{1}, r_{1}, \ldots, o_{t}, a_{t}, r_{t} Ht=o1,a1,r1,,ot,at,rt

智能体在采取当前动作的时候会依赖于它之前得到的历史,所以我们可以把整个游戏的状态看成关于这个历史的函数:

S t = f ( H t ) S_{t}=f\left(H_{t}\right) St=f(Ht)

Q:状态和观测有什么关系?

A:状态是对世界的完整描述,不会隐藏世界的信息。观测是对状态的部分描述,可能会遗漏一些信息。在深度强化学习中,我们几乎总是用实值的向量、矩阵或者更高阶的张量来表示状态和观测。例如, 我们可以用 RGB 像素值的矩阵来表示一个视觉的观测,可以用机器人关节的角度和速度来表示一个机器 人的状态。

环境有自己的函数 s t e = f e ( H t ) s_{t}^{e}=f^{e}\left(H_{t}\right) ste=fe(Ht) 来更新状态,在智能体的内部也有一个函数 s t a = f a ( H t ) s_{t}^{a}=f^{a}\left(H_{t}\right) sta=fa(Ht)来更新状 态。当智能体的状态与环境的状态等价的时候,即当智能体能够观察到环境的所有状态时,我们称这个环境是完全可观测的(fully observed)。在这种情况下面,强化学习通常被建模成一个马尔可夫决策过程 (Markov decision process,MDP)的问题。在马尔可夫决策过程中, o t = s t e = s t a o_{t}=s_{t}^{e}=s_{t}^{a} ot=ste=sta

但是有一种情况是智能体得到的观测并不能包含环境运作的所有状态,因为在强化学习的设定里面, 环境的状态才是真正的所有状态。比如智能体在玩 black jack 游戏,它能看到的其实是牌面上的牌。或者在 玩雅达利游戏的时候,观测到的只是当前电视上面这一帧的信息,我们并没有得到游戏内部里面所有的运 作状态。也就是当智能体只能看到部分的观测,我们就称这个环境是部分可观测的(partially observed)。 在这种情况下,强化学习通常被建模成**部分可观测马尔可夫决策过程(partially observable Markov decision process, POMDP)**的问题。部分可观测马尔可夫决策过程是马尔可夫决策过程的一种泛化。 部分可观测马尔可夫决策过程依然具有马尔可夫性质,但是假设智能体无法感知环境的状态,只能知道 部分观测值。比如在自动驾驶中,智能体只能感知传感器采集的有限的环境信息。部分可观测马尔可夫决策过程可以用一个七元组描述: ( S , A , T , R , Ω , O , γ ) (S,A,T,R,\Omega,O,\gamma) (S,A,T,R,Ω,O,γ)。其中 S S S 表示状态空间,为隐变量, A A A 为动作空间, T ( s ′ ∣ s , a ) T(s'|s,a) T(ss,a) 为状态转移概率, R R R 为奖励函数, Ω ( o ∣ s , a ) \Omega(o|s,a) Ω(os,a) 为观测概率, O O O 为观测空间, γ \gamma γ 为折扣系数。

动作空间

不同的环境允许不同种类的动作。在给定的环境中,有效动作的集合经常被称为动作空间(action space)。像雅达利游戏和围棋(Go)这样的环境有离散动作空间(discrete action space),在这个动作 空间里,智能体的动作数量是有限的。在其他环境,比如在物理世界中控制一个智能体,在这个环境中就有连续动作空间(continuous action space)。在连续动作空间中,动作是实值的向量。

例如,走迷宫机器人如果只有往东、往南、往西、往北这 4 种移动方式,则其动作空间为离散动作空 间;如果机器人可以向 360 度中的任意角度进行移动,则其动作空间为连续动作空间。

强化学习智能体的组成成分和类型

对于一个强化学习智能体,它可能有一个或多个如下的组成成分。

  • 策略(policy)。智能体会用策略来选取下一步的动作。

  • 价值函数(value function)。我们用价值函数来对当前状态进行评估。价值函数用于评估智能体进 入某个状态后,可以对后面的奖励带来多大的影响。价值函数值越大,说明智能体进入这个状态越有利。

  • 模型(model)。模型表示智能体对环境的状态进行理解,它决定了环境中世界的运行方式。 下面我们深入了解这 3 个组成部分的细节。

1.4.1 策略

策略是智能体的动作模型,它决定了智能体的动作。它其实是一个函数,用于把输入的状态变成动作。策略可分为两种:随机性策略和确定性策略。

**随机性策略(stochastic policy)**就是 π \pi π 函数,即 π ( a ∣ s ) = p ( a t = a ∣ s t = s ) \pi(a | s)=p\left(a_{t}=a | s_{t}=s\right) π(as)=p(at=ast=s)。输入一个状态 s s s,输出一个概率。
这个概率是智能体所有动作的概率,然后对这个概率分布进行采样,可得到智能体将采取的动作。比如可能是有 0.7 的概率往左,0.3 的概率往右,那么通过采样就可以得到智能体将采取的动作。

**确定性策略(deterministic policy)**就是智能体直接采取最有可能的动作,即 a ∗ = arg ⁡ max ⁡ a π ( a ∣ s ) a^{*}=\underset{a}{\arg \max} \pi(a \mid s) a=aargmaxπ(as)

通常情况下,强化学习一般使用随机性策略,随机性策略有很多优点。比如,在学习时可以通过引入一定的随机性来更好地探索环境;
随机性策略的动作具有多样性,这一点在多个智能体博弈时非常重要。采用确定性策略的智能体总是对同样的状态采取相同的动作,这会导致它的策略很容易被对手预测。

1.4.2 价值函数

价值函数的值是对未来奖励的预测,我们用它来评估状态的好坏。
价值函数里面有一个折扣因子(discount factor),我们希望在尽可能短的时间里面得到尽可能多的奖励。比如现在给我们两个选择:10天后给我们100块钱或者现在给我们100块钱。我们肯定更希望现在就给我们 100 块钱,因为我们可以把这 100 块钱存在银行里面,这样就会有一些利息。因此,我们可以把折扣因子放到价值函数的定义里面,价值函数的定义为

V π ( s ) ≐ E π [ G t ∣ s t = s ] = E π [ ∑ k = 0 ∞ γ k r t + k + 1 ∣ s t = s ] , 对于所有的 s ∈ S V_{\pi}(s) \doteq \mathbb{E}_{\pi}\left[G_{t} \mid s_{t}=s\right]=\mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^{k} r_{t+k+1} \mid s_{t}=s\right], \text{对于所有的} s \in S Vπ(s)Eπ[Gtst=s]=Eπ[k=0γkrt+k+1st=s],对于所有的sS

期望 E π \mathbb{E}_{\pi} Eπ 的下标是 π \pi π 函数, π \pi π 函数的值可反映在我们使用策略 π \pi π 的时候,到底可以得到多少奖励。

我们还有一种价值函数:Q 函数。Q 函数里面包含两个变量:状态和动作。其定义为
Q π ( s , a ) ≐ E π [ G t ∣ s t = s , a t = a ] = E π [ ∑ k = 0 ∞ γ k r t + k + 1 ∣ s t = s , a t = a ] Q_{\pi}(s, a) \doteq \mathbb{E}_{\pi}\left[G_{t} \mid s_{t}=s, a_{t}=a\right]=\mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^{k} r_{t+k+1} \mid s_{t}=s, a_{t}=a\right] Qπ(s,a)Eπ[Gtst=s,at=a]=Eπ[k=0γkrt+k+1st=s,at=a]
所以我们未来可以获得奖励的期望取决于当前的状态和当前的动作。Q 函数是强化学习算法里面要学习的一个函数。因为当我们得到 Q 函数后,进入某个状态要采取的最优动作可以通过 Q 函数得到。

1.4.3 模型

第3个组成部分是模型,模型决定了下一步的状态。下一步的状态取决于当前的状态以及当前采取的动作。它由状态转移概率和奖励函数两个部分组成。状态转移概率即
p s s ′ a = p ( s t + 1 = s ′ ∣ s t = s , a t = a ) p_{s s^{\prime}}^{a}=p\left(s_{t+1}=s^{\prime} \mid s_{t}=s, a_{t}=a\right) pssa=p(st+1=sst=s,at=a)

奖励函数是指我们在当前状态采取了某个动作,可以得到多大的奖励,即
R ( s , a ) = E [ r t + 1 ∣ s t = s , a t = a ] R(s,a)=\mathbb{E}\left[r_{t+1} \mid s_{t}=s, a_{t}=a\right] R(s,a)=E[rt+1st=s,at=a]
当我们有了策略、价值函数和模型3个组成部分后,就形成了一个马尔可夫决策过程(Markov decision process)。如图 1.15 所示,这个决策过程可视化了状态之间的转移以及采取的动作。

图 1.15 马尔可夫决策过程

我们来看一个走迷宫的例子。如图 1.16 所示,要求智能体从起点(start)开始,然后到达终点(goal)的位置。每走一步,我们就会得到 $-$1 的奖励。我们可以采取的动作是往上、下、左、右走。我们用现在智能体所在的位置来描述当前状态。

图 1.16 走迷宫的例子

我们可以用不同的强化学习方法来解这个环境。
如果我们采取基于策略的强化学习(policy-based RL)方法,当学习好了这个环境后,在每一个状态,我们都会得到一个最佳的动作。如图 1.17 所示,比如我们现在在起点位置,我们知道最佳动作是往右走;在第二格的时候,得到的最佳动作是往上走;第三格是往右走…通过最佳的策略,我们可以最快地到达终点。

图 1.17 使用基于策略的强化学习方法得到的结果

如果换成基于价值的强化学习(value-based RL)方法,利用价值函数作为导向,我们就会得到另外一种表征,每一个状态会返回一个价值。如图 1.18 所示,比如我们在起点位置的时候,价值是 $-$16,因为我们最快可以 16 步到达终点。因为每走一步会减1,所以这里的价值是 $-$16。
当我们快接近终点的时候,这个数字变得越来越大。在拐角的时候,比如现在在第二格,价值是-15,智能体会看上、下两格,它看到上面格子的价值变大了,变成 -14 了,下面格子的价值是 -16,那么智能体就会采取一个往上走的动作。所以通过学习的价值的不同,我们可以抽取出现在最佳的策略。
在这里插入图片描述

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

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

相关文章

colnames看似简单,却能优化数据处理流程

引言 在数据处理和分析中,变量名称是至关重要的,它们决定了数据的可读性和操作的简便性。在R语言中,colnames 函数以其简单的语法设计,提供了高效管理数据框列名的能力,尤其是在复杂的爬虫任务中显得尤为重要。本篇文…

【分布式】Hadoop完全分布式的搭建(零基础)

Hadoop完全分布式的搭建 环境准备: (1)VMware Workstation Pro17(其他也可) (2)Centos7 (3)FinalShell (一)模型机配置 0****)安…

ArcGIS中怎么把数据提取到指定范围(裁剪、掩膜提取)

最近,经常能收到怎么把数据提取到指定范围、栅格数据怎么裁剪、矢量数据怎么裁剪、栅格数据怎么掩膜提取的咨询。 下面是我对这个问题的解决思路: 对于矢量数据: ①首先把数据加载进来 ②软件界面上面的工具栏找到→地理处理→裁剪&#x…

intra-mart环境搭建笔记

一、前言 最近在做intra-mart项目,网上这些笔记比较少,在此做一下笔记。 intra-mart是由日本intra-mart公司开发和销售的工作流平台,国内确实不怎么用,日本企业用的多些,面试时会问有没有intra-mart经验。 这个自学…

智能型电瓶车充电桩在老居民区充电站中的应用优势

摘要 随着电瓶车数量的快速增长,小区内的电瓶车充电需求日益增加,但传统充电方式存在诸多安全隐患。电瓶车智能充电桩作为一种新型充电解决方案,能够有效解决充电难题,并提升充电安全性和便捷性。本文以ACX10A型电瓶车充电桩为…

生产看板真的有用吗?

​看板,对于从事制造行业的人员来说,这并不陌生。但是对于看板起到的作用,那可就是众说纷纭,有人说,看板是领导的“面子工程”,是混淆上级视察的工具;也有人说,看板真切地帮助车间提…

刷服务器固件

猫眼淘票票 大麦 一 H3C通用IP 注:算力服务器不需要存储 二 刷服务器固件 1 登录固定IP地址 2 升级BMC版本 注 虽然IP不一致但是步骤是一致的 3 此时服务器会出现断网现象,若不断网等上三分钟ping一下 4 重新登录 5 断电拔电源线重新登录查看是否登录成功

机器学习算法在推荐系统中的应用:从数据预处理到模型部署实战指南

机器学习算法在推荐系统中的应用:从数据预处理到模型部署实战指南 介绍 在当今信息爆炸的时代,推荐系统扮演了越来越重要的角色,它可以帮助用户发现和获取个性化的信息、产品或服务。而推荐系统中的机器学习算法则是其核心引擎,能…

上门按摩系统架构与功能分析

一、系统架构 服务端用Java语言(最低JDK1.8,支持JDK11以及JDK17)、MySQL数据库(标配5.7版本,支持MySQL8),Mybatis ORM框架,Redis缓存,nginx代理,前端用uniap…

使用mne对运动想象数据bciIV进行预处理

需要的库 mne numpy scipy scikit-learn pip install mne numpy scipy scikit-learn 数据下载 对Data sets 2a ‹4-class motor imagery› 四分类的运动想象来进行mne的处理。 BCI Competition IV 数据的说明如下 [22 EEG channels (0.5-100Hz; notch filtered), 3 EOG chann…

设计模式 行为型 策略模式(Strategy Pattern)与 常见技术框架应用 解析

策略模式(Strategy Pattern)核心思想是将算法的实现从使用该算法的类中分离出来,作为独立的对象,通过接口来定义算法家族,这样就可以很容易地改变或扩展算法。通过这种方式,可以避免在客户端代码中使用大量…

配置管理工具和k8s功能重叠部分的优势比较

通过自动化配置管理工具(如 Ansible、Puppet、Chef)和应用内管理机制,也可以实现自动部署、扩缩容、负载均衡和故障恢复等功能。Kubernetes(K8s)在这些方面具有哪些独特的优势呢,尤其是在云原生环境和大规模…

OpenHarmony AVScreenCaptureRecorder录屏开发指导

一、简介 OpenHarmony 5.0新增了AVScreenCaptureRecorder ArkTs API。用户可以调用录屏AVScreenCaptureRecorder API录制屏幕,采集音频源数据,获取封装后的音视频文件,然后通过文件的形式流转到其他模块进行播放或处理,用于以文件…

CSS Grid 布局示例(基本布局+代码属性描述)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>CSS Grid 布局示例</title><style>.gri…

爬虫学习案例3

爬取美女图片 优美图库地址 一页图片 安装依赖库文件 pip install selenium requests beautifulsoup4import time import requests import random from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service fr…

简单的spring boot tomcat版本升级

简单的spring boot tomcat版本升级 1. 需求 我们使用的springboot版本为2.3.8.RELEASE&#xff0c;对应的tomcat版本为9.0.41&#xff0c;公司tomcat对应版本发现攻击者可发送不完整的POST请求触发错误响应&#xff0c;从而可能导致获取其他用户先前请求的数据&#xff0c;造…

http源码分析

一、HttpURLConnection http连接池源码分析 二、HttpClient 连接池&#xff0c;每个路由最大连接数 三、OkHttp okhttp的连接池与socket连接

阿里云DDoS防护:如何更换IP地址,保护您的云服务器

随着网络攻击日益增多&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;攻击已经成为对企业和个人云资源的一大威胁。为了帮助用户抵御这类攻击&#xff0c;阿里云推出了强大的DDoS防护服务&#xff0c;保障您的云服务器免受恶意流量的影响。今天&#xff0c;九河云就来…

[sdx12] Qualcomm SDX12查看基线版本

about.html文件 Build部分 Product SDX12.LE.1.0-00263-NBOOT.NEFS.PROD-1.90789.1 Distribution SDX12.LE.1.0|AMSS|Standard|OEM: Build Components部分 从以上截图可以看到以下模块的版本号及格式 BOOT 基线版本号 BOOT.BF.3.1.c3-00010-SDX12AAAAANAZB-1 Distr…

Qt天气预报系统界面关闭

Qt天气预报系统界面关闭 1、点击右上角x退出1.1添加控件1.2修改控件名字1.3编程实现控件功能 2、鼠标右键退出2.1重写鼠标点击事件2.2添加定义2.3添加一个菜单2.3.1创建一个菜单指针2.3.2创建一个菜单对象2.3.3显示菜单2.3.4定义一个菜单退出动作2.3.5在当前鼠标位置显示菜单2.…