关于强化学习中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

智能推荐

怎么取消两台计算机共享,小编教你两台电脑如何共享文件-程序员宅基地

文章浏览阅读1.3k次。有朋友问两台电脑怎么设置共享文件,为了方便我们有时需要设置两台电脑共享文件,可大大提升效率,但是并不知道怎么设置,小编这就给大家介绍局域网共享文件的设置方法,如果你需要可以按照这个教程操作一遍。两台电脑共享文件夹可以很方便的在一台电脑访问另一台电脑的共享文件,并对文件进行各种操作,就像是本机的文件夹一样,两台电脑共享文件夹要怎么做呢?小编现在给各位介绍一下两台电脑共享文件的方法吧。1、配置IP地址..._共享资料可以移除其他电脑吗

Android随笔:Android 效果——水波特效_安卓水波特效不能从圆心开始-程序员宅基地

文章浏览阅读625次。说明: 本文算法部分整理自 GameRes 上的资料,原作者 Imagic。我只是在学习 Android 的过程中,想到这个特效,然后就在Android 上实现出来,并在源算法的基础上添加了雨滴滴落特效,以及划过水面时的涟漪特效。 该程序在模拟器和真机上运行速度都较慢,需要进一步优化或使用 JNI 实现。 示例程序下载:http://www.cppblog.com/_安卓水波特效不能从圆心开始

【OCC学习6】DRAW的图形显示命令_draw test harness线框模式和渲染模式如何设置-程序员宅基地

文章浏览阅读1.1k次。ivtksetdispmode:对象显示模式,0-线框, 1--渲染模式。vaspects:设置对象的属性,包括颜色、材料、透明度、线宽等;vsetmaterial: 设置对象的材料;ivtkdump:将显示窗口保存为图片;vsetcolorbg:设置背景颜色;ivtkinit:创建VTK窗口。ivtkdisplay:显示对象。vtriangle:创建三角形。vplane:创建一个平面;ivtkerase:删除对象。vdir:列表显示的对象;vaxis:创建一个轴线;vpoint:创建一个点;......._draw test harness线框模式和渲染模式如何设置

python自动化运维快速入门,python自动化运维开发-程序员宅基地

文章浏览阅读722次,点赞19次,收藏20次。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取哈)

nuc970 uboot nand-boot,kernel, filesystem 烧录位置_nuc970 uboot-spl.bin-程序员宅基地

文章浏览阅读1.2k次。title: nuc970 uboot nand-boot,kernel, filesystem 烧录位置mathjax: truedate: 2018-11-15 17:39:49tags:nuc970嵌入式开发文件烧写categories: 嵌入式一 烧写到Nand Flash**1.1&nbsp;**相关文件说明l BSP版本:nuc970bsp-release-..._nuc970 uboot-spl.bin

Arcgis 坐标系统的识别与处理_shp数据没有坐标怎么处理-程序员宅基地

文章浏览阅读3w次,点赞32次,收藏141次。 Arcgis中坐标系统及单位必须知道的知识(敲黑板!)1. 如果数据不存在坐标系统,则计算时无单位,许多操作都不能进行。2.投影坐标系统是平面坐标系统,单位是米、千米这些;而地理坐标系统是球面坐标系统,单位是度。 定义投影是定义坐标系统的意思,而不是单指定义投影坐标系统。3.图层的地图单位和显示单位,地图单位是你这个图层的使用的实际单位,一般默认你添加进来的第一个数据的坐标系..._shp数据没有坐标怎么处理

随便推点

高性能JavaScript——8、编程实践-程序员宅基地

文章浏览阅读654次,点赞28次,收藏20次。道理很简单:JavaScript的原生部分在你写代码之前已经存在浏览器中了,并且都是低级语音编写的,诸如C++。这意味着这些方法会编译成机器码,成为浏览器的一部分,所以不会像自己写的JavaScript代码那样受到各种限制。当你在JavaScript代码中执行另一段JavaScript代码时,都会导致双重求值的性能消耗。预加载适用于一个函数马上就要被用到, 井且在整个页面的生命周期中频繁出现的场合。调用延迟加载函数时,第一次总会消耗较长的时间,但随后调用相同的函数就会更快,因为不需要再执行检测逻辑。

Linux环境 solr-7.4.0安装【一篇就够】_using _default configset with data driven schema f-程序员宅基地

文章浏览阅读1w次,点赞4次,收藏12次。一、环境说明三台安装了CenOS7操作系统的虚拟机master(192.168.11.128)、slave1(192.168.11.129)、slave2(192.168.11.30)二、下载solr安装包地址:http://mirrors.shu.edu.cn/apache/lucene/solr/7.4.0/solr-7.4.0.zip三、解压solr安装包[root@..._using _default configset with data driven schema functionality. not recommen

安装Modelsim_modelsim环境变量设置-程序员宅基地

文章浏览阅读4.5k次,点赞7次,收藏12次。下面步骤1-10来自网络:1、关闭杀毒软件,关闭防火墙!2、运行modelsim-win64-10.4-se.exe,选择默认的安装目录C:\modeltech64_10.43、安装过程始终点击yes,直到最后reboot,选择no4、复制patch_dll.bat和MentorKG.exe到安装目录C:\modeltech64_10.4\win645、右击取消C:\model..._modelsim环境变量设置

5.24 初阶测评讲解-程序员宅基地

文章浏览阅读36次。后置++ p++解引用是*p 还没++5.24 初阶测评讲解。前一个恒为真,=是赋值。注释会被替换成空格。早期c是没有库函数的。

dggrid 取出数值_dgrid 取行数据-程序员宅基地

文章浏览阅读202次。1.dgrid 获取数值时,一定要拼成dgrid 式样的数据结构。详见官网。_dgrid 取行数据

C# 身份证号码验证正则和验证函数-程序员宅基地

文章浏览阅读318次。做身份证验证的时候要求能够按照标准18位身份证验证,普通正则表达式不能满足需求,所以在网上找到了这个函数,很好用,虽然还是有漏洞,不过一般乱填的号码都能被屏蔽掉 身份证验证函数(标准18位验证) private bool CheckIDCard18(string idNumber) { long..._c#+18位身份证正则表达式

推荐文章

热门文章

相关标签