深度强化学习入门(待修改)

目录

前言

一、强化学习

1.马可洛夫链

2.蒙地卡罗

3.时序差分TD

 4.gym学习​编辑

FrozenLake

二、RL基本算法

1.Q-learning和SARSA

 2.DQN

Deep network + Qlearning = DQN

三、PG策略算法

总结


前言

这段时间学习深度强化学习的总结。


一、强化学习

        强化学习是做出最佳决策的科学。它可以帮助我们制定活的物种所表现出的奖励动机行为。比方说,你想让一个孩子坐下来学习考试。要做到这一点非常困难,但是如果每次完成一章/主题时都给他一块巧克力,他就会明白,如果他继续学习,他会得到更多的巧克力棒。所以他会有一些学习考试的动机。
        孩子代表着Agent代理 。奖励制度和考试代表了Environment环境。今天的题目是类似于强化学习的States状态。所以,孩子必须决定哪些话题更重要(即计算每种行为的价值)。这将是我们的工作的 Value-Function价值方程。所以,每次他从一个国家到另一个国家旅行时,他都会得到Reward奖励,他用来在时间内完成主题的方法就是我们的Policy决策

1.马可洛夫链

马尔科夫链是用来描述智能体和环境互动的过程。

马尔科夫链包含三要素:state,action,reward

智能体在一个状态(S)下,选择了某个动作(A),进入了另外一个状态,并获得奖励(用R代表)的过程。

所以,我们希望通过让智能体在环境里获取最多的奖励,把智能体训练成我们想要的样子——就是能完成某些特定的任务。

马尔科夫链,其实应该叫马尔科夫树

S到A是agent的选择 ,而A到S时环境的随机性。

马尔科夫链具有不确定性。

2.蒙地卡罗

Q和V:

评估动作的价值,称为Q值:它代表了选择这个动作后,一直到最终状态奖励总和期望

评估状态的价值,称为V值:它代表了在这个状态下,一直到最终状态的奖励总和期望

算上奖励R,Q和V之间的关系:

V就是子节点的Q的期望,Q就是子节点的V的期望.

蒙地卡罗

我们把agent放到环境的任意状态;从这个状态开始按照策略进行选择动作,并进入新的状态。

重复上一步,直到最终状态;我们从最终状态开始向前回溯:计算每个状态的G值

重复前面多次,然后平均每个状态的G值,这就是我们需要求的V值。

缺点: 每一次都需要先从头走到尾,再进行回溯更新。如果最终状态很难达到,可能每一次都要转很久很久才能更新一次G值。就是说如果环境的状态空间非常大,或者最终状态只有非常小的概率达到。

3.时序差分TD

TD算法对蒙地卡罗(MC)进行了改进:

1. 和蒙地卡罗(MC)不同:TD算法只需要走N步。就可以开始回溯更新。

2. 和蒙地卡罗(MC)一样:小猴需要先走N步,每经过一个状态,把奖励记录下来。然后开始回溯。

3. 状态的V值计算:和蒙地卡罗一样,假设N步之后,就到达了最终状态了。

可以简单来说就是,TD不走完整段路程,而是半路就截断。用半路的路牌,更新当前的路牌。就是说不需要一直到最后,我们可以先用后面的估算,然后调整当前状态。

