毕设过程问题及解决

文章讲述了在做毕业设计过程中遇到的问题,如深度强化学习仿真实验中的数值溢出、Matplotlib版本冲突、奖励值波动及内存管理问题。同时提供了针对这些问题的解决方案,并介绍了深度强化学习模型的保存与应用技巧。
摘要由CSDN通过智能技术生成

做毕业设计过程中遇到的一些问题,整合成了散装bug集,仅作个人记录。

主要工作是应用深度强化学习进行仿真实验(使用莫烦的A3C pytorch版代码,自己写了一个环境)。

logit函数输出[nan,nan,nan,nan]

报错:ValueError: Expected parameter probs (Tensor of shape (1, 4)) of distribution Categorical(probs: torch.Size([1, 4])) to satisfy the constraint Simplex(), but found invalid values: tensor([[nan, nan, nan, nan]])

原因:在 Python 的 numpy.exp()函数中遇到的溢出错误,输入的状态 数值过大或过小,使得神经网络的输出值出现异常。

解决方法:查看之前的输入,是否有值是异常的,代码中写入数据热度约束的部分,查清楚溢出的情况

参考链接:http://t.csdnimg.cn/dYL64

画图报错

报错:AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

原因:Matplotlib 的版本过高,需要降低:

解决方法:pip uninstall matplotlib

pip install matplotlib==3.5.0

参考链接:http://t.csdnimg.cn/BbB1A

【Plt 绘图保存错误】AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘-腾讯云开发者社区-腾讯云

强化学习奖励值先升后降

问题:强化学习训练后,奖励值先上升,后下降,且收敛到了一个较低的值。如下图:

原因:可能是环境写的有问题,或者尝试降低神经网络的学习率。

解决方法:降低学习率,缩小到原来的1/10,reward升高后逐渐收敛

python中字典pop后是否会回收空间呢?

在 Python 中,pop() 函数用于从字典中移除指定键对应的值,并返回该值。但是,pop() 函数不会主动释放字典占用的内存空间。

Python 中的内存管理由解释器的垃圾回收机制来负责。当字典中的键值对被移除后,如果没有其他引用指向该值,垃圾回收机制会在合适的时机(通常是在内存空间不足时)将其回收,并释放相应的内存空间。这意味着,虽然 pop() 函数移除了键值对,但实际的内存释放由垃圾回收机制决定,而不是由 pop() 函数直接触发。

如果你需要确保字典占用的内存空间被释放,可以在移除键值对后,通过手动触发垃圾回收机制来释放内存空间。你可以使用 Python 的 gc 模块来手动触发垃圾回收,例如:

pythonCopy code
import gc

# 移除键值对
my_dict.pop('key')

# 手动触发垃圾回收
gc.collect()

请注意,手动触发垃圾回收通常是不必要的,Python 解释器会自动处理内存管理,而手动触发垃圾回收可能会影响性能。只有在特定情况下(例如大量内存占用、内存泄漏等)需要时,才建议手动触发垃圾回收。

来源:chatgpt

深度强化学习训练后,模型如何保存?

深度强化学习(Deep Reinforcement Learning, DRL)训练后保存模型主要是为了记录学习到的策略或价值函数,以便在后续任务中直接使用已训练好的模型进行决策或进一步的训练。与传统的监督学习模型相比,DRL模型通常包含更多的组件,如策略网络、价值网络、经验回放缓冲区(Replay Buffer)、优化器状态等。保存DRL模型时,可能需要考虑保存以下几个关键部分:

  1. 神经网络权重
    • 这是模型的核心,包含了通过与环境交互学习到的策略或价值函数的具体参数。对于基于PyTorch或TensorFlow等深度学习库构建的模型,可以使用相应的模型保存功能来保存网络的权重。例如,在PyTorch中,可以使用torch.save()函数保存模型的state_dict,如下所示:
torch.save(agent.policy_network.state_dict(), 'policy_net_weights.pth')
    • 在TensorFlow中,如果是使用Keras API构建的模型,可以直接使用model.save()方法保存整个模型(包括结构和权重),或者使用tf.saved_model.save()保存为SavedModel格式。
  1. 模型架构/类定义
    • 如果只是保存了权重,还需要有对应的模型类定义或架构描述来重新构建模型。对于简单的模型结构,可能只需保存类定义的源代码;对于复杂的结构,尤其是使用自定义层或模块的模型,可能需要保存模型结构的序列化表示(如JSON或YAML文件),或者保存为ONNX等跨平台格式。
  1. 优化器状态
    • 为了在后续训练中能够继续优化或者微调,有时还需要保存优化器(如Adam、RMSprop等)的状态,如累计的动量、指数移动平均等。这可以通过保存优化器实例的state_dict实现:
torch.save(agent.optimizer.state_dict(), 'optimizer_state.pth')
  1. 环境接口细节
    • 如果模型与特定环境接口紧密耦合(如特定动作空间、观测空间的编码方式等),可能需要保存这些接口细节或环境配置,以确保模型在恢复时能正确与环境交互。
  1. 其他元数据
    • 根据具体算法,可能还需要保存额外的元数据,如探索率 schedules、超参数、训练统计数据等,以确保模型恢复后能够准确地复现训练时的行为。
  1. 经验回放缓冲区
    • 对于某些算法(如DQN、DDPG等),经验回放缓冲区可能包含有价值的历史经验数据。是否保存缓冲区取决于具体需求,通常仅在需要继续使用已有经验数据进行训练或分析时才保存。

