美文网首页
PyTrch深度学习简明实战9 - 数据增强

PyTrch深度学习简明实战9 - 数据增强

作者: 薛东弗斯 | 来源:发表于2023-03-21 21:48 被阅读0次

学习笔记12:图像数据增强及学习速率衰减 - pbc的成长之路 - 博客园 (cnblogs.com)

数据增强

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import torchvision
import glob
from torchvision import transforms
from torch.utils import data
from PIL import Image

img_dir = r'./data/dataset2/*.jpg'
imgs = glob.glob(img_dir)

species = ['cloudy', 'rain', 'shine', 'sunrise']
species_to_idx = dict((c, i) for i, c in enumerate(species))
# species_to_idx   # {'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3}
idx_to_species = dict((v, k) for k, v in species_to_idx.items())
# idx_to_species  # {0: 'cloudy', 1: 'rain', 2: 'shine', 3: 'sunrise'}

labels = []
for img in imgs:
    for i, c in enumerate(species):
        if c in img:
            labels.append(i)
            
count = len(imgs)   # 1122

np.random.seed(2022)
index = np.random.permutation(count)
imgs = np.array(imgs)[index]
labels = np.array(labels, dtype=np.int64)[index]

sep = int(count*0.8)
train_imgs = imgs[ :sep]
train_labels = labels[ :sep]
test_imgs = imgs[sep: ]
test_labels = labels[sep: ]

# 数据增强
train_transform = transforms.Compose([
        transforms.Resize((256, 256)),  
        transforms.RandomCrop((224, 224)),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.ColorJitter(brightness=(0.7, 1.3), contrast=(0.7, 1.3), saturation=(0.7, 1.3), hue=(-0.05, 0.05)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

test_transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

class WT_dataset(data.Dataset):
    def __init__(self, imgs_path, lables, transform):
        self.imgs_path = imgs_path
        self.lables = lables
        self.transform = transform

    def __getitem__(self, index):
        img_path = self.imgs_path[index]
        lable = self.lables[index]
        
        pil_img = Image.open(img_path)
        pil_img = pil_img.convert("RGB")
        pil_img = self.transform(pil_img)
        return pil_img, lable

    def __len__(self):
        return len(self.imgs_path)
    
train_dataset = WT_dataset(train_imgs, train_labels, train_transform)
test_dataset = WT_dataset(test_imgs, test_labels, test_transform)

BTACH_SIZE = 16

train_dl = torch.utils.data.DataLoader(
                                       train_dataset,
                                       batch_size=BTACH_SIZE,
                                       shuffle=True
)

test_dl = torch.utils.data.DataLoader(
                                       test_dataset,
                                       batch_size=BTACH_SIZE,
)

imgs, labels = next(iter(train_dl))

im = imgs[0].permute(1, 2, 0)
im = im.numpy()
im = (im + 1)/2

model = torchvision.models.vgg16(pretrained=True)
  
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

model = model.to(device)
loss_fn = nn.CrossEntropyLoss()
for param in model.features.parameters():
    param.requires_grad = False
model.classifier[-1].out_features = 4
optimizer = torch.optim.Adam(model.classifier.parameters(), lr=0.0005)

#此处使用训练代码
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    train_loss, correct = 0, 0
    model.train()
    for X, y in dataloader:
        X, y = X.to(device), y.to(device)

        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item()
    train_loss /= num_batches
    correct /= size
    return train_loss, correct

def test(dataloader, model):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size

    return test_loss, correct

epochs = 30

train_loss = []
train_acc = []
test_loss = []
test_acc = []

for epoch in range(epochs):
    epoch_loss, epoch_acc = train(train_dl, model, loss_fn, optimizer)
    epoch_test_loss, epoch_test_acc = test(test_dl, model)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
    
    template = ("epoch:{:2d}, train_loss: {:.5f}, train_acc: {:.1f}% ," 
                "test_loss: {:.5f}, test_acc: {:.1f}%")
    print(template.format(
          epoch, epoch_loss, epoch_acc*100, epoch_test_loss, epoch_test_acc*100))
    
print("Done!")

学习率衰减

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import torchvision
import glob
from torchvision import transforms
from torch.utils import data
from PIL import Image

img_dir = r'./data/dataset2/*.jpg'
imgs = glob.glob(img_dir)

species = ['cloudy', 'rain', 'shine', 'sunrise']
species_to_idx = dict((c, i) for i, c in enumerate(species))
# species_to_idx   # {'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3}
idx_to_species = dict((v, k) for k, v in species_to_idx.items())
# idx_to_species  # {0: 'cloudy', 1: 'rain', 2: 'shine', 3: 'sunrise'}

labels = []
for img in imgs:
    for i, c in enumerate(species):
        if c in img:
            labels.append(i)
            
count = len(imgs)   # 1122

np.random.seed(2022)
index = np.random.permutation(count)
imgs = np.array(imgs)[index]
labels = np.array(labels, dtype=np.int64)[index]

sep = int(count*0.8)
train_imgs = imgs[ :sep]
train_labels = labels[ :sep]
test_imgs = imgs[sep: ]
test_labels = labels[sep: ]

# 数据增强
train_transform = transforms.Compose([
        transforms.Resize((256, 256)),  
        transforms.RandomCrop((224, 224)),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.ColorJitter(brightness=(0.7, 1.3), contrast=(0.7, 1.3), saturation=(0.7, 1.3), hue=(-0.05, 0.05)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

test_transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

class WT_dataset(data.Dataset):
    def __init__(self, imgs_path, lables, transform):
        self.imgs_path = imgs_path
        self.lables = lables
        self.transform = transform

    def __getitem__(self, index):
        img_path = self.imgs_path[index]
        lable = self.lables[index]
        
        pil_img = Image.open(img_path)
        pil_img = pil_img.convert("RGB")
        pil_img = self.transform(pil_img)
        return pil_img, lable

    def __len__(self):
        return len(self.imgs_path)
    
train_dataset = WT_dataset(train_imgs, train_labels, train_transform)
test_dataset = WT_dataset(test_imgs, test_labels, test_transform)

BTACH_SIZE = 16

train_dl = torch.utils.data.DataLoader(
                                       train_dataset,
                                       batch_size=BTACH_SIZE,
                                       shuffle=True
)

test_dl = torch.utils.data.DataLoader(
                                       test_dataset,
                                       batch_size=BTACH_SIZE,
)

imgs, labels = next(iter(train_dl))

im = imgs[0].permute(1, 2, 0)
im = im.numpy()
im = (im + 1)/2

model = torchvision.models.vgg16(pretrained=True)
  
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

for param in model.features.parameters():
    param.requires_grad = False
model.classifier[-1].out_features = 4

model = model.to(device)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)
# 使用pytorch内置的学习率衰减函数
from torch.optim import lr_scheduler
exp_lr_scheduler = lr_scheduler.StepLR(optimizer,step_size=5,gamma=0.9) # 每隔5步衰减0.9

#此处使用训练代码
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    train_loss, correct = 0, 0
    model.train()
    for X, y in dataloader:
        X, y = X.to(device), y.to(device)

        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item()
    train_loss /= num_batches
    correct /= size
    return train_loss, correct

def test(dataloader, model):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size

    return test_loss, correct

epochs = 40

def fit(epochs, train_dl, test_dl, model, loss_fn, optimizer):
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []

    for epoch in range(epochs):
        epoch_loss, epoch_acc = train(train_dl, model, loss_fn, optimizer)
        epoch_test_loss, epoch_test_acc = test(test_dl, model)

# 手动,每隔5个epoch对学习速率进行衰减
#         if epoch%5 == 0:
#             for p in optimizer.param_groups:
#                 p['lr'] *= 0.9

# 使用pytorch内置的学习率衰减函数

        
        train_loss.append(epoch_loss)
        train_acc.append(epoch_acc)
        test_loss.append(epoch_test_loss)
        test_acc.append(epoch_test_acc)
    
        template = ("epoch:{:2d}, train_loss: {:.5f}, train_acc: {:.1f}% ," 
                    "test_loss: {:.5f}, test_acc: {:.1f}%")
        print(template.format(
              epoch, epoch_loss, epoch_acc*100, epoch_test_loss, epoch_test_acc*100))
    print("Done!")
    
    return train_loss, test_loss, train_acc, test_acc

train_loss, test_loss, train_acc, test_acc = fit(epochs, 
                                                 train_dl, 
                                                 test_dl, 
                                                 model, 
                                                 loss_fn, 
                                                 optimizer)
    
print("Done!")
import torch
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import datasets, transforms, models
import os
import shutil
%matplotlib inline

train_transform = transforms.Compose([
    transforms.Resize(224),
    transforms.RandomCrop(192),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(0.2),
    transforms.ColorJitter(brightness = 0.5),
    transforms.ColorJitter(contrast = 0.5),
    transforms.ToTensor(),
    transforms.Normalize(mean = [0.5, 0.5, 0.5], std = [0.5, 0.5, 0.5])
])
test_transform = transforms.Compose([
    transforms.Resize((192, 192)),
    transforms.ToTensor(),
    transforms.Normalize(mean = [0.5, 0.5, 0.5], std = [0.5, 0.5, 0.5])
])
train_ds = datasets.ImageFolder(
    "C:/Users/DELL/data/4_weather/train",
    transform = train_transform
)
test_ds = datasets.ImageFolder(
    "C:/Users/DELL/data/4_weather/test",
    transform = test_transform
)
train_dl = torch.utils.data.DataLoader(train_ds, batch_size = 8, shuffle = True)
test_dl = torch.utils.data.DataLoader(test_ds, batch_size = 8)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

model = models.vgg16(pretrained = True)
for p in model.features.parameters():
    p.requries_grad = False
model.classifier[-1].out_features = 4
model.to(device)

optimizer = torch.optim.Adam(model.parameters(), lr = 0.0001)
epochs = 20
loss_func = torch.nn.CrossEntropyLoss()

exp_lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 
                                                   step_size = 5,
                                                   gamma = 0.9)

def fit(epoch, model, trainloader, testloader):
    correct = 0
    total = 0
    running_loss = 0
    
    model.train()
    for x, y in trainloader:
        x, y = x.to(device), y.to(device)
        y_pred = model(x)
        loss = loss_func(y_pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim = 1)
            correct += (y_pred == y).sum().item()
            total += y.size(0)
            running_loss += loss.item()

    exp_lr_scheduler.step()    # 规定一个step为一个epoch
    
    epoch_acc = correct / total
    epoch_loss = running_loss / len(trainloader.dataset)
    
    test_correct = 0
    test_total = 0
    test_running_loss = 0
    
    model.eval()
    with torch.no_grad():
        for x, y in testloader:
            x, y = x.to(device), y.to(device)
            y_pred = model(x)
            loss = loss_func(y_pred, y)
            y_pred = torch.argmax(y_pred, dim = 1)
            test_correct += (y_pred == y).sum().item()
            test_total += y.size(0)
            test_running_loss += loss.item()
    epoch_test_acc = test_correct / test_total
    epoch_test_loss = test_running_loss / len(testloader.dataset)
    
    print('epoch: ', epoch, 
          'loss: ', round(epoch_loss, 3),
          'accuracy: ', round(epoch_acc, 3),
          'test_loss: ', round(epoch_test_loss, 3),
          'test_accuracy: ', round(epoch_test_acc, 3))
    
    return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc

train_loss = []
train_acc = []
test_loss = []
test_acc = []
for epoch in range(epochs):
    epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch, model, train_dl, test_dl)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
epoch:  0 loss:  0.091 accuracy:  0.798 test_loss:  0.045 test_accuracy:  0.884
epoch:  1 loss:  0.035 accuracy:  0.91 test_loss:  0.06 test_accuracy:  0.88
epoch:  2 loss:  0.029 accuracy:  0.932 test_loss:  0.028 test_accuracy:  0.924
epoch:  3 loss:  0.018 accuracy:  0.951 test_loss:  0.024 test_accuracy:  0.964
epoch:  4 loss:  0.047 accuracy:  0.911 test_loss:  0.036 test_accuracy:  0.929
epoch:  5 loss:  0.018 accuracy:  0.949 test_loss:  0.016 test_accuracy:  0.964
epoch:  6 loss:  0.021 accuracy:  0.949 test_loss:  0.014 test_accuracy:  0.951
epoch:  7 loss:  0.012 accuracy:  0.973 test_loss:  0.016 test_accuracy:  0.964
epoch:  8 loss:  0.023 accuracy:  0.947 test_loss:  0.042 test_accuracy:  0.907
epoch:  9 loss:  0.022 accuracy:  0.948 test_loss:  0.023 test_accuracy:  0.956
epoch:  10 loss:  0.012 accuracy:  0.966 test_loss:  0.039 test_accuracy:  0.938
epoch:  11 loss:  0.013 accuracy:  0.969 test_loss:  0.024 test_accuracy:  0.96
epoch:  12 loss:  0.008 accuracy:  0.982 test_loss:  0.017 test_accuracy:  0.973
epoch:  13 loss:  0.018 accuracy:  0.952 test_loss:  0.022 test_accuracy:  0.942
epoch:  14 loss:  0.013 accuracy:  0.972 test_loss:  0.037 test_accuracy:  0.947
epoch:  15 loss:  0.013 accuracy:  0.961 test_loss:  0.031 test_accuracy:  0.938
epoch:  16 loss:  0.007 accuracy:  0.976 test_loss:  0.028 test_accuracy:  0.951
epoch:  17 loss:  0.008 accuracy:  0.979 test_loss:  0.017 test_accuracy:  0.973
epoch:  18 loss:  0.018 accuracy:  0.967 test_loss:  0.037 test_accuracy:  0.933
epoch:  19 loss:  0.009 accuracy:  0.974 test_loss:  0.07 test_accuracy:  0.933
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

import torchvision
from torchvision import transforms
import os

base_dir = r'./datasets/4weather'
train_dir = os.path.join(base_dir , 'train')
test_dir = os.path.join(base_dir , 'test') 

train_transform = transforms.Compose([
    transforms.Resize(224),
    transforms.RandomResizedCrop(192, scale=(0.6,1.0), ratio=(0.8,1.0)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(0.2),
    torchvision.transforms.ColorJitter(brightness=0.5, contrast=0, saturation=0, hue=0),
    torchvision.transforms.ColorJitter(brightness=0, contrast=0.5, saturation=0, hue=0),
    transforms.ToTensor(),
    transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

test_transform = transforms.Compose([
    transforms.Resize((192, 192)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
])

train_ds =  torchvision.datasets.ImageFolder(
        train_dir,
        transform=train_transform
    )
    
test_ds =  torchvision.datasets.ImageFolder(
        test_dir,
        transform=test_transform
    )
    
BTACH_SIZE = 32

train_dl = torch.utils.data.DataLoader(
                            train_ds,
                            batch_size=BTACH_SIZE,
                            shuffle=True
)

test_dl = torch.utils.data.DataLoader(
                            test_ds,
                            batch_size=BTACH_SIZE,
)

model = torchvision.models.vgg16(pretrained=True)

for param in model.features.parameters():
    param.requires_grad = False
    
model.classifier[-1].out_features = 4

if torch.cuda.is_available():
    model.to('cuda')
    
loss_fn = nn.CrossEntropyLoss()

# Decay LR by a factor of 0.1 every 7 epochs
from torch.optim import lr_scheduler
optimizer = torch.optim.Adam(model.classifier.parameters(), lr=0.001)
exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)

def fit(epoch, model, trainloader, testloader):
    correct = 0
    total = 0
    running_loss = 0
    for x, y in trainloader:
        if torch.cuda.is_available():
            x, y = x.to('cuda'), y.to('cuda')
        y_pred = model(x)
        loss = loss_fn(y_pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim=1)
            correct += (y_pred == y).sum().item()
            total += y.size(0)
            running_loss += loss.item()
    exp_lr_scheduler.step()
    epoch_loss = running_loss / len(trainloader.dataset)
    epoch_acc = correct / total
        
        
    test_correct = 0
    test_total = 0
    test_running_loss = 0 
    
    with torch.no_grad():
        for x, y in testloader:
            if torch.cuda.is_available():
                x, y = x.to('cuda'), y.to('cuda')
            y_pred = model(x)
            loss = loss_fn(y_pred, y)
            y_pred = torch.argmax(y_pred, dim=1)
            test_correct += (y_pred == y).sum().item()
            test_total += y.size(0)
            test_running_loss += loss.item()
    
    epoch_test_loss = test_running_loss / len(testloader.dataset)
    epoch_test_acc = test_correct / test_total
    
        
    print('epoch: ', epoch, 
          'loss: ', round(epoch_loss, 3),
          'accuracy:', round(epoch_acc, 3),
          'test_loss: ', round(epoch_test_loss, 3),
          'test_accuracy:', round(epoch_test_acc, 3)
             )
        
    return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc
    
epochs = 30

train_loss = []
train_acc = []
test_loss = []
test_acc = []

for epoch in range(epochs):
    epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch,
                                                                 model,
                                                                 train_dl,
                                                                 test_dl)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
    

plt.plot(range(1, epochs+1), train_loss, label='train_loss')
plt.plot(range(1, epochs+1), test_loss, label='test_loss')
plt.legend()
image.png
plt.plot(range(1, epochs+1), train_acc, label='train_acc')
plt.plot(range(1, epochs+1), test_acc, label='test_acc')
plt.legend()
image.png

相关文章

网友评论

      本文标题:PyTrch深度学习简明实战9 - 数据增强

      本文链接:https://www.haomeiwen.com/subject/plaprdtx.html