pytorch学习笔记

四个重要的包
torch.Torch
torch.autograd
torch.nn
torch.optim

一、tensor转化到gpu上运算:

默认情况下不允许跨 GPU 操作,除了 copy_()和 其他具有类似复制功能的方法,例如to()和cuda()。除非您启用点对点内存访问,否则任何在跨不同设备的张量上启动操作的尝试都会引发错误。

cuda = torch.device('cuda')     # Default CUDA device
cuda0 = torch.device('cuda:0')
cuda2 = torch.device('cuda:2')  # GPU 2 (these are 0-indexed)
#1. 直接参数设置
x = torch.tensor([1., 2.], device=cuda0)
# x.device is device(type='cuda', index=0)
#2. .cuda()
y = torch.tensor([1., 2.]).cuda()
# y.device is device(type='cuda', index=0)
3. .to(torch.device("cuda")
y=torch.tensor(1.,2.]).to(cuda)
# y.device is device(type='cuda', index=0)

二、修改tensor的requires_grad属性

x.requires_grad_(True)
x.requires_grad=True

三、model.zero_grad()和optimizer.zero_grad()和param.grad.zero_()

pytorch之object.grad.zero_()
【PyTorch】PyTorch中的model.zero_grad()和optimizer.zero_grad()使用
在用pytorch训练神经网络时,可以先用:

model.zero_grad()
optimizer.zero_grad()

这两种方式都是把模型中的参数的梯度设为0。
常用

for i in range(epoch):
    for j,(data,target) in tqdm(enumerate(train_loader)):
      logit = transfer_layer(resnet18(data.to(device)))
      # print (logit.shape)
      # print (target.shape)
      loss = torch.nn.functional.cross_entropy(logit.to(device),target.to(device))
      loss.backward()
      for param in transfer_layer.parameters():
        if param.grad is not None:
          param.grad.zero_()
      optimizer.step()

中的

 """Sets gradients of all model parameters to zero."""
for p in self.parameters():
	if p.grad is not None:
		p.grad.data.zero_()

将参数的梯度清零,否则参数梯度会叠加,这样相当于所有batch在一起使用了,比如每两次清一次零就相当于将两个batch合并成一个batch进行计算了。

四、pytorch完整训练神经网络过程

神经网络之特征图可视化

import torch
import torchvision
import torchvision.models as models
import torchvision.transforms as transforms
resnet18 = models.resnet18(pretrained = True)

# 得到对象 PIL.Image.Image image mode=RGB size=32x32 at 0x7FEECE0EEC50
# 如果需要对图像进行reshape或者归一化等操作,可以使用transforms.lambda(lambda x:---)进行定义
train_dataset = torchvision.datasets.CIFAR10('./data' ,train = True ,download=True, transform = transforms.Compose([transforms.ToTensor(),]))
test_dataset = torchvision.datasets.CIFAR10('./data' ,train = True ,download=False, transform = transforms.Compose([transforms.ToTensor(),]))
train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=10,shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset,batch_size=10,shuffle=True)

from tqdm import tqdm
epoch = 1
learning_rate = 0.001
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

category_list = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
resnet18 = resnet18.to(device)
transfer_layer = torch.nn.Linear(1000,10).to(device)
# 联合参数进行优化需使用如下方式。key只能是params
optimizer = torch.optim.SGD([{'params':transfer_layer.parameters()},{'params':resnet18.conv1.parameters()}],lr = learning_rate)

def train():
  for i in range(epoch):
    for j,(data,target) in tqdm(enumerate(train_loader)):
      logit = transfer_layer(resnet18(data.to(device)))
      # print (logit.shape)
      # print (target.shape)
      loss = torch.nn.functional.cross_entropy(logit.to(device),target.to(device))
      loss.backward()
      for param in transfer_layer.parameters():
        if param.grad is not None:
          param.grad.zero_()
      optimizer.step()
      # 上下两种优化网络参数方式都行。
      # for param in transfer_layer.parameters():
      #   param = (param - learning_rate*param.grad).detach().requires_grad_()

      if j % 500 == 0:
        print ('第{}次迭代,loss值为{}'.format(j*10,loss))

def test():
  correct_num = torch.tensor(0).to(device)
  for j,(data,target) in tqdm(enumerate(test_loader)):
    data = data.to(device)
    target = target.to(device)
    logit = transfer_layer(resnet18(data))
    pred = logit.max(1)[1]
    num = torch.sum(pred==target)
    correct_num = correct_num + num
  print (correct_num)
  print ('\n correct rate is {}'.format(correct_num/10000))

train()
test()

五、pytorch搭建模型

可以用model.parameters访问网络模型参数或者某层的参数
可以用print(model)访问网络模型

参考链接
pytorch基础入门教程/一小时学会pytorch
pytorch官方文档
pytorch中文文档

#coding=utf-8
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class Net(nn.Module):
    #定义Net的初始化函数,这个函数定义了该神经网络的基本结构
    def __init__(self):
        super(Net, self).__init__() #复制并使用Net的父类的初始化方法,即先运行nn.Module的初始化函数
        self.conv1 = nn.Conv2d(1, 6, 5) # 定义conv1函数的是卷积函数:输入为图像(1个频道,即灰度图),输出为 6张特征图(feature map), 卷积核为5x5正方形
        self.conv2 = nn.Conv2d(6, 16, 5) # 定义conv2函数的是卷积函数:输入为6张特征图(feature map),输出为16张特征图(feature map), 卷积核为5x5正方形
        self.fc1   = nn.Linear(16*5*5, 120) # 定义fc1(fullconnect)全连接函数1为线性函数:y = Wx + b,并将16*5*5个节点连接到120个节点上。
        self.fc2   = nn.Linear(120, 84) #定义fc2(fullconnect)全连接函数2为线性函数:y = Wx + b,并将120个节点连接到84个节点上。
        self.fc3   = nn.Linear(84, 10) #定义fc3(fullconnect)全连接函数3为线性函数:y = Wx + b,并将84个节点连接到10个节点上。

    #定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) #输入x经过卷积conv1之后,经过激活函数ReLU(原来这个词是激活函数的意思),使用2x2的窗口进行最大池化Max pooling,然后更新到x。
        x = F.max_pool2d(F.relu(self.conv2(x)), 2) #输入x经过卷积conv2之后,经过激活函数ReLU,使用2x2的窗口进行最大池化Max pooling,然后更新到x。
        x = x.view(-1, self.num_flat_features(x)) #view函数将张量x变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备。
        x = F.relu(self.fc1(x)) #输入x经过全连接fc1,再经过ReLU激活函数,然后更新x
        x = F.relu(self.fc2(x)) #输入x经过全连接fc2,再经过ReLU激活函数,然后更新x
        x = self.fc3(x) #输入x经过全连接3,然后更新x
        return x

    #使用num_flat_features函数计算张量x的总特征量(把每个数字都看出是一个特征,即特征总量),比如x是4*2*2的张量,那么它的特征总量就是16。
    def num_flat_features(self, x):
        size = x.size()[1:] # 这里为什么要使用[1:],是因为pytorch只接受批输入,也就是说一次性输入好几张图片,那么输入数据张量的维度自然上升到了4维。【1:】让我们把注意力放在后3维上面
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

################
net = Net()

# 以下代码是为了看一下我们需要训练的参数的数量
print (net)
params = list(net.parameters())

k=0
for i in params:
    l =1
    print "该层的结构:"+str(list(i.size()))
    for j in i.size():
        l *= j
    print "参数和:"+str(l)
    k = k+l

print "总参数和:"+ str(k)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值