在MC,G是更新目标,而在TD,把更新目标从G,改成r+gamma*V

 4.gym学习

  1. 导入:首先我们先import gym。导入gym包。
  2. 创建环境:env = gym.make('环境名')。 其中环境名可以在这找到,还有相关的说明。其中,env就是environment的简称。 一般我们会顺手进行初始化。env.unwrapped 或者我们一起写。env = gym.make('环境名').unwrapped
  3. 获取状态特征数和动作空间 N_S = env.observation_space N_A = env.action_space 还记得我们之前说的吗?状态特征,就是我们能观察到的环境。 例如自动驾驶汽车,交通灯算是一个状态特征,这个特征有不同的值,红灯/绿灯。距离最近的行人是一个特征,例如距离这个行人多远。自动驾驶汽车能观察的环境特征越多,感知能力越强,对抉择就越有帮助。所以不一般来说,工程师都会想不断利用各种算法和硬件,从真实环境提取环境特征。 GYM环境对于初学者方便的地方是,对于每个实验,环境都直接提供了环境特征。不需要我们自己去提取了。 如果是连续的状态空间,和动作空间,我们可以获取到边界值 s_low_bound = env.observation_space.low s_high_bound = env.observation_space.high 在这里大家可以理解为,老师出题的格式,和学生答案的格式。
  4. 初始化环境,并返回一个初始状态。我们一般这样写。 s = env.reset() 老师出的第一道题!
  5. 学生开始做题了。这里的f其实就是我们的算法。 现在我们就有了一个初始状态s。 假设有一个函数f(s),输入s,获得可以选择出动作a。我们的目标就是找出一个f,能让我们在这个环境中获取最多的reward。 a = f(s)
  6. 学生提交答案,老师改卷了。把分返回给学生。并且开始出下一题。 我们选取a后。代入step函数,会根据 环境配置,会返回:进入的下一个状态,当前获得的奖励r。除此之外,还有一个标志位done,表示是否进入最终状态。另外还有一个包含信息的值(info),但一般我们用不到。可以先忽略。 s_,r,done,info = env.step(a)
  7. 我们把s = s_.并把4-6组成一个循环,那么游戏就能自动进行下去了。
  8. render。如果有render可以把游戏给渲染出来。

FrozenLake

S:start,出发点。 G:target,终点。 F:可以走的路,但偶尔你会因为滑到,自动往前滑一格。 H:hole:是陷阱。

FrozenLake-v0是一个4*4的网络格子,每个格子可以是起始块,目标块、冻结块或者危险块。 我们的目标是让agent学习从开始块如何行动到目标块上,而不是移动到危险块上。 agent可以选择向上、向下、向左或者向右移动,同时游戏中还有可能吹来一阵风,将agent吹到任意的方块上。

我们的任务就是让我们的agent,从起点,走到终点。

二、RL基本算法

1.Q-learning和SARSA

V(St+1)的意义是,在St+1到最终状态获得的奖励期望值。 Q(St,At)的意义是,在Q(St,At)到最终状态获得的奖励期望值。 所以我们可以把V(St+1)看成是下山途中的一个路牌,这个路牌告诉我们下山到底还有多远,然后加上R这一段路,就知道Q(St,At)离山脚有多长的路。

因为从状态St+1到动作At+1之间没有奖励反馈,所以我们直接用At+1的Q价值,代替St+1的V价值。 

在St+1下,可能有很多动作At+1。不同动作的Q值自然是不同的。 所以Q(St+1,At+1)并不能等价于V(St+1)。

虽然不相等,但不代表不能用其中一个来代表V(St+1)。人们认为有个可能的动作产生的Q值能够一定程度代表V(St+1)。

  1. 在相同策略下产生的动作At+1。这就是SARSA。
  2. 选择能够产生最大Q值的动作At+1。这就是Qlearning。

Qlearning和SARSA唯一的不同,就是用什么动作的Q值替代St+1的V值。SARSA 选择的是在St同一个策略产生的动作。Qlearning 选择的是能够产生最大的Q值的动作。

Qleanring的更新流程。 我们将会在任意的state出发

1. 我们将会用noisy-greedy的策略选定动作A

2. 在完成动作后,我们将会进入新状态St+1;

3. 检查St+1中所有动作,看看哪个动作的Q值最大;

4. 用以下的公式更新当前动作A的Q值;

5. 继续从s'出发,进行下一步更新 1-6步我们作为一个EP,进行N个EP的迭代。 

"""Q-Table learning algorithm.
Non deep learning - TD Learning, Off-Policy, e-Greedy Exploration
Q(S, A) <- Q(S, A) + alpha * (R + lambda * Q(newS, newA) - Q(S, A))
See David Silver RL Tutorial Lecture 5 - Q-Learning for more details.
For Q-Network, see tutorial_frozenlake_q_network.py
EN: https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part-0-q-learning-with-tables-and-neural-networks-d195264329d0#.5m3361vlw
CN: https://zhuanlan.zhihu.com/p/25710327
tensorflow==2.0.0a0
tensorlayer==2.0.0
"""

import argparse
import os
import time

import gym
import matplotlib.pyplot as plt
import numpy as np

