关于强化学习中Q-learning和DQN的原理以及在论文中应用_q-learning论文-程序员宅基地

技术标签: 算法  人工智能  

本文中提到的论文应用环境以及代码均来自论文《Spectrum Sharing in Vehicular Networks Based on Multi-Agent Reinforcement Learning》,对于应用场景和其他公式的分析见我的此篇文章

强化学习的基本概念:

强化学习的主体:环境、代理agent
强化学习中的数据量:状态state、动作/行为action、奖励reward
强化学习的目标:找到能使长期累计奖励(某时刻到结束所有奖励的总和)最大化的策略
代理通过与环境进行数据信息的交互进行学习,机器需要通过尝试来发现各个动作产生的结果,而没有训练数据告诉机器应当做哪个动作

类比:强化学习中的“策略”相当于监督学习中的分类器(离散)或者回归器(连续),模型形式没有差别,但是在强化学习中没有监督学习中的有标记样本,只有等到最终的结果揭晓,才能通过“反思"之前动作是否正确来进行学习,因此强化学习在某种程度上可以看作具有”延迟标记信息“的监督学习问题

多代理与环境交互示例

策略/决策函数π

在代理与环境进行交互的过程中我们期望代理可以学习到最终能完成我们目标的策略(policy),对这个策略进行数据抽象可以抽象为函数,在数学上,这个函数表示如下,函数是个概率密度函数
在这里插入图片描述

状态转移函数p

另外一个概念叫做状态转移概率函数,状态转移是随机的(马尔可夫状态转移的随机性),其随机性是从环境里来的,将状态转移函数使用p函数进行表示
在这里插入图片描述

对上述式子中的元素进行解释,其中大写的A和S 表示随机变量,而小写的a和s表示所取到的具体的值

关于状态S和动作A的随机性

  • 动作的随机性:动作A根据policy函数π随机抽样得到的
  • 状态转移的随机性:在agent做出动作后,环境生成的下一个状态S具有随机性,根据p函数进行随机抽样

在这里插入图片描述

累计奖励值U

表示的为从当前时刻到最终任务结束累计的奖励值的总和,未来奖励的累计总和
在这里插入图片描述

  • 其中是指贴现率(0≦≦1),考虑未来的奖励,但是越久远的奖励在考虑其中时占比应当适当的减小。是一个超参数

越久远的应该占比越小是因为,如果很久之后的未来某次操作获得的奖励很大,但是中间过程的某一部失败率很大,那么可能会导致平均下来最终的结果并不理想,所以对于久远之后的奖励应该慎重考虑
此处放置网上搜索到的贴现率的定义:贴现率:又称“折现率”。指今后收到或支付的款项折算为现值的利率
通俗的讲,2003年的10块钱和现在(2023年)的10块钱能买的东西价值不一样了,那么可能现在(2023年)和20年后(2043年)的10块钱所能购买的东西的价值也不一样了

  • 对于任意的未来时刻i的奖励,会取决于状态和动作,所以就和t时刻开始未来所有的状态和动作都有关
  • 状态是随机变量,概率密度为( ′ | , )= ( ′ = ′ | = , = ),动作是随机变量,概率密度为( | ) = ( = | = ),所以也是随机变量

两种价值函数

在模型已知时,对任何策略能估计出该模型带来的期望累计奖励,以此来进行策略评估
动作价值函数 Action-value function
在这里插入图片描述

  • 与, , 有关,期望将未来的动作和状态都消除了,只留下状态和动作两变量
  • 含义:当处于状态s时, 给所有动作a打分

状态价值函数 State-value function
在这里插入图片描述

  • 与, 有关,与a无关,期望将所有A都考虑其中,所以函数V与A无关
  • 在使用某个决策的时候,评价当前状态(快赢了or快输了),状态s越好, ()越大
  • () 还可以评价决策的好坏,越好, (())越大(期望/均值)

两类学习方法

在对某个策略的累计奖励进行评估后,若发现其并非最优策略,则希望对其进行改进,下面是两种改进算法。算法的分类主要有基于策略(Policy-Based)和基于数值(Value-Based):最终目标都是最大化整体奖励,找到最优的策略。

基于决策略Policy-Based reinforcement learning

→ 每一步选择按照决策函数选择,目标函数:优化决策函数(概率),最大化奖励的期望值
在这里插入图片描述
参考文章指路

基于数值Value-Based reinforcement learning

