基于DQN和QMIX的控制延时算法

ChatGPT

从ChatGPT中询问得到一份简单的伪代码,如下:

1. 初始化经验回放缓存区 D,Q 网络 Q(s,a;θ) 和目标网络 Q'(s,a;θ')
2. 重复执行以下步骤:
   a. 根据 ε-greedy 策略选择行动 a_t
   b. 执行行动 a_t,得到下一个状态 s_{t+1} 和立即奖励 r_t
   c. 将转移数据 (s_t, a_t, r_t, s_{t+1}) 存储到经验回放缓存区 D 中
   d. 从 D 中随机采样一个小批量的经验数据 (s_i, a_i, r_i, s_{i+1}) 进行学习:
      i. 对于每个经验数据 (s_i, a_i, r_i, s_{i+1}),计算目标 Q 值 target:
         1. 如果 s_{i+1} 是终止状态,则 target = r_i
         2. 否则,选择一个时间步长 k,计算延迟奖励信号 R_{i,i+k} = r_{i+1} + γ^k max_a Q'(s_{i+k},a;θ')
            target = R_{i,i+k} + γ^k max_a Q(s_{i+k},a;θ)
      ii. 计算当前状态行动对的 Q 值:Q(s_i, a_i;θ)
      iii. 计算误差:error = target - Q(s_i, a_i;θ)
      iv. 使用均方误差损失函数对 Q 网络的参数 θ 进行梯度下降更新:
         θ = θ + α * ∇_θ Q(s_i, a_i;θ) * error
   e. 每 C 步将 Q 网络的参数 θ 复制到目标网络的参数 θ'

DQNPrioritizedReplay在平台中的使用


算法中名词解释

prioritized

中文意思:优先处理-ed

这是在DQNPrioritizedReplay中特殊的操作,经验池的选取不再是随机选取,而是使用某种方式来分辨不同经验的优先级。


Tensorflow用法解释

  1. TensorFlow与我们正常的编程思维略有不同:TensorFlow中的语句不会立即执行;而是等到开启会话session的时候,才会执行session.run()中的语句。如果run中涉及到其他的节点,也会执行到。

  1. Tesorflow模型中的所有的节点都是可以视为运算操作op或tensor


sess

tf.Session()

tf.Session():创建一个会话,当上下文管理器退出时会话关闭和资源释放自动完成。(with后会关闭)

tf.Session().as_default():创建一个默认会话,当上下文管理器退出时会话没有关闭,还可以通过调用会话进行run()和eval()操作。(with后不会关闭,可以调用sess.close()关闭,如下:)

import tensorflow as tf
a = tf.constant(1.0)
b = tf.constant(2.0)
with tf.Session().as_default() as sess:
   print(a.eval())  
   sess.close() # 关闭默认会话
print(b.eval(session=sess))# 此处会报错

Sess.run()

简单来说,就是运行各种节点。其中参数为:

run(fetches,   # 需要操作的张量
    feed_dict=None,   # 替换图中的某个tensor的值或设置graph的输入值。
    options=None,   
    run_metadata=None)

feed_dict不接受tensor格式的数据,只能使用普通格式传入。

  1. 显示变量

print(sess.run(state))
  1. 初始化变量

sess.run(tf.global_variables_initializer())
  1. 更改会话中变量的值

import tensorflow as tf
y = tf.Variable(1)
b = tf.identity(y)
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print(sess.run(b,feed_dict={y:3})) #使用3 替换掉
    #tf.Variable(1)的输出结果,所以打印出来3 
    #feed_dict{y.name:3} 和上面写法等价
 
    print(sess.run(b))  #由于feed只在调用他的方法范围内有效,所以这个打印的结果是 1
  1. 给占位符赋值

import tensorflow as tf
import numpy as np
 
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
 
output = tf.multiply(input1, input2)
 
with tf.Session() as sess:
    print(sess.run(output, feed_dict = {input1:[3.], input2: [4.]}))

tf.add()和tf.add_n()

tf.add()

tf.math.add(
    x, y, name=None
)

如果x和y维数相同,则直接相加,如果维数不同则会朝着维度较大的变量,进行广播:

import tensorflow as tf
a = tf.constant([[3, 5]]) # 广播为[[3, 5], [3, 5]]
b = tf.constant([[1, 6], [2, 9]])
c = tf.add(a, b)
sess = tf.Session()
print sess.run(c)
输出:
[[ 4 11]
 [ 5 14]]
 
import tensorflow as tf
a = tf.constant([[3], [5]]) # 广播为[[3, 3], [5, 5]]
b = tf.constant([[1, 6], [2, 9]])
c = tf.add(a, b)
sess = tf.Session()
print sess.run(c)
输出:
[[ 4  9]     【3+1,3+9】
 [ 7 14]]    【5+2,5+9】

