【强化学习】AC注释版本

## 强化学习 Actor-critic
# 和PG比起来主要的变化:
# 评估点由状态价值变成了TD_error,网络形式变了
# learn函数长得不一样
# action有一个优化函数,优化的是价值函数,希望最大化期望的reward,Critic网络也有一个reward,希望最小化现实和估计的误差(即td——error)
# Actor使用我们上一节讲到的策略函数,负责生成动作(Action)并和环境交互。而Critic使用我们之前讲到了的价值函数,负责评估Actor的表现,并指导Actor下一阶段的动作import gym
# import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.compat.v1.disable_eager_execution()
import numpy as np
import random
from collections import deque# Hyper Parameters
GAMMA = 0.95  # discount factor  衰减因子
LEARNING_RATE = 0.01  # 探索率class Actor():def __init__(self, env, sess):  # 初始化# init some parametersself.time_step = 0  # 某个地方需要用的步数self.state_dim = env.observation_space.shape[0]  # 状态维度self.action_dim = env.action_space.n  # 动作维度self.create_softmax_network()  # 创建softmax网络# Init session      初始化tensorflow参数self.session = tf.InteractiveSession()self.session.run(tf.global_variables_initializer())  # 初始化 tensorflow 参数。def create_softmax_network(self):  # 创建softmax网络# network weightsW1 = self.weight_variable([self.state_dim, 20])  # w1 权重,4*20的网络b1 = self.bias_variable([20])  # b1权重,y = w1*x + b1W2 = self.weight_variable([20, self.action_dim])b2 = self.bias_variable([self.action_dim])# input layerself.state_input = tf.placeholder("float", [None, self.state_dim])  # 状态输入层占位,多少组不知道,每组有4个状态self.tf_acts = tf.placeholder(tf.int32, [None, 2], name="actions_num")  # 给他的值对应于依据概率选择出来的动作self.td_error = tf.placeholder(tf.float32, None, "td_error")  # TD_error  PG中基于状态价值,这里评估点发生了一点变化# hidden layersh_layer = tf.nn.relu(tf.matmul(self.state_input, W1) + b1)  # 进行 y = w1*x + b1 的运算 ,并激活成可输出的状态# softmax layer# matmul返回两个数组的矩阵乘积,结果还是一个矩阵self.softmax_input = tf.matmul(h_layer, W2) + b2  # #进行 y = w2*x + b2 的运算,输出是两个是数(不确定)TODO# softmax outputself.all_act_prob = tf.nn.softmax(self.softmax_input, name='act_prob')  # softmax输出层,输出每个动作的概率# 计算logits 和 labels 之间的softmax 交叉熵# 函数先对 logits 进行 softmax 处理得到归一化的概率,将lables向量进行one-hot处理,然后求logits和labels的交叉熵:self.neg_log_prob = tf.nn.softmax_cross_entropy_with_logits(logits=self.softmax_input,labels=self.tf_acts)# TODO softmax_cross_entropy_with_logits 和 sparse_softmax_cross_entropy_with_logits 的区别是啥# 这句是在算损失函数了,定义为softmax交叉熵损失函数和TD_error的乘积self.exp = tf.reduce_mean(self.neg_log_prob * self.td_error)  # 策略梯度函数# 创建优化器 这里需要最大化当前策略的价值,因此需要最大化self.exp,即最小化-self.exp# 由于tensorflow要minimize误差 但是我们希望这个概率变大所以要加个负号# 利用tensorflow中的Adam优化算法最小化loss函数# Adam优化算法:是一个寻找全局最优点的优化算法,引入了二次方梯度校正。self.train_op = tf.train.AdamOptimizer(LEARNING_RATE).minimize(-self.exp)def weight_variable(self, shape):initial = tf.truncated_normal(shape)return tf.Variable(initial)def bias_variable(self, shape):initial = tf.constant(0.01, shape=shape)return tf.Variable(initial)def choose_action(self, observation):  # 依据概率选择动作"""选择动作 :这里的observation其实就是状态,当前的状态先传入state_input(也就相当于softmax网络的入口),softmax网络的输出是针对当前状态每个动作的概率,第一句就是运行了一个会话进行这个过程。#TODO prob_weights 应该是一个动作对应概率的矩阵,怎么查看数据类型来着忘了下一句就是依据概率选择动作了,选择概率最大的动作"""# np.newaxis功能:增加一个维度,具体见印象笔记prob_weights = self.session.run(self.all_act_prob, feed_dict={self.state_input: observation[np.newaxis, :]})# 这个range表示这个action的大小,后面的p表示概率分布, .ravel的意思是将数组维度拉成一维数组,也就是将矩阵向量化,见印象笔记action = np.random.choice(range(prob_weights.shape[1]), p=prob_weights.ravel())return actiondef learn(self, state, action, td_error):"""s,a 用于产生梯度上升法的方向,这时候的action是上面这个函数依据概率选择出来的动作td 来自Critic,用于告诉Actor这个方向对不对"""s = state[np.newaxis, :]  # 把state变成(4,1)的形状one_hot_action = np.zeros(self.action_dim)  # 初始化one_hot 形式的actionone_hot_action[action] = 1  # action是数字几就把第几个位置上的数变成1a = one_hot_action[np.newaxis, :]  # 然后再把它变成横向向量的形式# train on episodeself.session.run(self.train_op, feed_dict={self.state_input: s,self.tf_acts: a,     # 把动作传给了tf_actsself.td_error: td_error,})# critic网络中会用到的一些超级参数
EPSILON = 0.01  # final value of epsilon   epsilon 的最小值,当 epsilon 小于该值时,将不再随机选择行为。
REPLAY_SIZE = 10000  # experience replay buffer size  经验回放缓冲区大小
BATCH_SIZE = 32  # size of minibatch
REPLACE_TARGET_FREQ = 10  # frequency to update target Q networkclass Critic():def __init__(self, env, sess):# init some parametersself.time_step = 0self.epsilon = EPISODEself.state_dim = env.observation_space.shape[0]  # 状态维度self.action_dim = env.action_space.n  # 动作维度   TODO  .n是什么意思?self.create_Q_network()  # 创建Q网络self.create_training_method()  # 创建训练方法# Init session  初始化会话self.session = sessself.session.run(tf.global_variables_initializer())def create_Q_network(self):  # critic网络,使用类似于DQN的三层神经网络,但是只有一维输出值# network weightsW1q = self.weight_variable([self.state_dim, 20])b1q = self.bias_variable([20])W2q = self.weight_variable([20, 1])b2q = self.bias_variable([1])self.state_input = tf.placeholder(tf.float32, [1, self.state_dim], "state")  # 应该是指只输入了一组?# hidden layersh_layerq = tf.nn.relu(tf.matmul(self.state_input, W1q) + b1q)  # #进行 y = w1*x + b1 的运算 ,从线性状态激活成非线性状态# Q Value layerself.Q_value = tf.matmul(h_layerq, W2q) + b2q  # 进行 y = w2*x + b2 的运算,输出是两个是数(不确定)TODOdef create_training_method(self):  # 创建训练方法self.next_value = tf.placeholder(tf.float32, [1, 1], "v_next")self.reward = tf.placeholder(tf.float32, None, 'reward')# https://blog.csdn.net/tian_jiangnan/article/details/105047745# tf.variable_scope是一个变量管理器,下面的东东即使变量名一样,作用域不一样,引用的时候就不会出现穿插问题了with tf.variable_scope('squared_TD_error'):  # 在作用域名为squared_TD_error的作用域里面self.td_error = self.reward + GAMMA * self.next_value - self.Q_value  # 计算TD_errorself.loss = tf.square(self.td_error)  # tf.square是对td_error里面每一个元素求平方with tf.variable_scope('train'):  # 在作用域名为train的作用域里面# 利用tensorflow中的Adam优化算法最小化loss函数# Adam优化算法:是一个寻找全局最优点的优化算法,引入了二次方梯度校正。self.train_op = tf.train.AdamOptimizer(self.epsilon).minimize(self.loss)def train_Q_network(self, state, reward, next_state):   # 训练Q网络s, s_ = state[np.newaxis, :], next_state[np.newaxis, :]    # 当前状态和下一个状态# 由输入状态和Q_value计算状态价值函数v_ = self.session.run(self.Q_value, {self.state_input: s_})# 运行会话输出td_errortd_error, _ = self.session.run([self.td_error, self.train_op],{self.state_input: s, self.next_value: v_, self.reward: reward})  # 得到td误差return td_errordef weight_variable(self, shape):  # 权重变量initial = tf.truncated_normal(shape)  # 从一个正态分布片段中输出平均数值  shape:决定输出张量的形状return tf.Variable(initial)  # 更新参数,变量存在内存中def bias_variable(self, shape):  # 偏执变量initial = tf.constant(0.01, shape=shape)  # 生成常量矩阵return tf.Variable(initial)# Hyper Parameters
ENV_NAME = 'CartPole-v0'
EPISODE = 3000  # Episode limitation
STEP = 3000  # Step limitation in an episode
TEST = 10  # The number of experiment test every 100 episode  每训练100幕数据就做一次效果测试,测试10次取平均def main():# initialize OpenAI Gym env and dqn agentsess = tf.InteractiveSession()  # 开启会话env = gym.make(ENV_NAME)  # 导入环境actor = Actor(env, sess)  # 定义AC网络critic = Critic(env, sess)for episode in range(EPISODE):# initialize task# a) 初始化S为当前状态序列的第一个状态, 拿到其特征向量ϕ(S)state = env.reset()  # 初始化第一个状态# Trainfor step in range(STEP):  # 这部分actor网络和critic网络进行交互# b) 在Actor网络中使用ϕ(S)作为输入,输出动作A,基于动作A得到新的状态S′,反馈R。action = actor.choose_action(state)  # e-greedy action for train  输入状态,得到动作A#  c) 在Critic网络中分别使用ϕ(S),ϕ(S‘′)作为输入,得到Q值输出V(S),V(S′)next_state, reward, done, _ = env.step(action)  # 基于动作A得到新的状态next_state,回报reward# 由train_Q_network计算得到TD误差td_error = critic.train_Q_network(state, reward, next_state)  # gradient = grad[r + gamma * V(s_) - V(s)]# 更新Actor网络参数θactor.learn(state, action, td_error)  # true_gradient = grad[logPi(s,a) * td_error]   最大化价值函数state = next_state  # 为下一步做准备,下一个状态即为下一步的当前状态if done:  # 达到终止条件就退出循环break# Test every 100 episodesif episode % 100 == 0:total_reward = 0  # 初始化总回报for i in range(TEST):state = env.reset()  # 初始化环境for j in range(STEP):env.render()  # env.render()函数用于渲染出当前的智能体以及环境的状态action = actor.choose_action(state)  # # 根据状态选择动作state, reward, done, _ = env.step(action)  # 根据action执行step,得到三状态total_reward += reward  # 为了十次取一次平均,先加后除if done:  # 如果达到了终止条件,则退出breakave_reward = total_reward / TEST  # 求平均print('episode: ', episode, 'Evaluation Average Reward:', ave_reward)if __name__ == '__main__':main()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中sorted的用法append_Python中高阶函数sorted()用法

