首先给出论文地址和代码, Reinforcement Learning Based Scheduling Algorithm for Optimizing Age of Information in Ultra Reliable Low Latency Networks

从题目可以得知, 这是一篇有关强化学习的论文, 具体的工作是用A3C算法来优化10个sensor的AOI以及保证URLLC,所谓URLLC,即给每一个sensor都设定一个阈值,接着通过训练来保证每一个sensor的AOI不超过这个阈值,否则就会受到惩罚,给一个很负的奖励,通俗的来讲就是保证可靠性,这是优化目标。状态的设置是10个sensor的AOI和最后5个包的下载时间和吞吐量,将这些状态送往神经网络最后整合一下, 再通过一个全连接神经网络得到10个概率分布, 作者选择动作的方式和一般A3C选择动作的方式些许不同,但影响不大, 感兴趣的可以在代码里面查看,里面涉及到了很多知识, 模型的保存、交叉熵、tensorboard的可视化,模型的保存用于Test并给出最后的结果,也就是论文中的表格数据和图,Train文件夹是用来训练模型的,以上是作者所用的A3C算法,尽管这个模型还有很多的不足,但是很简单,作为学习入门是可以的了。

另外,我用最基本的DQN也实现了一下这篇论文, 最后的结果如下:

结果不比A3C差,我写的代码有时间也会上传到GitHub,以上。


1.DQN算法核心−learn1. DQN算法核心-learn1.DQN算法核心−learn
包括了train和模型保存两个重要的部分,算法基本的流程和大家所学的相差不大, 不过由于记忆池的变化,所以有稍许的改动,原作者的模型保存是使用了一个队列来传递梯度下降的值到另一个函数里面去, 虽然最后我搞明白了所谓队列在两个函数之间传输的特点,但是用在我的代码里面就是一直无法收敛,所以我索性放到了train里面。

 def prepare_learn(self, done):# check to replace target parameters  用eval网络替换tartget网络的参数,if self.learn_step_counter % self.replace_target_iter == 0:self.sess.run(self.replace_target_op)print('\ntarget_params_replaced\n')# sample batch memory from all memoryif self.memory_counter > self.memory_size:sample_index = np.random.choice(self.memory_size, size=self.batch_size)else:  # 如果计数累加不超过记忆池,从目前的memory_counter 中选32个索引值sample_index = np.random.choice(self.memory_counter, size=self.batch_size)batch_memory = self.memory[sample_index, :]  # 根据索引取memory中的数据 ,数据量是随机的不相关的数据# batch_memory 中都是状态,这些状态包含了next_state,q_eval = self.predict_eval(batch_memory[:, :, 0:self.s_dim[1]])q_next = self.predict_next(batch_memory[:, :, self.s_dim[1]: self.s_dim[0] - 2])q_target = q_eval.copy()batch_index = np.arange(self.batch_size, dtype=np.int32)action_vec = batch_memory[:, :, 11]reward_vec = batch_memory[:, :, 10]action_index = []# 数据是记忆库的数据reward = []for a in action_vec:i = np.argmax(a)action_index.append(i)# print(action_index)for r in reward_vec:i = r[0]reward.append(i)self.Reward_his.append(i)# 32个索引值, 原来源是memory中的act数据,eval_act_index = action_index# 无法得到未来的期望if done:q_target[batch_index, eval_act_index] = rewardelse:q_target[batch_index, eval_act_index] = reward + self.gamma * np.max(q_next, axis=1)self.epsilon = self.epsilon + self.e_greedy_increment if self.epsilon < self.epsilon_max else self.epsilon_maxself.learn_step_counter += 1_, cost = self.sess.run([self._train_op, self.loss],feed_dict={self.q_target: q_target,self.inputs_e: batch_memory[:, :, 0:self.s_dim[1]],})self.cost.append(cost)if self.learn_step_counter % 100 == 0:self.saver.save(self.sess, SUMMARY_DIR + "/nn_model_ep_" + str(self.learn_step_counter) + ".ckpt")print(f"MODEL READY_{self.learn_step_counter}!)")

