使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

在這篇文章中,我們將瞭解圖像增強的概念以及有什麼不同的圖像增強技術。我們還將使用PyTorch實現這些圖像增強技術來構建一個圖像分類深度學習模型。

為什麼我們需要圖像增強?

深度學習模型通常需要大量的數據來進行訓練。通常,數據越多,模型的性能越好。但是獲取海量數據面臨著自身的挑戰。並非每個人都擁有大公司的財力。

深度學習模型通常需要大量的訓練數據。一般來說,數據越多,模型的性能越好。但獲取大量數據本身也存在挑戰。

缺乏數據的問題是,我們的深度學習模型可能無法從數據中學習模式或功能,因此它可能無法在不可見的數據上提供良好的性能。

在這種情況下我們能怎麼做呢?我們可以利用圖像增強技術來降低數據收集難度。

使用PyTorch進行深度學習的圖像增強


圖像增強技術

圖像旋轉

圖像旋轉是最常用的增強技術之一。它可以幫助我們的模型對對象方向的變化變得健壯。即使我們旋轉圖像,圖像的信息也保持不變。即從不同的角度看汽車,汽車也還是汽車:


使用PyTorch進行深度學習的圖像增強

我們可以使用此技術通過從原始圖像創建旋轉圖像來增加數據大小。讓我們看看如何旋轉圖像:

使用PyTorch進行深度學習的圖像增強

讓我們導入圖像並首先對其進行可視化:

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

這是原始圖像。現在讓我們看看如何旋轉它。我將使用skimage庫的rotate函數旋轉圖像:

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

圖像平移

在某些情況下,圖像中的對象未完全對準中心。在這些情況下,可以使用圖像平移為圖像添加平移不變性。

通過移動圖像,我們可以更改對象在圖像中的位置,從而使模型更具多樣性。最終將導致更通用的模型。

圖像平移是一種幾何變換,可將圖像中每個對象的位置映射到最終輸出圖像中的新位置。

平移操作之後,輸入圖像中位置(x,y)上存在的對象將移位到新位置(X,Y):

  • X = x + dx
  • Y = y + dy

此處,dx和dy是沿不同尺寸的相應位移。讓我們看看如何將平移應用於圖像:

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強


平移超參數定義圖像應移動的像素數。在這裡,我將圖像移動了(25,25)像素。我再次使用了“wrap”,用圖像的其餘像素填充輸入邊界外的點。

翻轉圖像

翻轉是旋轉的延伸。它使我們可以在左右以及上下方向上翻轉圖像。讓我們看看如何實現翻轉:

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

在這裡,我使用了NumPy的fliplr函數來將圖像從左到右翻轉。它翻轉每行的像素值。同樣,我們可以上下翻轉圖像:

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

給圖像添加噪聲

圖像降噪是重要的增強步驟,可讓我們的深度學習模型學習如何將圖像中的信號與噪聲分離。

我們將使用skimage庫的random_noise函數為原始圖像添加一些隨機噪聲。我將要添加的噪聲的標準偏差設為0.155(您也可以更改此值)。

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

圖像模糊

由於圖像來自不同的源,因此,圖像的質量將不一樣。有些圖片可能是高質量的,而另一些可能是很差的。

在這種情況下,我們可以模糊圖像。這有什麼用呢?這有助於使我們的深度學習模型更健壯。

使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

Sigma是標準偏差。sigma值越高,模糊效果越多。將“ Multichannel”設置為true可確保分別過濾圖像的每個通道。

選擇正確的增強技術的基本準則

在根據您要解決的問題確定增強技術時,有一些準則很重要。

  1. 任何機器學習模型構建過程的第一步都是確保輸入的大小符合模型的期望。我們還必須確保所有圖像的大小應該相似。為此,我們可以調整圖像的大小到適當的大小。
  2. 假設您正在處理分類問題,並且數據樣本的數量相對較少。在這種情況下,您可以使用不同的增強技術,例如圖像旋轉,圖像降噪,翻轉,移位等。請記住,所有這些操作都適用於圖像中對象位置無關緊要的分類問題。
  3. 如果您正在執行對象檢測任務,而對象的位置正是我們要檢測的位置,那麼這些技術可能不合適。
  4. 對圖像像素值進行歸一化是保證機器學習模型更好更快收斂的一種良好策略。如果機器學習模型有特定的要求,我們必須根據機器學習模型的要求對圖像進行預處理。