parser = argparse.ArgumentParser()
parser.add_argument('--train', dest='train', action='store_true', default=True)
parser.add_argument('--test', dest='test', action='store_true', default=True)

parser.add_argument(
    '--save_path', default=None, help='folder to save if mode == train else model path,'
    'qnet will be saved once target net update'
)
parser.add_argument('--seed', help='random seed', type=int, default=0)
parser.add_argument('--env_id', default='FrozenLake-v0')
args = parser.parse_args()

## Load the environment
alg_name = 'Qlearning'
env_id = args.env_id
env = gym.make(env_id)
render = False  # display the game environment

##================= Implement Q-Table learning algorithm =====================##
## Initialize table with all zeros
Q = np.zeros([env.observation_space.n, env.action_space.n])
## Set learning parameters
lr = .85  # alpha, if use value function approximation, we can ignore it
lambd = .99  # decay factor
num_episodes = 10000
t0 = time.time()

if args.train:
    all_episode_reward = []
    for i in range(num_episodes):
        ## Reset environment and get first new observation
        s = env.reset()
        rAll = 0
        ## The Q-Table learning algorithm
        for j in range(99):
            if render: env.render()
            ## Choose an action by greedily (with noise) picking from Q table
            a = np.argmax(Q[s, :] + np.random.randn(1, env.action_space.n) * (1. / (i + 1)))
            ## Get new state and reward from environment
            s1, r, d, _ = env.step(a)
            ## Update Q-Table with new knowledge
            Q[s, a] = Q[s, a] + lr * (r + lambd * np.max(Q[s1, :]) - Q[s, a])
            rAll += r
            s = s1
            if d is True:
                break
        print(
            'Training  | Episode: {}/{}  | Episode Reward: {:.4f}  | Running Time: {:.4f}'.format(
                i + 1, num_episodes, rAll,
                time.time() - t0
            )
        )
        if i == 0:
            all_episode_reward.append(rAll)
        else:
            all_episode_reward.append(all_episode_reward[-1] * 0.9 + rAll * 0.1)

    # save
    path = os.path.join('model', '_'.join([alg_name, env_id]))
    if not os.path.exists(path):
        os.makedirs(path)
    np.save(os.path.join(path, 'Q_table.npy'), Q)

    plt.plot(all_episode_reward)
    if not os.path.exists('image'):
        os.makedirs('image')
    plt.savefig(os.path.join('image', '_'.join([alg_name, env_id])))

    # print("Final Q-Table Values:/n %s" % Q)

if args.test:
    path = os.path.join('model', '_'.join([alg_name, env_id]))
    Q = np.load(os.path.join(path, 'Q_table.npy'))
    for i in range(num_episodes):
        ## Reset environment and get first new observation
        s = env.reset()
        rAll = 0
        ## The Q-Table learning algorithm
        for j in range(99):
            ## Choose an action by greedily (with noise) picking from Q table
            a = np.argmax(Q[s, :])
            ## Get new state and reward from environment
            s1, r, d, _ = env.step(a)
            ## Update Q-Table with new knowledge
            rAll += r
            s = s1
            if d is True:
                break
        print(
            'Testing  | Episode: {}/{}  | Episode Reward: {:.4f}  | Running Time: {:.4f}'.format(
                i + 1, num_episodes, rAll,
                time.time() - t0
            )
        )

 2.DQN

Deep network + Qlearning = DQN

在Qlearning中,有一个Qtable,记录着在每一个状态下,各个动作的Q值。

Qtable的作用是当输入状态S,通过查表返回能够获得最大Q值的动作A。也就是需要找一个S-A的对应关系。

这种方式很适合格子游戏。因为格子游戏中的每一个格子就是一个状态,但在现实生活中,很多状态并不是离散而是连续的。

例如在GYM中经典的CartPole游戏,杆子的角度是连续而不是离散的。在Atari游戏中,状态也是连续的。

遇到这些情况,Qtable就没有办法解决。

Qtable的作用就是找一个S-A的对应关系。所以我们就可以用一个函数F表示,我们有F(S) = A。这样我们就可以不用查表了,而且还有个好处,函数允许连续状态的表示。

这时候,我们深度神经网络就可以派上用场了。因为神经网络可以看成一个万能的函数