→ 每一步选择按照最大未来奖励选择,目标函数:最大化未来累计奖励函数
在这里插入图片描述
参考文章指路


算法

以上为强化学习的基础知识的铺垫,下面将是q-learning、DQN和double DQN
这三种算法都是上述提到的value-based算法

q-learning

Q-Learning的算法流程如下
在这里插入图片描述

Q-Learning的核心主要为Q-Table,通过判断每一步action的value来进行下一步的动作,以一个简单的左右平移为例
在这里插入图片描述
通过选择数值较大的动作作为下一步的动作
-贪心算法:一般情况下,为了避免局部最优情况,从而进行更多的探索,会设置一个概率值,使算法以1-概率按照表格中的数值选择最大,以概率随机进行选择,这就是-贪心算法(比如在论文中选择的是线性退火算法)。
若奖励值的不确定性较大,例如概率分布较宽时,需要更多的探索,此时需要较大的值;若奖励值的不确定性较小,例如概率分布比较集中时,少量的探索就可以得到很好的近似真实奖励,此时需要的值较小。通常令去一个比较小的常数,如0.1或者0.01.然而,若果尝试的次数非常大,那么在一段时间后,单次奖励值可以很好的近似出来,不再需要探索,这种情况下可以让随着尝试次数的增加而逐步减小,例如令=1/√t。

def predict(sess, s_t, ep, test_ep = False):

    n_power_levels = len(env.V2V_power_dB_List)
    if np.random.rand() < ep and not test_ep:
        pred_action = np.random.randint(n_RB*n_power_levels)
    else:
        pred_action = sess.run(g_q_action, feed_dict={
    x: [s_t]})[0]
    return pred_action

DQN

最原始的Q-learning算法在执行过程中始终需要一个Q表进行记录,当维数不高的时候Q表尚可满足需求,但是遇到指数级别的维数时,Q表的效率就十分有限
DQN使用深度神经网络作为值函数的近似工具,用神经网络去近似Q函数(根据Q对求最大化得到的最优动作价值函数Q),将这个神经网络记为Q*(s,a;w),其中神经网络的参数为w,输入是状态s,输出为对所有可能动作的打分,每一个动作对应一个分数,通过奖励值来学习神经网络。这个神经网络给动作的打分会逐步改进,越来越准。
在这里插入图片描述
DQN对于policy的迭代更新过程(来自李宏毅老师ppt)(右边为DQN原理与现实问题的联想)
在这里插入图片描述
如果我想从秦皇岛去上海,途中经过北京,对于初始(或者旧的决策)我得出,从秦皇岛到北京可能需要3小时,从北京到上海可能需要7小时,那么我可以得到秦皇岛到上海的Q函数为10小时。
在这里插入图片描述
但是我现在坐车从秦皇岛到北京,发现实际上只用了2小时,也就是我得到了旅行途中一部分真实的时间,因为得到了一部分真实的数据,所以我打算对我原来的决策信息进行更新,现在由我得到的真实信息秦皇岛-北京的2小时,和我估计的北京-上海的7小时,我得到了一个比之前的决策信息可靠一点的Q函数9小时。
在这里插入图片描述
使用这个新的Q函数对神经网络进行训练,这是一个回归问题
在这里插入图片描述

double DQN

Double DQN和DQN之前的区别主要在于训练过程中的目标函数中(_+1) 因为是由决策函数得出的,所以也就是max (_+1, a)
DQN的目标函数
在这里插入图片描述
double DQN的目标函数
在这里插入图片描述
也就是使用两个Q函数,选择action的Q函数和计算value的Q函数不是同一个函数,避免过估计现象发生
具体原理参考此文

下面解析一下论文源码与此相关的部分
下面部分为搭建神经网络的部分,这里主要记录一下优化器RMSProp optim = tf.train.RMSPropOptimizer(learning_rate=0.001, momentum=0.95, epsilon=0.01).minimize(g_loss)
在这里插入图片描述

原理见文章

# main_marl_train.py中
# 搭建神经网络
n_hidden_1 = 500
n_hidden_2 = 250
n_hidden_3 = 120
n_input = len(get_state(env=env))
n_output = n_RB * len(env.V2V_power_dB_List)