综上所述,保存深度强化学习模型时通常涉及多个步骤,不仅要保存神经网络的权重,还可能需要保存模型结构、优化器状态、环境接口信息以及其他相关元数据。具体的保存方法会根据所使用的深度学习库(如PyTorch、TensorFlow)以及强化学习算法的实现细节而有所不同。在实践中,应根据项目的具体需求和所使用的技术栈来确定最合适的保存策略。

来源:通义千问(用了几次,感觉回答很详细,更适合中国宝宝)

保存模型后如何应用到训练集上

使用torch.save(gnet.state_dict(), 'gnet_weights.pth')保存了深度强化学习模型gnet的权重后,若要将该模型应用到训练集上,通常是指在新的训练周期中加载这些权重,以便继续训练(如微调或继续学习)或进行评估。以下是加载保存的模型权重并应用到训练集上的基本步骤:

1. 加载模型权重

首先,需要重新创建与保存模型相同结构的Net类实例。这通常涉及到重新定义Net类(如果未保存类定义)或导入包含该类定义的源代码。然后,创建一个新的Net实例并加载保存的权重:

# 如果需要,导入包含Net类定义的源代码文件

# 创建与保存模型具有相同结构的新Net实例
new_gnet = Net(N_S, N_A)

# 加载保存的模型权重
checkpoint = torch.load('gnet_weights.pth')
new_gnet.load_state_dict(checkpoint)

2. 应用到训练集

在强化学习中,“训练集”概念并不像监督学习那样直接对应一个静态的数据集。相反,智能体与环境互动的过程构成了训练过程。要将加载权重后的模型应用到“训练集”,实际上是让智能体在环境中执行策略,并根据环境反馈更新模型。以下是如何继续训练或评估的几种常见场景:

a) 继续训练(微调或继续学习)

  • 如果保存了优化器状态,也加载它:
# 加载优化器状态(假设保存了并需要继续使用同一优化器)
new_opt = SharedAdam(new_gnet.parameters(), lr=1e-5, betas=(0.92, 0.999))
new_opt.load_state_dict(torch.load('optimizer_state.pth'))
  • 恢复训练循环,包括创建工作进程、同步更新等步骤。代码中已有的Worker类和主循环逻辑可以复用,只需替换为新创建的new_gnetnew_opt实例。

b) 评估模型性能

  • 如果目标是评估模型在某个环境设定下的性能,可以创建一个评估环境(确保与训练环境一致),然后让智能体在该环境中执行策略,收集奖励、轨迹等评估指标。
eval_env = gym.make('MyEnv-v0')

# 设置模型为评估模式,通常禁用探索噪声等
new_gnet.eval()

episode_rewards = []
for _ in range(num_eval_episodes):
    s, item_info = eval_env.reset()
    episode_reward = 0
    while True:
        a = new_gnet.choose_action(v_wrap(s[None, :]))
        s_, r, done, _, _ = eval_env.step(item_info + [a])
        episode_reward += r
        if done:
            break
        s = s_
    episode_rewards.append(episode_reward)
avg_reward = sum(episode_rewards) / num_eval_episodes
print(f"Avg. evaluation reward: {avg_reward}")

c) 使用模型进行决策

  • 如果要在实际应用中使用模型作为决策代理,只需创建模型实例、加载权重,然后在需要做决策时调用choose_action方法:
# 创建模型实例并加载权重
deployed_gnet = Net(N_S, N_A)
deployed_gnet.load_state_dict(torch.load('gnet_weights.pth'))

# 在实际应用中,每当需要做出决策时:
state = get_current_environment_state()  # 获取当前环境状态
action = deployed_gnet.choose_action(v_wrap(state[None, :]))  # 使用模型选择动作
apply_action_to_environment(action)  # 将动作应用到环境中

总之,加载保存的模型权重后,要将其应用到“训练集”,实际上是指将加载了权重的模型投入到与环境的互动中,进行继续训练、评估或直接用于决策。根据具体需求,选择上述相应的应用场景并执行相应代码即可。

当完整数据未知时,如何将数据映射到某一个区间(或者是归一化)?

问题:强化学习奖励值包含了多个部分,为了统一奖励值的尺度,优化算法性能,可以对不同的奖励值进行归一化处理。可以使用但是数据的奖励值在实际场景下是无法预先得知所有奖励值的具体分布和最大最小值,一些常规的归一化方法不能直接使用,需要采用一种在线或者适应性的方式来处理新出现的奖励值。

优化算法性能包含两个方面:

加速收敛:归一化能够减小特征值的动态范围,使得梯度下降等优化算法在寻找最优解时,参数更新的步伐更为一致和稳定,从而加快收敛速度。

防止梯度消失/爆炸:在深度学习模型中,特别是神经网络,未经归一化的特征可能导致梯度在反向传播过程中快速衰减(梯度消失)或急剧增长(梯度爆炸),影响模型的学习与训练稳定性。归一化有助于维持梯度在合理范围内,保证有效的梯度传播。

解决方法:

利用训练集数据,保守估计一个奖励值范围,初始的最大值 `max_initial` 和最小值 `min_initial`。在实际应用的过程中,不断更新奖励值的最值,进行动态最小-最大归一化。

screen相关指令

#  新建screen
screen -S your_screen_name

# 进入screen
screen -r your_screen_name
# 如果使用大写的-R,和-r类似,但是没有对应名称的PID或者Name时,会自动创建新的虚拟终端。

Ctrl+D  # 在当前screen下,输入Ctrl+D,删除该screen
Ctrl+A,Ctrl+D  # 在当前screen下,输入先后Ctrl+A,Ctrl+D,退出该screen

#  显示screen list
screen -ls

# 释放命令
# 使用-R/-r/-S均可
screen -R [pid/Name] -X quit

相关链接:终端命令神器--Screen命令详解。助力Unix/Linux使用和管理 - 知乎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值