这个万能函数接受输入一个状态S,它能告诉我,每个动作的Q值是怎样的。

Qlearning和DQN并没有根本的区别。只是DQN用神经网络,也就是一个函数替代了原来Qtable而已。解决连续问题。

更新当前状态St下的某动作A的Q值:Q(S,A),我们可以这样做:

1. 执行A,往前一步,到达St+1;

2. 把St+1输入Q网络,计算St+1下所有动作的Q值;

3. 获得最大的Q值加上奖励R作为更新目标;

4. 计算损失 - Q(S,A)相当于有监督学习中的logits - maxQ(St+1) + R 相当于有监督学习中的lables - 用mse函数,得出两者的loss

5. 用loss更新Q网络。 

用Q网络估算出来的两个相邻状态的Q值,他们之间的距离,就是一个r的距离。

和有监督学习不同,深度强化学习中,我们需要自己找更新目标。通常在马尔科夫链体系下,两个相邻状态状态差一个奖励r,经常能被利用。 

"""
Deep Q-Network Q(a, s)
-----------------------
TD Learning, Off-Policy, e-Greedy Exploration (GLIE).
Q(S, A) <- Q(S, A) + alpha * (R + lambda * Q(newS, newA) - Q(S, A))
delta_w = R + lambda * Q(newS, newA)
See David Silver RL Tutorial Lecture 5 - Q-Learning for more details.
Reference
----------
original paper: https://storage.googleapis.com/deepmind-media/dqn/DQNNaturePaper.pdf
EN: https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part-0-q-learning-with-tables-and-neural-networks-d195264329d0#.5m3361vlw
CN: https://zhuanlan.zhihu.com/p/25710327
Note: Policy Network has been proved to be better than Q-Learning, see tutorial_atari_pong.py
Environment
-----------
# The FrozenLake v0 environment
https://gym.openai.com/envs/FrozenLake-v0
The agent controls the movement of a character in a grid world. Some tiles of
the grid are walkable, and others lead to the agent falling into the water.
Additionally, the movement direction of the agent is uncertain and only partially
depends on the chosen direction. The agent is rewarded for finding a walkable
path to a goal tile.
SFFF       (S: starting point, safe)
FHFH       (F: frozen surface, safe)
FFFH       (H: hole, fall to your doom)
HFFG       (G: goal, where the frisbee is located)
The episode ends when you reach the goal or fall in a hole. You receive a reward
of 1 if you reach the goal, and zero otherwise.
Prerequisites
--------------
tensorflow>=2.0.0a0
tensorlayer>=2.0.0
To run
-------
python tutorial_DQN.py --train/test
"""
import argparse
import os
import time

import gym
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

import tensorlayer as tl

# add arguments in command  --train/test
parser = argparse.ArgumentParser(description='Train or test neural net motor controller.')
parser.add_argument('--train', dest='train', action='store_true', default=True)
parser.add_argument('--test', dest='test', action='store_true', default=True)
args = parser.parse_args()

tl.logging.set_verbosity(tl.logging.DEBUG)

#####################  hyper parameters  ####################
env_id = 'FrozenLake-v0'
alg_name = 'DQN'
lambd = .99  # decay factor
e = 0.1  # e-Greedy Exploration, the larger the more random
num_episodes = 10000
render = False  # display the game environment

##################### DQN ##########################


def to_one_hot(i, n_classes=None):
    a = np.zeros(n_classes, 'uint8')
    a[i] = 1
    return a


## Define Q-network q(a,s) that ouput the rewards of 4 actions by given state, i.e. Action-Value Function.
# encoding for state: 4x4 grid can be represented by one-hot vector with 16 integers.
def get_model(inputs_shape):
    ni = tl.layers.Input(inputs_shape, name='observation')
    nn = tl.layers.Dense(4, act=None, W_init=tf.random_uniform_initializer(0, 0.01), b_init=None, name='q_a_s')(ni)
    return tl.models.Model(inputs=ni, outputs=nn, name="Q-Network")


def save_ckpt(model):  # save trained weights
    path = os.path.join('model', '_'.join([alg_name, env_id]))
    if not os.path.exists(path):
        os.makedirs(path)
    tl.files.save_weights_to_hdf5(os.path.join(path, 'dqn_model.hdf5'), model)


