Радиолокационная классификация целей с использованием машинного обучения и глубокого обучения

Этот пример показывает, как классифицировать радиолокационные возвраты как с помощью машинного, так и с помощью глубокого обучения. Подход машинного обучения использует редукцию данных вейвлет, связанное с машиной опорных векторов. Кроме того, проиллюстрированы два подхода глубокого обучения: передача обучения с помощью SqueezeNet и рекуррентная нейронная сеть Long Short-Term Memory (LSTM). Обратите внимание, что набор данных, используемый в этом примере, не требует расширенных методов, но рабочий процесс описан, потому что методы могут быть расширены до более сложных задач.

Введение

Классификация целей является важной функцией в современных радиолокационных системах. Этот пример использует машинное и глубокое обучение, чтобы классифицировать радиолокационные эхо-сигналы от цилиндра и конуса. Несмотря на то, что этот пример использует синтезированные выборки I/Q, рабочий процесс применим к реальным радарным возвратам.

Синтез RCS

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

Следующий код описывает шаблон цилиндра с радиусом 1 метр и высотой 10 метров. Рабочая частота радара составляет 850 МГц.

c = 3e8;
fc = 850e6;
[cylrcs,az,el] = rcscylinder(1,1,10,c,fc);
helperTargetRCSPatternPlot(az,el,cylrcs);

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

cyltgt = phased.BackscatterRadarTarget('PropagationSpeed',c,...
    'OperatingFrequency',fc,'AzimuthAngles',az,'ElevationAngles',el,'RCSPattern',cylrcs);

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

rng default;
N = 100;
az = 2*randn(1,N);                  
el = 2*randn(1,N);
cylrtn = cyltgt(ones(1,N),[az;el]);  


plot(mag2db(abs(cylrtn)));
xlabel('Time Index')
ylabel('Target Return (dB)');
title('Target Return for Cylinder');

Возврат конуса может быть сгенерирован аналогично. Чтобы создать набор обучающих данных, вышеописанный процесс повторяется для 5 произвольно выбранных радиусов цилиндра. В сложение для каждого радиуса моделируют 10 профилей движения путем изменения угла падения после 10 случайным образом сгенерированной синусоидальной кривой вокруг boresight. В каждом профиле движения 701 выборка, поэтому существует 701 на 50 выборки. Процесс повторяется для цели гидроцилиндра, что приводит к матрице обучающих данных 701 на 100 с 50 профилями цилиндров и 50 конусов. В тестовом наборе мы используем 25 цилиндров и 25 конусных профилей, чтобы создать набор обучающих данных 701 на 50. Из-за длительного времени расчета обучающие данные предварительно вычисляются и загружаются ниже.

load('RCSClassificationReturnsTraining');
load('RCSClassificationReturnsTest');

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

subplot(2,2,1)
plot(cylinderAspectAngle(1,:))
ylim([-90 90])
grid on
title('Cylinder Aspect Angle vs. Time'); xlabel('Time Index'); ylabel('Aspect Angle (degrees)');
subplot(2,2,3)
plot(RCSReturns.Cylinder_1); ylim([-50 50]);
grid on
title('Cylinder Return'); xlabel('Time Index'); ylabel('Target Return (dB)');
subplot(2,2,2)
plot(coneAspectAngle(1,:)); ylim([-90 90]); grid on;
title('Cone Aspect Angle vs. Time'); xlabel('Time Index'); ylabel('Aspect Angle (degrees)');
subplot(2,2,4);
plot(RCSReturns.Cone_1); ylim([-50 50]); grid on;
title('Cone Return'); xlabel('Time Index'); ylabel('Target Return (dB)');

Вейвлет

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

Ключевыми параметрами, которые нужно задать в сети вейвлет-рассеяния времени, являются шкала инварианта времени, количество вейвлет-преобразований и количество вейвлеты на октаву в каждой из банков вейвлет-фильтров. Во многих приложениях каскада двух блоков фильтров достаточно для достижения хорошей эффективности. В этом примере мы создадим сеть вейвлет-рассеяния времени с двумя группами фильтров: 4 вейвлет на октаву в первой группе фильтров и 2 вейвлет на октаву во второй группе фильтров. Шкала инвариации установлена на 701 выборку, длину данных.

sn = waveletScattering('SignalLength',701,'InvarianceScale',701,'QualityFactors',[4 2]);

Затем мы получаем преобразования рассеяния как обучающих, так и тестовых наборов.

sTrain = sn.featureMatrix(RCSReturns{:,:},'transform','log');
sTest = sn.featureMatrix(RCSReturnsTest{:,:},'transform','log');

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

TrainFeatures = squeeze(mean(sTrain,2))';
TestFeatures = squeeze(mean(sTest,2))';

Создайте метки для обучения и обучения

TrainLabels = repelem(categorical({'Cylinder','Cone'}),[50 50])';
TestLabels = repelem(categorical({'Cylinder','Cone'}),[25 25])';

Модель обучения

Подгонка модели машины опорных векторов с квадратичным ядром к функциям рассеяния и получение точности перекрестной валидации.

template = templateSVM('KernelFunction', 'polynomial', ...
    'PolynomialOrder', 2, ...
    'KernelScale', 'auto', ...
    'BoxConstraint', 1, ...
    'Standardize', true);
classificationSVM = fitcecoc(...
    TrainFeatures, ...
    TrainLabels, ...
    'Learners', template, ...
    'Coding', 'onevsone', ...
    'ClassNames', categorical({'Cylinder','Cone'}));
partitionedModel = crossval(classificationSVM, 'KFold', 5);
[validationPredictions, validationScores] = kfoldPredict(partitionedModel);
validationAccuracy = (1 - kfoldLoss(partitionedModel, 'LossFun', 'ClassifError'))*100
validationAccuracy = 100

Целевая классификация

Используя обученный SVM, классифицируйте функции рассеяния, полученные из тестового набора.

predLabels = predict(classificationSVM,TestFeatures);
accuracy = sum(predLabels == TestLabels )/numel(TestLabels)*100
accuracy = 100

Постройте график матрицы неточностей.

figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]);
ccDCNN = confusionchart(TestLabels,predLabels);
ccDCNN.Title = 'Confusion Chart';
ccDCNN.ColumnSummary = 'column-normalized';
ccDCNN.RowSummary = 'row-normalized';

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

Передача обучения с CNN

SqueezeNet - глубокая сверточная нейронная сеть (CNN), обученная для изображений в 1000 классах, как используется в ImageNet Large Scale Visual Recognition Challenge (ILSVRC). В этом примере мы повторно используем предварительно обученный SqueezeNet, чтобы классифицировать радиолокационные возвраты, принадлежащие к одному из двух классов.

Загрузка SqueezeNet.

snet = squeezenet;

SqueezeNet состоит из 68 слоев. Как и все DCNN, SqueezeNet каскадирует сверточные операторы с последующей нелинейностью и объединением или усреднением. SqueezeNet ожидает вход изображения размера 227 227 3, который можно увидеть со следующим кодом.

snet.Layers(1)
ans = 
  ImageInputLayer with properties:

                      Name: 'data'
                 InputSize: [227 227 3]

   Hyperparameters
          DataAugmentation: 'none'
             Normalization: 'zerocenter'
    NormalizationDimension: 'auto'
                      Mean: [1×1×3 single]

Кроме того, SqueezeNet настроен на распознавание 1000 различных классов, которые можно увидеть со следующим кодом.

snet.Layers(68)
ans = 
  ClassificationOutputLayer with properties:

            Name: 'ClassificationLayer_predictions'
         Classes: [1000×1 categorical]
    ClassWeights: 'none'
      OutputSize: 1000

   Hyperparameters
    LossFunction: 'crossentropyex'

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

Непрерывный Вейвлет преобразование

SqueezeNet предназначен для различения различий в изображениях и классификации результатов. Поэтому, в порядок использования SqueezeNet для классификации радиолокационных возвратов, мы должны преобразовать 1-D обратные временные ряды радара в изображение. Общим способом сделать это является использование частотно-временного представления (TFR). Существует ряд вариантов представления сигнала во временной частоте, и тот, который является наиболее подходящим, зависит от характеристик сигнала. Чтобы определить, какой TFR может быть подходящим для этой задачи, случайным образом выберите и постройте график нескольких радиолокационных возвратов из каждого класса.

rng default;
idxCylinder = randperm(50,2);
idxCone = randperm(50,2)+50;

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

cwt(RCSReturns{:,idxCylinder(1)},'VoicesPerOctave',8)

CWT одновременно захватывает как медленно изменяющиеся (низкочастотные) колебания, так и переходные явления. Контрастируйте CWT возврата цилиндра с одним от конусной цели.

cwt(RCSReturns{:,idxCone(2)},'VoicesPerOctave',8);

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

Подготовка изображений

Функция помощника, helpergenWaveletTFImg, получает CWT для каждого возврата радара, изменяет форму CWT так, чтобы она была совместима с SqueezeNet, и записывает CWT как файл jpeg. Чтобы запустить helpergenWaveletTFImg, выберите parentDir где у вас есть разрешение на запись. Этот пример использует tempdir, но вы можете использовать любую папку на вашем компьютере, где у вас есть разрешение на запись. Функция helper создает Training и Test установите папки в parentDir а также создание Cylinder и Cone подпапки в обеих Training и Test. Эти папки заполнены изображениями jpeg, которые будут использоваться в качестве входов для SqueezeNet.

parentDir = tempdir;
helpergenWaveletTFImg(parentDir,RCSReturns,RCSReturnsTest)
Generating Time-Frequency Representations...Please Wait
   Creating Cylinder Time-Frequency Representations ... Done
   Creating Cone Time-Frequency Representations ... Done
   Creating Cylinder Time-Frequency Representations ... Done
   Creating Cone Time-Frequency Representations ... Done

Теперь используйте imageDataStore для управления доступом к файлам из папок в порядок обучения SqueezeNet. Создайте хранилища данных для обучающих и тестовых данных.

trainingData= imageDatastore(fullfile(parentDir,'Training'), 'IncludeSubfolders', true,...
    'LabelSource', 'foldernames');
testData = imageDatastore(fullfile(parentDir,'Test'),'IncludeSubfolders',true,...
    'LabelSource','foldernames');

В порядок, чтобы использовать SqueezeNet с этой двоичной задачей классификации, нам нужно изменить пару слоев. Во-первых, мы изменяем последний обучаемый слой в SqueezeNet (слой 64), чтобы иметь то же количество сверток 1 на 1, что и наше новое количество классов 2.

lgraphSqueeze = layerGraph(snet);
convLayer = lgraphSqueeze.Layers(64);
numClasses = numel(categories(trainingData.Labels));
newLearnableLayer = convolution2dLayer(1,numClasses, ...
        'Name','binaryconv', ...
        'WeightLearnRateFactor',10, ...
        'BiasLearnRateFactor',10);
lgraphSqueeze = replaceLayer(lgraphSqueeze,convLayer.Name,newLearnableLayer);
classLayer = lgraphSqueeze.Layers(end);
newClassLayer = classificationLayer('Name','binary');
lgraphSqueeze = replaceLayer(lgraphSqueeze,classLayer.Name,newClassLayer);

Наконец, установите опции для переобучения SqueezeNet. Установите начальный темп обучения равный 1e-4, установите максимальное количество эпох равным 15, а размер мини-бата равным 10. Используйте стохастический градиентный спуск с импульсом.

ilr = 1e-4;
mxEpochs = 15;
mbSize =10;
opts = trainingOptions('sgdm', 'InitialLearnRate', ilr, ...
    'MaxEpochs',mxEpochs , 'MiniBatchSize',mbSize, ...
    'Plots', 'training-progress','ExecutionEnvironment','cpu');

Обучите сеть. Если у вас есть совместимый графический процессор, trainNetwork автоматически использует графический процессор, и обучение должно завершиться менее чем за одну минуту. Если у вас нет совместимого графического процессора, trainNetwork использует центральный процессор, и обучение должно занять около пяти минут. Время обучения варьируется в зависимости от ряда факторов. В этом случае обучение происходит на cpu путем установки ExecutionEnvironment параметр в cpu.

CWTnet = trainNetwork(trainingData,lgraphSqueeze,opts);
Initializing input data normalization.
|========================================================================================|
|  Epoch  |  Iteration  |  Time Elapsed  |  Mini-batch  |  Mini-batch  |  Base Learning  |
|         |             |   (hh:mm:ss)   |   Accuracy   |     Loss     |      Rate       |
|========================================================================================|
|       1 |           1 |       00:00:06 |       60.00% |       2.6639 |      1.0000e-04 |
|       5 |          50 |       00:01:08 |      100.00% |       0.0001 |      1.0000e-04 |
|      10 |         100 |       00:02:11 |      100.00% |       0.0002 |      1.0000e-04 |
|      15 |         150 |       00:03:12 |      100.00% |   2.2264e-05 |      1.0000e-04 |
|========================================================================================|

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

predictedLabels = classify(CWTnet,testData,'ExecutionEnvironment','cpu');
accuracy = sum(predictedLabels == testData.Labels)/50*100
accuracy = 100

Постройте график неточностей вместе с точностью и отзывом. В этом случае 100% тестовых выборок классифицируются правильно.

figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]);
ccDCNN = confusionchart(testData.Labels,predictedLabels);
ccDCNN.Title = 'Confusion Chart';
ccDCNN.ColumnSummary = 'column-normalized';
ccDCNN.RowSummary = 'row-normalized';

LSTM

В заключительном разделе этого примера описан рабочий процесс LSTM. Сначала определяются слои LSTM:

LSTMlayers = [ ...
    sequenceInputLayer(1)
    bilstmLayer(100,'OutputMode','last')
    fullyConnectedLayer(2)
    softmaxLayer
    classificationLayer
    ];
options = trainingOptions('adam', ...
    'MaxEpochs',30, ...
    'MiniBatchSize', 150, ...
    'InitialLearnRate', 0.01, ...
    'GradientThreshold', 1, ...
    'plots','training-progress', ...
    'Verbose',false,'ExecutionEnvironment','cpu');
trainLabels = repelem(categorical({'cylinder','cone'}),[50 50]);
trainLabels = trainLabels(:);
trainData = num2cell(table2array(RCSReturns)',2);
testData = num2cell(table2array(RCSReturnsTest)',2);
testLabels = repelem(categorical({'cylinder','cone'}),[25 25]);
testLabels = testLabels(:);
RNNnet = trainNetwork(trainData,trainLabels,LSTMlayers,options);

Точность для этой системы также нанесена.

predictedLabels = classify(RNNnet,testData,'ExecutionEnvironment','cpu');
accuracy = sum(predictedLabels == testLabels)/50*100
accuracy = 100

Заключение

Этот пример представляет рабочий процесс для выполнения классификации радиолокационных целей с использованием машинного и глубокого обучения методов. Хотя этот пример использовал синтезированные данные для обучения и проверки, он может быть легко расширен, чтобы включать реальные радиолокационные возвраты. Из-за характеристик сигнала вейвлета методов использовались как для машинного обучения, так и для подхода CNN.

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