Python-DQN代码阅读(13)

news2024/11/17 11:51:13

目录

1.代码

1.1 代码阅读

1.2 代码分解

1.2.1 导入库

1.2.2 data = np.loadtxt('performance.txt')

1.2.3 mva = np.zeros((data.shape[0]), dtype=np.float)

1.2.4 mva[i] = data[i,1],mva[i] = alpha * data[i,1] + (1.0 - alpha) * mva[i-1]

1.2.5 plt.plot(data[:,0], data[:,1]) ,plt.plot(data[:,0], mva) 

1.2.6 mvar[i] = alpha * data[i,2] + (1.0 - alpha) * mvar[i-1]

2.问题


1.代码

1.1 代码阅读

import numpy as np
import matplotlib.pyplot as plt

# 从文件中加载性能数据
data = np.loadtxt('performance.txt')

print(data.shape)

# 计算第一个图形中的移动平均值
alpha = 0.02
mva = np.zeros((data.shape[0]), dtype=np.float)
for i in range(data.shape[0]):
   if i == 0:
     mva[i] = data[i,1]
   else:
     mva[i] = alpha * data[i,1] + (1.0 - alpha) * mva[i-1] 

# 绘制第一个图形:episode数量与时间步数的关系
plt.plot(data[:,0], data[:,1])  # 绘制原始数据
plt.plot(data[:,0], mva)  # 绘制移动平均数据
plt.xlabel('episode #', fontsize=20)  # 设置x轴标签
plt.ylabel('# of time steps', fontsize=20)  # 设置y轴标签
plt.savefig('dqn1.png')  # 保存图形到文件

# 清空绘图缓存
plt.clf()
plt.close()

# 计算第二个图形中的移动平均值
alpha = 0.02
mvar = np.zeros((data.shape[0]), dtype=np.float)
for i in range(data.shape[0]):
   if i == 0:
     mvar[i] = data[i,2]
   else:
     mvar[i] = alpha * data[i,2] + (1.0 - alpha) * mvar[i-1] 

# 绘制第二个图形:时间步数与每个episode的奖励值的关系
plt.plot(data[:,3], data[:,2])  # 绘制原始数据
plt.plot(data[:,3], mvar)  # 绘制移动平均数据
plt.xlabel('time step #', fontsize=20)  # 设置x轴标签
plt.ylabel('episode reward', fontsize=20)  # 设置y轴标签
plt.savefig('dqn2.png')  # 保存图形到文件

这段代码通过加载 "performance.txt" 文件中的性能数据,计算并绘制了两个图形,分别表示 episode 数量与时间步数的关系以及时间步数与每个 episode 的奖励值的关系。移动平均值的计算采用了指数加权平均方法,使用了参数 alpha 控制平均值的权重。最后,通过 plt.savefig() 方法将绘制的图形保存到文件 "dqn1.png" 和 "dqn2.png" 中。

1.2 代码分解

1.2.1 导入库

import numpy as np
import matplotlib.pyplot as plt

这段代码导入了 NumPy 和 Matplotlib 库,这两个库在 Python 中用于进行数值计算和绘图。

  • NumPy 是一个强大的数值计算库,提供了很多用于处理数组和矩阵的函数,包括数值计算、线性代数、傅里叶变换等。
  • Matplotlib 是一个流行的数据可视化库,提供了绘制图形的功能,包括折线图、散点图、柱状图、饼图等,可以用于创建各种类型的图形。

这两个库经常一起使用,NumPy 用于处理数据,Matplotlib 用于将数据可视化。通过导入这两个库,你可以在 Python 程序中使用它们的函数和类来进行数值计算和绘图操作。

1.2.2 data = np.loadtxt('performance.txt')

data = np.loadtxt('performance.txt')

print(data.shape)

这行代码使用 NumPy 的 loadtxt() 函数从名为 performance.txt 的文本文件中加载数据,并将数据存储到名为 data 的 NumPy 数组中。然后,通过 data.shape 打印出 data 数组的形状信息。

performance.txt 文件中的数据可能包含了程序运行过程中的性能指标或者统计数据,例如每个 episode 的时步数、总奖励等。np.loadtxt() 函数可以读取文本文件中的数据,并将其转换为 NumPy 数组,便于后续的处理和分析。

print(data.shape)输出结果将显示 data 数组的形状,即 (m, n),其中 m 是数组的行数,n 是数组的列数。这可以帮助我们了解加载的数据的维度大小,以便后续的数据处理和绘图等操作。

