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)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值