Pytorch学习笔记

科研所迫,开始入坑深度学习。
之前断断续续的学过一些,了解一些概念,但没怎么敲过代码,看源码笔记费劲,更别谈复现了
好友给我推荐了一个通俗易懂的pytorch教程,花了三天看了一遍,这个教程讲得真的很好,为小土堆点赞

今后忘记了再去看一遍视频又十分耗时间,所以在此做一下学习笔记,一是加深印象,二是方便自己后面随时复习

cuda的安装检查

1
2
import torch
torch.cuda.is_available()

返回Ture,即GPU可用

返回Flase,即GPU不可用,需要去好好检查一下了。

Python两大法宝函数

以torch.cuda.is_available()这个函数为例

1
dir(torch.cuda.is_available)

以列表的形式返回 torch.cuda.is_available 所有的子函数or方法,具体效果如图所示:

1
torch.cuda.is_available?? 

在函数后加2个?,不要再加括号,即可返回该函数的具体用法,方便用户查看,具体效果如图所示:

Pytorch加载数据

Dataset 定义自己的数据类

torch.utils.data.Dataset 提供一种方式去获取数据及其label,方便用户去定义自己的数据类。在重写dataset抽象类的时候,需要定义__getitem__和__len__这个两个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import torch
from torch.utils.data import Dataset
from PIL import Image
import os

class MyData(Dataset):
def __init__(self,root_dir,label_dir):
# 后面的变量都需要一开始在这初始化
self.root_dir = root_dir
self.label_dir = label_dir
self.path = os.path.join(self.root_dir,self.label_dir)
self.img_path = os.listdir(self.path)


# __getitem__ 是必须要的重写函数,不要写错了
def __getitem__(self,index):
img_name = self.img_path[index]
img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
img = Image.open(img_item_path)
label = self.label_dir
# 返回的是一个数组
return img,label

def __len__(self):
return len(self.img_path)

# r表示不转义(python基础)
root_dir = r"hymenoptera_data\train"
ants_label_dir = "ants"
bees_label_dir = "bees"
ants_dataset = MyData(root_dir,ants_label_dir)
bees_dataset = MyData(root_dir,bees_label_dir)

# 返回的是一个数组,所以a = img ,b = label (python基础)
a,b = bees_dataset[1]
a

dataloader如何处理数据集中的数据

torch.utils.data.dataloader 官方文档解释为:

Combines a dataset and a sampler, and provides an iterable over the given dataset.

简而言之:在后面的步骤中,如何去处理数据集中的数据,常用的参数有

  • dataset:需要加载的是数据集是哪个 dataset from which to load the data.

  • batch_size:一次要加载多少个数据 how many samples per batch to load,default: 1

  • shuffle:每轮加载是否打乱顺序,set to True to have the data reshuffled at every epoch (default: False).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import torch
from torch.utils.data import DataLoader

#加载内置的数据集
test_set = torchvision.datasets.CIFAR10(root = './CIFAR10',train = False,transform = trans_tensor ,download=False)

#在后面的步骤中如何去处理数据集的数据呢,每次去64个,每轮采用中不打乱
test_loader = DataLoader(dataset = test_set, batch_size = 64, shuffle = True)

for data in test_loader:
# 一个data里有64个img,64个targets
imgs,targets = data

print(imgs.shape)
print(targets)

可以看到,imgs.shape = [64, 3, 32, 32] ,64张照片,3个通道,32*32像素

targets是一个64个数字的列表

由此验证,一个data里有64个img,64个targets。

TensorBoard的使用

what is TensorBoard

对大部分人而言,深度神经网络就像一个黑盒子,其内部的组织、结构、以及其训练过程很难理清楚,这给深度神经网络原理的理解和工程化带来了很大的挑战。

TensorBoard是tensorflow内置的一个可视化工具,现在在pytorch也可以使用,具体可以做:

  • 跟踪和可视化损失及准确率等指标
  • 可视化模型图(操作和层)
  • 查看权重、偏差或其他张量随时间变化的直方图
  • 将嵌入投射到较低的维度空间
  • 显示图片、文字和音频数据
  • ……