tf.add_n()

使用tf.add_n则可以进行多个tensor(张量)的相加,但不可以广播,如下:

import tensorflow as tf
a = tf.constant([[3, 1], [5, 1]]) 
b = tf.constant([[1, 6], [2, 9]])
c = tf.add_n([a, b, a])
sess = tf.Session()
print sess.run(c)
输出:
[[ 7  8]
 [12 11]]

tf.constant

这是用来创建常量的函数。内部为:

tf.constant(
    value,
    dtype=None, # 数据类型,一般可以是tf.float32, tf.float64
    shape=None, # 张量的“形状”,即维数以及每一维的大小 张量(torch.Tensor)理解为二维数组的堆叠
    #[[-1 -1 -1]
    # [-1 -1 -1]]是一个shape=[2,3]的张量
    name='Const',# 字符串
    verify_shape=False # 如果修改为True的话表示检查value的形状与shape是否相符,如果不符会报错。
)

使用.eval()得到value的返回值,但是使用的时候必须创建一个话题sess(),如下:

sess=tf.Session()
with sess.as_default():
    print('结果是:', tensor.eval())

tf.Variable

用于创建变量,重名系统自行处理,变量是一个特殊的张量,其可以是任意的形状和类型的张量。语法格式如下:

tf.Variable.init(initial_value, 
                    trainable=True, 
                    collections=None, 
                    validate_shape=True,
                    name=None)
)

涉及到变量的相关操作必须通过session会话控制。在tensorflow的世界里变量的定义和初始化是被分开的。

初始化变量使用tf.global_variables_initializer()用于初始化所有变量;w.initializer用于初始化单个变量。

import tensorflow as tf

w = tf.Variable([6,8,6])    #创建变量w
print(w)    #查看变量的shape,而不是值。
with tf.Session() as sess:
    sess.run(w.initializer)        #初始化变量
    print(sess.run(w))    #查看变量的值

#运行结果:
<tf.Variable 'Variable:0' shape=(3,) dtype=int32_ref>
[6 8 6]

获取变量(如果没有则创建)使用tf.get_variable (),重名报错。

显示变量

w = tf.Variable([6,8,6])    #创建变量w
print(sess.run(w))
#运行结果:
[6 8 6]

tf.identity

tf.identity是tensorflow定义变量的一种方法,用变量来定义变量:

import tensorflow as tf
x = tf.Variable(-1.0)
y = tf.identity(x) # 此时x和y只是值相同,而用x=y则两个代表同一个东西,只是标签

tf.assign

import tensorflow as tf 

ref_a = tf.Variable(tf.constant(1))
ref_b = tf.Variable(tf.constant(2))
update = tf.assign(ref_a, 10)
# ref_a = tf.assign(ref_a, 10) 这样则不需要sess.run(update)就可以完成赋值
ref_sum = tf.add(ref_a, ref_b)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(update)  # 唯一修改的地方
    print(sess.run(ref_sum))
------------------------------------------------------
输出结果:12

只有当sess.run(update)后,ref才会被赋值为new_value,否则ref的值不变。

tf.placeholder

函数形式

tf.placeholder(
    dtype, # 数据类型。常用的是tf.float32,tf.float64等数值类型
    shape=None, # 数据形状。默认是None,就是一维值,也可以是多维(比如[2,3], [None, 3]表示列是3,行不定)
    name=None
)

作用是:是在神经网络构建graph的时候在模型中的占位,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据

import tensorflow as tf
import numpy as np
 
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
 
output = tf.multiply(input1, input2)
 
with tf.Session() as sess:
    print(sess.run(output, feed_dict = {input1:[3.], input2: [4.]}))

tf.get_collection

从一个集合中取出变量。

 tf.get_collection(
    key,
    scope=None
)

tf.variable_scope

可以让变量有相同的命名即共享变量,包括tf.get_variable得到的变量,还有tf.Variable变量

它返回的是一个用于定义创建variable(层)的op的上下文管理器。

可变范围允许创建新的variable并分享已创建的variable,同时提供检查,不会意外创建或共享。

with tf.variable_scope("foo"):
    with tf.variable_scope("bar"):
        v = tf.get_variable("v", [1])
assert v.name == "foo/bar/v:0"

此时v这个变量的作用范围就更新到了foo/bar,在其他地方可以使用同样名字的变量。

tf.nn.conv2d

这是一个卷积函数,上述链接的例子是以图像为例,具体使用方法见链接内容。

tf.nn.conv2d (input,
        filter, 
        strides, 
        padding,
        use_cudnn_on_gpu=None, 
        data_format=None, 
        name=None
)

