exponenta event banner

Итеративный подход к созданию маркированных наборов сигналов с уменьшенными человеческими усилиями

В этом примере представлен итеративный глубокий основанный на обучении рабочий процесс для маркировки сигналов с уменьшенными усилиями по маркировке человека.

Маркировка сигнальных данных - утомительная и дорогостоящая задача, требующая больших человеческих усилий. Поиск способов сократить эти усилия может значительно ускорить разработку решений глубокого обучения для проблем обработки сигналов.

Рассмотрим задачу маркировки интересующих регионов в наборе данных сигнала. Первый подход состоит в маркировке всех данных вручную. Такой подход требует много времени и усилий. Альтернативный подход, изученный в этом примере, рассматривает процесс маркировки итеративно. На каждой итерации поднабор сигналов выбирается из немеченого набора данных и отправляется в заранее обученную глубокую сеть для автоматической маркировки. Человек-метчик проверяет полученные метки и исправляет неправильные метки. Проверенные маркированные сигналы добавляются к набору обучающих данных для переподготовки глубокой сети с расширенными обучающими данными.

На каждой итерации человек все еще должен посещать и исследовать все сигналы, помеченные сетью. Однако задача меняется с сигналов маркировки с нуля на исправление неточных меток, генерируемых надежной сетью. Эта последняя задача требует значительно меньших усилий по маркировке человека. На каждой новой итерации сеть обучается все большему количеству данных, что приводит к повышению производительности прогнозирования и маркировки сети. Следовательно, при каждой итерации для исправления меток требуется все меньшее и меньшее вмешательство человека.

Этот пример следует процедуре, представленной в Waveform Segmentation Using Deep Learning для обучения сети долговременной кратковременной памяти (LSTM), которая может классифицировать выборки сигналов ЭКГ как принадлежащие одной из трех областей, представляющих интерес.

Данные

В этом примере рассматривается маркировка областей сигналов ЭКГ с использованием данных, общедоступных в базе данных QT [1] [2]. Данные состоят примерно из 15 минут записей ЭКГ от в общей сложности 105 пациентов. Чтобы получить каждую запись, экзаменаторы разместили два электрода в разных местах на груди пациента, что привело к двухканальному сигналу. База данных предоставляет метки области сигнала, генерируемые автоматизированной экспертной системой [3]. Метки соответствуют местоположениям P-волн, T-волн и комплексных областей QRS в измерениях ЭКГ. Каждый канал из 105 двухканальных ЭКГ-сигналов был помечен независимо автоматизированной экспертной системой и обрабатывался независимо для общего количества 210 ЭКГ-сигналов, которые были сохранены вместе с метками области в 210 MAT-файлах. Файлы доступны в следующем расположении: https://www.mathworks.com/supportfiles/SPT/data/QTDatabaseECGData1.zip.

Загрузите набор данных с помощью downloadSupportFile функция.

% Download the data
datasetZipFile = matlab.internal.examples.downloadSupportFile('SPT',fullfile('data','QTDatabaseECGData1.zip'));
datasetFolder = fullfile(fileparts(datasetZipFile),'QTDataset');
if ~exist(datasetFolder,'dir')     
     unzip(datasetZipFile,fileparts(datasetZipFile));
end

unzip операция создает datasetFolder папка с 210 MAT-файлами в ней. Каждый файл содержит сигнал ЭКГ в переменной ecgSignal и таблица меток областей в переменной signalRegionLabels. Каждый файл также содержит частоту дискретизации сигнала в переменной Fs. В этом примере все сигналы имеют частоту дискретизации 250 Гц.

Создайте хранилище данных сигнала для доступа к данным в файлах. Укажите имена сигнальных переменных, которые требуется прочитать из каждого файла с помощью SignalVariableNames параметр.

