Hdqn代码学习记录
加粗样式
环境 mdp配置
StochasticMDPEnv
random.random() < 0.5 用于生成一个0到1的随机符点数。此处想要获得<0.5的随机数,可以视为概率0.5.
hdqn agent配置
hDQN
1.collections
是python中基础数据类型的容器模块。
collections.nametuple :nametuple(名称+元组),命名元组,使元组除了使用索引访问还可以使用名称访问。
两个参数:第一个是类名,第二个是类的各个字段名。
2.torch包
【参考】https://blog.csdn.net/ShuqiaoS/article/details/88708049?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-88708049-blog-114090945.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-88708049-blog-114090945.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=2
1.torch.nn:
pytorch中自带的一个函数库,里面包含了神经网络中使用的一些常用函数,如具有可学习参数的nn.Conv2d(),nn.Linear()和不具有可学习的参数(如ReLU,pool,DropOut等)(后面这几个是在nn.functional中),这些函数可以放在构造函数中,也可以不放.
2.torch.autograd:
【参考】https://blog.csdn.net/lj2048/article/details/113527400
torch.autograd包就是用来自动求导的。Autograd包为张量上所有的操作提供了自动求导功能,而torch.Tensor和torch.Function为Autograd的两个核心类,它们相互连接并生成一个有向非循环图。
3.torch.FloatTensor
torch.FloatTensor类型转换, 将list ,numpy转化为tensor。
torch.cuda.FloatTensor 与 torch.FloatTensor
Pytorch中的tensor又包括CPU上的数据类型和GPU上的数据类型,一般GPU上的Tensor是CPU上的Tensor加cuda()函数得到。
一般系统默认是torch.FloatTensor类型(即CPU上的数据类型)。例如data = torch.Tensor(2,3)是一个2*3的张量,类型为FloatTensor;data.cuda()就转换为GPU的张量型,torch.cuda.FloatTensor类型。
4.autograd.Variable类详解
【参考】https://blog.csdn.net/DUDUDUTU/article/details/125600317
torch.autograd包是pytorch搭建神经网络的核心,它为张量上的所有操作提供了自动求导机制。
Variable类是autograd包中很重要的一类,它的作用是包装Tensor,将一个tensor其变成计算图中的一个节点(变量)。 一个tensor转换为Variable后,将有以下三个重要的属性:
- .data:访问这个Variable存储的张量数据,即原始的张量值
- .grad:访问这个Variable的梯度信息
- grad_fn:访问这个Variable的运算信息,表示该变量是用户创建的变量还是中间计算出的结果变量。当变量是计算图的leaf nodes(叶节点)时(如a,b,c),.grad_fn为False,当变量是计算图中间的结果变量时(如f=a+b,g=b+c),.grad_fn为True。
在创建Variable时,需设置一个参数"requires_grad",其类型为bool(True或False),默认为False。 True代表此变量处需要计算梯度,False代表不需要。
当设置False时,在使用.backward()反向传播时该叶节点不会参与梯度计算,也就是该Variable的.grad属性一直为None;当设置为True时,在反向传播时则会对该叶节点计算梯度,并不断地积累。
5.torch.nn.Module类
pytorch中其实一般没有特别明显的Layer和Module的区别,不管是自定义层、自定义块、自定义模型,都是通过继承Module类完成的。
我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__构造函数和forward这两个方法。但有一些注意技巧:
(1)一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中,当然我也可以吧不具有参数的层也放在里面;
(2)一般把不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替
(3)forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心。
【原文链接】https://blog.csdn.net/qq_27825451/article/details/90550890
6.nn.Linear
nn.Linear定义一个神经网络的线性层.
torch.nn.Linear(in_features, # 输入的神经元个数
out_features, # 输出神经元个数
bias=True # 是否包含偏置 )
7. tensor张量
跟numpy数组、向量、矩阵的格式基本一样。但是是专门针对GPU来设计的,可以运行在GPU上来加快计算效率。
8.torch.no_grad()
一个上下文管理器,disable梯度计算。disable梯度计算对于推理是有用的,当你确认不会调用Tensor.backward()的时候。这可以减少计算所用内存消耗。这个模式下,每个计算结果的requires_grad=False,尽管输入的requires_grad=True。
如果有不想被track的计算部分可以通过这么一个上下文管理器包裹起来。这样可以执行计算,但该计算不会在反向传播中被记录。
9.pytorch 的max()[]
torch.max)(a,0) 返回每一列中最大值的那个元素,且返回索引(返回最大元素在这一列的行索引)
torch.max(a,1) 返回每一行中最大值的那个元素,且返回其索引(返回最大元素在这一行的列索引)
torch.max()[0], 只返回最大值的每个数
troch.max()[[1]],只返回最大值的每个索引
【参考】https://blog.csdn.net/Z_lbj/article/details/79766690
3.*args和**kwargs的区别
*args代表任何多个无名参数,返回的是元组;**kwargs表示关键字参数,所有传入的key=value,返回字典;
args和kwargs的用途:
args 和kwargs 主要用于函数定义, 可以将不定数量的参数传递给一个函数。
args 是用来发一个非键值对的可变数量的参数列表给一个函数; kwargs允许将一个不定长度的键值对,作为参数传递给一个函数。如果需要在一个函数中处理带名字的参数时,此时就应该使用kwargs了。
def ak(*args,**kwargs):
print('args=',args)
print('kwargs=',kwargs)
print('***************************************')
if __name__=='__main__':
ak(2,4,6,8)
ak(a=2,b=4,c=6,d=8)
ak(2,4,6,8,a=1,b=3,c=5)
ak('x', 2, None, a=4, b='6', c=8)
#ak('a', a=1, 1, None, b='2', c=3)
**kwargs :
两个星号是收集关键字参数,可以将参数收集到一个字典中,参数的名字是字典的 “键”,对应的参数的值是字典的 “值”。
4.super函数简介
python内置函数super()主要用于类的多继承中,用来查找并调用父类的方法,所以在单重继承中用不用 super 都没关系;但是,使用 super() 是一个好的习惯。一般我们在子类中需要调用父类的方法时才会这么用;
class Dog:
def __init__(self):
self.fly = False
def print_fly(self):
if self.fly:
print('不是普通狗,能飞')
else:
print('普用狗不会飞')
class xiaotianquan(Dog):
def __init__(self):
super().__init__() # 等效 super(xiaotianquan,self).__init__()
self.sound = True
def print_sing(self):
if self.sound:
print("汪汪汪")
else:
print("假狗狗")
if __name__ == '__main__':
dog = xiaotianquan()
dog.print_sing() # 能正常输出
dog.print_fly() # 用了super后不会报错
5.关于.data和.cpu().data
1.首先a是一个放在GPU上的Variable,a.data是把Variable里的tensor取出来,
可以看出与a的差别是:缺少了第一行(Variable containing)
2.a.cpu()和a.data.cpu()是分别把a和a.data放在cpu上,其他的没区别,另外:a.data.cpu()和a.cpu().data一样
3.a.data[0] | a.cpu().data[0] | a.data.cpu()[0]是一样的,都是把第一个值取出来,类型均为float
4.a.data.cpu().numpy()把tensor转换成numpy的格式