介紹在深度學(xué)習(xí)黑客競(jìng)賽中表現(xiàn)出色的技巧(或者坦率地說(shuō),是任何數(shù)據(jù)科學(xué)黑客競(jìng)賽) 通常歸結(jié)為特征工程,。 當(dāng)您獲得的數(shù)據(jù)不足以建立一個(gè)成功的深度學(xué)習(xí)模型時(shí),,你能發(fā)揮多少創(chuàng)造力? 我是根據(jù)自己參加多次深度學(xué)習(xí)黑客競(jìng)賽的經(jīng)驗(yàn)而談的,,在這次深度黑客競(jìng)賽中,,我們獲得了包含數(shù)百?gòu)垐D像的數(shù)據(jù)集——根本不足以贏得甚至完成排行榜的頂級(jí)排名。那我們?cè)趺刺幚磉@個(gè)問(wèn)題呢,? 答案,? 好吧,那要看數(shù)據(jù)科學(xué)家的技能了,! 這就是我們的好奇心和創(chuàng)造力脫穎而出的地方,。 這就是特征工程背后的理念——在現(xiàn)有特征的情況下,我們能多好地提出新特征,。當(dāng)我們處理圖像數(shù)據(jù)時(shí),,同樣的想法也適用。
圖像增強(qiáng)功能幫助我擴(kuò)充現(xiàn)有數(shù)據(jù)集,而無(wú)需費(fèi)時(shí)費(fèi)力,。 而且我相信您會(huì)發(fā)現(xiàn)這項(xiàng)技術(shù)對(duì)您自己的項(xiàng)目非常有幫助,。 因此,在本文中,,我們將了解圖像增強(qiáng)的概念,,為何有用以及哪些不同的圖像增強(qiáng)技術(shù)。 我們還將實(shí)現(xiàn)這些圖像增強(qiáng)技術(shù),,以使用PyTorch構(gòu)建圖像分類(lèi)模型,。 目錄
為什么需要圖像增強(qiáng)?深度學(xué)習(xí)模型通常需要大量的數(shù)據(jù)來(lái)進(jìn)行訓(xùn)練,。通常,,數(shù)據(jù)越多,模型的性能越好,。但是獲取海量數(shù)據(jù)面臨著自身的挑戰(zhàn),。不是每個(gè)人都有大公司的雄厚財(cái)力。 缺少數(shù)據(jù)使得我們的深度學(xué)習(xí)模型可能無(wú)法從數(shù)據(jù)中學(xué)習(xí)模式或功能,,因此在未見(jiàn)過(guò)的數(shù)據(jù)上可能無(wú)法提供良好的性能。 那么在那種情況下我們?cè)撛趺崔k,?我們可以使用圖像增強(qiáng)技術(shù),,而無(wú)需花費(fèi)幾天的時(shí)間手動(dòng)收集數(shù)據(jù)。
有多種圖像增強(qiáng)技術(shù),,我們將在下一節(jié)討論一些常見(jiàn)的和使用最廣泛的技術(shù),。 不同的圖像增強(qiáng)技術(shù)圖像旋轉(zhuǎn)圖像旋轉(zhuǎn)是最常用的增強(qiáng)技術(shù)之一。它可以幫助我們的模型對(duì)對(duì)象方向的變化變得健壯,。即使我們旋轉(zhuǎn)圖像,,圖像的信息也保持不變。汽車(chē)就是一輛汽車(chē),,即使我們從不同的角度看它: 因此,,我們可以使用此技術(shù),通過(guò)從原始圖像創(chuàng)建旋轉(zhuǎn)圖像來(lái)增加數(shù)據(jù)量,。讓我們看看如何旋轉(zhuǎn)圖像: # 導(dǎo)入所有必需的庫(kù)import warningswarnings.filterwarnings('ignore')import numpy as npimport skimage.io as iofrom skimage.transform import rotate, AffineTransform, warpfrom skimage.util import random_noisefrom skimage.filters import gaussianimport matplotlib.pyplot as plt% matplotlib inline 我將使用此圖像演示不同的圖像增強(qiáng)技術(shù),。你也可以根據(jù)自己的要求嘗試其他圖片。 我們先導(dǎo)入圖像并將其可視化:
這是原始圖像?,F(xiàn)在讓我們看看如何旋轉(zhuǎn)它,。我將使用skimage 庫(kù)的旋轉(zhuǎn)功能來(lái)旋轉(zhuǎn)圖像: print('Rotated Image')#rotating the image by 45 degreesrotated = rotate(image, angle=45, mode = 'wrap')#plot the rotated imageio.imshow(rotated) 很好!將模式設(shè)置為“wrap”,,用圖像的剩余像素填充輸入邊界之外的點(diǎn),。 平移圖像可能會(huì)出現(xiàn)圖像中的對(duì)象沒(méi)有完全居中對(duì)齊的情況。 在這些情況下,,可以使用圖像平移為圖像添加平移不變性,。 通過(guò)移動(dòng)圖像,我們可以更改對(duì)象在圖像中的位置,,從而使模型更具多樣性,。 最終將生成更通用的模型,。
在移位操作之后,,輸入圖像中的位置(x,y)處的對(duì)象被移位到新位置(X,,Y):
其中,,dx和dy分別是沿不同維度的位移。讓我們看看如何將shift應(yīng)用于圖像:
translation超參數(shù)定義圖像應(yīng)移動(dòng)的像素?cái)?shù),。這里,,我把圖像移了(25,25)個(gè)像素,。您可以隨意設(shè)置此超參數(shù)的值,。 我再次使用“wrap”模式,它用圖像的剩余像素填充輸入邊界之外的點(diǎn),。在上面的輸出中,,您可以看到圖像的高度和寬度都移動(dòng)了25像素。 翻轉(zhuǎn)圖像翻轉(zhuǎn)是旋轉(zhuǎn)的延伸,。 它使我們可以在左右以及上下方向上翻轉(zhuǎn)圖像,。 讓我們看看如何實(shí)現(xiàn)翻轉(zhuǎn): #flip image left-to-rightflipLR = np.fliplr(image)plt.imshow(flipLR)plt.title('Left to Right Flipped') 在這里,我使用了NumPy的fliplr 函數(shù)從左向右翻轉(zhuǎn)圖像,。 它翻轉(zhuǎn)每一行的像素值,,并且輸出確認(rèn)相同。 類(lèi)似地,,我們可以沿上下方向翻轉(zhuǎn)圖像:
這就是我們可以翻轉(zhuǎn)圖像并制作更通用的模型的方法,,該模型將學(xué)習(xí)到原始圖像以及翻轉(zhuǎn)后的圖像。 向圖像添加隨機(jī)噪聲也是圖像增強(qiáng)技術(shù),。 讓我們通過(guò)一個(gè)例子來(lái)理解它,。 給圖像添加噪點(diǎn)圖像噪聲是一個(gè)重要的增強(qiáng)步驟,使我們的模型能夠?qū)W習(xí)如何分離圖像中的信號(hào)和噪聲,。這也使得模型對(duì)輸入的變化更加健壯,。 我們將使用“skipage”庫(kù)的“random_noise”函數(shù)為原始圖像添加一些隨機(jī)噪聲 我將噪聲的標(biāo)準(zhǔn)差取為0.155(您也可以更改此值)。請(qǐng)記住,,增加此值將為圖像添加更多噪聲,,反之亦然: # 要添加到圖像中的噪聲的標(biāo)準(zhǔn)差sigma=0.155# 向圖像添加隨機(jī)噪聲noisyRandom = random_noise(image,var=sigma**2)plt.imshow(noisyRandom)plt.title('Random Noise') 我們可以看到隨機(jī)噪聲已添加到原始圖像中。 試一下不同的標(biāo)準(zhǔn)偏差的值,,看看得到的不同結(jié)果,。 模糊圖像所有攝影愛(ài)好者都會(huì)立即理解這個(gè)想法。 圖像有不同的來(lái)源。 因此,,每個(gè)來(lái)源的圖像質(zhì)量都將不同,。 有些圖像的質(zhì)量可能很高,而另一些則可能很差勁,。 在這種情況下,,我們可以使圖像模糊。 那將有什么幫助,? 好吧,,這有助于使我們的深度學(xué)習(xí)模型更強(qiáng)大。 讓我們看看我們?nèi)绾巫龅竭@一點(diǎn),。 我們將使用高斯濾波器來(lái)模糊圖像:
Sigma是高斯濾波器的標(biāo)準(zhǔn)差,。我將其視為1。sigma值越高,,模糊效果越強(qiáng),。 將* Multichannel *設(shè)置為true可確保分別過(guò)濾圖像的每個(gè)通道。 同樣,,您可以嘗試使用不同的sigma值來(lái)更改模糊度,。 這些是一些圖像增強(qiáng)技術(shù),,有助于使我們的深度學(xué)習(xí)模型健壯且可推廣,。這也有助于增加訓(xùn)練集的大小。 我們即將完成本教程的實(shí)現(xiàn)部分,。在此之前,,讓我們看看一些基本的準(zhǔn)則,以決定正確的圖像增強(qiáng)技術(shù),。 選擇正確的增強(qiáng)技術(shù)的基本準(zhǔn)則我認(rèn)為在根據(jù)您試圖解決的問(wèn)題來(lái)決定增強(qiáng)技術(shù)時(shí),,有一些準(zhǔn)則是很重要的。以下是這些準(zhǔn)則的簡(jiǎn)要概述:
現(xiàn)在,,不用再等了,,讓我們繼續(xù)到模型構(gòu)建部分。我們將應(yīng)用本文討論的增強(qiáng)技術(shù)生成圖像,,然后使用這些圖像來(lái)訓(xùn)練模型,。 我們將研究緊急車(chē)輛與非緊急車(chē)輛的分類(lèi)問(wèn)題。如果你看過(guò)我以前的PyTorch文章,,你應(yīng)該熟悉問(wèn)題的描述,。 該項(xiàng)目的目標(biāo)是將車(chē)輛圖像分為緊急和非緊急兩類(lèi)。你猜對(duì)了,,這是一個(gè)圖像分類(lèi)問(wèn)題,。您可以從這里下載數(shù)據(jù)集。 加載數(shù)據(jù)集我們開(kāi)始吧,!我們先把數(shù)據(jù)裝入notebook,。然后,我們將應(yīng)用圖像增強(qiáng)技術(shù),,最后,,建立一個(gè)卷積神經(jīng)網(wǎng)絡(luò)(CNN)模型。 讓我們導(dǎo)入所需的庫(kù): # 導(dǎo)入庫(kù)from torchsummary import summaryimport pandas as pdimport numpy as npfrom skimage.io import imread, imsavefrom tqdm import tqdmimport matplotlib.pyplot as plt%matplotlib inlinefrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_scorefrom skimage.transform import rotatefrom skimage.util import random_noisefrom skimage.filters import gaussianfrom scipy import ndimage 現(xiàn)在,,我們將讀取包含圖像名稱(chēng)及其相應(yīng)標(biāo)簽的CSV文件:
0表示該車(chē)為非緊急車(chē)輛,,1表示該車(chē)為緊急車(chē)輛。現(xiàn)在讓我們從數(shù)據(jù)集中加載所有圖像: # 加載圖像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'].valuestrain_x.shape, train_y.shape 數(shù)據(jù)集中共有1646幅圖像,。讓我們把這些數(shù)據(jù)分成訓(xùn)練和驗(yàn)證集,。我們將使用驗(yàn)證集來(lái)評(píng)估模型在未見(jiàn)過(guò)的數(shù)據(jù)上的性能:
我將“test_size”保持為0.1,因此10%的數(shù)據(jù)將隨機(jī)選擇作為驗(yàn)證集,,剩下的90%將用于訓(xùn)練模型,。訓(xùn)練集有1481個(gè)圖像,這對(duì)于訓(xùn)練深度學(xué)習(xí)模型來(lái)說(shuō)是相當(dāng)少的,。 因此,,接下來(lái),我們將增加這些訓(xùn)練圖像,,以增加訓(xùn)練集,,并可能提高模型的性能。 增強(qiáng)圖像我們將使用前面討論過(guò)的圖像增強(qiáng)技術(shù): 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]) 我們?yōu)橛?xùn)練集中的1481張圖像中的每一張生成了4張?jiān)鰪?qiáng)圖像。讓我們以數(shù)組的形式轉(zhuǎn)換圖像并驗(yàn)證數(shù)據(jù)集的大?。?/p>
這證實(shí)了我們已經(jīng)增強(qiáng)了圖像并增加了訓(xùn)練集的大小,。讓我們將這些增強(qiáng)圖像進(jìn)行可視化: 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') 這里的第一個(gè)圖像是來(lái)自數(shù)據(jù)集的原始圖像。其余四幅圖像分別使用不同的圖像增強(qiáng)技術(shù)(旋轉(zhuǎn),、從左向右翻轉(zhuǎn),、上下翻轉(zhuǎn)和添加隨機(jī)噪聲)生成的。 我們的數(shù)據(jù)集現(xiàn)在已經(jīng)準(zhǔn)備好了,。是時(shí)候定義我們的深度學(xué)習(xí)模型的結(jié)構(gòu),,然后在增強(qiáng)過(guò)的訓(xùn)練集上對(duì)其進(jìn)行訓(xùn)練了。我們先從PyTorch中導(dǎo)入所有函數(shù):
我們必須將訓(xùn)練集和驗(yàn)證集轉(zhuǎn)換為PyTorch格式: # 將訓(xùn)練圖像轉(zhuǎn)換為torch格式final_train = final_train.reshape(7405, 3, 224, 224)final_train = torch.from_numpy(final_train)final_train = final_train.float()# 將target轉(zhuǎn)換為torch格式final_target_train = final_target_train.astype(int)final_target_train = torch.from_numpy(final_target_train) 同樣,,我們將轉(zhuǎn)換驗(yàn)證集:
模型結(jié)構(gòu)接下來(lái),,我們將定義模型的結(jié)構(gòu)。這有點(diǎn)復(fù)雜,,因?yàn)槟P徒Y(jié)構(gòu)包含4個(gè)卷積塊,,然后是4個(gè)全連接層: torch.manual_seed(0)class Net(Module): def __init__(self): super(Net, self).__init__() self.cnn_layers = Sequential( # 定義2D convolution層 Conv2d(3, 32, kernel_size=3, stride=1, padding=1), ReLU(inplace=True), # 添加batch normalization層 BatchNorm2d(32), MaxPool2d(kernel_size=2, stride=2), # 添加 dropout Dropout(p=0.25), # 定義另一個(gè)2D convolution層 Conv2d(32, 64, kernel_size=3, stride=1, padding=1), ReLU(inplace=True), # 添加batch normalization層 BatchNorm2d(64), MaxPool2d(kernel_size=2, stride=2), # 添加 dropout Dropout(p=0.25), # 定義另一個(gè)2D convolution層 Conv2d(64, 128, kernel_size=3, stride=1, padding=1), ReLU(inplace=True), # 添加batch normalization層 BatchNorm2d(128), MaxPool2d(kernel_size=2, stride=2), # 添加 dropout Dropout(p=0.25), # 定義另一個(gè)2D convolution層 Conv2d(128, 128, kernel_size=3, stride=1, padding=1), ReLU(inplace=True), # 添加batch normalization層 BatchNorm2d(128), MaxPool2d(kernel_size=2, stride=2), # 添加 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) ) # 定義前向過(guò)程 def forward(self, x): x = self.cnn_layers(x) x = x.view(x.size(0), -1) x = self.linear_layers(x) return x 讓我們定義模型的其他超參數(shù),包括優(yōu)化器,、學(xué)習(xí)率和損失函數(shù):
訓(xùn)練模型為我們的深度學(xué)習(xí)模型訓(xùn)練20個(gè)epoch: torch.manual_seed(0)# 模型的batch sizebatch_size = 64# 訓(xùn)練模型的epoch數(shù)n_epochs = 20for 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) 這是訓(xùn)練階段的summary,。你會(huì)注意到,隨著epoch的增加,,訓(xùn)練loss會(huì)減少,。讓我們保存已訓(xùn)練的模型的權(quán)重,以便將來(lái)在不重新訓(xùn)練模型的情況下使用它們:
如果您不想在您的終端訓(xùn)練模型,,您可以使用此鏈接下載已訓(xùn)練了20個(gè)epoch的模型的權(quán)重,。 接下來(lái),,讓我們加載這個(gè)模型: the_model = torch.load('model.pt') 測(cè)試我們模型的性能最后,,讓我們對(duì)訓(xùn)練集和驗(yàn)證集進(jìn)行預(yù)測(cè),并檢查各自的準(zhǔn)確度:
訓(xùn)練集的準(zhǔn)確率超過(guò)91%,!很有希望,。但是,讓我們拭目以待吧,。我們需要對(duì)驗(yàn)證集進(jìn)行相同的檢查: # 預(yù)測(cè)驗(yàn)證集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) 驗(yàn)證準(zhǔn)確性約為78%,。 很好! 尾注當(dāng)我們開(kāi)始獲得的訓(xùn)練數(shù)據(jù)較少時(shí),,我們可以使用圖像增強(qiáng)技術(shù),。 在本文中,我們介紹了大多數(shù)常用的圖像增強(qiáng)技術(shù),。 我們學(xué)習(xí)了如何旋轉(zhuǎn),,移動(dòng)和翻轉(zhuǎn)圖像。 我們還學(xué)習(xí)了如何為圖像添加隨機(jī)噪聲或使其模糊。 然后,,我們討論了選擇正確的增強(qiáng)技術(shù)的基本準(zhǔn)則,。 您可以在任何圖像分類(lèi)問(wèn)題上嘗試使用這些圖像增強(qiáng)技術(shù),然后比較使用增強(qiáng)和不使用增強(qiáng)的性能,。 隨時(shí)在下面的評(píng)論部分中分享您的結(jié)果,。 |
|
來(lái)自: taotao_2016 > 《圖像處理》