sds = signalDatastore(datasetFolder,'SignalVariableNames',["ecgSignal","signalRegionLabels"])
sds = 
  signalDatastore with properties:

                       Files:{
                             ' .../MATLAB/Examples/R2021b/supportfiles/SPT/data/QTDataset/ecg1.mat';
                             ' .../MATLAB/Examples/R2021b/supportfiles/SPT/data/QTDataset/ecg10.mat';
                             ' .../MATLAB/Examples/R2021b/supportfiles/SPT/data/QTDataset/ecg100.mat'
                              ... and 207 more
                             }
                     Folders: {'/home/fboucher/Documents/MATLAB/Examples/R2021b/supportfiles/SPT/data/QTDataset'}
    AlternateFileSystemRoots: [0×0 string]
                    ReadSize: 1
         SignalVariableNames: ["ecgSignal"    "signalRegionLabels"]
       ReadOutputOrientation: "column"

Хранилище данных возвращает двухэлементный массив ячеек с сигналом ЭКГ и таблицей меток областей при каждом вызове read функция. Используйте preview функция хранилища данных, чтобы видеть, что содержание первого файла представляет собой 225000 выборок длинного сигнала ЭКГ и таблицу, содержащую 3385 меток области.

data = preview(sds)
data=2×1 cell array
    {225000×1 double}
    {  3385×2 table }

Посмотрите на первые несколько строк таблицы меток области и убедитесь, что каждая строка содержит индексы ограничения области и значение класса области (P, T или QRS).

head(data{2})
ans=8×2 table
    ROILimits     Value
    __________    _____

     83    117     P   
    130    153     QRS 
    201    246     T   
    285    319     P   
    332    357     QRS 
    412    457     T   
    477    507     P   
    524    547     QRS 

Визуализация меток для первых 1000 образцов с помощью signalMask объект.

MGroundTruth = signalMask(data{2});
plotsigroi(MGroundTruth,data{1}(1:1000))

Преобразуйте области, представляющие интерес, в категориальную последовательность, чтобы иметь возможность обучать глубокую сеть выполнять классификацию последовательности к последовательности. Используйте transform функция хранилища данных для применения преобразования при считывании данных сигнала с диска.

numFiles = numel(sds.Files);
sds = transform(sds,@getmask);

Изменение размера (разделение) сигналов и меток для получения множества сегментов длиной 5000 выборок и преобразование каждого сегмента ЭКГ во временную частотную область с использованием синхрокрещенного преобразования Фурье (FSST).

sds = transform(sds,@resizeData);
sdsFSST = transform(sds,@(x,fs)extractFSSTFeatures(x,250));

Используйте 70% файлов для обучения и 30% для тестирования. Перетасуйте набор данных так, чтобы обучающие и тестовые сигналы выбирались случайным образом.

rng default
[trainIdx,~,testIdx] = dividerand(numFiles,0.7,0,0.3);

trainDs = subset(sds,trainIdx); % resized 5000 sample signals and labels
trainDsFSST = subset(sdsFSST,trainIdx); % FSST-transformed signals and labels

testDsFSST = subset(sdsFSST,testIdx);

Считывайте все данные в память с помощью метода readall хранилищ данных. Это действие будет считывать каждый сигнал ЭКГ и применять все преобразования, описанные выше, чтобы вернуть множество сегментов ЭКГ, преобразованных синхроквизом Фурье. Используйте UseParallel возможность параллельного преобразования набора данных с использованием доступных процессоров на компьютере при наличии ™ Parallel Computing Toolbox.

% Get FSST-transformed signals
ecgFSSTData = readall(trainDsFSST,UseParallel=true);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 8).
testFSSTData = readall(testDsFSST,UseParallel=true);

ecgFSST = ecgFSSTData(:,1);
ecgLabels = ecgFSSTData(:,2);

testECGFSST = testFSSTData(:,1);
testLabels = testFSSTData(:,2);

% Get time domain signal segments so that we can plot some labeling results
ecgData = readall(trainDs);
ecgSignals = ecgData(:,1);

