学习笔记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()

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

网友评论