Pytorch相关操作

Pytorch下的张量操作

Tensors与NumPy中的 ndarrays类似,下面实现一些简单的操作,首先导入相应的包

from __future__ import print_function
import torch

张量

构造一个5X3的矩阵

x=torch.empty(5,3)
print(x)

输出:

tensor([[9.1837e-39, 4.6837e-39, 9.2755e-39],
        [1.0837e-38, 8.4490e-39, 1.1112e-38],
        [1.0194e-38, 9.0919e-39, 8.4490e-39],
        [9.6429e-39, 8.4490e-39, 9.6429e-39],
        [9.2755e-39, 1.0286e-38, 9.0919e-39]])

构造一个随机矩阵

x = torch.rand(5,3)
print(x)

输出:

tensor([[0.7028, 0.6747, 0.9585],
        [0.1216, 0.7152, 0.2926],
        [0.7292, 0.6155, 0.5695],
        [0.5835, 0.8147, 0.2758],
        [0.0413, 0.8445, 0.4681]])

构造类型为long的全零矩阵

 x = torch.zeros(5,3,dtype=torch.long)
 print(x)  

输出:

tensor([[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]])

用数据直接构造张量

x = torch.tensor([5.5,3])
print(x)

输出:

tensor([5.5000, 3.0000])

使用new_*方法构造张量

x = torch.zeros(5,3,dtype=torch.long)
x = x.new_ones(5,3,dtype=torch.double)
print(x)
    
x = torch.randn_like(x,dtype=torch.float)
print(x)

输出:

tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], dtype=torch.float64)
    tensor([[ 0.7960,  0.3521, -0.6110],
            [-1.3932, -0.4911, -0.7206],
            [ 0.1605,  0.5626, -0.5002],
            [-0.7352,  0.0382, -0.7809],
            [ 1.2041,  1.5645,  0.2425]])

基本操作

Addition:syntax 1

 x = torch.rand(5,3)
 y = torch.rand(5,3)
 print(x+y)

输出:

tensor([[1.2324, 0.6507, 1.3211],
            [1.2938, 1.2007, 0.5592],
            [1.5900, 1.0517, 1.1385],
            [0.4266, 1.0057, 0.9490],
            [1.0860, 0.2747, 1.6411]])

Addition: syntax 2

print(torch.add(x,y))

输出:

tensor([[1.2324, 0.6507, 1.3211],
        [1.2938, 1.2007, 0.5592],
        [1.5900, 1.0517, 1.1385],
        [0.4266, 1.0057, 0.9490],
        [1.0860, 0.2747, 1.6411]])

Addition:in-place(就地操作)

print(y.add_(x))

输出:

 tensor([[1.2324, 0.6507, 1.3211],
            [1.2938, 1.2007, 0.5592],
            [1.5900, 1.0517, 1.1385],
            [0.4266, 1.0057, 0.9490],
            [1.0860, 0.2747, 1.6411]])

将Torch张量转换为NumPy

a=torch.ones(5)
print(a)

输出:

tensor([1., 1., 1., 1., 1.])

转换为numpy

 b = a.numpy()
 print(b)

输出:

[1. 1. 1. 1. 1.]

注意:转换为a和b占用同一空间,一个改变,另一个也跟着改变

a.add_(1)
print(a)
print(b)

输出:

tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]

将NumPy转换为Torch张量

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a,1,out=a)
print(a)
print(b)

输出:

[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)

梯度

后向传播

x = torch.ones(2,2,requires_grad=True)
y = x+2
z = y*y*3
out = z.mean()
out.backward()

打印梯度d(out)/dx

 print(x.grad)

输出:

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

神经网络

在pytorch中,可以使用torch.nn包构造神经网络,其中nn.Module包含层,方法forward(input)返回output

对于一个神经网络而言,典型的训练过程如下:

  • 定义带有超参数的神经网络;
  • 在训练集上进行迭代;
  • 在网络上处理输入数据;
  • 计算损失;
  • 后向传播梯度到网络;
  • 更新权重。

定义一个网络

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
       super(Net,self).__init__()
       self.conv1 = nn.Conv2d(1,6,5)
       self.conv2 = nn.Conv2d(6,16,5)
       self.fc1 = nn.Linear(16*5*5,120)
       self.fc2 = nn.Linear(120,84)
       self.fc3 = nn.Linear(84,10)
    	
   