Этот пример показывает, что можно уменьшить усилия человека, связанные с маркировкой сигнала, путем итеративного обучения глубокой сети. При каждой итерации:

  1. Сеть маркирует подмножество немаркированных кадров данных с помощью ранее маркированных кадров.

  2. Человек-маркировщик исправляет любые ошибки маркировки вручную.

  3. Скорректированная маркировка добавляется к ранее помеченным рамкам.

  4. Расширенный набор маркированных сигналов используется для обучения сети следующей итерации.

Для количественного сравнения смоделируйте два сценария:

  • Для базового сценария, в котором человек маркирует весь набор данных с нуля, обучайте сеть, используя полный маркированный ecgFrames набор.

  • Для второго сценария сделайте вид, что ecgFrames данные не помечены и помечены с помощью итеративного метода

Производительность прогнозирования с использованием полностью маркированного набора данных ЭКГ

Построить сеть BiLSTM и обучить ее с полной маркировкой ecgFrames установка для получения верхней границы производительности прогнозирования. Как упоминалось выше, этот подход требует грубой маркировки всего набора данных и, следовательно, наибольших усилий по маркировке человека. Обучение сети с маркировкой ecgFrames и вычисляют точность прогнозирования на наборе тестовых данных.

Сетевая архитектура

Создание сети BiLSTM с использованием уровней глубокого обучения.

  • Укажите sequenceInputLayer с размером в качестве количества признаков в FSST сигналов, который является общим количеством выборок частотной области (40 в этом примере).

  • Укажите bilstmLayer с 200 скрытыми узлами и установите OutputMode кому sequence поскольку каждый образец сигнала имеет метку.

  • Укажите fullyConnectedLayer с размером выхода 4, соответствующим четырем категориям, P wave, QRS complex, T wave и N/A.

  • Добавить softmaxLayer и classificationLayer для вывода оценочных меток.

% Training with the full emulated unlabeled data set
layers = [ ...
    sequenceInputLayer(size(ecgFSST{1},1))
    bilstmLayer(200,'OutputMode','sequence')
    fullyConnectedLayer(4)
    softmaxLayer
    classificationLayer];

Использовать traningOptions чтобы указать решатель оптимизации и гиперпараметры для обучения сети. В этом примере используется оптимизатор ADAM с размером мини-партии 50. Обучение сети с помощью ЦП или графического процессора. Для использования графического процессора требуется Toolbox™ параллельных вычислений. Сведения о том, какие графические процессоры поддерживаются, см. в разделе Поддержка графических процессоров по выпуску (Панель инструментов параллельных вычислений). Сведения о других параметрах см. в разделе trainingOptions (инструментарий глубокого обучения). В этом примере используется графический процессор для обучения с использованием 'ExecutionEnvironmentПара имя-значение.

options = trainingOptions('adam', ...
    'MaxEpochs',10, ...
    'MiniBatchSize',50, ...
    'ExecutionEnvironment','gpu', ...
    'InitialLearnRate',0.01, ...
    'LearnRateDropPeriod',6, ...
    'LearnRateSchedule','piecewise', ...
    'GradientThreshold',1, ...
    'Shuffle','every-epoch',...
    'Plots','training-progress',...
    'Verbose',0,...
    'DispatchInBackground',true);

Обучение сети с помощью полностью маркированного ecgFrames набор данных.

baselineNet = trainNetwork(ecgFSST,ecgLabels,layers,options);

Классифицируйте тестовые кадры с использованием обученной сети и вычислите среднюю точность прогнозирования. Точность базового прогноза составляет около 90%.

predictLabelsAll = classify(baselineNet,testECGFSST,'MiniBatchSize',50);
accuracyAll = mean(cellfun(@(x,y)mean(x==y),predictLabelsAll,testLabels));
fprintf('The baseline prediction accuracy is %2.1f%%.\n',accuracyAll*100);
The baseline prediction accuracy is 89.9%.

Итеративная маркировка человеком в цикле

