前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pytorch demo 实践

pytorch demo 实践

作者头像
张俊怡
发布2018-04-24 14:23:02
2K0
发布2018-04-24 14:23:02
举报

相关环境

python opencv pytorch ubuntu 14.04

pytorch 基本内容

60分钟快速入门,参考:https://blog.csdn.net/u014630987/article/details/78669051 需要学习的内容包括

代码语言:javascript
复制
   1、基本概念Tensors、Variable、Numpy等
   2、如何搭建神经网络模型(包括卷积神经网络)
   3、如何定义损失函数和优化器(包括不同分类器和优化器的含义)
   4、如何训练(包括如何读取数据、如何在GPU上训练)
   5、如何测试(定义好评价指标,比如准确率和loss)
网络( 参考[1])

网络结构

对应代码(直接执行就行,有一个下载数据的过程,可能有一点耗时 参考[1])
代码语言:javascript
复制
#coding=utf-8
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable

# Training settings
batch_size = 64

# MNIST Dataset
train_dataset = datasets.MNIST(root='./mnist_data/',
                               train=True,
                               transform=transforms.ToTensor(),
                               download=True)

test_dataset = datasets.MNIST(root='./mnist_data/',
                              train=False,
                              transform=transforms.ToTensor())

# Data Loader (Input Pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size,
                                          shuffle=False)


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.l1 = nn.Linear(784, 520)
        self.l2 = nn.Linear(520, 320)
        self.l3 = nn.Linear(320, 240)
        self.l4 = nn.Linear(240, 120)
        self.l5 = nn.Linear(120, 10)Variable

    def forward(self, x):
        # Flatten the data (n, 1, 28, 28) --> (n, 784)
        x = x.view(-1, 784)
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return F.log_softmax(self.l5(x))
        #return self.l5(x)

model = Net()

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

def train(epoch):
    # 每次输入barch_idx个数据
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = Variable(data), Variable(target)

        optimizer.zero_grad()
        output = model(data)
        # loss
        loss = F.nll_loss(output, target)
        loss.backward()
        # update
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.data[0]))

def test():
    test_loss = 0
    correct = 0
    # 测试集
    for data, target in test_loader:
        data, target = Variable(data, volatile=True), Variable(target)
        output = model(data)
        # sum up batch loss
        test_loss += F.nll_loss(output, target).data[0]
        # get the index of the max
        #pred = output.data.max(1, keepdim=True)[1]
        pred = output.data.max(1)[1]
        correct += pred.eq(target.data.view_as(pred)).cpu().sum()

    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

for epoch in range(1,6):
    train(epoch)
    test()
亲自验证代码可行

运行结果

使用GPU

使用GPU计算这是核心

官方参考代码

由于我只有一块GPU,所以将这一行代码 if torch.cuda.device_count() > 1:改成了 if torch.cuda.device_count() >= 1:

代码语言:javascript
复制
"""
Optional: Data Parallelism
==========================
**Authors**: `Sung Kim <https://github.com/hunkim>`_ and `Jenny Kang <https://github.com/jennykang>`_

In this tutorial, we will learn how to use multiple GPUs using ``DataParallel``.

It's very easy to use GPUs with PyTorch. You can put the model on a GPU:

.. code:: python

    model.gpu()

Then, you can copy all your tensors to the GPU:

.. code:: python

    mytensor = my_tensor.gpu()

Please note that just calling ``mytensor.gpu()`` won't copy the tensor
to the GPU. You need to assign it to a new tensor and use that tensor on the GPU.

It's natural to execute your forward, backward propagations on multiple GPUs. 
However, Pytorch will only use one GPU by default. You can easily run your 
operations on multiple GPUs by making your model run parallelly using 
``DataParallel``:

.. code:: python

    model = nn.DataParallel(model)

That's the core behind this tutorial. We will explore it in more detail below.
"""


######################################################################
# Imports and parameters
# ----------------------
# 
# Import PyTorch modules and define parameters.
# 

import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader

# Parameters and DataLoaders
input_size = 5
output_size = 2

batch_size = 30
data_size = 100


######################################################################
# Dummy DataSet
# -------------
# 
# Make a dummy (random) dataset. You just need to implement the
# getitem 
#

class RandomDataset(Dataset):

    def __init__(self, size, length):
        self.len = length
        self.data = torch.randn(length, size)

    def __getitem__(self, index):
        return self.data[index]

    def __len__(self):
        return self.len

