前言:
本文基于预训练的卷积神经网络(Convolutional Neural Network,CNN)进行模型创建,进行调整后应用到已有的数据集电熔镁砂(Fused magnesium furnace, FMF)工况识别(实验室数据集,不公开)。
正文:
这里不对数据集背景展开介绍,为了方便说明,视FMF数据集为一个故障识别问题,故障工况的标签为1,非故障工况的标签为0。FMF数据集样本来自于实际电熔镁炉同一批炉次工况运行的片段,后期经过图像增强处理,图像大小为32X32X3的RGB图像。其中使用训练集traindata2.mat包含3010张图像,故障数与非故障数比例为1923:1087;使用测试集testdata4.mat包含626张图像,故障数与非故障数比例为416:210。
实验环境使用MATLAB 2022b的深度学习工具箱以及附加功能资源。
建议先安装好附加资源管理器的AlexNet
AlexNet安装
Alexnet的网络结构
修改全连接层
修改全连接层
非常失败的一次尝试,为了适应Alexnet网络输入,调整图片输入为227*227*3,训练结果只有91%的准确率,在测试集上效果不理想
%% Alexnet迁移学习
%% 清空环境和图窗
clear
close all
%% 导入模型
net = alexnet;
layers = net.Layers
layers(end-2) = fullyConnectedLayer(2); %故障识别为二分类
layers(end) = classificationLayer;
%% 准备数据集
load("traindata2.mat")
len = length(label);
img(:,:,:,len) = zeros(227,227,3); %预分配内存
for i = 1:len
img(:,:,:,i) = imresize(video(:,:,:,i),[227 227]); %调整输入大小为227*227*3
end
rng(10) % 设置seed,便于复现
randIndex = randperm(len);
len1 = round(0.7*len);
trainIndex = randIndex(1:len1);
testIndex = randIndex(len1+1:end);
trainlabels = label(trainIndex);
trainImages = img(:,:,:,trainIndex);
vallabels = label(testIndex);
valImages = img(:,:,:,testIndex);
trainlabels = categorical(trainlabels);
vallabels = categorical(vallabels);
%% 模型训练
options = trainingOptions('adam',...
'ExecutionEnvironment','gpu',...
'InitialLearnRate',0.01,...
'MiniBatchSize',128,...
'MaxEpochs',100,...
'Shuffle','every-epoch',...
'ValidationData',{valImages,vallabels},...
'ValidationFrequency',50,...
'Verbose',false,...
'Plots','training-progress');
net = trainNetwork(trainImages,trainlabels,layers,options);
Alexnet模型训练过程
%% 测试集验证
load('testdata4_label.mat')
testlabels = categorical(label);
len1 = length(testlabels);
img1(:,:,:,len1) = zeros(227,227,3);
for i = 1:len1
img1(:,:,:,i) = imresize(video(:,:,:,i),[227 227]);
end
pred_labels = classify(net,img1);
test_Acc = sum(pred_labels == testlabels')/len1
cm = confusionchart(testlabels',pred_labels); %推荐使用
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';
cm.Title = 'SAPI-FMF Confusion Matrix';
测试集上训练效果
对比实验,使用自定义的CNN,网络结构更简单,不对原始输入进行调整
自定义的模型结构
%% 清空变量和图窗
clear;
close all;
%% 导入数据集
load("traindata2.mat")
len = length(label);
rng(10) % 设置seed,便于复现
randIndex = randperm(len);
len1 = round(0.7*len);
trainIndex = randIndex(1:len1);
testIndex = randIndex(len1+1:end);
trainlabels = label(trainIndex);
trainImages = video(:,:,:,trainIndex);
vallabels = label(testIndex);
valImages = video(:,:,:,testIndex);
trainlabels = categorical(trainlabels);
vallabels = categorical(vallabels);
%% 定义神经网络
layers = [
imageInputLayer([32,32,3])
convolution2dLayer(5,32,'Padding','same')
maxPooling2dLayer(2,"Stride",2,"Padding","same")
dropoutLayer(0.3)
convolution2dLayer(3,32)
batchNormalizationLayer
reluLayer
maxPooling2dLayer(2,'Stride',2)
fullyConnectedLayer(2)
softmaxLayer
classificationLayer
];
options = trainingOptions('adam',...
'ExecutionEnvironment','multi-gpu',...
'InitialLearnRate',0.01,...
'MiniBatchSize',128,...
'MaxEpochs',100,...
'Shuffle','every-epoch',...
'ValidationData',{valImages,vallabels},...
'ValidationFrequency',50,...
'Verbose',false,...
'Plots','training-progress');
自定义模型训练过程
net = trainNetwork(trainImages,trainlabels,layers,options);
%% 测试集验证
load('testdata4_label.mat')
testlabels = categorical(label);
testImages = video;
len2 = length(testlabels);
pred_labels = classify(net,testImages);
test_Acc = sum(pred_labels == testlabels')/len2
cm = confusionchart(testlabels',pred_labels); %推荐使用
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';
cm.Title = 'SAPI-FMF Confusion Matrix';
cm.RowSummary = 'row-normalized';
cm.Title = 'SAPI-FMF Confusion Matrix';
针对二维卷积神经网络的模型,训练效果均不太理想,同时由于所选数据集分布不合理,训练的模型倾向于无故障的分类(实际的数据集比所选数据集要多),模型准确性和泛化能力更差;另一方面,模型参数和优化参数没有充分调整。本文借助于MATLAB进行初步的验证和尝试,后面会使用基于python的深度学习框架pytorch或者Tensorflow进行模型的搭建和训练。