案例研究:解決圖像分類問題並應用圖像增強

該項目的目的是將車輛圖像分類為non-emergency 或emergency 。這是圖像分類問題。您可以從此處下載數據集。

加載機器學習數據集

我們將應用圖像增強技術,最後建立卷積神經網絡(CNN)模型。讓我們導入所需的Python庫:

# importing the libraries
from torchsummary import summary
import pandas as pd
import numpy as np
from skimage.io import imread, imsave
from tqdm import tqdm
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from skimage.transform import rotate
from skimage.util import random_noise
from skimage.filters import gaussian
from scipy import ndimage


使用PyTorch進行深度學習的圖像增強

現在,我們將讀取包含圖像名稱及其相應標籤的CSV文件:

# loading dataset
data = pd.read_csv('emergency_vs_non-emergency_dataset/emergency_train.csv')
data.head()


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

這裡的0表示該車輛為non-emergency 車輛,1表示其為emergency 車輛。現在,讓我們從機器學習數據集中導入有圖像:

# loading images
train_img = []
for img_name in tqdm(data['image_names']):
image_path = 'emergency_vs_non-emergency_dataset/images/' + img_name
img = imread(image_path)
img = img/255
train_img.append(img)
train_x = np.array(train_img)
train_y = data['emergency_or_not'].values
train_x.shape, train_y.shape


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

機器學習數據集中共有1,646張圖像。讓我們將這些數據分為訓練集和驗證集。我們將使用驗證集來評估深度學習模型在看不見的數據上的表現:

train_x, val_x, train_y, val_y = train_test_split(train_x, train_y, test_size = 0.1, random_state = 13, stratify=train_y)
(train_x.shape, train_y.shape), (val_x.shape, val_y.shape)


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

我將test_size保持為0.1,因此將隨機選擇10%的數據作為驗證集,其餘的90%的數據將用於訓練模型。我們在訓練集中有1,481張圖像,這不足以訓練深度學習模型。

因此,接下來,我們將增強這些訓練圖像,以增強訓練集,這可以改善深度學習模型的性能。

圖像增強

final_train_data = []
final_target_train = []
for i in tqdm(range(train_x.shape[0])):
final_train_data.append(train_x[i])
final_train_data.append(rotate(train_x[i], angle=45, mode = 'wrap'))
final_train_data.append(np.fliplr(train_x[i]))
final_train_data.append(np.flipud(train_x[i]))
final_train_data.append(random_noise(train_x[i],var=0.2**2))
for j in range(5):
final_target_train.append(train_y[i])


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

我們為訓練集中的1,481張圖像中的每張圖像生成了4張增強圖像。讓我們以數組形式轉換圖像並驗證數據集的大小:

len(final_target_train), len(final_train_data)
final_train = np.array(final_train_data)
final_target_train = np.array(final_target_train)


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

讓我們可視化這些圖像:

fig,ax = plt.subplots(nrows=1,ncols=5,figsize=(20,20))
for i in range(5):
ax[i].imshow(final_train[i+30])
ax[i].axis('off')


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

這裡的第一張圖片是數據集中的原始圖片。其餘四幅圖像是使用不同的圖像增強技術生成的。

現在是時候定義深度學習模型的體系結構了,然後在訓練集上對其進行訓練了。

# PyTorch libraries and modules
import torch
from torch.autograd import Variable
from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, Conv2d, MaxPool2d, Module, Softmax, BatchNorm2d, Dropout
from torch.optim import Adam, SGD


使用PyTorch進行深度學習的圖像增強

我們必須將訓練集和驗證集都轉換為PyTorch格式:

# converting training images into torch format
final_train = final_train.reshape(7405, 3, 224, 224)
final_train = torch.from_numpy(final_train)
final_train = final_train.float()
# converting the target into torch format
final_target_train = final_target_train.astype(int)
final_target_train = torch.from_numpy(final_target_train)


使用PyTorch進行深度學習的圖像增強

同樣,我們將轉換驗證集:

# converting validation images into torch format
val_x = val_x.reshape(165, 3, 224, 224)
val_x = torch.from_numpy(val_x)
val_x = val_x.float()
# converting the target into torch format
val_y = val_y.astype(int)
val_y = torch.from_numpy(val_y)