另外在训练过程中的可视化也极为重要, 因为代码一开始是肯定无法收敛的,除非你是天选之子,如上代码的收敛是在不断测试下有的,甚至让笔者一度怀疑这算法到底可不可行。
可视化有多种方法,可以是一个特定数据反映数据是否收敛, 更好的当然是最为直接的图了,我在写代码的过程中发现如果选择每一个sensor的概率接近10%,即平均的更新每一个sensor,这样对应到奖励值上也会有一个不太差的结果, 但是在DQNDQNDQN中, 我发现选择频率最高的sensor接近收敛与19% , 这和A3CA3CA3C是有一些不同的,它的概率通过softmaxsoftmaxsoftmax输出就是稳定在10%左右, 这里体现了算法的差异性。这是一方面, 另一方面是在训练过程中,不同的算法选择更新sensor的临界点不同,这是上面所说的概率的另一个更加具体的体现,即sensor1sensor_1sensor1​的阈值为303030,那么DQNDQNDQN会选择在它的AOIAOIAOI达到19时就更新它,不让它继续增加下去了,这和算法本身的训练过程有关, 优化目标既然是最小化所有SensorAOISensor AOISensorAOI, 那么这个算法就认为在19更新它的AOIAOIAOI我可以获得最大的奖励, 但对于A3CA3CA3C肯定是不一样了, 具体的数据我没有论证, 大家如果感兴趣可以统计一下每一个算法在哪一个数值更新它的AOIAOIAOI, 对比一下两个算法的不同.


2.DQN神经网络参数分析2.DQN神经网络参数分析2.DQN神经网络参数分析

    def build_eval_net(self):with tf.variable_scope('eval_net', ):# 这个inputs理应是sinputs = tflearn.input_data(shape=[None, self.s_dim[0], self.s_dim[1]])split_0 = tflearn.fully_connected(inputs[:, 0:1, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_1 = tflearn.fully_connected(inputs[:, 1:2, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_2 = tflearn.fully_connected(inputs[:, 2:3, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_3 = tflearn.fully_connected(inputs[:, 3:4, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_4 = tflearn.fully_connected(inputs[:, 4:5, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_5 = tflearn.fully_connected(inputs[:, 5:6, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_6 = tflearn.fully_connected(inputs[:, 6:7, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_7 = tflearn.fully_connected(inputs[:, 7:8, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_8 = tflearn.fully_connected(inputs[:, 8:9, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))split_9 = tflearn.fully_connected(inputs[:, 9:10, -1], Neu, activation='relu', bias_init=tf.constant_initializer(0.1))# 此处Neu应做卷积核个数, 4 为其sizesplit_20 = tflearn.conv_1d(inputs[:, 10:11, :], Neu, 4, activation='relu',bias_init=tf.constant_initializer(0.1))split_21 = tflearn.conv_1d(inputs[:, 11:12, :], Neu, 4, activation='relu',bias_init=tf.constant_initializer(0.1))split_20_flat = tflearn.flatten(split_20)split_21_flat = tflearn.flatten(split_21)merge_net = tflearn.merge([split_0, split_1, split_2, split_3, split_4, split_5, split_6, split_7, split_8, split_9,split_20_flat, split_21_flat], 'concat')dense_net_0 = tflearn.fully_connected(merge_net, Neu, activation='linear',bias_init=tf.constant_initializer(0.1))q_eval = tflearn.fully_connected(dense_net_0, self.a_dim, activation='linear', bias_init=tf.constant_initializer(0.1))return inputs, q_eval

调用:调用:调用:

        self.inputs_e, self.q_eval = self.build_eval_net()

这里用的搭建神经网络的模块是集成在TensorFlow上的高级API,TflearnAPI, TflearnAPI,Tflearn。
应用也十分简单, 给定一个inputs设定输入格式, 然后选用其中的数据即可, 这里因为我们的状态和每一个sensor的AOI有关, 所以可以看到前10个状态都是将一个个sensor的值传入了一个全连接神经网络, 再将两个一行五列的的数据放入卷积神级网络,为了维度匹配, 这里的神经元个数都是相同的,接着将这些值按行扩展拼接起来,再通过一个全连接网络,最后就可以输出q_eval值了, q_target的网络结构和以上一样, 这里不再赘述。

Trick of network

在调试的过程中发现神级网络参数的设置十分重要, 一些小的技巧可以使得模型更快的收敛。

Neu = 66
Filter = 66