g = tf.Graph()
with g.as_default():
    # ============== Training network ========================
    x = tf.placeholder(tf.float32, [None, n_input])

    w_1 = tf.Variable(tf.truncated_normal([n_input, n_hidden_1], stddev=0.1))
    w_2 = tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2], stddev=0.1))
    w_3 = tf.Variable(tf.truncated_normal([n_hidden_2, n_hidden_3], stddev=0.1))
    w_4 = tf.Variable(tf.truncated_normal([n_hidden_3, n_output], stddev=0.1))

    b_1 = tf.Variable(tf.truncated_normal([n_hidden_1], stddev=0.1))
    b_2 = tf.Variable(tf.truncated_normal([n_hidden_2], stddev=0.1))
    b_3 = tf.Variable(tf.truncated_normal([n_hidden_3], stddev=0.1))
    b_4 = tf.Variable(tf.truncated_normal([n_output], stddev=0.1))

    layer_1 = tf.nn.relu(tf.add(tf.matmul(x, w_1), b_1))
    layer_1_b = tf.layers.batch_normalization(layer_1)
    layer_2 = tf.nn.relu(tf.add(tf.matmul(layer_1_b, w_2), b_2))
    layer_2_b = tf.layers.batch_normalization(layer_2)
    layer_3 = tf.nn.relu(tf.add(tf.matmul(layer_2_b, w_3), b_3))
    layer_3_b = tf.layers.batch_normalization(layer_3)
    y = tf.nn.relu(tf.add(tf.matmul(layer_3, w_4), b_4))
    g_q_action = tf.argmax(y, axis=1)   #取出y中元素最大值所对应的索引

    # compute loss
    g_target_q_t = tf.placeholder(tf.float32, None, name="target_value")
    g_action = tf.placeholder(tf.int32, None, name='g_action')
    action_one_hot = tf.one_hot(g_action, n_output, 1.0, 0.0, name='action_one_hot')
    q_acted = tf.reduce_sum(y * action_one_hot, reduction_indices=1, name='q_acted')

    g_loss = tf.reduce_mean(tf.square(g_target_q_t - q_acted), name='g_loss')
    optim = tf.train.RMSPropOptimizer(learning_rate=0.001, momentum=0.95, epsilon=0.01).minimize(g_loss)

    # ==================== Prediction network ========================
    x_p = tf.placeholder(tf.float32, [None, n_input])

    w_1_p = tf.Variable(tf.truncated_normal([n_input, n_hidden_1], stddev=0.1))
    w_2_p = tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2], stddev=0.1))
    w_3_p = tf.Variable(tf.truncated_normal([n_hidden_2, n_hidden_3], stddev=0.1))
    w_4_p = tf.Variable(tf.truncated_normal([n_hidden_3, n_output], stddev=0.1))

    b_1_p = tf.Variable(tf.truncated_normal([n_hidden_1], stddev=0.1))
    b_2_p = tf.Variable(tf.truncated_normal([n_hidden_2], stddev=0.1))
    b_3_p = tf.Variable(tf.truncated_normal([n_hidden_3], stddev=0.1))
    b_4_p = tf.Variable(tf.truncated_normal([n_output], stddev=0.1))

    layer_1_p = tf.nn.relu(tf.add(tf.matmul(x_p, w_1_p), b_1_p))
    layer_1_p_b = tf.layers.batch_normalization(layer_1_p)

    layer_2_p = tf.nn.relu(tf.add(tf.matmul(layer_1_p_b, w_2_p), b_2_p))
    layer_2_p_b = tf.layers.batch_normalization(layer_2_p)

    layer_3_p = tf.nn.relu(tf.add(tf.matmul(layer_2_p_b, w_3_p), b_3_p))
    layer_3_p_b = tf.layers.batch_normalization(layer_3_p)

    y_p = tf.nn.relu(tf.add(tf.matmul(layer_3_p_b, w_4_p), b_4_p))

    g_target_q_idx = tf.placeholder('int32', [None, None], 'output_idx')
    target_q_with_idx = tf.gather_nd(y_p, g_target_q_idx)

    init = tf.global_variables_initializer()
    saver = tf.train.Saver()

if语句中为double DQN算法,第一行代码pred_action为下图中的Q函数,q_t_plus_1为下图中的Q’函数,即使用两个Q函数,选择action的Q函数和计算value的Q函数不是同一个函数,避免过估计现象发生,batch_target_q_t为累计奖励(包含贴现率current_agent.discount)
在这里插入图片描述

else语句中为DQN算法 q_t_plus_1为决策做出的选择a=(_+1),max_q_t_plus_1为在同一Q函数中选择的Q的最大值,batch_target_q_t为累计奖励(包含贴现率current_agent.discount)
在这里插入图片描述