rand_loader = DataLoader(dataset=RandomDataset(input_size, 100),
                         batch_size=batch_size, shuffle=True)


######################################################################
# Simple Model
# ------------
# 
# For the demo, our model just gets an input, performs a linear operation, and 
# gives an output. However, you can use ``DataParallel`` on any model (CNN, RNN,
# Capsule Net etc.) 
#
# We've placed a print statement inside the model to monitor the size of input
# and output tensors. 
# Please pay attention to what is printed at batch rank 0.
# 

class Model(nn.Module):
    # Our model

    def __init__(self, input_size, output_size):
        super(Model, self).__init__()
        self.fc = nn.Linear(input_size, output_size)

    def forward(self, input):
        output = self.fc(input)
        print("  In Model: input size", input.size(), 
              "output size", output.size())

        return output


######################################################################
# Create Model and DataParallel
# -----------------------------
# 
# This is the core part of the tutorial. First, we need to make a model instance
# and check if we have multiple GPUs. If we have multiple GPUs, we can wrap 
# our model using ``nn.DataParallel``. Then we can put our model on GPUs by
# ``model.gpu()`` 
# 

model = Model(input_size, output_size)
if torch.cuda.device_count() >= 1:
  print("Let's use", torch.cuda.device_count(), "GPUs!")
  # dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs
  model = nn.DataParallel(model)

if torch.cuda.is_available():
   print "cuda cuda cuda"
   model.cuda()


######################################################################
# Run the Model
# -------------
# 
# Now we can see the sizes of input and output tensors.
# 

for data in rand_loader:
    if torch.cuda.is_available():
        input_var = Variable(data.cuda())
    else:
        input_var = Variable(data)

    output = model(input_var)
    print("Outside: input size", input_var.size(),
          "output_size", output.size())


######################################################################
# Results
# -------
# 
# When we batch 30 inputs and 30 outputs, the model gets 30 and outputs 30 as
# expected. But if you have GPUs, then you can get results like this.
# 
# 2 GPUs
# ~~~~~~
#
# If you have 2, you will see:
# 
# .. code:: bash
# 
#     # on 2 GPUs
#     Let's use 2 GPUs!
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#         In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
#         In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
#     Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
# 
# 3 GPUs
# ~~~~~~
# 
# If you have 3 GPUs, you will see:
# 
# .. code:: bash
# 
#     Let's use 3 GPUs!
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#         In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#     Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
# 
# 8 GPUs
# ~~~~~~~~~~~~~~
# 
# If you have 8, you will see:
# 
# .. code:: bash
# 
#     Let's use 8 GPUs!
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#     Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#         In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
#     Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
# 


######################################################################
# Summary
# -------
# 
# DataParallel splits your data automatically and sends job orders to multiple
# models on several GPUs. After each model finishes their job, DataParallel
# collects and merges the results before returning it to you.
# 
# For more information, please check out
# http://pytorch.org/tutorials/beginner/former\_torchies/parallelism\_tutorial.html.
# 

如果运行遇到了这个问题

代码语言:javascript
复制
RuntimeError: cublas runtime error : library not initialized at /b/wheel/pytorch-src/torch/lib/THC/THCGeneral.c:387

解决办法

代码语言:javascript
复制
尝试执行 sudo rm -rf ~/.nv 
执行结果

执行结果

Pytorch 的几种数据读取方式介绍

1、torchvision.datasets的使用 参考[2]

上边的minist实战的数据读取就是用这种方式

对于常用数据集,可以使用torchvision.datasets直接进行读取。torchvision.dataset是torch.utils.data.Dataset的实现,该包提供了以下数据集的读取。

torchvision.dataset和torch.utils.data.Dataloader的代码实现

参考https://zhuanlan.zhihu.com/p/28200166

包含的数据集如下
代码语言:javascript
复制
MNIST
COCO (Captioning and Detection)
LSUN Classification
ImageFolder
Imagenet-12
CIFAR10 and CIFAR100
STL10

将该种方式读取的数据打印出来看看,是一些Tensor。

代码语言:javascript
复制
#coding=utf-8
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import torchvision
from torch.autograd import Vari上边的minist实战的数据读取就是用这种方式able
import matplotlib.pyplot as plt
import numpy as np
import cv2
# Training settings
batch_size = 2

