文章目錄
- 1、數據集準備
- 2、網絡搭建
- 3、訓練網絡
- 4、測試神經網絡
- 5、進行預測
- 6、完整代碼
1、數據集準備
首先準備一個包含十個數字文件夾的DigitsData,每個數字文件夾里包含1000張對應這個數字的圖片,圖片的尺寸都是 28×28×1 像素的,如下圖所示
matlab 中imageDatastore
函數會根據文件夾名稱自動為圖像進行分類標注。該數據集包含 10 個類別。
% 創建一個圖像數據存儲對象 `imds`,用于從名為 "DigitsData" 的文件夾中加載圖像數據
imds = imageDatastore("DigitsData", ...IncludeSubfolders=true, ... % 指定在加載數據時包含子文件夾中的圖像LabelSource="foldernames"); % 使用子文件夾的名稱作為圖像的標簽(自動分類)% 獲取數據集中所有的類別名稱(即文件夾名),并將其存儲在變量 classNames 中
classNames = categories(imds.Labels); % 將 imds.Labels
將數據劃分為訓練集、驗證集和測試集。使用 70% 的圖像作為訓練數據,15% 作為驗證數據,15% 作為測試數據。指定使用 “randomized”(隨機化),以便從每個類別中按指定比例隨機分配圖像到新的數據集中。
splitEachLabel
函數用于將圖像數據存儲對象劃分成三個新的數據存儲對象。
% 使用 splitEachLabel 函數將原始圖像數據集 imds 隨機劃分為訓練集、驗證集和測試集
[imdsTrain, imdsValidation, imdsTest] = splitEachLabel(imds, 0.7, 0.15, 0.15, "randomized");
splitEachLabel
:MATLAB 中的函數,用于根據每個標簽(類別)分別劃分圖像數據集。這樣可以確保每個類別在訓練集、驗證集和測試集中都有代表性。imds
:原始的圖像數據存儲對象,包含所有圖像和對應的標簽。0.7
:表示將每個類別中 70% 的圖像用于訓練集。0.15
:表示每個類別中 15% 的圖像用于驗證集。0.15
:表示每個類別中 15% 的圖像用于測試集。"randomized"
:表示在劃分數據集時使用隨機抽樣,避免按文件順序導致劃分不均衡。[imdsTrain, imdsValidation, imdsTest]
:返回三個新的imageDatastore
對象,分別代表:
imdsTrain
:訓練數據集imdsValidation
:驗證數據集imdsTest
:測試數據集
2、網絡搭建
這里,我們需要借用到matlab工具欄里APPS里的Deep Network Designer,如下圖所示
在Deep Network Designer, 我們創建一個空白Designer畫布
然后我們可以拖動相應的層到Designer里,并連接各個層,如下圖所示
這里,我們只需要改一下輸入層的InputSize就行,如下圖
然后,我們可以檢查這個網絡可行不可行,通過Analyze按鈕,就會得到這個網絡的分析結果,如下圖
沒有錯誤,就可以通過Export按鈕輸出這個網絡到Matlab工作區,這個網絡被自動被命名為net_1。
3、訓練網絡
指定訓練選項。不同選項的選擇需要依賴實驗分析(即通過反復試驗和比較來確定最優配置)。
% 設置用于網絡訓練的選項,這里使用的是隨機梯度下降動量法(SGDM)
% 最大訓練輪數(epoch):訓練過程中將整個訓練集完整迭代 4 次
% 指定驗證數據集,用于在訓練過程中評估模型的泛化能力
% 每訓練 30 個 mini-batch 執行一次驗證評估
% 在訓練過程中顯示實時圖形界面,包括損失值和準確率的變化曲線
% 指定訓練期間關注的評估指標為準確率(accuracy)
% 禁止在命令行窗口輸出詳細訓練信息(安靜模式)
options = trainingOptions("sgdm", ... MaxEpochs = 4, ... ValidationData = imdsValidation, ... ValidationFrequency = 30, ... Plots = "training-progress", ... Metrics = "accuracy", ... Verbose = false);
trainingOptions
是 MATLAB 中用于設置神經網絡訓練參數的函數。
"sgdm"
是一種常用優化算法,適用于多數分類問題。
MaxEpochs=4
設置為 4 是為了快速試驗,實際訓練中可以設置更大,比如 10、20 甚至更多。
ValidationFrequency=30
表示每 30 次 mini-batch 后在驗證集上評估一次性能,值越小越頻繁,但也會增加驗證的耗時。
Plots="training-progress"
是非常有用的調試和可視化工具,能幫助你觀察訓練是否收斂。
Verbose=false
適合在圖形界面中查看結果時使用;如果希望看到文字日志,可以設置為true
。
使用 trainnet
函數訓練神經網絡。由于目標是分類任務,因此使用交叉熵損失函數(cross-entropy loss)。
% 使用 trainnet 函數對神經網絡進行訓練
net = trainnet(imdsTrain, net_1, "crossentropy", options);
imdsTrain
:訓練數據集,是一個圖像數據存儲對象(imageDatastore),包含用于訓練的圖像和對應標簽。net_1
:要訓練的神經網絡結構(可由layerGraph
或dlnetwork
等方式定義的網絡)。"crossentropy"
:指定損失函數為交叉熵損失函數(cross-entropy loss),這是分類任務中最常用的損失函數,特別適用于多類分類問題。options
:訓練選項,由前面設置的trainingOptions
定義,包含訓練輪數、驗證數據、優化器、可視化等信息。返回值:
net
:訓練完成后的神經網絡,包含了優化后的權重和結構,可用于后續的預測或評估。
4、測試神經網絡
使用 testnet
函數對神經網絡進行測試。對于單標簽分類任務,評估指標為準確率(accuracy),即預測正確的百分比。默認情況下,testnet
函數會在可用時自動使用 GPU。如果希望手動選擇執行環境,可以使用 testnet
函數的 ExecutionEnvironment
參數進行設置。
% 使用 testnet 函數對訓練好的神經網絡進行驗證,并評估其準確率
accuracy = testnet(net, imdsTest, "accuracy");
net
:已訓練好的神經網絡模型,是前面通過trainnet
得到的結果。imdsTest
:測試數據集,是一個圖像數據存儲對象(imageDatastore),用于測試模型的性能。"accuracy"
:評估指標,這里指定為準確率,即預測正確的樣本數量占總樣本數量的百分比。返回值:
accuracy
:一個介于 0 和 1 之間的小數,表示模型在測試集上的準確率。例如,accuracy = 0.93
表示模型在測試集中有 93% 的預測是正確的。
testnet
函數自動根據你的硬件情況選擇在 CPU 還是 GPU 上運行。如果你想手動指定環境,比如使用 CPU,可以這樣寫:accuracy = testnet(net, imdsTest, "accuracy", ExecutionEnvironment="cpu");
5、進行預測
使用 minibatchpredict
函數進行預測,并通過 scores2label
函數將預測得分轉換為類別標簽。默認情況下,如果有可用的 GPU,minibatchpredict
會自動使用 GPU 進行計算。
% 對測試集進行批量預測,輸出每個圖像對應的類別得分(概率)
scores = minibatchpredict(net, imdsValidation);% 將得分(scores)轉換為類別標簽,使用 classNames 映射到原始類名
YValidation = scores2label(scores, classNames);
可視化部分預測結果:
% 獲取測試集圖像的總數量
numTestObservations = numel(imdsTest.Files);% 從測試集中隨機選取 9 個樣本用于可視化
idx = randi(numTestObservations, 9, 1);% 創建一個新的圖形窗口
figure
tiledlayout("flow") % 使用自動流式布局排列子圖(tiled layout)% 遍歷 9 張圖像,顯示圖像并在標題中標注預測類別
for i = 1:9nexttile % 在下一個網格位置準備繪圖img = readimage(imdsTest, idx(i)); % 讀取第 idx(i) 張圖像imshow(img) % 顯示圖像title("Predicted Class: " + string(YTest(idx(i)))) % 設置標題,顯示預測類別
end
6、完整代碼
% 創建一個圖像數據存儲對象 `imds`,用于從名為 "DigitsData" 的文件夾中加載圖像數據
imds = imageDatastore("DigitsData", ...IncludeSubfolders=true, ... % 指定在加載數據時包含子文件夾中的圖像LabelSource="foldernames"); % 使用子文件夾的名稱作為圖像的標簽(自動分類)% 獲取數據集中所有的類別名稱(即文件夾名),并將其存儲在變量 classNames 中
classNames = categories(imds.Labels); % 將 imds.Labels%%
% 使用 splitEachLabel 函數將原始圖像數據集 imds 隨機劃分為訓練集、驗證集和測試集
[imdsTrain, imdsValidation, imdsTest] = splitEachLabel(imds, 0.7, 0.15, 0.15, "randomized");% 設置用于網絡訓練的選項,這里使用的是隨機梯度下降動量法(SGDM)
% 最大訓練輪數(epoch):訓練過程中將整個訓練集完整迭代 4 次
% 指定驗證數據集,用于在訓練過程中評估模型的泛化能力
% 每訓練 30 個 mini-batch 執行一次驗證評估
% 在訓練過程中顯示實時圖形界面,包括損失值和準確率的變化曲線
% 指定訓練期間關注的評估指標為準確率(accuracy)
% 禁止在命令行窗口輸出詳細訓練信息(安靜模式)
options = trainingOptions("sgdm", ... MaxEpochs = 4, ... ValidationData = imdsValidation, ... ValidationFrequency = 30, ... Plots = "training-progress", ... Metrics = "accuracy", ... Verbose = false); % 使用 trainnet 函數對神經網絡進行訓練
net = trainnet(imdsTrain, net_1, "crossentropy", options);%%
% 使用 testnet 函數對訓練好的神經網絡進行驗證,并評估其準確率
accuracy = testnet(net, imdsTest, "accuracy");%%
% 對測試集進行批量預測,輸出每個圖像對應的類別得分(概率)
scores = minibatchpredict(net, imdsTest);% 將得分(scores)轉換為類別標簽,使用 classNames 映射到原始類名
YTest = scores2label(scores, classNames);% 獲取測試集圖像的總數量
numTestObservations = numel(imdsTest.Files);% 從測試集中隨機選取 9 個樣本用于可視化
idx = randi(numTestObservations, 9, 1);% 創建一個新的圖形窗口
figure
tiledlayout("flow") % 使用自動流式布局排列子圖(tiled layout)% 遍歷 9 張圖像,顯示圖像并在標題中標注預測類別
for i = 1:9nexttile % 在下一個網格位置準備繪圖img = readimage(imdsTest, idx(i)); % 讀取第 idx(i) 張圖像imshow(img) % 顯示圖像title("Predicted Class: " + string(YTest(idx(i)))) % 設置標題,顯示預測類別
end