经过测试, 神经元和卷积核的数量设置以上数据是合理的。
更为重要的是,上图代码的神经网络的偏差的设置也十分关键, 也即bias的值,我在莫凡走迷宫的代码中配置了我的DQN代码,加上bias要比不加agent走进出口的概率要大很多,所以我在这里加上了bias,同理, 也可以加初始化的www, 大家可以尝试一下。

    def __init__(self,sess,a_dim,state_dim,#  dqn中的学习率表示 α * (Q_target - Q_eval) = α * (R + gammma * max(Q(s',a1), Q(s', a3) ...)) - [Q(#  s1, a1), Q(s1, a2),..] ,learning_rate=0.01,# Gammareward_decay=0.9,e_greedy=0.9,replace_target_iter=100,memory_size=9999,batch_size=32,e_greedy_increment=None,):

Initialization parameter 记忆池设定在了9999, 学习率由A3C的0.001增加到了0.01模型很快就收敛了,batch_size稳定设置在32。

Activation
经过测试, 在DQNDQNDQN中, 最后一层或者两层用linearlinearlinear效果更好, 其余用的是relurelurelu, 注意,我只测试过DQNDQNDQN用哪一种激活函数比较好, 如果对别的神级网络的参数调试有好的建议和想法可以一起讨论!


动作选择与Agent

        # -------------------Start next step--------------------------sensor_selection = dqn.choose_action(np.reshape(state_, (1, S_INFO, S_LEN)))time_stamp += 1q_eval = dqn.predict_eval(np.reshape(state_, (1, S_INFO, S_LEN)))# 记录交叉熵entropy = dqn_.compute_entropy(q_eval[0])entropy_record.append(entropy)if (len(r_batch) >= TRAIN_SEQ_LEN and len(r_batch) % 10 == 0) or done == True:print("Training.....")dqn.prepare_learn(done)# 记录下熵看何时保存模型if done:dqn.plot_reward()dqn.plot_cost()x = np.arange(len(entropy_record))y = entropy_recordx_new = np.linspace(min(x), max(x), 100)y_new = make_interp_spline(x, y)(x_new)plt.plot(x_new, y_new)plt.xlabel('steps')plt.ylabel('Entropy')plt.show()break
      if k == 79999:done = True

在训练的过程中给定一个结束状态,当训练结束时就传入learn中结束掉训练, 同时绘制奖励和loss曲线 ,这里我绘图用了插值拟合, 这样可以更清晰的看到曲线的波动,而不是一团密集的折现,如下:


这里只训练了59999次,所以奖励值还有少许的波动
动作选择:

    def choose_action(self, inputs):if np.random.uniform() < self.epsilon:q_eval = self.sess.run(self.q_eval, feed_dict={self.inputs_e: inputs})sensor_index = np.argmax(q_eval)else:sensor_index = np.random.randint(0, self.a_dim)  # 从动作集合中随便选一个return sensor_index

动作还是选择使q_eval最大的索引, 作为动作。但是我一直不知道对于多个动作空间的选择是如何设置的,目前我遇到的都是选择单个动作, 如果动作的维度复杂,在复杂的动作空间是如何输出的?目前网上没有找到关于这方面的资源。

Agent参数

# coding=gb2312
import os
import matplotlib.pyplot as plt
import numpy as np
import tensorflow._api.v2.compat.v1 as tf  # 这样的导入有1.0的提示
from scipy.interpolate import make_interp_spline
import dqn_
import env
import load_tracenp.set_printoptions(suppress=True)
# tf.reset_default_graph()tf.logging.set_verbosity(tf.logging.ERROR)
tf.disable_v2_behavior()
os.environ['CUDA_VISIBLE_DEVICES'] = ''S_INFO = 12
S_LEN = 5
A_DIM = 10
NUM_AGENTS = 1TRAIN_SEQ_LEN = 1000
MODEL_SAVE_INTERVAL = 100
M_IN_K = 200.0DEFAULT_SELECTION = 1  # default video quality without agent
RANDOM_SEED = 42  # 随机数种子
SUMMARY_DIR = './results/models'LOG_FILE = './results/log'
TRAIN_TRACES = './cooked_traces/'  # 训练路径
NN_MODEL = None
lamba = 1000  # 传感器的权重初始乘值

两种深度强化学习算法在网络调度上的应用与优化(DQN A3C)相关推荐

  1. 17种深度强化学习算法用Pytorch实现(附链接)

    来源:新智元 本文约1300字,建议阅读5分钟. 本文为你介绍一个用PyTorch实现了17种深度强化学习算法的教程和代码库,帮助大家在实践中理解深度RL算法. [ 导读 ]深度强化学习已经在许多领域 ...

  2. openssl 添加自定义算法_GitHub:用PyTorch实现17种深度强化学习算法

    [新智元导读]深度强化学习已经在许多领域取得了瞩目的成就,并且仍是各大领域受热捧的方向之一.本文推荐一个用 PyTorch 实现了 17 种深度强化学习算法的教程和代码库,帮助大家在实践中理解深度 R ...

  3. 【重磅】Tensorflow2.0实现29种深度强化学习算法大汇总

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要3分钟 Follow小博主,每天更新前沿干货 来源:深度强化学习实验室 作者:王健树 [导读]今天给大家推荐一个超赞的强化学习项目资料,该项目 ...

  4. 【招聘推荐】启元世界招聘深度强化学习算法工程师

    深度强化学习实验室 官网:http://www.neurondance.com/ 论坛:http://deeprl.neurondance.com/ 编辑.排版:DeepRL 深度强化学习算法工程师 ...

  5. 近端策略优化深度强化学习算法

    PPO:Proximal Policy Optimization Algorithms,其优化的核心目标是: ppo paper 策略梯度 以下是马尔可夫决策过程MDP的相关基础以及强化学习的优化目标 ...

  6. 深度强化学习算法调参

    深度强化学习调参技巧:以D3QN.TD3.PPO.SAC算法为例 这个参考链接. 如何选择深度强化学习算法? 参考链接. 影响PPO算法性能的10个关键技巧(附PPO算法简洁Pytorch实现) 主要 ...

  7. 深度学习(四十)——深度强化学习(3)Deep Q-learning Network(2), DQN进化史

    Deep Q-learning Network(续) Nature DQN DQN最早发表于NIPS 2013,该版本的DQN,也被称为NIPS DQN.NIPS DQN除了提出DQN的基本概念之外, ...

  8. 基于深度强化学习的智能车间调度方法研究

    摘要: 工业物联网的空前繁荣为传统的工业生产制造模式开辟了一条新的道路.智能车间调度是整个生产过程实现全面控制和柔性生产的关键技术之一,要求以最大完工时间最小化分派多道工序和多台机器的生产调度.首先, ...

  9. AI周报丨标清变4k?B站超分辨率算法开源;强化学习算法控制核聚变登上《nature》

    AI周刊丨标清变4k?B站超分辨率算法开源:强化学习算法控制核聚变登上<nature> 2022年2月22日 极链AI云 文章目录 AI周刊丨标清变4k?B站超分辨率算法开源:强化学习算法 ...

最新文章

  1. QRadioButton 使用方法
  2. 怎么切换用户_走进通信:4G手机跟基站是怎么“交流”的
  3. 浅谈深度学习(Deep Learning)的基本思想和方法
  4. scala 方法、函数定义小结
  5. RTX5 | 消息队列06 - (实战技巧)FDCAN接收中断ISR同步线程
  6. HTML5开发APP有哪些优点和缺点?HTML5优势和劣势大对比
  7. 吴恩达深度学习5.2练习_Sequence Models_Operations on word vectors
  8. 微软官方工具_时隔20年再出发!微软官方推出最强Windows工具集
  9. YOLOv2-darknet 内容解析
  10. Sun Virtualbox说明文件的Bug
  11. mysql carnation_RDS mysql5.6 数据库还原到本地
  12. 宏观视角看抖音全生态
  13. 小白入门级的视频剪辑软件
  14. 独立站谷歌付费广告关键词选词技巧实操
  15. 无线连接打印服务器,如何用旧电脑架设无线网络打印服务器
  16. 泛型中extends和super的区别
  17. 防火墙单个ip映射多台服务器,使用防火墙构建器管理多个服务器的单个防火墙策略...
  18. UPC第41场,第42场部分题解
  19. 【Java8 Stream】:探秘Stream实现的核心:Collector,模拟Stream的实现
  20. 实景三维在自然资源地质环境监测预警的应用

热门文章

  1. 福州php前景,重磅!福州市未来三年棚改计划出炉!看看都拆哪?
  2. axure9怎么让页面上下滑动_Axure制作:页面上下滑动时的菜单栏悬浮吸顶效果
  3. 修改git全局用户名,邮箱和密码
  4. Java从键盘输入数据
  5. 笔记本屏幕30hz_开学在即,最适合大学生的笔记本电脑买起来
  6. 内网渗透-Metasploit之——基本后渗透命令
  7. Python Selenium UI自动化测试
  8. 第二章Linux 基本命令操作
  9. 一圆形游泳池如图所示,现在需在其周围建一圆形过道,并在其四周围上栅栏。栅栏造价为$35/m,过道造价为$20/m2。过道宽度为3m,现在给出游泳池半径要求编程计算并栅栏和过道的造价。
  10. iphone换机android,换机很麻烦?iPhone、Android 手机资料转移靠 6 招!