注意:在运行这行代码之前,需要确保当前工作目录下存在名为 performance.txt 的文件,并且文件中包含了正确格式的数据。如果文件不存在或者文件格式不正确,np.loadtxt() 函数可能会抛出异常或者加载不成功。

1.2.3 mva = np.zeros((data.shape[0]), dtype=np.float)

alpha = 0.02
mva = np.zeros((data.shape[0]), dtype=np.float)

这段代码定义了一个变量 alpha 并赋值为 0.02,然后创建了一个长度为 data.shape[0] 的零数组 mva,数据类型为浮点数 (dtype=np.float)。这将用于存储移动平均值

alpha 是用于计算移动平均值的权重,控制着历史值在计算中的权重大小。较小的 alpha会使得历史值在计算中的权重较大,从而导致移动平均值对历史数据更加敏感变化较为迅速。而较大的 alpha 值会使得历史值在计算中的权重较小,从而导致移动平均值对历史数据变化较不敏感,变化较为平滑。在这段代码中,设置 alpha 为 0.02 可以使得移动平均值对历史数据变化较为敏感,变化较为迅速。

data.shape[0] 表示 data 数据的行数,即数据矩阵的第一维度的大小。在这段代码中,data 是一个二维数组,data.shape[0] 返回的是 data 的行数,即数据的数量。这个值会用于控制循环的次数,对每一行数据进行处理。

1.2.4 mva[i] = data[i,1],mva[i] = alpha * data[i,1] + (1.0 - alpha) * mva[i-1]

for i in range(data.shape[0]):
   if i == 0:
     mva[i] = data[i,1]
   else:
     mva[i] = alpha * data[i,1] + (1.0 - alpha) * mva[i-1] 

这段代码实现了计算移动平均值(Moving Average)的操作。循环遍历 data 中的每一行数据,其中 data.shape[0] 表示数据的行数。在每一次循环中,使用当前行的第二列数据 data[i,1] 更新移动平均值 mva[i]

如果 i 等于 0,说明是第一行数据,此时直接将当前行的第二列数据赋值给 mva[i],作为初始值。

如果 i 大于 0,说明不是第一行数据,此时使用指数加权平均(Exponential Weighted Average,EMA)的方法计算移动平均值。公式为:

mva[i] = alpha * data[i,1] + (1.0 - alpha) * mva[i-1] 

alpha 是平滑系数,通常取一个小于1的值,用于控制移动平均的权重。data[i,1] 表示第 i 行数据的第二列值(索引为 1),即在 data 数据中的第二列数据mva[i-1] 表示上一个位置(索引为 i-1)的指数移动平均值。

根据指数移动平均的定义,当前位置的指数移动平均值(mva[i])等于当前位置的数据(data[i,1])乘以平滑系数 alpha,再加上上一个位置的指数移动平均值(mva[i-1])乘以 (1.0 - alpha)。这样可以实现对历史数据的加权平均,使得新数据在计算中占有较大的权重,而旧数据在计算中的权重逐渐减小。这样计算出的指数移动平均值具有较好的平滑效果,能够较好地反映数据的趋势变化

(1)问:这里的新数据是指什么,为什么在计算中占有较大的比重?

在这段代码中,新数据指的是 data 数据中的第二列值,即 data[i,1]。在指数移动平均中,新数据占有较大的比重是因为乘以了平滑系数 alpha。较小的 alpha 值会使得新数据在计算中占有较大的权重,而旧数据在计算中的权重逐渐减小。

具体地说,alpha 控制了新数据在指数移动平均中的权重,取值范围为 0 到 1 之间,通常取一个小于1的值。当 alpha 较小的时候,新数据的权重较大,而旧数据的权重较小。这样可以使得指数移动平均能够较快地反应最近的数据变化,对数据的瞬时波动更加敏感。而随着时间的推移,旧数据的权重逐渐减小,使得指数移动平均能够对数据的趋势变化更具平滑性。因此,新数据在计算中占有较大的比重,能够较好地反映数据的近期变化趋势。

(2)问:alpha较小,为何新数据权重较大?

在指数移动平均中,实际上是新数据乘以平滑系数 alpha 加上旧数据乘以剩余的权重 (1-alpha)。当 alpha 较小时,新数据乘以 alpha 的结果会比较小,但是由于是累积计算,新数据会不断地被乘以 alpha 的结果,因此在指数移动平均中新数据的权重会逐渐增大。