在Python中,有内置的排序方法:sorted(iterable, key, reverse)。Sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序。key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。print(s…

【强化学习】A3C原理

先解释一下什么叫异步、什么叫并发: **异步:**和同步相对,同步是顺序执行,而异步是彼此独立,在等待某个事件的过程中继续做自己的事,不要等待这一事件完成后再工作。线程是实现异步的一个方式,异…

天玑机器人颈椎_天玑骨科手术机器人亮相机器人大会 误差不到1毫米

千龙网北京8月22日讯(记者 詹婷婷)8月23日-27日,年度科技盛典--2017年世界机器人大会将登陆北京亦创国际会展中心。100多家国内外机器人顶尖企业将携手机器人亮相。大会期间将秀出人工智能系统、特种机器人、服务机器人、工业机器人以及智慧家居机器人等先进产品。参…

jboss eap 7.0_创建委托登录模块(用于JBoss EAP 6.1)

jboss eap 7.0[如果只想查看代码,请向下滚动] 动机 在RHQ中,我们需要一个安全域,该域可用于通过容器管理的安全性来保护REST-api及其Web应用程序。 过去,我只是使用经典的DatabaseServerLoginModule对DatabaseServerLoginModule进…

cdn简单理解_简单地聊聊CDN原理作用及实现方法

释放双眼,带上耳机,听听看~!相信只要会网上冲浪的都会接触到CDN吧,今天我们来聊聊对CDN的理解,给大家作为参考,本文将会以简单的描述来解释相关原理,供大家理解,希望相关专业同学进行…

JDK 10:FutureTask获取一个toString()

我已经有很长时间了,对于大多数具有独特属性的Java类,开发人员应该花时间重写Object.toString() ,即使它只是通过IDE生成的实现或使用诸如Apache之类的库类来实现Commons Lang的ToStringBuilder 。 如果要手动实现toSt…

【强化学习】A3C代码注释版本

########################################## # A3C做出的改进: # 解决AC难以收敛的问题 # 不一样的地方: #import threading # import tensorflow as tf import tensorflow.compat.v1 as tftf.compat.v1.disable_eager_execution() import numpy as np …

用python做人脸识别的程序怎么做_手把手教你用Python实现人脸识别

作者:Kangvcar简书专栏:http://www.jianshu.com/u/d9c480744afd环境要求:Ubuntu17.10Python 2.7.14环境搭建:1. 安装 Ubuntu17.10 > 安装步骤在这里2. 安装 Python2.7.14 (Ubuntu17.10 默认Python版本为2.7.14)3. 安装 git 、c…

【强化学习】PPO代码注释版本

# PPO主要通过限制新旧策略的比率,那些远离旧策略的改变不会发生# import tensorflow as tf import tensorflow.compat.v1 as tf tf.compat.v1.disable_eager_execution() import numpy as np import matplotlib.pyplot as plt import gym# 定义一些超级参量 EP_MAX…

【强化学习】可视化学习tensorboard

tensorflow定义了一个图结构: 代码: a tf.constant(3.0, name"a")b tf.constant(4.0, name"b")c tf.add(a, b, name"add")var tf.Variable(tf.random_normal([2, 3], mean0.0, stddev1.0), name"variable"…

面向初学者的JSF 2.0教程

1.什么是JSF? JSF是Java Server Faces的首字母缩写。 它是一种服务器端处理技术,它允许将服务器端代码嵌入到网页中。 由于可以将服务器端处理和呈现代码嵌入网页本身,因此使项目的整体编码更加简单。 减少总体数量以及文件大小。 JSF包含2个…

篡改referer_HTTP_REFERER的用法及伪造

引言在php中,可以使用$_SERVER[‘HTTP_REFERER’]来获取HTTP_REFERER信息,关于HTTP_REFERER,php文档中的描述如下:“引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项&a…

华为nova7保密柜_华为发布nova8系列新品 轻松拍出Vlog黄金脸占比

2020年12月23日,华为nova8系列手机正式发布。作为深受年轻人喜爱的手机品牌之一,华为nova8系列此次延续其强大的前置视觉实力、强悍的设计性能以及独特的设计美学,带来业内首款专为Vlog拍摄设计的5G手机。随着短视频和Vlog的崛起,…

从拉格朗日乘数法到KKT条件

从拉格朗日乘数法到KKT条件 最近看论文遇到了Karush–Kuhn–Tucker (KKT)条件,想搞清楚这是个什么东东,因此就把这个东西认真学习一下并且分享出来,希望对大家有用。学习KKT就不得不先学习一下拉格朗日乘数法&#xf…

26.0.0-alpha1_WildFly 8.0.0.Alpha1的发布和一些历史

26.0.0-alpha1自从我们发布WildFly 8.0.0.Alpha1版本以来, 已经过去了大约2周。 该下载位于WildFly下载页面上 。 我敢肯定,你们中的许多人可能会想知道WildFly是什么,而其中一些知道它是什么的人可能不会知道已经发布了。 我将尝试回答其中的…

单机最大负载_分布式高可靠之负载均衡,今天看了你肯定会

到目前为止,我已经为你介绍了分布式起源、分布式协调与同步、分布式资源管理与负载调度、分布式计算技术、分布式通信技术和分布式数据存储。可以说,掌握了这些内容,基本上就掌握了分布式的关键技术。然而,只有可靠的分布式系统才…

【强化学习】一文带你理清强化学习

整理不易,希望留个赞再走哦!! 学习路线 这个图描述的比较清晰,蓝框里是整个强化学习的一些概念基础了,橙色是一些学习方法,可以针对性的选择一些,废话不多说,接下来就按照这个路线图…

了解Java缓冲池

了解Java缓冲池 缓冲池空间位于垃圾收集器管理的内存之外。 这是分配本地堆外内存的一种方法。 使用缓冲池有什么好处? 为了回答这个问题,让我们首先了解什么是字节缓冲区。 字节缓冲区 非直接缓冲区 ByteBuffer类附带了java.nio包。 它允许我们分配直接…

java 循环拼接字符串用分号隔开_Java 8中字符串拼接新姿势:StringJoiner

在为什么阿里巴巴不建议在for循环中使用””进行字符串拼接一文中,我们介绍了几种Java中字符串拼接的方式,以及优缺点。其中还有一个重要的拼接方式我没有介绍,那就是Java 8中提供的StringJoiner ,本文就来介绍一下这个字符串拼接…

module ‘tensorflow_core.compat.v1‘ has no attribute ‘contrib‘问题的完美解决

问题描述&#xff1a; Instructions for updating: Use keras.layers.Dense instead. Traceback (most recent call last):File "run_cnn.py", line 200, in <module>model TextCNN(config)File "D:\MY DATA\学习资料\研究生\深度学习\text-classificat…