pytorch学习-组成与实战结合

第三、四章:pytorch的基本组成和实战

1.pytorch的基本组成

pytorch的基本组成包括:基本配置、数据读入、模型构建、模型初始化、损失函数、训练与评估、可视化和优化器。

以下结合实战对各个组成进行学习:

实战内容是对10个类别的“时装”图像进行分类,使用的数据集是[FashionMINIST数据集]https://github.com/zalandoresearch/fashion-mnist/tree/master/data/fashion

训练集60000张,测试集1000张。

2.基本配置

导入常用的包

import os
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

3.配置训练环境和超参数

默认CPU,使用GPU则需要配置

# 配置GPU,这里有两种方式
## 方案一:使用os.environ
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
# 方案二:使用“device”,后续对要使用GPU的变量用.to(device)即可
device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")

## 配置其他超参数,如batch_size, num_workers, learning rate, 以及总的epochs
batch_size = 256
num_workers = 4   # 对于Windows用户,这里应设置为0,否则会出现多线程错误
lr = 1e-4
epochs = 20

4.数据读入

数据读入有2种方法:

  • 一种是使用常用数据集;
  • 一种是自己构建数据集Dataset(更重要);

以下讲解自己构建数据集:

## 读取方式二:读入csv格式的数据,自行构建Dataset类
# csv数据下载链接:https://www.kaggle.com/zalando-research/fashionmnist
class FMDataset(Dataset):
    def __init__(self, df, transform=None):
        self.df = df
        self.transform = transform
        self.images = df.iloc[:,1:].values.astype(np.uint8)
        self.labels = df.iloc[:, 0].values
        
    def __len__(self):
        return len(self.images)
    
    def __getitem__(self, idx):
        image = self.images[idx].reshape(28,28,1)
        label = int(self.labels[idx])
        if self.transform is not None:
            image = self.transform(image)
        else:
            image = torch.tensor(image/255., dtype=torch.float)
        label = torch.tensor(label, dtype=torch.long)
        return image, label

train_df = pd.read_csv("./FashionMNIST/fashion-mnist_train.csv")
test_df = pd.read_csv("./FashionMNIST/fashion-mnist_test.csv")
train_data = FMDataset(train_df, data_transform)
test_data = FMDataset(test_df, data_transform)

在构建完训练和测试数据集后,需实例化DataLoader类,用于训练和测试时加载数据:

train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=num_workers, drop_last=True)
test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=False, num_workers=num_workers)

5.模型设计

此处需要自己搭建网络用于训练,定义一个网络结构类,该类包含网络结构信息和前向传播

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 32, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2),
            nn.Dropout(0.3),
            nn.Conv2d(32, 64, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2),
            nn.Dropout(0.3)
        )
        self.fc = nn.Sequential(
            nn.Linear(64*4*4, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )
        
    def forward(self, x):
        x = self.conv(x)
        x = x.view(-1, 64*4*4)
        x = self.fc(x)
        # x = nn.functional.normalize(x)
        return x

model = Net()
model = model.cuda()

6.设定损失函数

pytorch自身带有很多损失函数,对于自身的模型需要自己设计损失函数,损失函数决定的训练效果。

criterion = nn.CrossEntropyLoss()

7.设定优化器

优化器用于对初始化参数(网络内参数)进行初始化。

optimizer = optim.Adam(model.parameters(), lr=0.001)

8.训练和验证

训练和验证都需要封装成函数,用于后续调用,两者存在差别:

  • 模型的状态设置不同;

  • 验证无序设置优化器

  • 验证没有损失回传

  • 验证不会更新优化器

    def train(epoch):
        model.train()
        train_loss = 0
        for data, label in train_loader:
            data, label = data.cuda(), label.cuda()
            optimizer.zero_grad()
            output = model(data)
            loss = criterion(output, label)
            loss.backward()
            optimizer.step()
            train_loss += loss.item()*data.size(0)
        train_loss = train_loss/len(train_loader.dataset)
        print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch, train_loss))
    
    def val(epoch):       
        model.eval()
        val_loss = 0
        gt_labels = []
        pred_labels = []
        with torch.no_grad():
            for data, label in test_loader:
                data, label = data.cuda(), label.cuda()
                output = model(data)
                preds = torch.argmax(output, 1)
                gt_labels.append(label.cpu().data.numpy())
                pred_labels.append(preds.cpu().data.numpy())
                loss = criterion(output, label)
                val_loss += loss.item()*data.size(0)
        val_loss = val_loss/len(test_loader.dataset)
        gt_labels, pred_labels = np.concatenate(gt_labels), np.concatenate(pred_labels)
        acc = np.sum(gt_labels==pred_labels)/len(pred_labels)
        print('Epoch: {} \tValidation Loss: {:.6f}, Accuracy: {:6f}'.format(epoch, val_loss, acc))
    

    开始训练

    for epoch in range(1, epochs+1):
        train(epoch)
        val(epoch)
    

你可能感兴趣的:(pytorch,人工智能,算法,学习)