更具体地说,当 alpha 接近 0 时,新数据的权重接近 0,而旧数据的权重接近 1,这是因为 (1-alpha)^nn 取较大值时会趋近于 0。因此,当 alpha 较小时,新数据在指数移动平均中的权重较大,能够较好地反映数据的近期变化趋势。

1.2.5 plt.plot(data[:,0], data[:,1]) ,plt.plot(data[:,0], mva) 

plt.plot(data[:,0], data[:,1])  # 绘制原始数据
plt.plot(data[:,0], mva)  # 绘制移动平均数据
plt.xlabel('episode #', fontsize=20)  # 设置x轴标签
plt.ylabel('# of time steps', fontsize=20)  # 设置y轴标签
plt.savefig('dqn1.png') 

plt.clf()
plt.close()

这段代码用于绘制原始数据指数移动平均数据的折线图,并保存为图片文件 "dqn1.png"。

  • plt.plot(data[:,0], data[:,1]) 绘制原始数据的折线图,其中 data[:,0] 是 x 轴数据,data[:,1] 是 y 轴数据。
  • plt.plot(data[:,0], mva) 绘制指数移动平均数据的折线图,其中 data[:,0] 是 x 轴数据,mva 是 y 轴数据,即通过指数移动平均计算得到的平均值。
  • plt.xlabel('episode #', fontsize=20) 设置 x 轴标签为 "episode #",字体大小为 20。
  • plt.ylabel('# of time steps', fontsize=20) 设置 y 轴标签为 "# of time steps",字体大小为 20。
  • plt.savefig('dqn1.png') 将绘制的图保存为 "dqn1.png" 图片文件。
  • plt.clf() 是用于清除当前图像的函数,它会将当前图像中的所有绘图元素(如线条、点、文本等)清除,但不会关闭图像窗口

  • plt.close() 是用于关闭当前图像的函数,它会关闭当前图像窗口,释放相关的系统资源。这样可以避免在后续的绘图中出现不必要的重叠或混淆。

plt.plot(data[:,0], data[:,1]) 

plt.plot(data[:,0], data[:,1]) 是用于绘制原始数据的折线图。

  • data[:,0]data 数据中的第一列,表示 x 轴数据。
  • data[:,1]data 数据中的第二列,表示 y 轴数据。

这段代码将使用 data[:,0] 作为 x 轴数据,data[:,1] 作为 y 轴数据,绘制折线图。具体绘制的内容和形式取决于 data[:,0]data[:,1] 中的数据,可能表示了游戏的不同关卡或不同轮次的性能数据。

plt.plot(data[:,0], mva)

plt.plot(data[:,0], mva) 是用于绘制移动平均数据的折线图。

  • data[:,0]data 数据中的第一列,表示 x 轴数据。
  • mva 是通过计算得到的移动平均数据,作为 y 轴数据。

这段代码将使用 data[:,0] 作为 x 轴数据,mva 作为 y 轴数据,绘制移动平均折线图。移动平均线是通过对原始数据进行平滑处理得到的,用于平滑数据的波动,以便更好地观察数据的趋势和变化。具体绘制的内容和形式取决于 data[:,0]mva 中的数据,可能表示了游戏的不同关卡或不同轮次的移动平均性能数据。

plt.clf()
plt.close()

plt.clf() 是用于清除当前图像的函数,它会将当前图像中的所有绘图元素(如线条、点、文本等)清除,但不会关闭图像窗口

plt.close() 是用于关闭当前图像的函数,它会关闭当前图像窗口,释放相关的系统资源。这样可以避免在后续的绘图中出现不必要的重叠或混淆。

这两个函数通常在生成多个图像时使用,可以帮助清除之前的图像并关闭图像窗口,以便绘制新的图像或在生成图像后释放系统资源。

1.2.6 mvar[i] = alpha * data[i,2] + (1.0 - alpha) * mvar[i-1]

alpha = 0.02
mvar = np.zeros((data.shape[0]), dtype=np.float)
for i in range(data.shape[0]):
   if i == 0:
     mvar[i] = data[i,2]
   else:
     mvar[i] = alpha * data[i,2] + (1.0 - alpha) * mvar[i-1] 

# 绘制第二个图形:时间步数与每个episode的奖励值的关系
plt.plot(data[:,3], data[:,2])  # 绘制原始数据
plt.plot(data[:,3], mvar)  # 绘制移动平均数据
plt.xlabel('time step #', fontsize=20)  # 设置x轴标签
plt.ylabel('episode reward', fontsize=20)  # 设置y轴标签
plt.savefig('dqn2.png')  # 保存图形到文件