在if…else语句外的最后一行语句通过计算损失函数Loss对神经网络进行更新

def q_learning_mini_batch(current_agent, current_sess):
    """ Training a sampled mini-batch """

    batch_s_t, batch_s_t_plus_1, batch_action, batch_reward = current_agent.memory.sample()

    if current_agent.double_q:  # double DQN
        pred_action = current_sess.run(g_q_action, feed_dict={
    x: batch_s_t_plus_1})
        q_t_plus_1 = current_sess.run(target_q_with_idx, {
    x_p: batch_s_t_plus_1, g_target_q_idx: [[idx, pred_a] for idx, pred_a in enumerate(pred_action)]})
        batch_target_q_t = current_agent.discount * q_t_plus_1 + batch_reward
    else:   # DQN
        q_t_plus_1 = current_sess.run(y_p, {
    x_p: batch_s_t_plus_1})
        max_q_t_plus_1 = np.max(q_t_plus_1, axis=1)
        batch_target_q_t = current_agent.discount * max_q_t_plus_1 + batch_reward

    _, loss_val = current_sess.run([optim, g_loss], {
    g_target_q_t: batch_target_q_t, g_action: batch_action, x: batch_s_t})
    return loss_val

参考文章汇总
Q-learning原理及其实现方法_北木.的博客-程序员宅基地_qlearning原理
强化学习入门这一篇就够了!!!万字长文_CC-Mac的博客-程序员宅基地_强化学习
Value-Based Reinforcement Learning-DQN_CC-Mac的博客-程序员宅基地
Policy-based Reinforcement learning_CC-Mac的博客-程序员宅基地
深度强化学习系列(5): Double Q-Learning原理详解_@RichardWang的博客-程序员宅基地_double q-learning

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/x_fengmo/article/details/129031126

智能推荐

FTP命令字和返回码_ftp 登录返回230-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏13次。为了从FTP服务器下载文件,需要要实现一个简单的FTP客户端。FTP(文件传输协议) 是 TCP/IP 协议组中的应用层协议。FTP协议使用字符串格式命令字,每条命令都是一行字符串,以“\r\n”结尾。客户端发送格式是:命令+空格+参数+"\r\n"的格式服务器返回格式是以:状态码+空格+提示字符串+"\r\n"的格式,代码只要解析状态码就可以了。读写文件需要登陆服务器,特殊用..._ftp 登录返回230

centos7安装rabbitmq3.6.5_centos7 安装rabbitmq3.6.5-程序员宅基地

文章浏览阅读648次。前提:systemctl stop firewalld 关闭防火墙关闭selinux查看getenforce临时关闭setenforce 0永久关闭sed-i'/SELINUX/s/enforcing/disabled/'/etc/selinux/configselinux的三种模式enforcing:强制模式,SELinux 运作中,且已经正确的开始限制..._centos7 安装rabbitmq3.6.5

idea导入android工程,idea怎样导入Android studio 项目?-程序员宅基地

文章浏览阅读5.8k次。满意答案s55f2avsx2017.09.05采纳率:46%等级:12已帮助:5646人新版Android Studio/IntelliJ IDEA可以直接导入eclipse项目,不再推荐使用eclipse导出gradle的方式2启动Android Studio/IntelliJ IDEA,选择 import project3选择eclipse 项目4选择 create project f..._android studio 项目导入idea 看不懂安卓项目

浅谈AI大模型技术:概念、发展和应用_ai大模型应用开发-程序员宅基地

文章浏览阅读860次,点赞2次,收藏6次。AI大模型技术已经在自然语言处理、计算机视觉、多模态交互等领域取得了显著的进展和成果,同时也引发了一系列新的挑战和问题,如数据质量、计算效率、知识可解释性、安全可靠性等。城市运维涉及到多个方面,如交通管理、环境监测、公共安全、社会治理等,它们需要处理和分析大量的多模态数据,如图像、视频、语音、文本等,并根据不同的场景和需求,提供合适的决策和响应。知识搜索有多种形式,如语义搜索、对话搜索、图像搜索、视频搜索等,它们可以根据用户的输入和意图,从海量的数据源中检索出最相关的信息,并以友好的方式呈现给用户。_ai大模型应用开发

非常详细的阻抗测试基础知识_阻抗实部和虚部-程序员宅基地

