介紹
過去兩年的大部分時間,我幾乎都在深度學習領域工作。這是一個相當好的經歷,這中間我參與了圖像和視頻數據相關的多個項目。
在那之前,我處於邊緣地帶,我迴避了對象檢測和人臉識別等深度學習概念。直到2017年底才開始深入研究。在這段時間裡,我遇到了各種各樣的難題。我想談談四個最常見的問題,大多數深度學習實踐者和愛好者在他們的旅程中都會遇到。
如果你之前參與過深度學習項目,你就能很快理解這些障礙。好消息是克服它們並不像你想的那麼難!
在本文中,我們將採用一種非常實際的方法。首先,我們將建立我上面提到的四個常見難題。然後,我們將直接深入Python代碼,學習與這些難題作鬥爭和克服這些難題的關鍵技巧和技巧。這裡有很多東西需要打開,讓我們開始吧!
目錄
- 深度學習模型的共同難題
- 車輛分類案例研究概述
- 了解每個難題以及如何克服難題以提高深度學習模型的性能
- 案例研究:改善我們的車輛分類模型的性能
深度學習模型的共同難題
深度學習模型通常在大多數數據上的表現都非常好。在圖像數據方面,深度學習模型,尤其是卷積神經網絡(CNN),幾乎勝過所有其他模型。
我通常的方法是在遇到圖像相關項目(例如圖像分類項目)時使用CNN模型。
這種方法效果很好,但是在某些情況下,CNN或其他深度學習模型無法執行。我遇到過幾次。我的數據很好,模型的體系結構也正確定義,損失函數和優化器也正確設置,但是我的模型沒有達到我的預期。
這是我們大多數人在使用深度學習模型時面臨的常見難題。
如上所述,我將解決四個此類難題:
- 缺乏可用於訓練的數據
- 過擬合
- 欠擬合
- 訓練時間長
在深入探討和理解這些難題之前,讓我們快速看一下我們將在本文中解決的案例研究。
車輛分類案例研究概述
本文是我一直在寫的PyTorch面向初學者系列的一部分。你可以在此處查看前三篇文章(我們將從那裡引用一些內容):
- PyTorch入門指南
- 在PyTorch中使用卷積神經網絡建立圖像分類模型
- 使用PyTorc進行遷移學習
我們將繼續閱讀上一篇文章中看到的案例研究。這裡的目的是將車輛圖像分類為緊急或非緊急。
首先,讓我們快速構建一個CNN模型,並將其用作基準。我們還將嘗試改善此模型的性能。這些步驟非常簡單,在之前的文章中我們已經看過幾次。
因此,我不會在這裡深入每一步。相反,我們將重點放在代碼上,你始終可以在我上面連結的先前文章中更詳細地進行檢查。你可以從此處獲取數據集:https://drive.google.com/file/d/1EbVifjP0FQkyB1axb7KQ26yPtWmneApJ/view。
這是為我們的車輛分類項目構建CNN模型的完整代碼。
導入庫
# 導入庫
import pandas as pd
import numpy as np
from tqdm import tqdm
# 用於讀取和顯示圖像
from skimage.io import imread
from skimage.transform import resize
import matplotlib.pyplot as plt
%matplotlib inline
# 用於創建驗證集
from sklearn.model_selection import train_test_split
# 用於評估模型
from sklearn.metrics import accuracy_score
# PyTorch庫和模塊
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
# 預訓練模型
from torchvision import models
加載數據集
# 加載數據集
train = pd.read_csv('emergency_train.csv')
# 加載訓練圖片
train_img = []
for img_name in tqdm(train['image_names']):
# 定義圖像路徑
image_path = '../Hack Session/images/' + img_name
# 讀取圖片
img = imread(image_path)
# 標準化像素值
img = img/255
img = resize(img, output_shape=(224,224,3), mode='constant', anti_aliasing=True)
# 轉換為浮點數
img = img.astype('float32')
# 添加圖片到列表
train_img.append(img)
# 轉換為numpy數組
train_x = np.array(train_img)
train_x.shape
創建訓練和驗證集
# 定義目標
train_y = train['emergency_or_not'].values
# 創建驗證集
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)
將圖像轉換為torch格式
# 轉換訓練圖片到torch格式
train_x = train_x.reshape(1481, 3, 224, 224)
train_x = torch.from_numpy(train_x)
# 轉換目標到torch格式
train_y = train_y.astype(int)
train_y = torch.from_numpy(train_y)
# 轉換驗證圖像到torch格式
val_x = val_x.reshape(165, 3, 224, 224)
val_x = torch.from_numpy(val_x)
# 轉換目標到torch格式
val_y = val_y.astype(int)
val_y = torch.from_numpy(val_y)
定義模型架構
torch.manual_seed(0)
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# 定義2D卷積層
Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
MaxPool2d(kernel_size=2, stride=2),
# 另一個2D卷積層
Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
MaxPool2d(kernel_size=2, stride=2)
)
self.linear_layers = Sequential(
Linear(32 * 56 * 56, 2)
)
# 前項傳播
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x
定義模型參數
# 定義模型
model = Net()
# 定義優化器
optimizer = Adam(model.parameters(), lr=0.0001)
# 定義損失函數
criterion = CrossEntropyLoss()
# 檢查GPU是否可用
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
print(model)
訓練模型
torch.manual_seed(0)
# 模型batch大小
batch_size = 128
# epoch數
n_epochs = 25
for epoch in range(1, n_epochs+1):
# 保持記錄訓練與驗證集損失
train_loss = 0.0
permutation = torch.randperm(train_x.size()[0])
training_loss = []
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
訓練集上預測
# 訓練集預測
prediction = []
target = []
permutation = torch.randperm(train_x.size()[0])
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
# 訓練集精度
accuracy = []
for i in range(len(prediction)):
accuracy.append(accuracy_score(target[i],prediction[i]))
print('training accuracy: \\t', np.average(accuracy))
驗證集上預測
# 驗證集預測
prediction_val = []
target_val = []
permutation = torch.randperm(val_x.size()[0])
for i in tqdm(range(0,val_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = val_x[indices], val_y[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_val.append(predictions)
target_val.append(batch_y)
# 驗證集精度
accuracy_val = []
for i in range(len(prediction_val)):
accuracy_val.append(accuracy_score(target_val[i],prediction_val[i]))
print('validation accuracy: \\t', np.average(accuracy_val))
這是我們的CNN模型。訓練精度在88%左右,驗證精度接近70%。
我們將努力改進這個模型的性能。但在此之前,讓我們先花點時間了解一下難題,這些難題可能是造成這種低性能的原因。
深度學習的難題
1:缺乏可用的數據來訓練我們的模型
深度學習模型通常需要大量的訓練數據。一般來說,數據越多,模型的性能就越好。缺乏數據的問題是,我們的深度學習模型可能無法從數據中學習模式或功能,因此它可能無法在未看到的數據上提供良好的性能。
如果你看一下汽車分類的案例研究,我們只有大約1650張圖片,因此這個模型在驗證集上表現不佳。在使用計算機視覺和深度學習模型時,數據較少的難題是很常見的。
你可以想像,手工收集數據是一項繁瑣而耗時的任務。因此,我們可以利用數據增強技術來代替花費數天時間來收集數據。
數據增強是在不實際收集新數據的情況下,生成新數據或增加數據以訓練模型的過程。
圖像數據有多種數據增強技術,常用的增強技術有旋轉、剪切、翻轉等。
這是一個非常好的主題,因此我決定寫一篇完整的文章。我的計劃是在下一篇文章中討論這些技術及其在PyTorch中的實現。
2:模型過擬合
我相信你聽說過過擬合。這是數據科學家剛接觸機器學習時最常見的難題(和錯誤)之一。但這個問題實際上超越了該領域,它也適用於深度學習。
當一個模型在訓練集上執行得非常好,但是在驗證集(或不可見的數據)上性能下降時,就會被認為是過擬合。
例如,假設我們有一個訓練集和一個驗證集。我們使用訓練數據來訓練模型,並檢查它在訓練集和驗證集上的性能(評估指標是準確性)。訓練的準確率是95%而驗證集的準確率是62%。聽起來熟悉嗎?
由於驗證精度遠低於訓練精度,因此可以推斷模型存在過擬合問題。下面的例子會讓你更好地理解什麼是過擬合:
上圖中藍色標記的部分是過擬合模型,因為訓練誤差非常小並且測試誤差非常高。過擬合的原因是該模型甚至從訓練數據中學習了不必要的信息,因此它在訓練集上的表現非常好。
但是,當引入新數據時,它將無法執行。我們可以向模型的架構中引入Dropout,以解決過擬合的問題。
使用Dropout,我們隨機關閉神經網絡的某些神經元。假設我們在最初有20個神經元的圖層上添加了機率為0.5的Dropout層,因此,這20個神經元中的10個將被抑制,我們最終得到了一個不太複雜的體系結構。
因此,該模型將不會學習過於複雜的模式,可以避免過擬合。現在讓我們在架構中添加一個Dropout層,並檢查其性能。
模型架構
torch.manual_seed(0)
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# 定義2D卷積層
Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
MaxPool2d(kernel_size=2, stride=2),
# Dropout層
Dropout(),
#另一個2D卷積層
Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
MaxPool2d(kernel_size=2, stride=2),
# Dropout層
Dropout(),
)
self.linear_layers = Sequential(
Linear(32 * 56 * 56, 2)
)
# 前向傳播
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x
在這裡,我在每個卷積塊中添加了一個Dropout層。默認值為0.5,這意味著一半神經元將被隨機關閉。這是一個超參數,你可以選擇0到1之間的任何值。
接下來,我們將定義模型的參數,例如損失函數,優化器和學習率。
模型參數
# 定義模型
model = Net()
# 定義優化器
optimizer = Adam(model.parameters(), lr=0.0001)
# 定義損失函數
criterion = CrossEntropyLoss()
# 檢查GPU是否可用
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
print(model)
在這裡,你可以看到Dropout中的默認值為0.5。最後,讓我們在添加Dropout層之後訓練模型:
訓練模型
torch.manual_seed(0)
# 模型batch大小
batch_size = 128
# epoch數
n_epochs = 25
for epoch in range(1, n_epochs+1):
# 保持記錄訓練與驗證集損失
train_loss = 0.0
permutation = torch.randperm(train_x.size()[0])
training_loss = []
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
現在,讓我們使用此訓練模型檢查訓練和驗證的準確性。
檢查模型性能
#
prediction = []
target = []
permutation = torch.randperm(train_x.size()[0])
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
# 訓練集精度
accuracy = []
for i in range(len(prediction)):
accuracy.append(accuracy_score(target[i],prediction[i]))
print('training accuracy: \\t', np.average(accuracy))
同樣,讓我們檢查驗證集準確性:
# 驗證集預測
prediction_val = []
target_val = []
permutation = torch.randperm(val_x.size()[0])
for i in tqdm(range(0,val_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = val_x[indices], val_y[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_val.append(predictions)
target_val.append(batch_y)
# 驗證集精度
accuracy_val = []
for i in range(len(prediction_val)):
accuracy_val.append(accuracy_score(target_val[i],prediction_val[i]))
print('validation accuracy: \\t', np.average(accuracy_val))
讓我們將其與以前的結果進行比較:
上表表示沒有Dropout和有Dropout的準確性。如果你觀察沒有遺漏的模型的訓練和驗證準確性,它們是不同步的。訓練精度過高,驗證精度較低。因此,這可能是一個過擬合的例子。
當我們引入Dropout時,訓練和驗證集的準確性是同步的。因此,如果你的模型過擬合,你可以嘗試添加Dropout層,以減少模型的複雜性。
要添加的Dropout數量是一個超參數,你可以使用該值進行操作。現在讓我們看看另一個難題。
深度學習難題3:模型欠擬合
深度學習模型也可能欠擬合,聽起來似乎不太可能。
欠擬合是指模型無法從訓練數據本身中學習模式,因此訓練集上的性能較低。
這可能是由於多種原因造成的,例如沒有足夠的數據來訓練,架構太簡單,模型的訓練次數較少等。
為了克服欠擬合的問題,你可以嘗試以下解決方案:
- 增加訓練數據
- 製作一個複雜的模型
- 增加訓練的epoch
對於我們的問題,欠擬合不是問題,因此,我們將繼續研究提高深度學習模型性能的下一種方法。
深度學習難題4:訓練時間過長
有些情況下,你可能會發現你的神經網絡需要花很多時間來收斂。這背後的主要原因是輸入到神經網絡層的分布發生了變化。
在訓練過程中,神經網絡各層的權值發生變化,激活也隨之變化。現在,這些激活是下一層的輸入,因此每一次連續的疊代都會改變分布。
由於這種分布的變化,每一層都必須適應不斷變化的輸入—這就是為什麼訓練時間增加的原因。
為了克服這一問題,我們可以應用批處理標準化(batch normalization),其中我們正常化的激活隱藏層,並試圖作出相同的分布。
現在讓我們向架構中添加batchnorm層,並檢查它在車輛分類問題上的表現:
torch.manual_seed(0)
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# 定義2D卷積層
Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# BN層
BatchNorm2d(16),
MaxPool2d(kernel_size=2, stride=2),
#另一個2D卷積層
Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# BN層
BatchNorm2d(32),
MaxPool2d(kernel_size=2, stride=2),
)
self.linear_layers = Sequential(
Linear(32 * 56 * 56, 2)
)
# 前向傳播
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x
定義模型參數
# 定義模型
model = Net()
# 定義優化器
optimizer = Adam(model.parameters(), lr=0.00005)
# 定義損失函數
criterion = CrossEntropyLoss()
# 檢查GPU是否可用
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
print(model)
訓練模型
torch.manual_seed(0)
# 模型batch大小
batch_size = 128
# epoch數
n_epochs = 5
for epoch in range(1, n_epochs+1):
# 保持記錄訓練與驗證集損失
train_loss = 0.0
permutation = torch.randperm(train_x.size()[0])
training_loss = []
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
顯然,該模型能夠很快學習。在第5個epoch時,我們的訓練損失為0.3386,而當我們不使用批量標準化時要25個epoch之後,我們的訓練損失才為0.3851。
因此,引入批標準化無疑減少了訓練時間。讓我們檢查訓練和驗證集的性能:
prediction = []
target = []
permutation = torch.randperm(train_x.size()[0])
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
# 訓練集精度
accuracy = []
for i in range(len(prediction)):
accuracy.append(accuracy_score(target[i],prediction[i]))
print('training accuracy: \\t', np.average(accuracy))
# 驗證集預測
prediction_val = []
target_val = []
permutation = torch.randperm(val_x.size()[0])
for i in tqdm(range(0,val_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = val_x[indices], val_y[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_val.append(predictions)
target_val.append(batch_y)
# 驗證集精度
accuracy_val = []
for i in range(len(prediction_val)):
accuracy_val.append(accuracy_score(target_val[i],prediction_val[i]))
print('validation accuracy: \\t', np.average(accuracy_val))
添加批量標準化可以減少訓練時間,但是這裡存在一個問題。你能弄清楚它是什麼嗎?該模型現在過擬合,因為我們在訓練上的準確性為91%,在驗證集上的準確性為63%。記住,我們沒有在最新模型中添加Dropout層。
這些是我們可以用來改善深度學習模型性能的一些技巧。現在,讓我們結合到目前為止所學的所有技術。
案例研究:提高車輛分類模型的性能
我們已經看到Dropout和批標準化如何幫助減少過擬合併加快訓練過程。現在是時候將所有這些技術結合在一起並建立模型了。
torch.manual_seed(0)
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# 定義2D卷積層
Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# BN層
BatchNorm2d(16),
MaxPool2d(kernel_size=2, stride=2),
# 添加dropout
Dropout(),
#另一個2D卷積層
Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
ReLU(inplace=True),
# BN層
BatchNorm2d(32),
MaxPool2d(kernel_size=2, stride=2),
# 添加dropout
Dropout(),
)
self.linear_layers = Sequential(
Linear(32 * 56 * 56, 2)
)
# 前向傳播
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x
現在,我們將定義模型的參數:
# 定義模型
model = Net()
# 定義優化器
optimizer = Adam(model.parameters(), lr=0.00025)
# 定義損失函數
criterion = CrossEntropyLoss()
# 檢查GPU是否可用
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
print(model)
最後,讓我們訓練模型:
torch.manual_seed(0)
# 模型batch大小
batch_size = 128
# epoch數
n_epochs = 10
for epoch in range(1, n_epochs+1):
# 保持記錄訓練與驗證集損失
train_loss = 0.0
permutation = torch.randperm(train_x.size()[0])
training_loss = []
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
接下來,讓我們檢查模型的性能:
prediction = []
target = []
permutation = torch.randperm(train_x.size()[0])
for i in tqdm(range(0,train_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = train_x[indices], train_y[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)
# 訓練集精度
accuracy = []
for i in range(len(prediction)):
accuracy.append(accuracy_score(target[i],prediction[i]))
print('training accuracy: \\t', np.average(accuracy))
# 驗證集預測
prediction_val = []
target_val = []
permutation = torch.randperm(val_x.size()[0])
for i in tqdm(range(0,val_x.size()[0], batch_size)):
indices = permutation[i:i+batch_size]
batch_x, batch_y = val_x[indices], val_y[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_val.append(predictions)
target_val.append(batch_y)
# 驗證集精度
accuracy_val = []
for i in range(len(prediction_val)):
accuracy_val.append(accuracy_score(target_val[i],prediction_val[i]))
print('validation accuracy: \\t', np.average(accuracy_val))
驗證準確性明顯提高到73%。太棒了!
結尾
在這篇文章中,我們研究了在使用深度學習模型(如CNNs)時可能面臨的不同難題。我們還學習了所有這些難題的解決方案,最後,我們使用這些解決方案建立了一個模型。
在我們將這些技術添加到模型之後,模型在驗證集上的準確性得到了提高。總有改進的空間,以下是一些你可以嘗試的方法:
- 調整Dropout率
- 增加或減少卷積層的數量
- 增加或減少Dense層的數量
- 調整隱藏層中的神經元數量,等等。