这段代码根据 data 中的第三列数据(每个 episode 的奖励值)计算了指数移动平均,并绘制了原始数据和移动平均数据的图形。

首先,创建了一个名为 mvar 的全零数组,用于存储每个时间步的移动平均值。

然后,使用循环遍历 data 中的每一行,计算移动平均值,并将结果存储在 mvar 数组中。

移动平均值的计算方式与之前的例子类似,使用了指数加权平均方法,其中 alpha 是平滑系数,控制了新数据和历史数据的权重。

最后,使用 plt.plot() 函数分别绘制了原始数据和移动平均数据的折线图,并使用 plt.xlabel()plt.ylabel() 设置了 x 轴和 y 轴的标签。最后,使用 plt.savefig() 将图形保存到文件中。

2.问题

(1)问:为何再次执行程序从第一个回合开始写入performance.txt文件,但是在内容的末尾追加,而没有覆盖原先的数据,是为什么?

 f = open("experiments/" + str(env.spec.id) + "/performance.txt", "a+") 这段代码中使用了 "a+" 模式来打开文件,表示以追加模式进行文件操作。

在 Python 中,文件操作模式通常由第二个参数来指定,其中 "a+" 表示以追加模式打开文件进行读写操作。具体解释如下:

  • 'a':追加模式(append mode),允许在文件末尾进行写入操作,如果文件不存在则创建文件。
  • '+':允许同时进行读写操作。
  • 'a+':追加模式 + 读写操作,既可以在文件末尾追加内容,也可以进行读取和写入操作。

因此,使用 "a+" 模式打开文件后,可以在文件末尾追加新的内容,而不会覆盖原先的数据。如果文件不存在,将会创建一个新的文件。在进行文件操作时,请注意谨慎操作,避免误删除或覆盖重要数据。

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

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

相关文章

【C++项目】高并发内存池

前言: 本篇博客大致记录基于tcmalloc实现高并发内存池的思想与实现方案。 使用语言:C,编译器:vs2022,开始时间:2023/4/3,结束时间:2023/4/12。 项目源码地址:Cproject: 我…

第八天并发编程篇

一、简述线程、进程、程序的基本概念? 1.进程: 我们把运行中的程序叫做进程,每个进程都会占用内存与CPU资源,进程与进程之间互相独立. 2.线程: 线程就是进程中的一个执行单元,负责当前进程中程序的执行。一个进程可以包含多个线程…

【电子秤方案】LCD口袋秤芯片方案

LCD高精度口袋电子秤方案,即便携式称重仪,是一种应用于生活中的称重设备。便珠宝秤具有体积小、重量轻、功耗低、结构紧凑等特点。 LCD高精度口袋电子秤方案产品简介 口袋电子秤是一种体积小、重量轻、功耗低,可用于多种场合的电子秤。它通常…

如何检查 Linux 内存使用量是否耗尽?这5个命令堪称绝了!

在 Linux 操作系统中,内存是一个关键资源,用于存储正在运行的程序和操作系统本身的数据。如果系统的内存使用量过高,可能会导致性能下降、应用程序崩溃或者系统崩溃。因此,了解如何检查 Linux 内存使用量是否耗尽是非常重要的。下…

【网络安全】文件上传绕过思路

引言 分享一些文件上传绕过的思路,下文内容多包含实战图片,所以打码会非常严重,可多看文字表达;本文仅用于交流学习, 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人…

什么是划分子网?网络工程师划分子网有啥技巧?

随着互联网的快速发展,越来越多的组织和企业在其内部建立了复杂的网络系统来满足日常的信息传输和资源共享需求。而在这些网络系统中,划分子网(也称为子网划分)作为一种常见的网络管理方法,为组织和企业提供了更加灵活…

【面试】记一次安恒面试及总结

文章目录SQL 注入sql注入的原理?如何通过SQL注入判断对方数据库类型?补充一下其他方法判断数据库类型时间盲注的函数XPath注入抓不到http/https包,怎么办?app无自己的ssl证书app有自己的ssl证书-证书绑定(SSL pinning)逻辑漏洞有哪…

【学习笔记】滑动窗口

acwing.滑动窗口https://www.acwing.com/problem/content/156/ 给定一个大小为 n≤106≤106 的数组。 有一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子: …

