pytorch使用笔记

pytorch

参数 & 命令行 & 辅助

logger

logger模块解释 —— CSDN
logger使用案例

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等

yacs.config

yacs使用 —— 知乎

yacs库,用于为一个系统构建config文件

需要创建CN()这个作为容器来装载我们的参数,这个容器可以嵌套

设备相关

torch.cuda.synchronize()

等待当前设备上所有流中的所有核心完成。

🌰:测试时间的代码

# code 1
start = time.time()
result = model(input)
end = time.time()

# code 2
torch.cuda.synchronize()
start = time.time()
result = model(input)
torch.cuda.synchronize()
end = time.time()

# code 3
start = time.time()
result = model(input)
print(result)
end = time.time()

代码2是正确的。因为在pytorch里面,程序的执行都是异步的。
如果采用代码1,测试的时间会很短,因为执行完end=time.time()程序就退出了,后台的cu也因为python的退出退出了。
如果采用代码2,代码会同步cu的操作,等待gpu上的操作都完成了再继续成形end = time.time()

代码3和代码2的时间是类似的。
因为代码3会等待gpu上的结果执行完传给print函数,所以时间就和代码2同步的操作的时间基本上是一致的了。
将print(result)换成result.cpu()结果是一致的。

数据加载

图像数据变换

transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

Normalize是把图像数据从[0,1]变成[-1,1],变换公式是image=(image-mean)/std,那么其中的参数就分别是三个通道的mean和std,这个均值和标准差需要自己计算,范围就是训练集和验证集的所有图像。

DataLoader

CSDN原文链接
collate_fn参数使用详解 —— 知乎
num_works参数 —— CSDN


加载一个batch的数据这一步需要使用一个torch.utils.data.DataLoader对象,并且DataLoader是一个基于某个dataset的iterable,这个iterable每次从dataset中基于某种采样原则取出一个batch的数据。
也可以这样说:Torch中可以创建一个torch.utils.data.Dataset对象,并与torch.utils.data.DataLoader一起使用,在训练模型时不断为模型提供数据。

torch.utils.data.DataLoader

定义:Data loader. Combines a dataset and a sampler, and provides an iterable over the given dataset.
构造函数:

torch.utils.data.DataLoader(dataset, 
							batch_size=1, 
							shuffle=False, 
							sampler=None,
							batch_sampler=None, num_workers=0, collate_fn=None,
							pin_memory=False, drop_last=False, timeout=0,
							worker_init_fn=None)
  • dataset: 抽象类,包含两种类型
    • map-style datasets
    • iterable-style datasets
  • batch_size : 每一次抽样的batch-size大小
  • shuffle : True则随机打乱数据
  • Num_works:将batch加载进RAM的进程数。内存开销大,CPU负担大。可能之后几次迭代的数据在本次迭代的时候已经加载进内存。
  • collate_fn:如何取样本的,我们可以定义自己的函数来准确地实现想要的功能。
  • drop_last:告诉如何处理数据集长度除于batch_size余下的数据。True就抛弃,否则保留。

Map-style datasets

是一个类,要求有 __getitem__()and__len__()这两个构造函数,代表一个从索引映射到数据样本。

  • __getitem__(): 根据索引index遍历数据
  • __len__(): 返回数据集的长度
  • 可编写独立的数据处理函数
    • __getitem()__ 函数中进行调用
    • 直接将数据处理函数写在 __getitem()__ 或者 __init()__ 函数中,但是__getitem()__
      必须根据index返回响应的值,该值会通过index传到dataloader中进行后续的batch批处理。

基本需要满足:

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

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

getitem()方法用来从datasets中读取一条数据,这条数据包含训练图片(已CV距离)和标签,参数index表示图片和标签在总数据集中的Index。

len()方法返回数据集的总长度(训练集的总数)。

实现 MyDatasets 类

  1. 简单直白

把 x 和 label 分别装入两个列表 self.src 和 self.trg ,然后通过 getitem(self, idex) 返回对应元素

import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
 
class My_dataset(Dataset):
    def __init__(self):
        super().__init__()
        ## 使用sin函数返回10000个时间序列,如果不自己构造数据,就使用numpy,pandas等读取自己的数据为x即可。
        ## 以下数据组织这块既可以放在init方法里,也可以放在getitem方法里
        self.x = torch.randn(1000,3)
        self.y = self.x.sum(axis=1)
        self.src,  self.trg = [], []
        for i in range(1000):
            self.src.append(self.x[i])
            self.trg.append(self.y[i])
    
           
    def __getitem__(self, index):
        return self.src[index], self.trg[index]

    def __len__(self):
        return len(self.src) 
        
 ## 或者return len(self.trg), src和trg长度一样
 