Чтобы уменьшить усилия маркировки, попробуйте итеративный подход: Сделать вид, что ecgFrames набор данных первоначально не помечен, и данные помечены вручную. В действительности в примере используются метки истинности основания, предоставляемые набором данных.

Обучение начальной сети

Начните с выбора 25 кадров из ecgFrames установка и маркировка их вручную. Обучите сеть BiLSTM с этим начальным набором меток, чтобы она служила в качестве начального шага итеративного процесса.

numInitFrames = 25;

currentTrainingSet = ecgFSST(1:numInitFrames,1);
currentTrainingLabels = ecgLabels(1:numInitFrames);

Установите параметры обучения, чтобы иметь больше периодов обучения и меньший размер мини-партии, поскольку в исходном наборе данных обучения имеется только 25 кадров.

options = trainingOptions('adam', ...
    'MaxEpochs',20, ...
    'MiniBatchSize',5, ...
    'ExecutionEnvironment','gpu', ...
    'InitialLearnRate',0.01, ...
    'LearnRateDropPeriod',6, ...
    'LearnRateSchedule','piecewise', ...
    'GradientThreshold',1, ...
    'Shuffle','every-epoch', ...
    'Plots','none',...
    'Verbose',0,...
    'DispatchInBackground',true);

Обучите сеть BiLSTM начальному набору обучающих данных и спрогнозируйте метки, используя тот же набор тестовых данных, который использовался для установления базового уровня производительности. Точность прогнозирования этой исходной сети составляет около 40%.

initNet = trainNetwork(currentTrainingSet,currentTrainingLabels,layers,options);
initPrediction = classify(initNet,testECGFSST,'MiniBatchSize',50); 
initAccuracy = mean(cellfun(@(x,y)mean(x==y),initPrediction,testLabels));
fprintf('The prediction accuracy is %2.1f%%.\n',initAccuracy*100);
The prediction accuracy is 43.7%.

Маркировка

На следующем шаге выберите 200 новых кадров данных из ecgFrames установить и подать их в подготовленную сеть, initNet, для автоматической маркировки сигналов.

iteration = 1;
% Number of frames to label at each iteration
numFrames = 200; 
% Select the next set of frames to label
indexNext = numInitFrames+1:numInitFrames+numFrames;
% Use classify to label the new frames
currentPrediction = classify(initNet,ecgFSST(indexNext),'MiniBatchSize',50);

Оцените результаты маркировки, сгенерированные сетью, и сравните их с достоверностью данных. Найдите индексы сигналов ЭКГ, которые получили наилучшую и наихудшую производительность в этой сети.

errs = cellfun(@(x,y)sum(x~=y),ecgLabels(indexNext),currentPrediction);
[~,bestIndex] = min(errs);
[~,worstIndex] = max(errs);

Для наилучшего сценария постройте график первых 750 образцов, наложенных метками «земля-истина» и метками, предсказанными сетью.

ecgSignalOfInterest = ecgSignals{indexNext(bestIndex)};
groundTruthLabels = ecgLabels{indexNext(bestIndex)};
predictedLabels = currentPrediction{bestIndex};

MGroundTruth = signalMask(groundTruthLabels);
figure
plotsigroi(MGroundTruth,ecgSignalOfInterest(1:750))
title('Ground Truth - best-case scenario')

MPredicted = signalMask(predictedLabels);
figure
plotsigroi(MPredicted,ecgSignalOfInterest(1:750))
title('Labeling by Network - best-case scenario')

Сеть проделала хорошую работу по маркировке этого кадра. В результате человек, проверяющий результаты сети, может исправить предсказанные метки с небольшими усилиями.

Однако бывают случаи, когда производительность маркировки сети не столь сильна. Постройте график результатов, полученных в наихудшем сценарии.

ecgSignalOfInterest = ecgSignals{indexNext(worstIndex)};
groundTruthLabels = ecgLabels{indexNext(worstIndex)};
predictedLabels = currentPrediction{worstIndex};

MGroundTruth = signalMask(groundTruthLabels);
figure
plotsigroi(MGroundTruth,ecgSignalOfInterest(1:750))
title('Ground Truth - worst-case scenario')