def load_ckpt(model):  # load trained weights
    path = os.path.join('model', '_'.join([alg_name, env_id]))
    tl.files.save_weights_to_hdf5(os.path.join(path, 'dqn_model.hdf5'), model)


if __name__ == '__main__':

    qnetwork = get_model([None, 16])
    qnetwork.train()
    train_weights = qnetwork.trainable_weights

    optimizer = tf.optimizers.SGD(learning_rate=0.1)
    env = gym.make(env_id)

    t0 = time.time()
    if args.train:
        all_episode_reward = []
        for i in range(num_episodes):
            ## Reset environment and get first new observation
            s = env.reset()  # observation is state, integer 0 ~ 15
            rAll = 0
            if render: env.render()
            for j in range(99):  # step index, maximum step is 99
                ## Choose an action by greedily (with e chance of random action) from the Q-network
                allQ = qnetwork(np.asarray([to_one_hot(s, 16)], dtype=np.float32)).numpy()
                a = np.argmax(allQ, 1)

                ## e-Greedy Exploration !!! sample random action
                if np.random.rand(1) < e:
                    a[0] = env.action_space.sample()
                ## Get new state and reward from environment
                s1, r, d, _ = env.step(a[0])
                if render: env.render()
                ## Obtain the Q' values by feeding the new state through our network
                Q1 = qnetwork(np.asarray([to_one_hot(s1, 16)], dtype=np.float32)).numpy()

                ## Obtain maxQ' and set our target value for chosen action.
                maxQ1 = np.max(Q1)  # in Q-Learning, policy is greedy, so we use "max" to select the next action.
                targetQ = allQ
                targetQ[0, a[0]] = r + lambd * maxQ1
                ## Train network using target and predicted Q values
                # it is not real target Q value, it is just an estimation,
                # but check the Q-Learning update formula:
                #    Q'(s,a) <- Q(s,a) + alpha(r + lambd * maxQ(s',a') - Q(s, a))
                # minimizing |r + lambd * maxQ(s',a') - Q(s, a)|^2 equals to force Q'(s,a) ≈ Q(s,a)
                with tf.GradientTape() as tape:
                    _qvalues = qnetwork(np.asarray([to_one_hot(s, 16)], dtype=np.float32))
                    _loss = tl.cost.mean_squared_error(targetQ, _qvalues, is_mean=False)
                grad = tape.gradient(_loss, train_weights)
                optimizer.apply_gradients(zip(grad, train_weights))

                rAll += r
                s = s1
                ## Reduce chance of random action if an episode is done.
                if d ==True:
                    e = 1. / ((i / 50) + 10)  # reduce e, GLIE: Greey in the limit with infinite Exploration
                    break

            ## Note that, the rewards here with random action
            print('Training  | Episode: {}/{}  | Episode Reward: {:.4f} | Running Time: {:.4f}' \
                  .format(i, num_episodes, rAll, time.time() - t0))

            if i == 0:
                all_episode_reward.append(rAll)
            else:
                all_episode_reward.append(all_episode_reward[-1] * 0.9 + rAll * 0.1)

        save_ckpt(qnetwork)  # save model
        plt.plot(all_episode_reward)
        if not os.path.exists('image'):
            os.makedirs('image')
        plt.savefig(os.path.join('image', '_'.join([alg_name, env_id])))

    if args.test:
        load_ckpt(qnetwork)  # load model
        for i in range(num_episodes):
            ## Reset environment and get first new observation
            s = env.reset()  # observation is state, integer 0 ~ 15
            rAll = 0
            if render: env.render()
            for j in range(99):  # step index, maximum step is 99
                ## Choose an action by greedily (with e chance of random action) from the Q-network
                allQ = qnetwork(np.asarray([to_one_hot(s, 16)], dtype=np.float32)).numpy()
                a = np.argmax(allQ, 1)  # no epsilon, only greedy for testing

                ## Get new state and reward from environment
                s1, r, d, _ = env.step(a[0])
                rAll += r
                s = s1
                if render: env.render()
                ## Reduce chance of random action if an episode is done.
                if d: break

            print('Testing  | Episode: {}/{}  | Episode Reward: {:.4f} | Running Time: {:.4f}' \
                  .format(i, num_episodes, rAll, time.time() - t0))

