torch.nn包里的Functional包含convolution函数,pooling函数,非线性函数、激活函数等函数,torch.nn.optim包含各种优化算法,Momentum、RMSProp等。
Tensor
torch.Tensor是一种包含单一数据类型元素的多维矩阵。
Torch定义了七种CPU tensor类型和八种 tensor类型:
torch.Tensor是默认的tensor类型(torch.FloatTensor)的简称。
一个张量tensor可以从Python的list或序列构建:
>>>torch.FloatTensor([[1,2,3],[4,5,6]])
tensor([[1., 2., 3.],
[4., 5., 6.]])>>>torch.Tensor([[3,2,1],[6,5,4]])
tensor([[3., 2., 1.],
[6., 5., 4.]])
空张量tensor可以通过规定其大小来构建:
>>>torch.IntTensor(2,4).zero_()
tensor([[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=torch.int32)
可以用python的索引和切片来获取和修改一个张量tensor中的内容:
>>>x=torch.FloatTensor([[1,2,3],[4,5,6]])
>>>print(x[1][2])
tensor(6.)
>>>print(x[0][1])
tensor(2.)
>>>x[0][1]=8
>>>print(x)
tensor([[1., 8., 3.],
[4., 5., 6.]])
每一个张量tensor都有一个相应的tourch.Storage用来保存其数据。
注意:会改变tensor的函数操作会用一个下划线后缀来表示。比如,torch.FloatTensor.abs_()会在原地计算绝对值,并返回改变后的tensor,而torch.FloatTensor.abs()将会在一个新的tensor中计算结果。
创建张量时有个参数是requires_grad,如果设置 requires_grad为 True,那么将会追踪所有对于该张量的操作吗,默认False。 当完成计算后通过调用 .backward(),自动计算所有的梯度, 这个张量的所有梯度将会自动积累到 .grad属性。
torch.squeeze
torch.squeeze(input,dim=None,out=None):将输入张量形状中的1去除并返回。当给定dim时,那么挤压操作只在给定维度上。
>>>x=torch.zeros(2,1)
>>>x
tensor([[0.],
[0.]])
>>>y=torch.squeeze(x)
>>>y
tensor([0., 0.])
torch.abs
torch.abs(input,out=None):计算输入张量的每个元素的绝对值
>>>torch.abs(torch.Tensor([-1,-2,-3]),out=z)
tensor([1., 2., 3.])
>>>z
tensor([1., 2., 3.])
torch.add
torch.add(input,value,out=None),对输入张量input逐元素加上标量值value,并返回结果得到一个新的张量out。
>>>a=torch.rand(4)
>>>a
tensor([0.0694, 0.6366, 0.6938, 0.8872])
>>>torch.add(a,20)
tensor([20.0694, 20.6366, 20.6938, 20.8872])
torch.mean
torch.mean(input,dim,out=None):返回输入张量给定维度dim上每行的均值。0是列,1是行。
>>>a=torch.rand(4,4)
>>>a
tensor([[0.7413, 0.5828, 0.0070, 0.0146],
[0.1668, 0.6566, 0.1865, 0.0700],
[0.7603, 0.8017, 0.3065, 0.8772],
[0.7918, 0.8798, 0.7355, 0.1142]])
>>>torch.mean(a,1)
tensor([0.3364, 0.2700, 0.6864, 0.6303])
比较运算符
torch.eq
torch.eq(input,other,out=None):比较元素相等性。第二个参数可以为一个数或与第一个参数同类型形状的张量。
>>>torch.eq(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
tensor([[ True, False],
[False, True]])
如果两个张量有相同的形状和元素值,则返回True,否则返回False。
>>>torch.equal(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
False>>>torch.equal(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,2],[3,4]]))
True
torch.ge
torch.ge(input,other,out=None):逐元素比较input和other。即是否 input>=otherinput>=other。如果两个张量有相同的形状和元素值,则返回True。否则返回False。第二个参数可以为一个数或与第一个参数相同形状和类型的张量。
>>>torch.ge(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
tensor([[ True, True],
[False, True]])
torch.gt
torch.gt(input,other,out=None):逐元素比较input和other。即input>otherinput>other。如果两个张量有相同的形状和元素值,则返回True。否则返回False。第二个参数可以为一个数或与第一个参数相同形状和类型的张量。PS:这个和ge有什么区别?
>>>torch.gt(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
tensor([[False, True],
[False, False]])
torch.le
torch.le(input, other, out=None):逐元素比较input和other , 即是否input<=otherinput<=other 第二个参数可以为一个数或与第一个参数相同形状和类型的张量
>>>torch.le(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
tensor([[ True, False],
[ True, True]])
torch.lt
torch.lt(input, other, out=None):逐元素比较input和other , 即是否 input<otherinput<other。第二个参数可以为一个数或与第一个参数相同形状和类型的张量
>>>torch.lt(torch.Tensor([[1,2],[3,4]]),torch.Tensor([[1,1],[4,4]]))
tensor([[False, False],
[ True, False]])
Variable
Variable和Tensor本质上没有区别,不过Variable会被放入一个计算图中,然后进行前向传播、反向传播、自动求导。
首先Variable是在torch.autograd.Variable中,要将tensor变成Variable,只需要Variable(a)就可以了。Variable有三个比较重要的组成属性:data、grad、grad_fn。data可以取出variable里面的tensor值,grad_fn表示的是得到这个Variable的操作(op),grad是这个Variable的反向传播梯度。
>>>from torch.autograd import Variable
>>>x=Variable(torch.Tensor([1]),requires_grad=True)
>>>w=Variable(torch.Tensor([2]),requires_grad=True)
>>>b=Variable(torch.Tensor([3]),requires_grad=True)
>>>y=w*x+b
>>>y
tensor([5.], grad_fn=)
>>>print(y.backward())
None
>>>print(x.grad)
tensor([2.])
>>>print(w.grad)
tensor([1.])
>>>print(b.grad)
tensor([1.])
>>>print(x.grad_fn)
None
>>>print(y.grad_fn)
构建Variable,我们传入了一个参数requires_grad=True,这个参数表示是否对这个变量求梯度,默认的是False,也就是不对这个变量求梯度。
parameters
paramerters(memo=None):返回一个包含模型所有参数的迭代器。一般用来当作optimizer的参数。
backward
如果需要计算导数,可以在Tensor上调用.backward()。 如果Tensor是一个标量(即它包含一个元素数据)则不需要为backward()指定任何参数, 但是如果它有更多的元素,需要指定一个gradient参数来匹配张量的形状。
zero_grad
zero_grad():清空所有被优化过的Variable的梯度
1 |
|
单独设置参数
我们还可以为每个参数单独设置选项。Optimizer也支持为每个参数单独设置选项。若想这么做,不要直接传入Variable的iterable,而是传入dict的iterable。每一个dict都分别定 义了一组参数,并且包含一个param键,这个键对应参数的列表。其他的键应该optimizer所接受的其他参数的关键字相匹配,并且会被用于对这组参数的优化。
你仍然能够传递选项作为关键字参数。在未重写这些选项的组中,它们会被用作默认值。当你只想改动一个参数组的选项,但其他参数组的选项不变时,这是非常有用的。
例如,当我们想指定每一层的学习率时,这是非常有用的:
optim.SGD([{'params': model.base.parameters()}, {'params': model.classifier.parameters(), 'lr':1e-3], lr=1e-2, momentum=0.9)
单次优化
使用optimizer.step(),这是大多数optimizer支持的版本,一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数。
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
补充
我看到优化算法时,发现中文文档好像没有调整学习率的函数。补充一下。torch.optim.lr_scheduler提供了几种方法来根据epoches的数量调整学习速率。 两种机制:LambdaLR机制和StepLR机制;
LambdaLR机制:
class torch.optim.lr_scheduler.LambdaLR(optimizer,lr_lambda,last_epoch=-1)
将每一个参数组的学习率设置为初始学习率lr的某个函数倍.当last_epoch=-1时,设置初始学习率为lr.
参数:
optimizer(Optimizer对象)—优化器
lr_lambda(是一个函数,或者列表(list))— 当是一个函数时,需要给其一个整数参数,使其计算出一个乘数因子,用于调整学习率,通常该输入参数是epoch数目或者是一组上面的函数组成的列表,
last_epoch(int类型):最后一次epoch的索引,默认为-1.
StepLR机制
class torch.optim.lr_scheduler.StepLR(optimizer,step_size,gamma=0.1,last_epoch=-1)
设置每个参数组的学习率为 lr*λn, n=epoch/step_size。当last_epoch=-1时,令lr=lr
参数:
optimizer(Optimizer对象)—优化器
step_size(整数类型): 调整学习率的步长,每过step_size次,更新一次学习率
gamma(float 类型):学习率下降的乘数因子
last_epoch(int类型):最后一次epoch的索引,默认为-1.
其它API
其它的API不想做搬运工了,上网址。pytorch中文文档
看文档我发现torch.nn包里面和nn.functional都有卷积等一些函数。其实nn.functional中的函数仅仅定义了一些具体的基本操作,不能构成pytorch中的一个Layer。当我们需要自定义一些非标准Layer时,可以在其中调用nn.functional中的操作。例如,relu仅仅是一个函数,参数包括输入和计算需要的参数,返回计算的结果,它不能存储任何上下文的信息。
torch.nn包里面只是包装好了神经网络架构的类,nn.functional 与torch.nn包相比,nn.functional是可以直接调用函数的。