文章浏览阅读8.2k次,点赞12次,收藏121次。为什么要测量阻抗呢?阻抗能代表什么?阻抗测量的注意事项... ...很多人可能会带着一系列的问题来阅读本文。不管是数字电路工程师还是射频工程师,都在关注各类器件的阻抗,本文非常值得一读。全文13000多字,认真读完大概需要2小时。一、阻抗测试基本概念阻抗定义:阻抗是元器件或电路对周期的交流信号的总的反作用。AC 交流测试信号 (幅度和频率)。包括实部和虚部。​图1 阻抗的定义阻抗是评测电路、元件以及制作元件材料的重要参数。那么什么是阻抗呢?让我们先来看一下阻抗的定义。首先阻抗是一个矢量。通常,阻抗是_阻抗实部和虚部

小学生python游戏编程arcade----基本知识1_arcade语言 like-程序员宅基地

文章浏览阅读955次。前面章节分享试用了pyzero,pygame但随着想增加更丰富的游戏内容,好多还要进行自己编写类,从今天开始解绍一个新的python游戏库arcade模块。通过此次的《连连看》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。_arcade语言 like

随便推点

【增强版短视频去水印源码】去水印微信小程序+去水印软件源码_去水印机要增强版-程序员宅基地

文章浏览阅读1.1k次。源码简介与安装说明:2021增强版短视频去水印源码 去水印微信小程序源码网站 去水印软件源码安装环境(需要材料):备案域名–服务器安装宝塔-安装 Nginx 或者 Apachephp5.6 以上-安装 sg11 插件小程序已自带解析接口,支持全网主流短视频平台,搭建好了就能用注:接口是公益的,那么多人用解析慢是肯定的,前段和后端源码已经打包,上传服务器之后在配置文件修改数据库密码。然后输入自己的域名,进入后台,创建小程序,输入自己的小程序配置即可安装说明:上传源码,修改data/_去水印机要增强版

verilog进阶语法-触发器原语_fdre #(.init(1'b0) // initial value of register (1-程序员宅基地

文章浏览阅读557次。1. 触发器是FPGA存储数据的基本单元2. 触发器作为时序逻辑的基本元件,官方提供了丰富的配置方式,以适应各种可能的应用场景。_fdre #(.init(1'b0) // initial value of register (1'b0 or 1'b1) ) fdce_osc (

嵌入式面试/笔试C相关总结_嵌入式面试笔试c语言知识点-程序员宅基地

文章浏览阅读560次。本该是不同编译器结果不同,但是尝试了g++ msvc都是先计算c,再计算b,最后得到a+b+c是经过赋值以后的b和c参与计算而不是6。由上表可知,将q复制到p数组可以表示为:*p++=*q++,*优先级高,先取到对应q数组的值,然后两个++都是在后面,该行运算完后执行++。在电脑端编译完后会分为text data bss三种,其中text为可执行程序,data为初始化过的ro+rw变量,bss为未初始化或初始化为0变量。_嵌入式面试笔试c语言知识点

57 Things I've Learned Founding 3 Tech Companies_mature-程序员宅基地

文章浏览阅读2.3k次。57 Things I've Learned Founding 3 Tech CompaniesJason Goldberg, Betashop | Oct. 29, 2010, 1:29 PMI’ve been founding andhelping run techn_mature

一个脚本搞定文件合并去重,大数据处理,可以合并几个G以上的文件_python 超大文本合并-程序员宅基地

文章浏览阅读1.9k次。问题:先讲下需求,有若干个文本文件(txt或者csv文件等),每行代表一条数据,现在希望能合并成 1 个文本文件,且需要去除重复行。分析:一向奉行简单原则,如无必要,绝不复杂。如果数据量不大,那么如下两条命令就可以搞定合并:cat a.txt >> new.txtcat b.txt >> new.txt……去重:cat new...._python 超大文本合并

支付宝小程序iOS端过渡页DFLoadingPageRootController分析_类似支付宝页面过度加载页-程序员宅基地

文章浏览阅读489次。这个过渡页是第一次打开小程序展示的,点击某个小程序前把手机的开发者->network link conditioner->enable & very bad network 就会在停在此页。比如《支付宝运动》这个小程序先看这个类的.h可以看到它继承于DTViewController点击左上角返回的方法- (void)back;#import "DTViewController.h"#import "APBaseLoadingV..._类似支付宝页面过度加载页

推荐文章

热门文章

相关标签