Error executing bearing failure detection code using deep learning transfer learning in MATLAB: How can I solve it?

15 views (last 30 days)
Hello everyone.
I'm working on a project where I'm trying to detect faults in bearings using transfer learning with deep learning in MATLAB (R2022b version). However, I've come across an issue a couple of times that has me a bit stuck, and I was wondering if you could provide some guidance.
The error message I'm receiving is literally:
  1. Error in predmaint.​internal.p​mdata.PMDa​tastore/re​ad (line192) thow(E)
  2. Error in BearingFaultDiagnosisCWRU>convertSignalToScalogram data = read(ensemble)
I've gone through my code multiple times and verified that my data is in the correct format, the necessary libraries are imported, and the parameters are set up properly. Despite my efforts, the error persists, and I'm certain there must be something I'm overlooking. I also have seen in the community that someone have had a similar issue an maybe it can be related with directories thart Matlab is using but I'm not sure. I'd like to ask if they could provide me guidance to troubleshooting this specific error.
I appreciate any suggestions, advice, or hints you can provide in advance, and I attached below these three scripts:
  • BearingFaultDiagnosisCWRU (the main script where I'm working)
  • readMFPTBearing (auxiliary program to read specific data from a bearing file)
  • PMDa​tastore (only a part of the code until the error)
This is "BearingFaultDiagnosisCWRU":
% SCALOGRAM OF BEARING DATA %
% Import data with inner race fault
data_inner = load('C:\Program Files\MATLAB\R2022b\toolbox\predmaint\predmaintdemos\bearingFaultDiagnosis\RollingElementBearingFaultDiagnosis-Data-master\train_data\InnerRrace_0.mat');
% Plot bearing signal and scalogram
plotBearingSignalAndScalogram(data_inner)
% Import data with outer race fault
data_outer = load('C:\Program Files\MATLAB\R2022b\toolbox\predmaint\predmaintdemos\bearingFaultDiagnosis\RollingElementBearingFaultDiagnosis-Data-master\test_data\OuterRace_8.mat');
% Plot original signal and its scalogram
plotBearingSignalAndScalogram(data_outer)
% Import normal bearing data
data_normal = load('C:\Program Files\MATLAB\R2022b\toolbox\predmaint\predmaintdemos\bearingFaultDiagnosis\RollingElementBearingFaultDiagnosis-Data-master\train_data\baseline_0.mat');
% Plot original signal and its scalogram
plotBearingSignalAndScalogram(data_normal)
% PREPARE TRAINING DATA %
fileLocation = 'C:\Program Files\MATLAB\R2022b\toolbox\predmaint\predmaintdemos\bearingFaultDiagnosis\RollingElementBearingFaultDiagnosis-Data-master\train_data';
fileExtension = '.mat';
ensembleTrain = fileEnsembleDatastore(fileLocation, fileExtension);
ensembleTrain.ReadFcn = @readMFPTBearing;
ensembleTrain.DataVariables = ["gs", "sr", "rate", "load", "BPFO", "BPFI", "FTF", "BSF"];
ensembleTrain.ConditionVariables = ["Label", "FileName"];
ensembleTrain.SelectedVariables = ["gs", "sr", "rate", "load", "BPFO", "BPFI", "FTF", "BSF", "Label", "FileName"]
reset(ensembleTrain)
while hasdata(ensembleTrain)
folderName = 'train_image';
convertSignalToScalogram(ensembleTrain,folderName);
end
% Create image datastore to store all training images
path = fullfile('.', folderName);
imds = imageDatastore(path, ...
'IncludeSubfolders',true,'LabelSource','foldernames');
% Use 20% training data as validation set
[imdsTrain,imdsValidation] = splitEachLabel(imds,0.8,'randomize');
% TRAIN NETWORK WITH TRANFER LEARNING %
net = squeezenet
analyzeNetwork(net)
lgraph = layerGraph(net);
numClasses = numel(categories(imdsTrain.Labels));
newConvLayer = convolution2dLayer([1, 1],numClasses,'WeightLearnRateFactor',10,'BiasLearnRateFactor',10,"Name",'new_conv');
lgraph = replaceLayer(lgraph,'conv10',newConvLayer);
newClassificationLayer = classificationLayer('Name','new_classoutput');
lgraph = replaceLayer(lgraph,'ClassificationLayer_predictions',newClassificationLayer);
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.0001, ...
'MaxEpochs',4, ...
'Shuffle','every-epoch', ...
'ValidationData',imdsValidation, ...
'ValidationFrequency',30, ...
'Verbose',false, ...
'MiniBatchSize',20, ...
'Plots','training-progress');
net = trainNetwork(imdsTrain,lgraph,options);
% VALIDATE USING TEST DATA SETS %
fileLocation = fullfile('.', 'RollingElementBearingFaultDiagnosis-Data-master', 'test_data');
fileExtension = '.mat';
ensembleTest = fileEnsembleDatastore(fileLocation, fileExtension);
ensembleTest.ReadFcn = @readMFPTBearing;
ensembleTest.DataVariables = ["gs", "sr", "rate", "load", "BPFO", "BPFI", "FTF", "BSF"];
ensembleTest.ConditionVariables = ["Label", "FileName"];
ensembleTest.SelectedVariables = ["gs", "sr", "rate", "load", "BPFO", "BPFI", "FTF", "BSF", "Label", "FileName"];
reset(ensembleTest)
while hasdata(ensembleTest)
folderName = 'test_image';
convertSignalToScalogram(ensembleTest,folderName);
end
path = fullfile('.','test_image');
imdsTest = imageDatastore(path, ...
'IncludeSubfolders',true,'LabelSource','foldernames');
YPred = classify(net,imdsTest,'MiniBatchSize',20);
YTest = imdsTest.Labels;
accuracy = sum(YPred == YTest)/numel(YTest)
figure
confusionchart(YTest,YPred)
% ADITIONAL FUNCTIONS %
function plotBearingSignalAndScalogram(data)
% Convert 1-D bearing signals to scalograms through wavelet transform
fs = data.bearing.sr;
t_total = 0.1; % seconds
n = round(t_total*fs);
bearing = data.bearing.gs(1:n);
[cfs,frq] = cwt(bearing,'amor', fs);
% Plot the original signal and its scalogram
figure
subplot(2,1,1)
plot(0:1/fs:(n-1)/fs,bearing)
xlim([0,0.1])
title('Vibration Signal')
xlabel('Time (s)')
ylabel('Amplitude')
subplot(2,1,2)
surface(0:1/fs:(n-1)/fs,frq,abs(cfs))
shading flat
xlim([0,0.1])
ylim([0,max(frq)])
title('Scalogram')
xlabel('Time (s)')
ylabel('Frequency (Hz)')
end
function convertSignalToScalogram(ensemble,folderName)
% Convert 1-D signals to scalograms and save scalograms as images
data = read(ensemble); %<<<----------------------------------------------[HERE IS THE ERROR 2]
fs = data.sr;
x = data.gs{:};
label = char(data.Label);
fname = char(data.FileName);
ratio = 5000/97656;
interval = ratio*fs;
N = floor(numel(x)/interval);
% Create folder to save images
path = fullfile('.',folderName,label);
if ~exist(path,'dir')
mkdir(path);
end
for idx = 1:N
sig = envelope(x(interval*(idx-1)+1:interval*idx));
cfs = cwt(sig,'amor', seconds(1/fs));
cfs = abs(cfs);
img = ind2rgb(round(rescale(flip(cfs),0,255)),jet(320));
outfname = fullfile('.',path,[fname '-' num2str(idx) '.jpg']);
imwrite(imresize(img,[227,227]),outfname);
end
end
This is "readMFPTBearing":
function data = readMFPTBearing(filename, variables)
% Read variables from a file, used by the ReadFcn of a
% fileEnsembleDatastore object.
%
% Inputs:
% filename - a string of the file name to read from
% variables - a string array containing variable names to read
%
% Output:
% data - return a table with a single row
%
% Note: This function uses dynamic field references to read data from
% files, see
% https://www.mathworks.com/help/matlab/matlab_prog/generate-field-names-from-variables.html
% for more information
data = table();
mfile = matfile(filename); % Allows partial loading
[~, fname] = fileparts(filename);
bearing = mfile.bearing;
for ct = 1:numel(variables)
if strcmp(variables{ct},'FileName')
%Return filename
val = string(fname);
elseif strcmp(variables{ct},'Label')
%Set label based on filename
cfname = char(fname);
switch cfname(1:3)
case 'Nor'
val = "Normal";
case 'Inn'
val = "Inner Race Fault";
case 'Out'
val = "Outer Race Fault";
otherwise
val = "Unknown";
end
else
% The data could be either stored at top level or within bearing structure
if isfield(bearing, variables{ct})
val = bearing.(variables{ct});
else
val = mfile.(variables{ct});
end
% Handle unstructured data
% e.g. numeric data in string type or missing data
if ischar(val)
val = str2double(val);
elseif isempty(val)
val = nan;
end
if numel(val) > 1
val = {val};
end
end
data.(variables{ct}) = val;
end
end
This is a part of "PMDatastore" (Error in line 191 is indicated in comments at the end):
classdef PMDatastore < ...
matlab.io.Datastore & ...
matlab.io.datastore.Partitionable
%PMDATASTORE
%
% Datastore subclass used for predictive maintenance. Key extensions
% are to add notions of
% - data variables
% - independent variables
% - condition variables
%
% Copyright 2017-2021 The MathWorks, Inc.
properties (Access = protected)
InternalDataset
Index uint32
end
properties(Access = public, Dependent = true)
%DATAVARIABLES Names of data variables in the ensemble
%
% A string array of the names of data variables in the
% ensemble. The default value is an empty string array.
%
% Data variables are the main content of the members in an
% ensemble and include measured data as well as derived data
% that is used for analysis and development of predictive
% maintenance algorithms. Examples are vibration signals, and
% derived values such as mean vibration value, or peak vibration
% frequency.
%
% The data variable names are used to identify data in the ensemble
% and are also the variable names (column names) of the table
% returned by the ensemble read() method.
%
DataVariables string
%INDEPENDENTVARIABLES Names of independent variables in the ensemble
%
% A string array of the names of independent variables in the
% ensemble. The default value is an empty string array.
%
% Independent variables are typically used to order the members
% in an ensemble. Examples are time stamps, number of operating
% hours, or miles driven.
%
% The independent data variable names are used to identify data
% in the ensemble and are also the variable names (column names)
% of the table returned by the ensemble read() method.
%
IndependentVariables string
%CONDITIONVARIABLES Names condition variables in the ensemble
%
% A string array of the names of the condition variables in the
% ensemble. The default value is an empty string array.
%
% Condition variables are used to label the members in a
% ensemble and are typically labels describing the fault
% condition of the ensemble member.
%
% The condition variable names are used to identify data in the
% ensemble and are also the variable names (column names) of the
% table returned by the ensemble read() method.
%
ConditionVariables string
%SelectedVariables Names of data variables to read from the ensemble
%
% A string array of the names of data variables to read from the
% ensemble. The default value is an empty string array.
%
% The SelectedVariables are used by the ensemble read() method
% to specify the data variables that the read() method returns.
% The read() method returns a table with table variables (table
% columns) for each name defined in SelectedVariables.
%
SelectedVariables string
%ReadSize Number of members to read from the ensemble
%
% A positive finite integer value specifying the number of
% members to read from the ensemble. The default value is 1.
%
% The ReadSize is used by the ensemble read() method to
% determine the number of ensemble members that the read()
% method returns. The read() method returns a table with table
% ReadSize number of rows where each row is an ensemble member.
%
ReadSize(1,1) {mustBeNumeric, mustBePositive, mustBeFinite}
end
properties(GetAccess = public, SetAccess = protected, Dependent = true)
%NumMembers Number of members in the ensemble
%
% A read-only integer value giving the number of members in the
% ensemble.
%
NumMembers uint32
%LastMemberRead
%
% A read-only value specifying the member that the ensemble last
% read. The value is [] when the ensemble is reset and updates
% when the ensemble read() command is used.
%
LastMemberRead
end
properties(Hidden, Dependent) % App use
IVUnit(1,:) cell
DVUnit(1,:) cell
CVUnit(1,:) cell
end
properties(Access = {?predmaintguis.internal.data.DataInfo,?dfeapp.internal.data.DataInfo, ?predmaint.internal.pmdata.var.DatasetManager}) % App use
VarInfoArray
end
properties(Access = protected)
FcnData function_handle %Function to retrieve data for specified member
FcnIV function_handle %Function to retrieve IV value for specified member
FcnCondition function_handle %Function to retrieve condition data for specified member
FcnCommon function_handle %Function to retrieve all values for a specified member
FcnWriteToMember function_handle %Function to write data to a member
DataVariables_ string
IndependentVariables_ string
ConditionVariables_ string
SelectedVariables_ string
ReadSize_ double = 1;
VariableTypes
% app use
IVUnit_
DVUnit_
CVUnit_
end
methods (Abstract, Access = protected)
tf = hasdata_(obj);
n = getNumMembers_(obj);
reset_(obj)
Member = getNextMember(obj);
Member = getLastMemberRead(obj);
resetLastMemberRead(obj)
[tf,msg] = supportsWrite(obj);
sobj = subset_(obj,idx);
end
methods (Access = protected, Abstract, Static)
info = getMemberInfo(data, Member);
end
%Datastore API methods
methods
function [data, info] = read(obj)
%READ Read member data from the ensemble
%
% Increment the ensemble current member and return data from
% the current member.
%
% The data read is specified by the SelectedVariables
% property. Only one independent variable can be specified by
% the SelectedVariables property.
%
% [data,info] = read(obj)
%
% Outputs:
% data - table row containing data read from the current
% entry in the data store
% info - a structure with the file name where the data was
% read from and size of the data
%
if ~hasdata(obj)
error(message('predmaint:general:errPMDatastore_Empty'));
end
numRead = 0;
resetLastMemberRead(obj)
while numRead < obj.ReadSize
if numRead > 0 && ~hasdata(obj)
%Got to end of datastore
break
end
Member = getNextMember(obj); % increments current member counter
try
rdata = reader(obj,Member);
numRead = numRead+1;
catch E
throw(E) %<<<----------------------------------------[HERE IS ERROR 1]
end
rinfo = obj.getMemberInfo(rdata, Member, obj.Index);
if numRead > 1
data = [data;rdata]; %#ok<AGROW>
info = [info;rinfo]; %#ok<AGROW>
else
info = rinfo;
data = rdata;
end
if isempty(obj.Index)
obj.Index = 1;
else
obj.Index = obj.Index+1;
end
end
end

Answers (1)

Varun
Varun on 5 Sep 2023
Hi,
I see that you're encountering an error in the "PMDa​tastore.m" file, specifically in the given section:
try
rdata = reader(obj,Member);
numRead = numRead+1;
catch E
throw(E) %<<<--------------- [HERE IS ERROR 1]
end
As, you are calling reader(obj,Member) but it is neither defined in PMDatastoreclass methods, it is parent classes matlab.io.Datastore and matlab.io.datastore.Partitionable methods nor anywhere in the list of abstract methods that you have declared in PMDatastore” class.
Hence, while executing in try block it is unable to find reader definition and goes to catch block where throw(E) is executed which throws an error and the program is terminated.
So, you should also define reader method in PMDatastore class or declare it as abstract so that any child class implementing PMDatastore” class define “reader” method in it.
Hope this helps.

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!