Tensor
Tensor是一种数据结构,类似于numpy数组,与numpy不同点,可以在GPU计算。
使用 a.is_leaf 来判断a 是否是Tensor
is_cuda 判断是否在GPU
Tensor.item() 可直接打印tensor的数值
. . … . . …CPU tensor … … … . … . GPU tensor
32位: torch.FloatTensor … … . torch.cuda.FloatTensor
64位:torch.DoubleTensor. … . . . .torch.cuda.DoubleTensor
import torch
a = torch.Tensor(2,3) #默认32位float
b = torch.empty(2,3) #可以创建任意类型
c= torch.tensor(np.array([1.0]))
d = torch.zeros([2, 2], dtype=torch.int32)
e = torch.ones([2, 4], dtype=torch.float64, device=torch.device('cuda:0'))
y=torch.Tensor([1.0])
print(y.item())
>>>1.0
Variable
variable 是一个变量对象 包含:
①这个变量的tensor数值a.data
②这个变量的梯度值–a.grad
③这个变量是否要保存反向传播过程中的梯度a.requires_grad
④得到这个变量的最后一次操作grad_fn
—— data 包含Tensor
—— grad 保存这这个Varible 的梯度
—— requires_grad 反向传递的是否保存梯度,可用来冻结某层网络的梯度,是这层的w权重不更新。
——grad_fn 得到这个变量最后一次操作
'''把Tensor 变成Variable '''
import torch
from torch.autograd import Variable
x= torch.Tensor([1.0]).cuda()
x = Variable (x, requires_grad=True)
images = Variable(torch.from_numpy(images).cuda().type(torch.FloatTensor))
w2=Variable (torch.Tensor([3.0]).cuda(), requires_grad=False)
b2=Variable (torch.Tensor([2.0]).cuda(), requires_grad=True)
反向传播backward() 梯度权值跟新
L.backward() 会报错。L是个向量,不能反向求导,只有标量才能反向求导。
#使用
L=(10-d).sum() 代替
反向传播的时候,逐层求梯度,然后乘以学习率来跟新权重,
在这个过程中可以,冻结一部分的梯度,但是不影响其它层的梯度传播
下面假设是一个简化后的三层网络:
冻结w2层的参数
import torch
from torch.autograd import Variable
import torch.nn as nn
x= torch.Tensor([1.0]).cuda()
x = Variable (x, requires_grad=True)
w1 = Variable (torch.Tensor([2.0]).cuda(), requires_grad=True)
b1= Variable (torch.Tensor([4.0]).cuda(), requires_grad=True)
w2=Variable (torch.Tensor([3.0]).cuda(), requires_grad=False)
b2=Variable (torch.Tensor([2.0]).cuda(), requires_grad=True)
w3=Variable (torch.Tensor([2.0]).cuda(), requires_grad=True)
b3=Variable (torch.Tensor([4.0]).cuda(), requires_grad=True)
y1= (x * w1) +b1
y2=y1*w2 +b2
y3 = y2*w3 + b3
#y3=((x * w1) +b1)*w2+b2
print(y3)
'''print(y2.grad_fn) 返回得到y2的最后一步操作'''
y3.backward()
print(w3)
print(w3.grad)
lr=0.2
w3 = w3+ w3.grad * lr #权重跟新
#
#print(w3)