三、PG策略算法


总结

对深度强化学习的初步学习,从强化学习到深度强化学习,学习了一下算法,之后还需要深入实验,如GYM等。加油加油。

好的参考:

强化学习极简入门:通俗理解MDP、DP MC TC和Q学习、策略梯度、PPO_强化学习极简入门:通俗理解mdp、dpmc-CSDN博客

【强化学习】Q-Learning算法详解-CSDN博客

强化学习方法汇总 | 莫烦Python (mofanpy.com)

深度强化学习【1】-强化学习入门必备基础(含Python迷宫游戏求解实例)_强化学习 迷宫-CSDN博客

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

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

相关文章

vue-electron 项目创建记录及注意事项

vue-electron 项目创建记录及注意事项 1、使用vue ui或者命令行创建vue项目 2、添加electron插件 3、安装element-plus: npm install --save element-plus 4、修改配置文件如下图: vue.config.js增加配置&#xff1a; pluginOptions:{ electronOutput: { contextIsolation…

centos物理电脑安装过程(2024年1月)

开机时&#xff1a;CtrlAltDelete键重启电脑 重启开始时&#xff1a;按F11&#xff0c;桌面弹出蓝色框&#xff0c;选择第二个SSK SFD142 1.00&#xff0c;回车 选择install centos7安装 选择后弹出选择安装选项&#xff0c;选择语言 连接无线网络 安装设置&#xff0c;选择磁…

gpt批量原创文章生成器,不限制内容的生成器

在当今的数字化时代&#xff0c;内容创作是网站持续发展的重要组成部分。然而&#xff0c;对于拥有大量内容需求的网站来说&#xff0c;手动创作文章可能会耗费大量时间和精力。为了解决这一问题&#xff0c;许多GPT&#xff08;生成式预训练模型&#xff09;文章生成软件应运而…

lv20 QT事件