Python使用Opencv进行图像人脸、眼睛识别实例演示

效果展示 下面使用 haarcasecade_eye.xml 进行人眼识别的效果图: 人脸识别是一种可以自动检测图像或视频中存在的人脸的技术。它可以用于各种应用,例如安全控制,自动标记照片和视频,以及人脸识别解锁设备等。在这篇博客中&#…

水声功率放大器模块基于通道接收和发射的水声通信机的应用

实验名称:基于多通道接收和发射的水声通信机 研究方向:水声通信 测试设备:数模转化器、ATA-ML180水声功率放大器模块、示波器、接收换能器、发射换能器等。 图:实验原理 一、发射机的双通道发送实验: 实验过程&#xf…

Redis与本地缓存组合使用(IT枫斗者)

Redis与本地缓存组合使用 前言 我们开发中经常用到Redis作为缓存,将高频数据放在Redis中能够提高业务性能,降低MySQL等关系型数据库压力,甚至一些系统使用Redis进行数据持久化,Redis松散的文档结构非常适合业务系统开发&#xf…

探索六西格玛在医疗行业的应用,提升医疗企业的市场竞争力

六西格玛是一种基于数据的管理方法,旨在通过对医疗流程和服务进行量化分析和改进,以优化医疗企业的运营和管理。它能够有效地解决医疗企业面临的各种问题和挑战,提高医疗服务的质量和效率,降低医疗成本和风险,增强医疗…

Linux: 性能分析之内存增长和泄漏

文章目录1. 前言2. 背景3. 内存增长和泄漏分析方法3.1 跟踪 malloc(), free() 等接口3.1.1 用 perf 采样3.1.2 用 ebpf 来跟踪3.2 跟踪 brk() 调用3.2.1 使用 perf 跟踪 brk()3.2.2 使用 ebpf 跟踪 brk()3.3 跟踪 mmap() 调用3.3.1 使用 perf 跟踪 mmap()3.3.2 使用 ebpf 跟踪 …

【FPGA】多功能ALU

目录 实验要求 源代码 顶层模块 数据输入模块 ALU运算模块 结果处理模块 扫描数码管模块 扫描数码管顶层 分频器 数码管显示 仿真代码 结构层图 管脚配置 实验板卡:xc7a100tlc sg324-2L,共20个开关 实验要求 通过高低位控制,实现32位数…

74-快速排序——一路快排

快速排序是影响二十世纪最伟大的排序算法之一。 JDK的双轴快速排序就是对快排的优化,本质还是快排。 从待排序区间选择一个数,作为基准值/分区点(pivot),此时默认选择数组的第一个元素作为比较的基准值。partition&a…

【 SpringBoot 配置⽂件 】

文章目录一、配置⽂件作⽤二、配置文件格式2.1 特殊说明2.2 为配置⽂件安装提示插件三、properties 配置⽂件说明3.1 properties 基本语法3.2 读取配置⽂件3.3 解决 properties 中文乱码3.4 properties 缺点分析四、yml 配置⽂件说明4.1 yml 基本语法4.2 yml 配置读取4.3 yml 使…

前后端分离——SpringBoot+Vue——3天速成企业级项目

前后端分离——SpringBootVue使用到的技术:vue3(区别vue2)前言vue2 vs vue3双向绑定更新实例化生命周期获取props数据和方法的定义watchEffect那么什么是 watchEffect ?组件通信注意attrs和listeners路由vue3路由写法:…

ROS学习——艰辛的环境安装之路一VMware

文章目录VMware 安装下载安装VMware 安装 一些没用的介绍: VMware Workstation中文版是一个“虚拟 PC”软件。它使你可以在一台机器上同时运行二个或更多 Windows、DOS、LINUX 系统。与“多启动”系统相比,VMWare 采用了完全不同的概念。多启动系统在一…

《Web前端应用开发》考试试卷(模拟题)

一、产品搜索页面 打开“考试文件夹”中的input.html,完成以下步骤: 注意:本题仅能在input.html的(1)为产品名称所在的div添加样式属性,使得产品名称保持在文本框的左边; (2&#xf…

PPT NO.1【用ppt如何做一张海报+字体】

PPT做得好的人,一定是站在观众的角度思考的人。 1、设置幻灯片尺寸大小: 设置完成后如下: 2、加载一张自己喜欢的图片进来:【图片越高清越好】 将图片铺满空白的地方,调整好自己喜欢的区域: 做裁剪&#xf…