# MNIST Dataset
train_dataset = datasets.MNIST(root='./mnist_data/',
                               train=True,
                               transform=transforms.ToTensor(),
                               download=True)

test_dataset = datasets.MNIST(root='./mnist_data/',
                              transform=transforms.ToTensor())

# Data Loader (Input Pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size,
                                          shuffle=False)

dataiter = iter(train_loader)
image,lables = dataiter.next()

print image[0] #打印第一张图片的矩阵
print lables[0] #打印第一张图片的标签值

#分别用opencv matlabplot读取和显示本地图片
im = cv2.imread("1.jpg")
win = cv2.namedWindow('opencv test win', flags=0)
cv2.imshow("opencv test win",im)
cv2.waitKey(5)
plt.imshow(im)
plt.show("matplotlib")
#plt.imshow(image.reshape(image.shape[0], image.shape[1]), cmap=plt.cm.Greys)

结果

2、自定义标签数据集的读取(参考文献[2]) 比如现在有文件text.txt, 格式如下,第一个是文件名,后边的数字是标签

代码语言:javascript
复制
0.jpg  1 2 3 4 5 6
1.jpg  2 3 4 5 6 7
2.jpg  6 7 8 9 0 1

第一步:继承torch.utils.data.Dataset类,完成图像及标签的读取,图像存在某个目录下,比如..../images

代码来源文献[2]
代码语言:javascript
复制
import os  
import torch  
import torch.utils.data as data  
from PIL import Image  
  
def default_loader(path):  
    return Image.open(path).convert('RGB')  
  
class myImageFloder(data.Dataset):  
    def __init__(self, root, label, transform = None, target_transform=None, loader=default_loader):  
        fh = open(label)  
        c=0  
        imgs=[]  
        class_names=[]  
        for line in  fh.readlines():  
            if c==0:  
                class_names=[n.strip() for n in line.rstrip().split('   ')]  
            else:  
                cls = line.split()   
                fn = cls.pop(0)  
                if os.path.isfile(os.path.join(root, fn)):  
                    imgs.append((fn, tuple([float(v) for v in cls])))  
            c=c+1  
        self.root = root  
        self.imgs = imgs  
        self.classes = class_names  
        self.transform = transform  
        self.target_transform = target_transform  
        self.loader = loader  
  
    def __getitem__(self, index):  
        fn, label = self.imgs[index]  
        img = self.loader(os.path.join(self.root, fn))  
        if self.transform is not None:  
            img = self.transform(img)  
        return img, torch.Tensor(label)  
  
    def __len__(self):  
        return len(self.imgs)  
      
    def getName(self):  
        return self.classes 

第二步:实例化torch.utils.data.DataLoader 获取到实例,就能获得data跟label,就能扔到模型训练或者测试啦。

代码语言:javascript
复制
    mytransform = transforms.Compose([  
        transforms.ToTensor()  
        ]  
    )  
      
    # torch.utils.data.DataLoader  
    imgLoader = torch.utils.data.DataLoader(  
             myFloder.myImageFloder(root = "../data/testImages/images", label = "../data/testImages/test.txt", transform = mytransform ),   
             batch_size= 2, shuffle= False, num_workers= 2)  
      
    for i, data in enumerate(imgLoader, 0):  
        print(data[i][0])  
        # opencv  
        img2 = data[i][0].numpy()*255  
        img2 = img2.astype('uint8')  
        img2 = np.transpose(img2, (1,2,0))  
        img2=img2[:,:,::-1]#RGB->BGR  
        cv2.imshow('img2', img2)  
        cv2.waitKey()  
        break  
感谢以下博客大神们的文章,本文在多人的博客和论文基础上总结而来,如有侵权或者内容不妥,请简书私信联系作者。

参考文献

1.https://blog.csdn.net/m0_37306360/article/details/79309849 2.https://blog.csdn.net/tfygg/article/details/73354235 3.https://zhuanlan.zhihu.com/p/28200166 4.https://blog.csdn.net/m0_37306360/article/details/79309849 5.https://translate.google.com.hk/translate?hl=zh-CN&sl=en&u=https://github.com/torch/cutorch/issues/677&prev=search

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.03.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相关环境
  • pytorch 基本内容
  • 使用GPU
  • Pytorch 的几种数据读取方式介绍
    • 感谢以下博客大神们的文章,本文在多人的博客和论文基础上总结而来,如有侵权或者内容不妥,请简书私信联系作者。
    • 参考文献
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档