data_train = My_dataset()
data_test = My_dataset()
data_loader_train = DataLoader(data_train, batch_size=5, shuffle=False)
data_loader_test = DataLoader(data_test, batch_size=5, shuffle=False)
## i_batch的多少根据batch size和def __len__(self)返回的长度确定
## batch_data返回的值根据def __getitem__(self, index)来确定
## 对训练集:(不太清楚enumerate返回什么的时候就多print试试)
for i_batch, batch_data in enumerate(data_loader_train):
    print(i_batch)  ## 打印batch编号
    print(batch_data[0])  ## 打印该batch里面src
    print(batch_data[1])  ## 打印该batch里面trg
## 对测试集:(下面的语句也可以)
for i_batch, (src, trg) in enumerate(data_loader_test):
    print(i_batch)  ## 打印batch编号
    print(src)  ## 打印该batch里面src的尺寸
    print(trg)  ## 打印该batch里面trg的尺寸    

生成的data_train可以通过 data_train[xxx]直接索引某个元素,或者通过next(iter(data_train)) 得到一条条的数据。

  1. 借助TensorDataset将数据包装成dataset
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader, TensorDataset
 
src = torch.sin(torch.arange(1, 1000, 0.1))
trg = torch.cos(torch.arange(1, 1000, 0.1))
 
data = TensorDataset(src, trg)
data_loader = DataLoader(data, batch_size=5, shuffle=False)
for i_batch, batch_data in enumerate(data_loader):
    print(i_batch)  ## 打印batch编号
    print(batch_data[0].size())  ## 打印该batch里面src
    print(batch_data[1].size())  ## 打印该batch里面trg
  1. 地址读取,生成数据的路径 txt文件
import os

from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import matplotlib.image as mpimg



## 对所有图片生成path-label map.txt 这个程序可根据实际需要适当修改
def generate_map(root_dir):
	##得到当前绝对路径
    current_path = os.path.abspath('.')
    ##os.path.dirname()向前退一个路径
    father_path = os.path.abspath(os.path.dirname(current_path) + os.path.sep + ".")

    with open(root_dir + 'map.txt', 'w') as wfp:
        for idx in range(10):
            subdir = os.path.join(root_dir, '%d/' % idx)
            for file_name in os.listdir(subdir):
                abs_name = os.path.join(father_path, subdir, file_name)
                ## linux_abs_name = abs_name.replace("\\", '/')
                wfp.write('{file_dir} {label}\n'.format(file_dir=linux_abs_name, label=idx))

## 实现MyDatasets类
class MyDatasets(Dataset):

    def __init__(self, dir):
        ## 获取数据存放的dir
        ## 例如d:/images/
        self.data_dir = dir
        ## 用于存放(image,label) tuple的list,存放的数据例如(d:/image/1.png,4)
        self.image_target_list = []
        ## 从dir--label的map文件中将所有的tuple对读取到image_target_list中
        ## map.txt中全部存放的是d:/.../image_data/1/3.jpg 1 路径最好是绝对路径
        with open(os.path.join(dir, 'map.txt'), 'r') as fp:
            content = fp.readlines()
            ##s.rstrip()删除字符串末尾指定字符(默认是字符)
            ## 得到 [['d:/.../image_data/1/3.jpg', '1'], ...,]
            str_list = [s.rstrip().split() for s in content]
            ## 将所有图片的dir--label对都放入列表,如果要执行多个epoch,可以在这里多复制几遍,然后统一shuffle比较好
            self.image_target_list = [(x[0], int(x[1])) for x in str_list]

    def __getitem__(self, index):
        image_label_pair = self.image_target_list[index]
        ## 按path读取图片数据,并转换为图片格式例如[3,32,32]
        ## 可以用别的代替
        img = mpimg.imread(image_label_pair[0])
        return img, image_label_pair[1]

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


if __name__ == '__main__':
    ## 生成map.txt
    ## generate_map('train/')

    train_loader = DataLoader(MyDatasets('train/'), batch_size=128, shuffle=True)

    for step in range(20000):
        for idx, (img, label) in enumerate(train_loader):
            print(img.shape)
            print(label.shape)

网络搭建Trick

with torch.no_grad()

参考:https://blog.csdn.net/sazass/article/details/116668755

作用:在该模块下,所有计算得出的tensor的requires_grad都自动设置为False。当requires_grad设置为False时,反向传播时就不会自动求导了,因此大大节约了显存或者说内存。

基本功能函数

torch.max()

torch.max(input) → Tensor:返回输入tensor中所有元素的最大值

torch.max(input, dim, keepdim=False, out=None) -> (Tensor, LongTensor): 按维度dim 返回最大值,并且返回索引。

torch.max()[0], 只返回最大值的每个数

troch.max()[1], 只返回最大值的每个索引

torch.max()[1].data 只返回variable中的数据部分(去掉Variable containing:)

torch.max()[1].data.numpy() 把数据转化成numpy ndarry

torch.max()[1].data.numpy().squeeze() 把数据条目中维度为1 的删除掉

python

str.lower() 全部转化为小写字母

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值