MPredicted = signalMask(predictedLabels);
figure
plotsigroi(MPredicted,ecgSignalOfInterest(1:750))
title('Labeling by Network - worst-case scenario')

Производительность сети по этому сигналу не так хороша. В этом случае человек-маркировщик должен внести несколько поправок в прогнозируемые метки.

Чтобы количественно оценить усилия по коррекции для 200 кадров данных, вычислите частоту ошибок маркировки сети и среднее количество выборок на кадр, которые должны быть скорректированы человеком-метчиком.

numSamplesPerFrame = 5000;
networkLabelingErrorRate(iteration) = 1-mean(cellfun(@(x,y)mean(x==y),currentPrediction,ecgLabels(indexNext)));
averageNumOfCorrectionsPerFrame(iteration) = networkLabelingErrorRate(iteration) * numSamplesPerFrame;
fprintf('The average number of corrections per frame is %2.1f.\n',averageNumOfCorrectionsPerFrame(iteration));
The average number of corrections per frame is 2211.3.

Для первой итерации существует в среднем около 2200 выборок на кадр, которые должны быть скорректированы человеком. Скорректированные выборки на кадр являются удобной метрикой для отображения усилий человека. Однако следует отметить, что на практике человек-маркировщик не обязан корректировать этикетку каждого образца. Вместо этого человек-маркировщик должен только расширить или сократить границы региона.

В конце первой итерации человек осмотрит 200 кадров и изменит любую метку с неправильными значениями. С помощью сети и человека-этикетировщика кадры данных имеют правильные метки в конце итерации.

На следующей итерации 200 вновь помеченных кадров могут быть добавлены в currentTrainingSet для переподготовки сети и повторения итерации маркировки. Эта диаграмма иллюстрирует рабочий процесс в каждой итерации после первой итерации.

Повторить итерации маркировки

Расширьте обучающий набор, добавив вновь исправленные маркированные кадры, выберите еще 200 кадров данных для маркировки и повторяйте итерацию маркировки до тех пор, пока производительность не будет удовлетворительной.

% Include the initial training set and the 200 newly labeled data frames
maxIter = 15;
indexTraining = 1:numInitFrames+numFrames;

networkAccuracy = zeros(1,15);
networkAccuracy(iteration) = initAccuracy;

options = trainingOptions('adam', ...
    'MaxEpochs',20, ...
    'MiniBatchSize',50, ...
    'ExecutionEnvironment','gpu', ...
    'InitialLearnRate',0.01, ...
    'LearnRateDropPeriod',6, ...
    'LearnRateSchedule','piecewise', ...
    'GradientThreshold',1, ...
    'Shuffle','every-epoch', ...
    'Plots','none', ...
    'Verbose',0);

for iteration = 2:maxIter
    % Extended training data set
    currentTrainingSet = ecgFSST(indexTraining,1);    
    % Emulate human correction by assigning ground-truth labels to the
    % extended training set
    currentTrainingLabels = ecgLabels(indexTraining);

    % Train network with extended training set
    currentNet = trainNetwork(currentTrainingSet,currentTrainingLabels,layers,options);
    
    % Predict labels for the test data set and calculate the accuracy to
    % compare to baseline performance
    currentTestSetPrediction = classify(currentNet,testECGFSST,'MiniBatchSize',50);
    networkAccuracy(iteration) = mean(cellfun(@(x,y)mean(x==y),currentTestSetPrediction,testLabels));
    
    % Get another numFrames data frames for human labeler
    indexNext = indexTraining(end)+1:indexTraining(end)+numFrames;
    
    % Measure average number of human corrections per frame in this iteration
    currentPrediction = classify(currentNet,ecgFSST(indexNext),'MiniBatchSize',50);
    networkLabelingErrorRate(iteration) = 1-mean(cellfun(@(x,y)mean(x==y),currentPrediction,ecgLabels(indexNext)));
    averageNumOfCorrectionsPerFrame(iteration) = networkLabelingErrorRate(iteration) * numSamplesPerFrame;
    
    indexTraining = 1:indexNext(end);
