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用法解释
TensorFlow与我们正常的编程思维略有不同:TensorFlow中的语句不会立即执行;而是等到开启会话session的时候,才会执行session.run()中的语句。如果run中涉及到其他的节点,也会执行到。
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格式的数据,只能使用普通格式传入。
显示变量
print(sess.run(state))
初始化变量
sess.run(tf.global_variables_initializer())
更改会话中变量的值
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
给占位符赋值
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
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 # 属性名
)