how to use TensorBoard in pytorch

直接在代码里记录吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import torch
import numpy as np
from PIL import Image
from torch.utils.tensorboard import SummaryWriter

# 给本次的可视化结果命个名,运行代码之后会发现多一个logs文件夹
writer = SummaryWriter("logs")

for i in range(100):
# 在可视化结果添加一个表格,表格名字为"y=2x",纵坐标为2*i,横坐标为i
writer.add_scalar("y=2x",2*i,i)

image_path = r"hymenoptera_data\train\ants\0013035.jpg"
image = Image.open(image_path)

image_array = np.array(image)

# 在可视化结果添加一张照片,表格名字为"y=2x",纵坐标为img_tensor ,横坐标为step第几步骤了
# If you have non-default dimension setting, set the dataformats argument.
writer.add_image("TEST",img_tensor = image_array,global_step = 1,dataformats=("HW3"))

writer.close()

我对TensorBoard的理解是一个嵌入式的强大Excel,方便我们对于训练过程的理解

transform的使用

torchvision.transforms是pytorch中的图像预处理包,包含了很多种对图像数据进行变换的函数

就是将图像数据的格式做各种转化,满足后续的使用

下面写一下常用的变换方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import torch
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")

# 加载一张照片进来做测试
image_path = r"hymenoptera_data\train\ants\892108839_f1aad4ca46.jpg"
image = Image.open(image_path)

# ToTensor
# Convert a PIL Image or numpy.ndarray to tensor.
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(image)

writer.add_image("ToTensor",img_tensor)

# Normalize逐channel的对图像进行标准化(均值变为0,标准差变为1),可以加快模型的收敛
trans_norm = transforms.Normalize([3,4,80],[3,4,5])
img_norm = trans_norm(img_tensor)

writer.add_image("Normalize",img_norm,3)

# Resize
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img_tensor)

writer.add_image("Resize",img_resize,4)

# Compose 把多个transforms的功能按照列表集合到一起
trans_resize_2 = transforms.Resize((1026,512))
trans_compose = transforms.Compose([trans_resize_2,trans_tensor])
img_resize_2 = trans_compose(image)
writer.add_image("Compose",img_resize_2,2)

# RandomCrop 随机裁剪,不按照比例进行缩放
trans_RandomCrop = transforms.RandomCrop((300))
trans_compose_2 = transforms.Compose([trans_RandomCrop,trans_tensor])
for i in range(10):
img_crop = trans_compose_2(image)
writer.add_image("RandomCrop",img_crop,i)

writer.close()

数据集的使用

pytorch提供了很多自带的开源数据集,我们只需要通过很简单的几行代码即可调用

方便初期的学习使用,后期就需要构建自己的数据集

影像数据集地址:https://pytorch.org/vision/stable/datasets.html

CIFAR10论文地址:https://www.cs.toronto.edu/~kriz/cifar.html

这里我们以CIFAR10为例

1
2
3
4
5
6
7
8
9
import torch
import torchvision
from torch.utils.data import DataLoader

# 把我们加载进来的图片转变成tensor格式,方便后续处理
trans_tensor = torchvision.transforms.ToTensor()

train_set = torchvision.datasets.CIFAR10(root = './CIFAR10',train = True,transform = trans_tensor ,download=False)
test_set = torchvision.datasets.CIFAR10(root = './CIFAR10',train = False,transform = trans_tensor ,download=False)

不同数据集参数的调用上会有一些差别,基本大同小异,这里以CIFAR10为例;

root:数据集路径在哪

train:这是数据集中的训练集吗

transform:需要对数据集中的数据做哪些预处理吗,我这里的ToTensor就是变换张量处理

download:是否需要从网络上下载该数据集,如果下载过慢可以自己去相应的下载地址里用IDM等工具主动下载