tf.nn.relu

线性整流函数,又称修正线性单元,将输入小于0的值幅值为0,输入大于0的值不变。

tf.matmul

matmul(
    a,
    b,
    transpose_a=False,
    transpose_b=False,
    adjoint_a=False,
    adjoint_b=False,
    a_is_sparse=False,
    b_is_sparse=False,
    name=None
)

将矩阵 a 乘以矩阵 b,生成a * b

tf.GraphKeys

  1. tf.GraphKeys.GLOBAL_VARIABLES:

返回一个字符串"variables",表示使用tf.get_variable()或者tf.Variable()创建的变量都会放入名为"variables"的集合。 我们熟悉的tf.global_variables_initializer()就是初始化这个集合内的Variables。

tf.reduce_sum

按一定方式计算张量中元素之和

tf.reduce_sum(
    input_tensor, 
    axis=None,  # 指定按哪个维度进行加和,默认将所有元素进行加和;
    keepdims=None, # 默认为False,表示不维持原来张量的维度,反之维持原张量维度;
    name=None
)

tf.reduce_mean

tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。

reduce_mean(input_tensor,
                axis=None,
                keep_dims=False,
                name=None,
                reduction_indices=None)

tf.squared_difference

计算张量 x、y 对应元素差的平方,每个位置分别减去后平方

squared_difference(
    x,
    y,
    name=None
)

tf.cast

将x的数据格式转化成dtype数据类型.例如,原来x的数据格式是bool,

那么将其转化成float以后,就能够将其转化成0和1的序列。反之也可以

cast(
    x,
    dtype,
    name=None
)

tf.train.RMSPropOptimizer

RMSprop优化算法

tf.concat

用来拼接张量

  t1 = [[1, 2, 3], [4, 5, 6]]
  t2 = [[7, 8, 9], [10, 11, 12]]
  tf.concat([t1, t2], 0)  # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
  tf.concat([t1, t2], 1)  # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
 
  # tensor t3 with shape [2, 3]
  # tensor t4 with shape [2, 3]
  tf.shape(tf.concat([t3, t4], 0))  # [4, 3]
  tf.shape(tf.concat([t3, t4], 1))  # [2, 6]

tf.layers.dense

全连接层 相当于添加一个层

tf.layers.dense(

    inputs,# 输入该网络层的数据

    units,# 输出的维度大小,改变inputs的最后一维

    activation=None, # 激活函数,即神经网络的非线性变化

    use_bias=True,# 使用bias为True(默认使用),不用bias改成False即可,是否使用偏置项

    kernel_initializer=None,  ##卷积核的初始化器

    bias_initializer=tf.zeros_initializer(),  ##偏置项的初始化器,默认初始化为0

    kernel_regularizer=None,    ##卷积核的正则化,可选

    bias_regularizer=None,    ##偏置项的正则化,可选

    activity_regularizer=None,   ##输出的正则化函数

    kernel_constraint=None,   

    bias_constraint=None,

    trainable=True,

    name=None,  ##层的名字

    reuse=None  ##是否重复使用参数

)

tf.nn.softmax

tf.nn.softmax(logits,
            axis=None,
            name=None,
            dim=None)

输入: 全连接层(往往是模型的最后一层)的值

输出: 归一化的值,含义是属于该位置的概率;


python用法解释

with .. as..

with expression [as var]:

当expression返回的对象是支持环境管理协议的时候,就可以使用with。

as var是可选的,如果不使用as var,expression返回对象将被丢弃,如果使用as var,就会将expression的返回对象赋值给变量var。也就是接下来一部分的代码可以使用var变量。

推出with则关闭var。

简单来说,就是with开一个环境用as后的来代表,结束with自动关闭环境。

assert

在出现错误条件时就程序崩溃,后边加的是需要满足的内容,不满足则崩溃。

def  zero(s):
    a = int(s)
    assert a > 0,"a超出范围"   #这句的意思:如果a确实大于0,程序正常往下运行
    return a

zero("-2")  #但是如果a是小于0的,程序会抛出AssertionError错误,报错为参数内容“a超出范围”

[:,:]

arr[ : , : ]表示的是对数组中不同维度索引, 若存在关键字None则表示维度扩充

arr1 = np.array([1, 2, 3])
arr2 = np.array([1, 2, 3])
arr1[:,None]
# 则arr1变成了[  [1],[2],[3]  ] ,shape(3,1)
arr2[None,:]
# 则arr1变成了[  [1,2,3]  ] ,shape(1,3)

hasattr

如果对象有该属性返回 True,否则返回 False。

hasattr(object ,# 对象
         name # 属性名
)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岂止是狼子野心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值