Pytorch机器学习/深度学习代码笔记

导入模块

import torch
from tensorboardX import SummaryWriter  //可视化

设置参数

batch_size=64
works=4
epochs=20
train_path="train"
val_path="val"

数据预处理

流程:先定义数据集,再将定义的数据集导入数据载入器(Dataloader)来读取数据。

定义数据集有两种方式,一种是自定义Dataset包装类,和DataLoader类一样,它是torch.utils.data的里的一个类,另一种是直接调用ImageFolder函数,它是torchvision.datasets里的函数。

定义数据集

1.Dataset

Dataset是一个抽象类,可以自定义数据集,为了能够方便的读取,需要将要使用的数据包装为Dataset类。
自定义的Dataset需要继承它并且实现两个成员方法:
1.__getitem__():该方法定义用索引(0到len(self))获取一条数据或一个样本。
2.__len__()方法返回数据集的总长度。
模板如下:

import torch.utils.data
#定义一个数据集
class CaptionDataset(Dataset):
    """ 数据集演示 """
    def __init__(self,transform=None):  
        """实现初始化方法,在初始化的时候将数据读载入"""
        ....(包括加载数据路径)
    def __getitem__(self):
        return self....
        
    def __len__(self):
        return len(...)

# 实例化这个类,然后我们就得到了Dataset类型的数据,记下来就将这个类传给DataLoader,就可以了。    
train_data= CaptionDataset(transform=transform) #transform需自己定义(见下面torchvision.transforms)

2.ImageFolder

ImageFolder假设所有的文件按文件夹保存,每个文件夹下存储同一个类别的图片,文件夹名为类名,其构造函数如下:

import torchvision.datasets
ImageFolder(root, transform=None, target_transform=None, loader=default_loader)

各参数含义:

root:在root指定的路径下寻找图片

transform:对PIL Image进行的转换操作,transform的输入是使用loader读取图片的返回对象

target_transform:对label的转换

loader:给定路径后如何读取图片,默认读取为RGB格式的PIL Image对象

label:按照文件夹名顺序排序后存成字典,即{类名:类序号(从0开始)}

举例如下:

import torchvision.datasets
#此处transform需自己定义(见下面torchvision.transforms),其他参数为默认值
train_data=torchvision.datasets.ImageFolder(root=train_path,transform=transform) 

加载数据集

DataLoader

DataLoader是一个数据加载器类,实现了对数据集进行随机采样和多轮次迭代的功能。在训练过程中,可以非常方便地实现多轮次小批量随机梯度下降训练。
常用参数有:Dataset数据集实例,batch_size(每个batch的大小,shuffle(是否进行搅乱操作),num_workers(加载数据的时候使用几个子进程),返回一个可迭代对象。

import torch.utils.data
train_loader = torch.utils.data.DataLoader(
        CaptionDataset(train_data, transform=transform),
        batch_size=batch_size, shuffle=True, num_workers=workers)

详细有关参数见博客:PyTorch 中的数据类型 torch.utils.data.DataLoader

torchvision–数据预处理要使用的库

torchvision是Pytorch中专门用来处理图像的库。
提供了常用图片数据集(datasets);
训练好的模型(models);
一般的图像转换操作类(transforms),

torchvision.datasets

torchvision.datasets可以理解为PyTorch团队自定义的dataset,这些dataset帮我们提前处理好了很多的图片数据集,我们拿来就可以直接使用:

  • MNIST
  • COCO
  • Captions
  • Detection
  • LSUN
  • ImageFolder
  • Imagenet-12
  • CIFAR
  • STL10
  • SVHN
  • PhotoTour
    以上我们可以直接用(其他的只能通过自己自定义数据集),示例如下:
import torchvision.datasets as datasets
trainset = datasets.MNIST(root='./data', # 表示 MNIST 数据的加载的目录
                                      train=True,  # 表示是否加载数据库的训练集,false的时候加载测试集
                                      download=True, # 表示是否自动下载 MNIST 数据集
                                      transform=None) # 表示是否需要对数据进行预处理,none为不进行预处理

torchvision.models

torchvision提供了训练好的模型,可以加载后直接使用(见下面代码),或者在进行迁移学习torchvision.models模块的子模块中包含以下模型结构:

  • AlexNet
  • VGG
  • ResNet
  • SqueezeNet
  • DenseNet
#导入预训练模型
import torchvision.models
model = torchvision.models.vgg16(pretrained=True) #True代表已经训练好的模型

torchvision.transforms

transform模块提供了一般的图像转换操作类,用作数据处理和数据增强。
主要提供了对PIL Image对象和Tensor对象的常用操作。

对PIL Image对象的常用操作有:

  • Resize:调整图片尺寸
  • CenterCrop、RandomCrop、RandomSizedCrop:裁剪图片
  • Pad:填充
  • ToTensor:将PIL Image对象转成Tensor,会自动将[0,255]归一化至[0,1]

对Tensor对象的常用操作有:

  • Normalize:标准化,即减均值,除以标准差
  • ToPILImage:将Tensor转为PIL Image对象。
import torchvision.transforms as transforms
transform = transforms.Compose([
    transforms.RandomCrop(32, padding=4),  #先四周填充0,在把图像随机裁剪成32*32
    transforms.RandomHorizontalFlip(),  #图像一半的概率翻转,一半的概率不翻转
    transforms.RandomRotation((-45,45)), #随机旋转
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225)), #R,G,B每层的归一化用到的均值和方差
])

