深度学习相关知识:
基本配置
导入包:
import os
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import torch.optim as optimizer
涉及到表格信息的读入很可能用到pandas,对于不同的项目可能还需要导入一些更上层的包如cv2等。如果涉及可视化还会用到matplotlib、seaborn等。涉及到下游分析和指标计算也常用到sklearn。
超参数可以统一设置,方便后续调试时修改:
batch_size = 16
lr = 1e-4
max_epochs = 100
GPU的设置有两种常见的方式:
# 方案一:使用os.environ,这种情况如果使用GPU不需要设置
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'
# 方案二:使用“device”,后续对要使用GPU的变量用.to(device)即可
device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
数据读入:
简单描述一下流程图,首先在for循环中去使用DataLoader,进入DataLoader之后是否采用多进程进入DataLoaderlter,进入DataLoaderIter之后会使用sampler去获取Index,拿到索引之后传输到DatasetFetcher,在DatasetFetcher中会调用Dataset,Dataset根据给定的Index,在getitem中从硬盘里面去读取实际的Img和Label,读取了一个batch_size的数据之后,通过一个collate_fn将数据进行整理,整理成batch_Data的形式,接着就可以输入到模型中训练。代码有些表述不一样,但是流程差不多。后续还将仔细整理一下。
pytorch - 数据读取机制中的Dataloader与Dataset - 全栈程序员必看
class MyDataset(Dataset):
def __init__(self, data_dir, info_csv, image_list, transform=None):
"""
Args:
data_dir: path to image directory.
info_csv: path to the csv file containing image indexes
with corresponding labels.
image_list: path to the txt file contains image names to training/validation set
transform: optional transform to be applied on a sample.
"""
label_info = pd.read_csv(info_csv)
image_file = open(image_list).readlines()
self.data_dir = data_dir
self.image_file = image_file
self.label_info = label_info
self.transform = transform
def __getitem__(self, index):
"""
Args:
index: the index of item
Returns:
image and its labels
"""
image_name = self.image_file[index].strip('\n') #按行读取图片,去掉每行的换行符"\n"
raw_label = self.label_info.loc[self.label_info['Image_index'] == image_name]
#显示索引:.loc,第一个参数为 index切片,第二个为 columns列名
#https://blog.csdn.net/zz5957/article/details/118549238
label = raw_label.iloc[:,0]
#.iloc[:,0]隐式索引:.iloc(integer_location),只能传入整数
image_name = os.path.join(self.data_dir, image_name)
#path.join拼接规则 https://www.jianshu.com/p/3090f7875f9b
image = Image.open(image_name).convert('RGB')
if self.transform is not None:
#https://blog.csdn.net/weixin_40123108/article/details/85099449
image = self.transform(image)
return image, label#返回的单个样本
def __len__(self):
return len(self.image_file)
#构建好Dataset后,就可以使用DataLoader来按批次读入数据了,实现代码如下:
from torch.utils.data import DataLoader
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=4, shuffle=True, drop_last=True)
val_loader = torch.utils.data.DataLoader(val_data, batch_size=batch_size, num_workers=4, shuffle=False)
-
batch_size:样本是按“批”读入的,batch_size就是每次读入的样本数
-
num_workers:有多少个进程用于读取数据
-
shuffle:是否将读入的数据打乱
-
drop_last:对于样本最后一部分没有达到批次数的样本,使其不再参与训练
PyTorch中的DataLoader的读取可以使用next和iter来完成:
import matplotlib.pyplot as plt
images, labels = next(iter(val_loader))
print(images.shape)
plt.imshow(images[0].transpose(1,2,0))
plt.show()
next () 返回迭代器的下一个项目。next() 函数要和生成迭代器的 iter () 函数一起使用。
iter () 函数获取这些可迭代对象的迭代器。对获取到的迭代器不断使用 next () 函数来获取下⼀条数据,调用了可迭代对象的 iter 方法.
iterable – 可迭代对象,default – 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。
模型构建:
基于 Module 类的模型来完成的,它让模型构造更加灵活。
Module 类是 nn 模块里提供的一个模型构造类,是所有神经网络模块的基类,我们可以继承它来定义我们想要的模型。下面继承 Module 类构造多层感知机。这里定义的 MLP 类重载了 Module 类的 init 函数和 forward 函数。它们分别用于创建模型参数和定义前向计算。前向计算也即正向传播。
import torch
from torch import nn
class MLP(nn.Module):
# 声明带有模型参数的层,这里声明了两个全连接层
def __init__(self, **kwargs):
# 调用MLP父类Block的构造函数来进行必要的初始化。这样在构造实例时还可以指定其他函数
super(MLP, self).__init__(**kwargs)
self.hidden &