本文基于matlab2020版官方网页DocumentationCrack Identification From Accelerometer Data及个人理解。
该示例显示了如何使用小波wavelet和深度学习技术来检测横向路面裂缝并确定其位置。该示例演示了将小波散射序列用作门控循环单元(GRU)和一维卷积网络的输入,以便根据是否存在裂缝对时间序列进行分类。数据是从安装在前排乘客座椅车轮的转向节上的传感器获得的垂直加速度测量值。及早发现发展中的横向裂缝对于评估和维护路面性能非常重要。可靠的自动检测方法可实现更频繁,更广泛的监视。
本文主要介绍其中的第三部分,一维卷积神经网络的设置、训练和测试。
1D-CNN训练集
用小波散射序列训练一个一维卷积网络。散射序列为38×58,其中58为时间步长,38为散射路径数。为了在一个1-D卷积网络中使用它,将散射序列转置和重塑为58×1×38×Nsig,其中Nsig是训练样本的数量。
scatCONVTrain = zeros(58,1,38,length(XTrainSCAT),'single');% 训练集
for kk = 1:length(XTrainSCAT)
scatCONVTrain(:,:,:,kk) = reshape(XTrainSCAT{kk}',[58,1,38]);
end
1D-CNN网络结构
通过调用网络层,搭建一个1D-CNN的结构
conv1dLayers = [
imageInputLayer([58 1 38]);
convolution2dLayer([3 1],64,'stride',1);
batchNormalizationLayer;
reluLayer;
maxPooling2dLayer([2 1]);
convolution2dLayer([3 1],32);
reluLayer;
maxPooling2dLayer([2 1]);
fullyConnectedLayer(500);
fullyConnectedLayer(2);
softmaxLayer;
classificationLayer;
];
进行1D-CNN的训练
通过convoptions设置训练相关参数,然后进行训练并返回网络scatCONV1dnet和训练信息infoCONV
convoptions = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'LearnRateSchedule','piecewise', ...
'LearnRateDropFactor',0.5, ...
'LearnRateDropPeriod',5, ...
'Plots','training-progress',...
'MaxEpochs',50,...
'Verbose',0,...
'Plots','none',...
'MiniBatchSize',15);
[scatCONV1dnet,infoCONV] = ...
trainNetwork(scatCONVTrain,TrainLabels,conv1dLayers,convoptions);
绘制训练过程中每个迭代的准确度和损失
iterPerEpoch = floor(size(scatCONVTrain,4)/15);
figure
subplot(2,1,1)
smoothedACC = filter(1/iterPerEpoch*ones(iterPerEpoch,1),1,...
infoCONV.TrainingAccuracy);
smoothedLoss = filter(1/iterPerEpoch*ones(iterPerEpoch,1),1,...
infoCONV.TrainingLoss);
plot(smoothedACC)
title(['Training Accuracy (Smoothed) '...
num2str(iterPerEpoch) ' iterations per epoch'])
ylabel('Accuracy (%)')
ylim([0 100.1])
grid on
xlim([1 length(smoothedACC)])
subplot(2,1,2)
plot(smoothedLoss)
ylim([-0.01 1])
grid on
xlim([1 length(smoothedLoss)])
ylabel('Loss')
xlabel('Iteration')
运行结果
1D-CNN测试
转换测试集的小波散射序列,作为1D-CNN的测试输入
scatCONVTest = zeros(58,1,38,length(XTestSCAT));
for kk = 1:length(XTestSCAT)
scatCONVTest(:,:,:,kk) = reshape(XTestSCAT{kk}',58,1,38);
end
进行1D-CNN测试,绘制混淆矩阵
miniBatchSize = 15;
YPredSCAT = classify(scatCONV1Dnet,scatCONVTest,...
'MiniBatchSize',miniBatchSize);
figure
confusionchart(TestLabels,YPredSCAT,'RowSummary','row-normalized',...
'ColumnSummary','column-normalized');
title({'1-D Convolutional Network-- Wavelet Scattering Sequences'; ...
'Confusion chart with precision and recall'});
可以看到,基于散射序列的一维卷积网络性能优良,优于GRU网络。少数类的精确率 Precision和召回率recall证明了网络学习的鲁棒性。
原始数据的1D-CNN测试结果
在imageInputLayer的原始序列集合inputSize =[461 1]上训练一维卷积网络。可以加载和测试该网络。
load(fullfile(saveFolder,"transverse_crack_latest","tsCONV1Dnet.mat"));% 使用原始训练集训练过的1D-CNN
XTestData = cell2mat(TestData');
XTestData = reshape(XTestData,[461 1 1 66]);
miniBatchSize = 15;
YPredRAW = classify(tsCONV1Dnet,XTestData,...
'MiniBatchSize',miniBatchSize);
confusionchart(TestLabels,YPredRAW,'RowSummary','row-normalized',...
'ColumnSummary','column-normalized');
title({'1-D Convolutional Network-- Raw Sequences'; ...
'Confusion chart with precision and recall'});
可以看到,原始序列的一维卷积网络的性能优于GRU网络,但不如小波散射序列训练的卷积神经网络。此外,通过散射变换沿着数据的时间维进行压缩,得到的网络比在原始数据上训练的卷积网络小约8.5倍(不知道小指的是哪方面)。
综述,原始信号1D-CNN < 原始信号GRU < 小波散射GRU < 小波散射1D-CNN
References
[1] Yang, Qun and Shishi Zhou. “Identification of asphalt pavement transverse cracking based on vehicle vibration signal analysis.”, Road Materials and Pavement Design, 2020, 1-19. https://doi.org/10.1080/14680629.2020.1714699.
[2] Zhou,Shishi. “Vehicle vibration data.” https://data.mendeley.com/datasets/3dvpjy4m22/1. Data is used under CC BY 4.0. Data is repackaged from original Excel data format to MAT-files. Speed label removed and only “crack” or “nocrack” label retained.
附录
本示例中使用的辅助函数如下
function smat = helperscat(datain)
% This helper function is only in support of Wavelet Toolbox examples.
% It may change or be removed in a future release.
datain = single(datain);
sf = waveletScattering('SignalLength',length(datain),...
'OversamplingFactor',1,'qualityfactors',[8 1],...
'InvarianceScale',0.05,'Boundary','reflect','SamplingFrequency',1280);
smat = sf.featureMatrix(datain);
end
%-----------------------------------------------------------------------
function dataUL = equalLenTS(data)
% This function in only in support of Wavelet Toolbox examples.
% It may change or be removed in a future release.
N = length(data);
dataUL = cell(N,1);
for kk = 1:N
L = length(data{kk});
switch L
case 461
dataUL{kk} = data{kk};
case 369
Ndiff = 461-369;
pad = Ndiff/2;
dataUL{kk} = [flip(data{kk}(1:pad)); data{kk} ; ...
flip(data{kk}(L-pad+1:L))];
otherwise
Ndiff = L-461;
zrs = Ndiff/2;
dataUL{kk} = data{kk}(zrs:end-zrs-1);
end
end
end
%--------------------------------------------------------------------------
function [fmat,x] = featureVectors(data,sf)
% This function is only in support of Wavelet Toolbox examples.
% It may change or be removed in a future release.
data = single(data);
N = length(data);
dt = 1/1280;
if N < 461
Ndiff = 461-N;
pad = Ndiff/2;
dataUL = [flip(data(1:pad)); data ; ...
flip(data(N-pad+1:N))];
rate = 5e4/3600;
dx = rate*dt;
x = 0:dx:(N*dx)-dx;
elseif N > 461
Ndiff = N-461;
zrs = Ndiff/2;
dataUL = data(zrs:end-zrs-1);
rate = 3e4/3600;
dx = rate*dt;
x = 0:dx:(N*dx)-dx;
else
dataUL = data;
rate = 4e4/3600;
dx = rate*dt;
x = 0:dx:(N*dx)-dx;
end
fmat = sf.featureMatrix(dataUL);
fmat = reshape(fmat',[58 1 38]);
end
%------------------------------------------------------------------------------
function [mra,chngpts] = helperMRA(data,x)
% This function is only in support of Wavelet Toolbox examples.
% It may change or be removed in a future release.
mra = modwtmra(modwt(data,'sym3'),'sym3');
mraLev = mra(4:6,:);
Ns = size(mraLev,1);
thresh = [2, 4, 8];
chngpts = false(size(mraLev));
% Determine changepoints. We want different thresholds for different
% resolution levels.
for ii = 1:Ns
chngpts(ii,:) = ischange(mraLev(ii,:),"linear",2,"Threshold",thresh(ii));
end
for kk = 1:Ns
idx = double(chngpts(kk,:));
idx(idx == 0) = NaN;
subplot(Ns,1,kk)
plot(x,mraLev(kk,:))
if kk == 1
title('MRA Components')
end
yyaxis right
hs = stem(x,idx);
hs.ShowBaseLine = 'off';
hs.Marker = '^';
hs.MarkerFaceColor = [1 0 0];
end
grid on
axis tight
xlabel('Distance (m)')
end