详细有关transforms的用法见博客:PyTorch 学习笔记(三):transforms的二十二个方法

训练网络参数

训练前的准备

设置指定的训练设备(GPU、CPU)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

定义损失函数

torch.nn模块中定义了很多标准地损失函数。

import torch.nn as nn
xentropy=nn.CrossEntropyLoss() #此处定义一个交叉熵损失函数对象,该对象可以调用backward()方法实现误差反向传播。

定义优化器

torch.optim模块提供了很多优化算法类,
比如:torch.optim.SGD,torch.optim.Adam,torch.optim.RMSprop。这里以SGD为例。

#import torch.optim
net=CNN().to(device) #使用gpu构造一个CNN对象
optimizer=torch.optim.SGD(params=net.parameters(),lr=0.01,momentum=0.9) 
#上式参数依次为:需要网络模型的参数、学习率、动量参数

详细参数见博客:torch.optim.SGD()各参数的解释

训练过程

神经网络训练过程的一步迭代包含四个主要步骤:

  • 前向运算,计算给定输入的预测结果
  • 计算损失函数值
  • 反向传播(BP),计算参数梯度(计算之前要先梯度清零)
  • 使用梯度下降法更新参数值

详细代码如下:

def train(net,optimizer,loss_fn,num_epoch,data_loader,device):
'''参数分别为网络模型、损失函数(对应之前的xentropy)、epoch总次数、数据加载器、训练设备'''
	net.train() #进入训练模型
	for epoch in range(num_epoch):
		print('Epoch {}/{}'.format(epoch+1, num_epochs))
		running_loss=0
		running_corrects=0
		for i,data in enumerate(data_loader):
			inputs=data[0].to(device)  #输入
			labels=data[1].to(device)  #真实值标签
			#下面优化过程
			optimizer.zero_grad() #先把前一步的梯度清除,设置梯度值为0
			outputs=net(inputs)  #前向运算,计算网络模型在inputs上的输出outputs
			loss=loss_fn(outputs,labels) #计算损失函数值
			loss.backward() #进行反向传播,计算梯度
			optimizer.step() #使用优化器的step()方法,进行梯度下降,更新模型参数
			
			#可以输出两种loss,loss为每次迭代的loss,running_loss为每个epoch的loss,之后再取平均值。
			running_loss+=loss.item() #计算每个epoch的loss总值
			_, preds = torch.max(outputs, 1)
			running_corrects += torch.sum(preds == labels).item()
		epoch_loss=running__loss/len(train_data) #计算每个epoch的平均loss
		epoch_acc = running_corrects / len(train_data)
        print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                'train', epoch_loss, epoch_acc))				
	

验证/测试过程

测试和验证集过程不用反向传播,也不用更新梯度。

def evaluate(net,loss_fn,data_load,device):
	net.eval() #进入模型评估模式,验证和测试都是这个
	running_loss=0
	correct=0.0
	total=0
	
	for data in data_loader:
		inputs=data[0].to(device)  #输入
		labels=data[1].to(device)  #真实值标签
		with torch.no_grad():	
			outputs=net(inputs)
		loss=loss_fn(outputs,labels)
		
		running_loss+=loss.item()
		_,predicted=torch.max(outputs.data,1)
		total+=labels.size(0) #另一种计算总数的方法
		correct+=(predicted==labels).sum().item() #计算预测对的数
	epoch_loss = running_loss/len(val_data)
	acc=correct/total #计算准确率
	
    print('{} Loss: {:.4f} Acc: {:.4f}'.format(
            'valid', epoch_loss, acc))	

运行

有两种方式:

  • 1.设立一个主函数main(),将for epoch in epochs:以及train函数和test函数放到main()里运行就可以了。
  • 2.将for epoch in epochs:和test函数放入train函数,再直接运行train()函数就可以了。
    完整代码实例:pytorch实现图像分类代码实例
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值