end

Производительность маркировки

После 15 итераций маркировки имеется 2825 кадров данных в currentTrainingSet, что соответствует примерно половине из 6543 кадров данных, содержащихся в полном ecgDataset набор. Точность прогнозирования сети, обученной с помощью 2825 кадров, уже очень близка к базовой точности.

accuDiff = accuracyAll-networkAccuracy(end);
fprintf('The accuracy difference is %2.1f%%.\n',accuDiff*100);
The accuracy difference is 2.1%.

Постройте график точности сетевого прогнозирования для набора тестовых данных относительно размера набора обучающих данных на каждой итерации. Отображение верхней границы точности, полученной с помощью полностью помеченного набора данных. По мере проверки достоверности большего количества кадров данных точность прогнозирования в сети повышается.

figure
examinedDataSize = 25:200:2825;
plot(examinedDataSize,networkAccuracy,'*-')
hold on
% Prediction accuracy upper bound
plot(examinedDataSize,ones(1,15)*accuracyAll,'r--')
grid on
xlabel('Training set size')
title('Accuracy for the test data set')
xlim([25 2825])
legend('Labeling Network','Upper Bound','Location','southeast')

По мере выполнения итераций среднее число человеческих корректировок на кадр уменьшается по мере увеличения размера обучающего набора данных. Поскольку больше кадров данных проверяются и используются для обучения сети, для исправления меток выбранных кадров требуется меньше человеческих усилий.

figure
plot(examinedDataSize,averageNumOfCorrectionsPerFrame,'*-')
grid on
xlabel('Training set size')
title('Average number of human corrections per frame')
xlim([25 2825])

На протяжении всех 15 итераций маркировки в среднем около 700 выборок сигнала на кадр требовали человеческих поправок. Как упоминалось ранее, на практике человек корректирует меченые области путем расширения или укорочения пределов области, а не путем изменения отдельных меток образца.

fprintf('The average number of corrections per frame is %2.1f.\n',mean(averageNumOfCorrectionsPerFrame));
The average number of corrections per frame is 716.9.

Заключение

Этот пример показал, что маркировка только половины набора данных ЭКГ позволяет глубокой сети достигать точности прогнозирования, аналогичной той, которая достигается той же сетью при обучении с помощью полностью маркированного набора данных. При предлагаемой последовательности операций итеративной маркировки человек должен просматривать только половину набора данных и корректировать в среднем 700 выборок сигнала на кадр. С другой стороны, маркировка грубой силы требует просмотра каждого кадра в наборе данных и маркировки всех его образцов с нуля.

Ссылки

[1] Голдбергер, Ари Л., Луис А. Н. Амарал, Леон Гласс, Джеффери М. Хаусдорфф, Пламен Ч. Иванов, Роджер Г. Марк, Джозеф Э. Миет, Джордж Б. Муди, Чон-Кан Пэн и Х. Эугал «PhysioBank, PhysioToolkit и PhysioNet: компоненты нового исследовательского ресурса для сложных физиологических сигналов». Циркуляция. Том 101, номер 23, 2000, стр. e215-e220. [Электронные страницы тиража; http://circ.ahajournals.org/content/101/23/e215.full].

[2] Лагуна, Пабло, Роджер Г. Марк, Ари Л. Голдбергер и Джордж Б. Муди. «База данных для оценки алгоритмов измерения QT и других интервалов формы сигнала в ЭКГ». Компьютеры в кардиологии. Vol.24, 1997, стр 673–676.

[3] Лагуна, Пабло, Раймон Джане и Пер Каминал. «Автоматическое обнаружение границ волн в многолучевых сигналах ЭКГ: валидация с базой данных CSE». Компьютеры и биомедицинские исследования. Том 27, номер 1, 1994, стр. 45-60.

См. также

|