def forward(self,x):
	x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
	x = F.max_pool2d(F.relu(self.conv2(x)),2)
	x = x.view(-1,self.num_flat_features(x))
	x = F.relu(self.fc1(x))
	x = F.relu(self.fc2(x))
	x = self.fc3(x)
	return x

def num_flat_features(self,x):
	size = x.size()[1:]
	num_features = 1
	for s in size:
		num_features *= s
	return num_features

net = Net()
print(net)

输出:

Net(
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

上面尽管只定义了forward函数,backward函数将在使用autograd函数时自动定义。模型需要学习的参数可以使用net.parameters()查看

params = list(net.parameters())
print(len(params))
print(params[0].size())

输出:

10
torch.Size([6, 1, 5, 5])

损失函数

nn包中有各种各样的损失函数,常见的比如:nn.MSELoss
例如:

input = torch.randn(1,1,32,32)
output = net(input)
target = torch.randn(10)
target = target.view(1,-1)
criterion = nn.MSELoss()
loss = criterion(output,target)
print(loss)

输出:

tensor(0.9953, grad_fn=<MseLossBackward>)

训练一个分类器

将从下面几个步骤执行

  • 使用torchvision加载CIFAR10训练和测试样本集,帮对其进行归一化处理
  • 定义卷积神经网络
  • 定义损失函数
  • 在训练集上训练网络
  • 在测试集上测试网络

1.加载和归一化CIFAR10

import torch
import torchvision
import torchvision.transforms as transforms

torchvison数据集的输出时PILImage图像,其范围在[0,1],因此需归一化到[-1,1]

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)
testloader=torch.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=2)
classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')

输出:

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\cifar-10-python.tar.gz
100.0%Files already downloaded and verified

显示部分训练集图像

import matplotlib.pyplot as plt
import numpy as np

def imshow(img):
     img = img/2+0.5
     npimg = img.numpy()
     plt.imshow(np.transpose(npimg,(1,2,0)))
     plt.show()

dataiter = iter(trainloader)
images,labels = dataiter.next()

imshow(torchvision.utils.make_grid(images))
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

输出:
输出

frog  frog   dog plane

2.定义卷积神经网络

import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2,2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16*5*5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
    
net = Net()

3.定义损失函数和优化器

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

4.训练网络

for epoch in range(2):
    running_loss=0.0
    for i,data in enumerate(trainloader,0):
	inputs,labels = data
	optimizer.zero_grad()
	outputs = net(inputs)
	loss=criterion(outputs,labels)
	loss.backward()
	optimizer.step()
	running_loss += loss.item()
	if i%2000==1999:
		print('[%d,%5d] loss:%.3f' %(epoch+1,i+1,running_loss/2000))
		running_loss=0.0
print('Finished Training')

输出

[1, 2000] loss:2.186
[1, 4000] loss:1.822
[1, 6000] loss:1.639
[1, 8000] loss:1.550
[1,10000] loss:1.512
[1,12000] loss:1.453
[2, 2000] loss:1.400
[2, 4000] loss:1.344
[2, 6000] loss:1.336
[2, 8000] loss:1.305
[2,10000] loss:1.284
[2,12000] loss:1.279
Finished Training

5.在测试集上测试网络

dataiter = iter(testloader)
images,labels=dataiter.next()

imshow(torchvision.utils.make_grid(images))
print('GroundTruth:',' '.join('%5s' %classes[labels[j]] for j in range(4)))

输出:
out image

GroundTruth:   cat  ship  ship plane

outputs = net(images)
_,predicted = torch.max(outputs,1)
print('Predicted: ',' '.join('%5s' %classes[predicted[j]] for j in range(4)))

输出:

Predicted:    cat  ship   car plane

6.下面展示在整个数据集上的性能

correct = 0
total = 0
with torch.no_grad():
     for data in testloader:
	 image,labels=data
	 outputs=net(images)
	 _,predicted=torch.max(outputs.data,1)
	 total += labels.size(0)
	 correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (100*correct/total))

输出:

Accuracy of the network on the 10000 test images: 51 %

从结果来看,模型并不是很好。

7.在GPU上训练

device = torch.device("cuda:0" if torch.cuda.is_available() else "cup")
print(device)

输出:

cuda:0

同时需要将inputstargets送入GPU,即

inputs,labels = inputs.to(device),labels.to(device)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值