-
Notifications
You must be signed in to change notification settings - Fork 5
PyTorch文档阅读笔记
DingfengShi edited this page Mar 1, 2018
·
6 revisions
试用了一下PyTorch,发现PyTorch不但上手快,而且用着灵活,写起来也非常有条理,易读性非常好!
-
使用Variable包装Tensor,Variable其实只是一个装Tensor的容器,可用于自动求导
x = torch.randn(3) x = Variable(x, requires_grad=True) y = x * 2 y.backward(...) #省略号里面shape要和y相同 #此时 x.grad #可以得到梯度值
-
使用torch.nn包来加速模型建立
#例子 #nn里分为两种类型Module(直接在nn里),functional。两者的差别就是该层需不需要参数 #比如卷积层,声明需要定义一些参数: nn.Conv2d(1, 6, 5)(inputTensor) #需要声明类后要通过__call__方式调用 #而functional对于无参数的网络结构则更方便,比如 x = nn.functional.relu(inputTensor) #一般functional也有Module的实现,比如 x = nn.Relu()(inputTersor)
注意:torch.nn的输入一定是要带batch维度的,所以就算只有一条数据,也要在最前面补上一个值为1的维度:data.unsqueeze(0)
-
继承torch.nn.Module来定义模型或者模块
通过继承该类并重写forward方法即可,不需要写反向传播class Net(nn.Module): ... def __init__(self): #通过把子模块赋值给该Module,PyTorch会自动注册(register)到模型的参数列表里,这样对Module调用cuda()等方法的时候便会连同处理到这些子模块 self.Cov1=nn.Conv2d(10,10,4) #用sequential能很方便的按顺序堆叠模型 self.fc = nn.Sequential( nn.Linear(input, 64, bias=False), nn.BatchNorm1d(64), nn.ReLU(True)) ... #只需要重写前向传播,不需要自己写反向传播 def forward(input): return self.fc(input) ... net=Net() #使用GPU,直接对Module调用cuda()方法即可使里面原定义好的参数放入GPU net=net.cuda() #模型变成GPU以后,输入数据也要调用cuda方法 out = net.forward(data.cuda()) #一开始要对模型参数的梯度缓存归零 net.zero_grad() loss = loss_fn(out,target) loss.backward(...)
-
权值的初始化 直接调用nn里的模块不会自动初始化,需要手动处理
#对某个模块初始化,比如卷积层 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3) nn.init.xavier_uniform(self.conv1.weight) nn.init.constant(self.conv1.bias, 0.1) #一般定义模块的时候,可以统一对里面的各种层初始化 def weights_init(m): classname=m.__class__.__name__ if classname.find('Conv') != -1: nn.init.xavier_uniform(m.weight) nn.init.xavier_uniform(m.bias) net = Net() #对一个模块调用apply方法,传入的是个函数,会对该模块的所有子模块执行该函数 net.apply(weights_init)
-
使用optimizer更新权值
对loss进行反向传播只会在缓存里更改grad值,要更新权值还是需要optimizer去处理,用起来也很简单,比如Adamimport torch.optim as optim net = Net() optimizer = optim.Adam(net.parameters, lr = 0.0001) ... loss = .. loss.backward() #执行一次更新操作 optimizer.step()
-
使用GPU
如果单独对某些Variable或者Tensor存入GPU中,只需对其执行cuda()方法即可。(Variable和Tensor都右cuda()方法,先把Tensor放入GPU再用Variable包装,和先把Tensor放入Variable都能得到同样的结果)ten = torch.FloatTensor(2) ten_cuda = ten1.cuda() V = autograd.Variable(ten_cuda) #和下面能得到同样结果 ten = torch.FloatTensor(2) V = autograd.Variable(ten) V = V.cuda()