使用PyTorch進行深度學習的圖像增強

模型架構

接下來,我們將定義深度學習模型的體系結構。該體系結構包含4個卷積塊,然後是4個全連接的dense層:

torch.manual_seed(0)
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# Defining a 2D convolution layer
Conv2d(3, 32, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# adding batch normalization
BatchNorm2d(32),
MaxPool2d(kernel_size=2, stride=2),
# adding dropout
Dropout(p=0.25),
# Defining another 2D convolution layer
Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# adding batch normalization
BatchNorm2d(64),
MaxPool2d(kernel_size=2, stride=2),
# adding dropout
Dropout(p=0.25),
# Defining another 2D convolution layer
Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# adding batch normalization
BatchNorm2d(128),
MaxPool2d(kernel_size=2, stride=2),
# adding dropout
Dropout(p=0.25),
# Defining another 2D convolution layer
Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# adding batch normalization
BatchNorm2d(128),
MaxPool2d(kernel_size=2, stride=2),
# adding dropout
Dropout(p=0.25),
)
self.linear_layers = Sequential(
Linear(128 * 14 * 14, 512),
ReLU(inplace=True),
Dropout(),
Linear(512, 256),
ReLU(inplace=True),
Dropout(),
Linear(256,10),
ReLU(inplace=True),
Dropout(),
Linear(10,2)

)
# Defining the forward pass
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x


使用PyTorch進行深度學習的圖像增強

讓我們定義模型的其他超參數,包括優化器,學習率和損失函數:

# defining the model
model = Net()
# defining the optimizer

optimizer = Adam(model.parameters(), lr=0.000075)
# defining the loss function
criterion = CrossEntropyLoss()
# checking if GPU is available
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
print(model)


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

訓練模型

讓我們訓練20個epochs:

torch.manual_seed(0)
# batch size of the model
batch_size = 64
# number of epochs to train the model
n_epochs = 20
for epoch in range(1, n_epochs+1):
train_loss = 0.0

permutation = torch.randperm(final_train.size()[0])
training_loss = []
for i in tqdm(range(0,final_train.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = final_train[indices], final_target_train[indices]

if torch.cuda.is_available():
batch_x, batch_y = batch_x.cuda(), batch_y.cuda()

optimizer.zero_grad()
outputs = model(batch_x)
loss = criterion(outputs,batch_y)
training_loss.append(loss.item())
loss.backward()
optimizer.step()

training_loss = np.average(training_loss)
print('epoch: \\t', epoch, '\\t training loss: \\t', training_loss)


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

您會注意到,隨著時間的增加,訓練損失會減少。讓我們保存經過訓練的深度學習模型的權重:

torch.save(model, 'model.pt')

加載這個深度學習模型的Python代碼:

the_model = torch.load('model.pt')

檢查模型的性能

最後,讓我們對訓練和驗證集進行預測,並檢查各自的準確性:

torch.manual_seed(0)
# prediction for training set
prediction = []
target = []
permutation = torch.randperm(final_train.size()[0])
for i in tqdm(range(0,final_train.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = final_train[indices], final_target_train[indices]
if torch.cuda.is_available():
batch_x, batch_y = batch_x.cuda(), batch_y.cuda()
with torch.no_grad():
output = model(batch_x.cuda())
softmax = torch.exp(output).cpu()
prob = list(softmax.numpy())
predictions = np.argmax(prob, axis=1)
prediction.append(predictions)
target.append(batch_y)

# training accuracy
accuracy = []
for i in range(len(prediction)):
accuracy.append(accuracy_score(target[i].cpu(),prediction[i]))

print('training accuracy: \\t', np.average(accuracy))


使用PyTorch進行深度學習的圖像增強


使用PyTorch進行深度學習的圖像增強

我們在訓練集上的準確性超過91%!我們需要對驗證集進行相同的檢查:

# checking the performance on validation set
torch.manual_seed(0)
output = model(val_x.cuda())
softmax = torch.exp(output).cpu()
prob = list(softmax.detach().numpy())
predictions = np.argmax(prob, axis=1)
accuracy_score(val_y, predictions)


使用PyTorch進行深度學習的圖像增強

最後

在本文中,我們介紹了大多數常用的圖像增強技術。您可以在任何圖像分類問題上嘗試這些圖像增強技術,然後比較有無增強時的性能。


分享到:


相關文章: