2401_82753220 2024-05-16 16:54 采纳率: 80%
浏览 14
已结题

DQN模型不收敛,目标求解也不好

这段DQN代码存在什么问题,为什么跑出来不收敛,而且效果不好


import numpy as np
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import random
from collections import deque
from tensorflow.keras import layers,models
import tensorflow as tf
from Job_Shop import Situation
from tensorflow.keras.optimizers import Adam
from Instance_Generator import Processing_time,A,D,M_num,Op_num,J,O_num,J_num
import matplotlib.pyplot as plt
 
 
class DQN:
    def __init__(self,):
        self.Hid_Size = 30
 
        # ------------Hidden layer=5   30 nodes each layer--------------
        model = models.Sequential()
        model.add(layers.Input(shape=(7,)))
        model.add(layers.Dense(self.Hid_Size, name='l1'))
        model.add(layers.Dense(self.Hid_Size, name='l2'))
        model.add(layers.Dense(self.Hid_Size, name='l3'))
        model.add(layers.Dense(self.Hid_Size, name='l4'))
        model.add(layers.Dense(self.Hid_Size, name='l5'))
        model.add(layers.Dense(6, name='l6'))
        model.compile(loss='mse',
                      optimizer=Adam(learning_rate=0.001))
        # # model.summary()
        self.model = model
 
        #------------Q-network Parameters-------------
        self.act_dim=[1,2,3,4,5,6]                        #神经网络的输出节点
        self.obs_n=[0,0,0,0,0,0,0]                            #神经网路的输入节点
        self.gama = 0.95  # γ经验折损率
        # self.lr = 0.001  # 学习率
        self.global_step = 0
        self.update_target_steps = 200  # 更新目标函数的步长
        self.target_model = self.model
 
        #-------------------Agent-------------------
        self.e_greedy=0.6
        self.e_greedy_decrement=0.0001
        self.L=40          #Number of training episodes L
 
        #---------------Replay Buffer---------------
        self.buffer=deque(maxlen=2000)
        self.Batch_size=10       # Batch Size of Samples to perform gradient descent
 
    def replace_target(self):
        self.target_model.get_layer(name='l1').set_weights(self.model.get_layer(name='l1').get_weights())
        self.target_model.get_layer(name='l2').set_weights(self.model.get_layer(name='l2').get_weights())
        self.target_model.get_layer(name='l3').set_weights(self.model.get_layer(name='l3').get_weights())
        self.target_model.get_layer(name='l4').set_weights(self.model.get_layer(name='l4').get_weights())
        self.target_model.get_layer(name='l5').set_weights(self.model.get_layer(name='l5').get_weights())
        self.target_model.get_layer(name='l6').set_weights(self.model.get_layer(name='l6').get_weights())
 
    def replay(self):
        if self.global_step % self.update_target_steps == 0:
            self.replace_target()
        # replay the history and train the model
        minibatch = random.sample(self.buffer, self.Batch_size)
        for state, action, reward, next_state, done in minibatch:
            target = reward
            if not done:
                k=self.target_model.predict(next_state)
                target = (reward + self.gama *
                          np.argmax(self.target_model.predict(next_state)))
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        self.global_step += 1
 
    def Select_action(self,obs):
        # obs=np.expand_dims(obs,0)
        if random.random()<self.e_greedy:
            act=random.randint(0,5)
        else:
            act=np.argmax(self.model.predict(obs))
        self.e_greedy = max(
            0.01, self.e_greedy - self.e_greedy_decrement)  # 随着训练逐步收敛,探索的程度慢慢降低
        return act
 
    def _append(self, exp):
        self.buffer.append(exp)
 
    def main(self,J_num, M_num, O_num, J, Processing_time, D, A):
        k = 0
        x=[]
        Total_tard=[]
        TR=[]
        for i in range(self.L):
            Total_reward = 0
            x.append(i+1)
            print('-----------------------开始第',i+1,'次训练------------------------------')
            obs=[0 for i in range(7)]
            obs = np.expand_dims(obs, 0)
            done=False
            Sit = Situation(J_num, M_num, O_num, J, Processing_time, D, A)
            for i in range(O_num):
                k+=1
                # print(obs)
                at=self.Select_action(obs)
                # print(at)
                if at==0:
                    at_trans=Sit.rule1()
                if at==1:
                    at_trans=Sit.rule2()
                if at==2:
                    at_trans=Sit.rule3()
                if at==3:
                    at_trans=Sit.rule4()
                if at==4:
                    at_trans=Sit.rule5()
                if at==5:
                    at_trans=Sit.rule6()
                # at_trans=self.act[at]
                print('这是第',i,'道工序>>','执行action:',at,' ','将工件',at_trans[0],'安排到机器',at_trans[1])
                Sit.scheduling(at_trans)
                obs_t=Sit.Features()
                if i==O_num-1:
                    done=True
                #obs = obs_t
                obs_t = np.expand_dims(obs_t, 0)
                # obs = np.expand_dims(obs, 0)
                # print(obs,obs_t)
                r_t = Sit.reward(obs[0][6],obs[0][5],obs_t[0][6],obs_t[0][5],obs[0][0],obs_t[0][0])
                self._append((obs,at,r_t,obs_t,done))
                if k>self.Batch_size:
                    # batch_obs, batch_action, batch_reward, batch_next_obs,done= self.sample()
                    self.replay()
                Total_reward+=r_t
                obs=obs_t
            total_tadiness=0
            Job=Sit.Jobs
            E=0
            K=[i for i in range(len(Job))]
            End=[]
            for Ji in range(len(Job)):
                End.append(max(Job[Ji].End))
                if max(Job[Ji].End)>D[Ji]:
                    total_tadiness+=abs(max(Job[Ji].End)-D[Ji])
            print('<<<<<<<<<-----------------total_tardiness:',total_tadiness,'------------------->>>>>>>>>>')
            Total_tard.append(total_tadiness)
            print('<<<<<<<<<-----------------reward:',Total_reward,'------------------->>>>>>>>>>')
            TR.append(Total_reward)
            # plt.plot(K,End,color='y')
            # plt.plot(K,D,color='r')
            # plt.show()
        plt.plot(x,Total_tard)
        plt.show()
        return Total_reward
 
 
d=DQN()
d.main(J_num, M_num, O_num, J, Processing_time, D, A)
 
 

  • 写回答

2条回答 默认 最新

  • 阿里嘎多学长 2024-05-16 16:54
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    您想要解决的问题

    您提问的目的是解决在运行深度Q网络(DQN)模型时遇到的不收敛问题,以及模型效果不佳的问题。

    问题出现原因

    1. 学习率设置:模型使用的Adam优化器的学习率可能过高或过低,导致模型难以收敛。
    2. 探索-利用平衡e_greedy策略的参数可能没有很好地平衡探索和利用,导致模型学习效率低下。
    3. 目标网络更新频率:目标网络更新的步长可能过大或过小,影响模型稳定性。
    4. 经验回放(Replay Buffer):可能存在经验回放的策略问题,如样本多样性不足或样本更新不及时。
    5. 网络结构:神经网络的结构可能不适合当前问题,如层数、节点数设置不当。
    6. 损失函数:使用均方误差(MSE)作为损失函数可能不适合DQN,通常DQN使用Huber损失或均方误差损失的变体。
    7. 训练数据:训练数据可能存在问题,如数据不平衡或数据量不足。

    问题解决方案

    1. 调整学习率:尝试不同的学习率,找到适合当前问题的最优学习率。
    2. 优化探索-利用策略:调整e_greedy参数,如降低e_greedy_decrement的值,以更慢地减少探索。
    3. 调整目标网络更新频率:尝试不同的更新步长,以提高模型稳定性。
    4. 改进经验回放机制:确保样本的多样性和及时更新。
    5. 调整网络结构:根据问题复杂度调整网络的层数和节点数。
    6. 选择更合适的损失函数:考虑使用Huber损失或其他适合DQN的损失函数。
    7. 增加训练数据:如果可能,增加训练数据的量和多样性。

    提供代码

    由于代码较长,这里提供一些关键的修改建议,而不提供完整的代码:

    # 1. 调整学习率
    optimizer=Adam(learning_rate=0.0003)
    
    # 6. 选择更合适的损失函数
    model.compile(loss='huber',  # 或者尝试其他适合DQN的损失函数
                  optimizer=optimizer)
    
    # 2. 优化探索-利用策略
    self.e_greedy_decrement = 0.00005  # 根据需要调整
    
    # 3. 调整目标网络更新频率
    self.update_target_steps = 100  # 根据需要调整
    
    # 5. 调整网络结构
    # 根据问题复杂度,可能需要调整网络层数和节点数
    model.add(layers.Dense(50, name='l1'))  # 举例:增加节点数
    

    代码运行方式

    运行代码需要有Python环境,安装了必要的库,如numpy, tensorflow, matplotlib等。运行方式通常是在命令行或IDE中直接运行脚本。

    代码预期运行结果

    期望通过上述修改,DQN模型能够更好地收敛,并且模型效果有所提升。预期结果是模型能够在训练过程中逐步提高其预测的准确性,减少总的延迟时间(Total_tard)。

    推荐相关链接

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月28日
  • 已采纳回答 5月20日
  • 创建了问题 5月16日

悬赏问题

  • ¥20 找辅导 初学者 想实现一个项目 没有方向
  • ¥15 关于渗漏场的电场分布模拟
  • ¥24 matlab怎么修改仿真初始时间
  • ¥15 两分段线性回归模型分析阈值效应
  • ¥15 前端和后端代码都没报错,但是点登录没反应的?
  • ¥100 需要远程解决QSQLITE问题!
  • ¥15 利用光场表达式画出初始光场强度分布图像等几个问题在这两个图片里
  • ¥15 gozero求手把手教学,400一天
  • ¥15 泥浆冲清水的泥浆分布
  • ¥15 LASSO回归分析筛选关键基因,适合多大样本量?