1 事件模型 2 事件处理 virtual void keyPressEvent(QKeyEvent *event) virtual void keyReleaseEvent(QKeyEvent *event) virtual void mouseDoubleClickEvent(QMouseEvent *event) virtual void mouseMoveEvent(QMouseEvent *event) virtual void mousePressEvent(QMou…

C++笔记(六)--- 静态成员变量/函数(static)

目录 C语言中静态变量 C静态成员变量 C静态成员函数 C语言中静态变量 1.函数内部用static修饰的变量&#xff0c;只能在此函数使用&#xff0c;但所修饰的变量不随函数释放而释放&#xff0c;下次调用时的值仍为上次结束时的值2.static修饰的全局变量只能在其定义的文件使用…

吴恩达《机器学习》学习笔记

本笔记资料来源于 http://www.ai-start.com/ml2014/&#xff0c;该笔记来自于https://blog.csdn.net/dadapongi6/article/details/105668394&#xff0c;看了忘&#xff0c;忘了看&#xff0c;再看一遍。 时间统计&#xff1a;2024.2.29 5个番茄钟&#xff0c;从week1开始&…

智慧城市:打造宜居环境,引领未来可持续发展

随着科技的不断进步与创新&#xff0c;我们的城市正步入一个崭新的时代——智慧城市。智慧城市是指运用信息技术和大数据等现代科技手段&#xff0c;对城市基础设施、公共服务和社会管理进行智能化改造&#xff0c;实现城市各领域的智能化、信息化和高效化。今天&#xff0c;就…

【六袆 - MySQL】MySQL 5.5及更高版本中,InnoDB是新表的默认存储引擎;

InnoDB 这是一个MySQL组件&#xff0c;结合了高性能和事务处理能力&#xff0c;以确保可靠性、健壮性和并发访问。它体现了ACID设计哲学。它作为一个存储引擎存在&#xff0c;处理使用ENGINEINNODB子句创建的或修改的表。请参阅第14章“InnoDB存储引擎”以获取有关架构细节和管…

Prometheus 安装指南

目录 介绍 安装 介绍 Prometheus是一款开源监控系统&#xff0c;适用于容器化和微服务。它使用多维数据模型&#xff0c;支持PromQL查询语言&#xff0c;可以通过多种方式采集数据。具备灵活的告警和通知机制&#xff0c;可集成图形工具创建仪表盘。通过本地存储高效保存时间…

2024-02-29(Flink)

1.Flink原理&#xff08;角色分工&#xff09; 2.Flink执行流程 on yarn版&#xff1a; 3.相关概念 1&#xff09;DataFlow&#xff1a;Flink程序在执行的时候会被映射成一个数据流模型&#xff1b; 2&#xff09;Operator&#xff1a;数据流模型中的每一个操作被称作Operat…

IDC 中搭建 Serverless 应用平台:通过 ACK One 和 Knative 玩转云资源

作者&#xff1a;元毅、庄宇 如何打造云上&#xff08;公共云&#xff09;、云下&#xff08;IDC 数据中心&#xff09;统一的云原生 Serverless 应用平台&#xff0c;首先我们来看一下 ChatGPT 4 会给出什么样的答案&#xff1a; 如何打造云上、云下统一的云原生 Serverless…

Linux Shell脚本练习(三)

1、测试用户名与密码是否正确。 2、输出1-1000内的素数。 3、对 100 以内的所有正整数相加求和(1234...100)。 4、输出9*9 乘法表。 5、编写脚本,显示进度条。 、 6、输入三个数并进行升序排序

PVE开启IPV6

echo "net.ipv6.conf.all.accept_ra2net.ipv6.conf.default.accept_ra2net.ipv6.conf.vmbr0.accept_ra2net.ipv6.conf.all.autoconf2net.ipv6.conf.default.autoconf2net.ipv6.conf.vmbr0.autoconf2" > /etc/sysctl.conf然后执行 sysctl -p最后再查询IP地址即可看…

技术实践|百度安全「大模型内容安全」高级攻击风险评测

1、引子 2023年10月16日&#xff0c;OWASP发布了《OWASP Top 10 for LLM Applications》&#xff0c;这对于新兴的大语言模型安全领域&#xff0c;可谓一份纲领性的重要报告。 OWASP是开放式Web应用程序安全项目&#xff08;Open Web Application Security Project&#xff0…

基于springboot+vue的编程训练系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Web自动化测试平台开发---Automated_platform

一、项目简介 历时一个假期&#xff0c;Automated_platform 第一版完工&#xff0c;是一款基于po模式的自动化测试平台,采用后端技术为DjangoceleryRabbitMQmysql 配置mysql数据库&#xff0c;进行数据迁移后&#xff0c;运行项目后&#xff0c;即可成功访问http://127.0.0.1:8…

【通信基础知识】完整通信系统的流程图及各模块功能详解

2024.2.29 抱歉最近在写毕设大论文&#xff0c;因此没有太多时间更新。然而&#xff0c;在写论文的过程中&#xff0c;发现自己对通信系统的了解还不够全明白&#xff0c;因此差了一些硕博论文总结了一个完整的通信系统流程图。若有不对的地方请多多指正//部分内容有参考ChatGP…

SpringCloud Alibaba(保姆级入门及操作)

第一章 微服务概念 1.0 科普一些术语 科普一下项目开发过程中常出现的术语,方便后续内容的理解。 **服务器:**分软件与硬件,软件:类型tomcat这种跑项目的程序, 硬件:用来部署项目的电脑(一般性能比个人电脑好) **服务:**操作系统上术语:一个程序,开发中术语:一个…

nm readelf objdump objcopy 命令之间的关系

nm readelf objdump objcopy 命令之间的关系 在解析可执行文件和链接库时&#xff0c;经常涉及到上述命令&#xff0c;但之前一直没有梳理清楚这几个命令之间的关系。如下整理了 概述 objdump, readelf, nm, 和 objcopy 是 GNU Binutils 套件的一部分&#xff0c;它们用于处…

Opencv基础与学习路线

Opencv Opencv每一篇目具体&#xff1a; Opencv(1)读取与图像操作 Opencv(2)绘图与图像操作 Opencv(3)详解霍夫变换 Opencv(4)详解轮廓 Opencv(5)平滑处理 具体Opencv相关demo代码欢迎访问我的github仓库&#xff08;包含python和c代码&#xff09; demo代码 文章目录 Opencv一…