ECG Signal Classification Using Transfer Learning and Wavelet Transform in MATLAB

%% Load ECG dataset and apply preprocessing
load('ECGData.mat');
[sigData, sigLabels] = preprocessECG(ECGData);

%% Extract time-frequency features using CWT
sampleFreq = 128;
waveletBank = cwtfilterbank('SignalLength', 1000, 'VoicesPerOctave', 12);
waveletFeats = extractWaveletFeatures(sigData, waveletBank);

%% Apply data augmentation and split dataset
augmentedFeats = augmentDataset(waveletFeats);
[trainSet, testSet, trainLbl, testLbl] = partitionData(augmentedFeats, sigLabels);

%% Configure transfer learning with GoogLeNet
pretrainedNet = imagePretrainedNetwork('googlenet');
adaptedNet = customizeNetworkForECG(pretrainedNet);

%% Train and evaluate the model
trainingConfig = trainingOptions('sgdm', 'MaxEpochs', 20, 'MiniBatchSize', 15);
trainedModel = trainNetwork(trainSet, trainLbl, adaptedNet, trainingConfig);
classificationAccuracy = assessPerformance(trainedModel, testSet, testLbl);
fprintf('Classification Accuracy: %.2f%%\n', classificationAccuracy * 100);

Key Module Implementations

Data Preprocessing Function

function [sigData, sigLabels] = preprocessECG(ECGData)
    % Normalize signal length via truncation or zero-padding
    targetLength = 65536;
    sigData = cell(size(ECGData.Data));
    
    for i = 1:numel(ECGData.Data)
        rawSignal = ECGData.Data(i, :);
        if numel(rawSignal) < targetLength
            padLength = targetLength - numel(rawSignal);
            rawSignal = [rawSignal, zeros(1, padLength)];
        else
            rawSignal = rawSignal(1:targetLength);
        end
        sigData{i} = rawSignal;
    end
    
    % Convert string labels to numeric indices
    labelDictionary = containers.Map({'ARR', 'CHF', 'NSR'}, [1, 2, 3]);
    sigLabels = cellfun(@(x) labelDictionary(x), ECGData.Labels);
end

Wavelet Feature Extraction

function waveletFeats = extractWaveletFeatures(sigData, waveletBank)
    numSamples = numel(sigData);
    waveletFeats = zeros(numSamples, 1000, 128);
    
    for i = 1:numSamples
        inputSignal = sigData{i};
        [coeffMatrix, freqRange] = wt(waveletBank, inputSignal);
        waveletFeats(i, :, :) = abs(coeffMatrix);
    end
end

Data Augmentation Pipeline

function augmentedFeats = augmentDataset(waveletFeats)
    augmentedFeats = [];
    
    for i = 1:size(waveletFeats, 1)
        % Temporal shifting augmentation
        shiftAmount = randi([0, 50]);
        shiftedFeat = circshift(waveletFeats(i, :, :), [0, shiftAmount]);
        augmentedFeats = [augmentedFeats; shiftedFeat];
        
        % Gaussian noise injection
        noisyFeat = awgn(waveletFeats(i, :, :), 10, 'measured');
        augmentedFeats = [augmentedFeats; noisyFeat];
    end
end

Network Architecture Modification

function adaptedNet = customizeNetworkForECG(pretrainedNet)
    % Replace final classification layers for 3-class output
    regularizationLayer = dropoutLayer(0.6, 'Name', 'custom_dropout');
    classificationLayer = fullyConnectedLayer(3, 'Name', 'custom_fc', ...
        'WeightLearnRateFactor', 5, 'BiasLearnRateFactor', 5);
    
    netLayers = pretrainedNet.Layers;
    netLayers(end-3) = regularizationLayer;
    netLayers(end-2) = classificationLayer;
    netLayers(end) = softmaxLayer('Name', 'output_prob');
    
    adaptedNet = assembleNetwork(netLayers);
end

Complete Workflow

Step 1: Dataset Preparation

% Retrieve PhysioNet ECG dataset
dataURL = 'https://example.com/physionet-ECG.zip';
websave('ECGData.zip', dataURL);
unzip('ECGData.zip', 'dataset');
load(fullfile('dataset', 'ECGData.mat'));

Step 2: Feature Visualization

% Generate CWT time-frequency representation for sample ECG
sampleSignal = sigData{1};
[coeffMatrix, freqRange] = wt(waveletBank, sampleSignal);

figure;
pcolor((0:numel(sampleSignal)-1)/sampleFreq, freqRange, abs(coeffMatrix));
shading interp;
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title('CWT Time-Frequency Map of ECG Signal');

Step 3: Model Training

trainingConfig = trainingOptions('adam', ...
    'MaxEpochs', 50, ...
    'MiniBatchSize', 20, ...
    'InitialLearnRate', 1e-4, ...
    'Shuffle', 'every-epoch', ...
    'ValidationData', {testSet, testLbl}, ...
    'Plots', 'training-progress');

trainedModel = trainNetwork(trainSet, trainLbl, adaptedNet, trainingConfig);

Step 4: Performance Evaluation

% Generate confusion matrix
predictedLbl = classify(trainedModel, testSet);
confMatrix = confusionmat(testLbl, predictedLbl);

figure;
confusionchart(confMatrix, {'ARR', 'CHF', 'NSR'}, 'RowSummary', 'row-normalized');

% Plot ROC curve
[falsePosRate, truePosRate, threshold, areaUnderCurve] = perfcurve(testLbl, predictedLbl, 2);

figure;
plot(falsePosRate, truePosRate);
xlabel('False Positive Rate');
ylabel('True Positive Rate');
title(sprintf('ROC Curve (AUC = %.2f)', areaUnderCurve));

Algorithm Comparison and Optimizasion

Method Accuracy Advantages Limitations
Baseline CNN 82.3% Simple implemantation Requires extensive labeled data
GoogLeNet Transfer 91.7% Exploits pretrained features High computational demands
SqueezeNet 89.5% Compact model architecture Weaker feature representation
LSTM+CNN Hybrid 93.2% Captures temporal dependencies Extended training duration

Optimization Strategies:

  1. Data Augmentation: Incorporate random noise, temporal shifts, and amplitude scaling to expand training samples
  2. Attention Mechanisms: Integrate SE blocks into CNN architecture to emphasize discriminative features
  3. Multi-Scale Input: Combine wavelet coefficients across differrent scales (e.g., scales 1-32) for richer feature representation

Implementation Considerations

  1. Hardware Requirements: NVIDIA GPU recommended for accelerated training (Parallel Computing Toolbox required)
  2. Class Imbalance: Apply oversampling techniques to underrepresented classes such as CHF
  3. Model Deployment: Generate standalone applications using MATLAB Compiler for production environments

Tags: MATLAB ECG classification transfer learning Wavelet Transform Deep Learning

Posted on Fri, 22 May 2026 19:45:41 +0000 by ovisopa