exponenta event banner

Тестирование глубокой нейронной сети с захваченными данными для обнаружения олицетворения маршрутизатора WLAN

В этом примере показано, как обучить радиочастотную (RF) сверточную нейронную сеть (CNN) снятым данным. Вы регистрируете кадры радиомаяка беспроводной локальной сети (WLAN) от реальных маршрутизаторов, используя программно-определяемое радио (SDR). Вы программируете второй SDR для передачи неизвестных кадров маяка и их захвата. Вы тренируете CNN, используя эти захваченные сигналы. Затем программируется программно-определяемое радио (SDR) в качестве олицетворения маршрутизатора, которое передает сигналы маяка с адресом управления доступом к среде (MAC) одного из известных маршрутизаторов и использует CNN для идентификации его как олицетворения.

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

Поезд с захваченными данными

Сбор набора данных из кадров радиомаяка 802.11a/g/n/ac OFDM без высокой пропускной способности (не HT) от реальных маршрутизаторов WLAN. Как описано в примере «Design a Deep Neural Network with Simulated Data to Detect WLAN Router Impersonation» (Проектирование глубокой нейронной сети с моделируемыми данными для обнаружения олицетворения маршрутизатора WLAN), во избежание зависимости данных в качестве обучающих блоков используется только поле Long training Field (L-LT), присутствующее training field, присутствующее в преамбуле.

В этом примере данные были собраны с использованием сценария, показанного на следующем рисунке. Наблюдатель - стационарное радио ADALM-PLUTO. Известные данные маршрутизатора были собраны следующим образом:

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

  2. Прием кадра маяка

  3. Извлеките сигнал L-LTF

  4. Декодирование MAC-адреса, используемого в качестве метки

  5. Сохранить сигнал L-LTF вместе с его меткой

  6. Повторите шаги 2-5 для сбора numFramesPerRouter кадры из numKnownRouters маршрутизаторы.

Неизвестные кадры маяка маршрутизатора моделируются с использованием мобильного радиоблока ADALM-PLUTO в качестве передатчика. Это радио многократно передает кадры маяка со случайным MAC-адресом. Неизвестные данные маршрутизатора были собраны следующим образом:

  1. Формирование кадров маяка со случайным MAC-адресом

  2. Начать повторную передачу кадров маяка с использованием радиоблока ADALM-PLUTO

  3. Собраться NUMFRAMES кадры маяка

  4. Извлеките сигнал L-LTF

  5. Сохраните кадры L-LTF с меткой «Неизвестно»

  6. Переместить радиоблок в другое место

  7. Повторите шаги 3-6 для сбора данных из NUMLOC местоположения

Этот объединенный набор данных известных и неизвестных маршрутизаторов используется для обучения той же модели DL, что и в примере «Design a Deep Neural Network with Simulated Data to Detection WLAN Router Impersonation».

В этом примере загружаются обучающие данные и обучаемая сеть из https://www.mathworks.com/supportfiles/spc/RFFingerprinting/RFFingerprintingCapturedData.tar.gz. Если подключение к Интернету отсутствует, можно загрузить файл вручную на компьютер, подключенный к Интернету, и сохранить его в том же каталоге, что и файлы текущего примера. Из соображений конфиденциальности MAC-адреса были анонимизированы в загруженных данных. Чтобы реплицировать результаты этого примера, соберите собственные данные, как описано в Приложении: Сбор данных известного и неизвестного маршрутизатора.

rfFingerprintingDownloadData('captured')
Starting download of data files from:
	https://www.mathworks.com/supportfiles/spc/RFFingerprinting/RFFingerprintingCapturedData.tar.gz
Download and extracting files done

Для быстрого запуска этого примера используйте загруженную предварительно обученную сеть. Чтобы обучить сеть на компьютере, выберите опцию «Обучить сеть сейчас» (т. е. установить trainNow true). Обучение этой сети занимает около 5 минут с помощью графического процессора Nvidia (R) Titan Xp. Обучение на CPU может привести к очень длительной продолжительности обучения.

trainNow = false;  %#ok<*UNRCH> 

В этом примере используются данные от четырех известных маршрутизаторов. Набор данных содержит 3600 кадров на маршрутизатор, где 90% используется в качестве учебных кадров, а 10% - в качестве тестовых кадров.

numKnownRouters = 4;
numFramesPerRouter = 3600;
numTrainingFramesPerRouter = numFramesPerRouter * 0.9;
numTestFramesPerRouter = numFramesPerRouter * 0.1;
frameLength = 160;

Предварительная обработка известных и неизвестных данных маршрутизатора

Разделите собранные комплексные данные основной полосы на синфазные и квадратурные компоненты и преобразуйте их в матрицу 2 x frameLength x 1 x numFramesPerRouter * numKnureRouters. Повторите тот же процесс для неизвестных данных маршрутизатора. В следующем коде используются ранее собранные и предварительно обработанные данные. Для использования собственных данных сначала соберите данные, как описано в Приложении: Сбор данных известного и неизвестного маршрутизатора. Копирование новых файлов данных с именемrfFingerprintingCapturedDataUser.mat и rfFingerprintingCapturedUnknownFramesUser.mat в тот же каталог, что и в этом примере. Затем обновите load для загрузки этих файлов.

if trainNow
  % Load known router data
  load('rfFingerprintingCapturedData.mat')
  
  % Create label vectors
  yTrain = repelem(MACAddresses, numTrainingFramesPerRouter);
  yTest = repelem(MACAddresses, numTestFramesPerRouter);
  
  % Separate between I and Q
  numTrainingSamples = numTrainingFramesPerRouter*numKnownRouters*frameLength;
  xTrainingFrames = xTrainingFrames(1:numTrainingSamples,1);
  xTrainingFrames = [real(xTrainingFrames), imag(xTrainingFrames)];
  numTestSamples = numTestFramesPerRouter*numKnownRouters*frameLength;
  xTestFrames = xTestFrames(1:numTestSamples,1);
  xTestFrames = [real(xTestFrames), imag(xTestFrames)];
  
  % Reshape dataset into an 2 x frameLength x 1 x numTrainingFramesPerRouter*numKnownRouters matrix
  xTrainingFrames = permute(...
    reshape(xTrainingFrames,[frameLength,numTrainingFramesPerRouter*numKnownRouters, 2, 1]),...
    [1 3 4 2]);
  
  % Reshape dataset into an 2 x frameLength x 1 x numTestFramesPerRouter*numKnownRouters matrix
  xTestFrames = permute(...
    reshape(xTestFrames,[frameLength,numTestFramesPerRouter*numKnownRouters, 2, 1]),...
    [1 3 4 2]);
  
  % Load unknown router data
  load('rfFingerprintingCapturedUnknownFrames.mat')
  
  % Number of training units
  numUnknownFrames = size(unknownFrames, 4);
  
  % Split data into 90% training and 10% test
  numUnknownTrainingFrames = floor(numUnknownFrames*0.9);
  numUnknownTest = numUnknownFrames - numUnknownTrainingFrames;
  
  % Add ADALM-PLUTO data into training and test datasets
  xTrainingFrames(:,:,:,(1:numUnknownTrainingFrames) + numTrainingFramesPerRouter*numKnownRouters) ...
    = unknownFrames(:,:,:, 1:numUnknownTrainingFrames);
  xTestFrames(:,:,:,(1:numUnknownTest) + numTestFramesPerRouter*numKnownRouters) ...
    = unknownFrames(:,:,:, (1:numUnknownTest) + numUnknownTrainingFrames);
  
  % Shuffle data
  vr = randperm(numKnownRouters*numTrainingFramesPerRouter+numUnknownTrainingFrames);
  xTrainingFrames = xTrainingFrames(:,:,:,vr);
  
  % Add "unknown" label and shuffle
  yTrain = [yTrain, repmat("Unknown", [1, numUnknownTrainingFrames])];
  yTrain = categorical(yTrain(vr));
  
  yTest = [yTest, repmat("Unknown", [1, numUnknownTest])];
  yTest = categorical(yTest);
end

Тренировать CNN

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

poolSize = [2 1];
strideSize = [2 1];
% Create network architecture
layers = [
  imageInputLayer([frameLength 2 1], 'Normalization', 'none', 'Name', 'Input Layer')
  
  convolution2dLayer([7 1], 50, 'Padding', [1 0], 'Name', 'CNN1')
  batchNormalizationLayer('Name', 'BN1')
  leakyReluLayer('Name', 'LeakyReLu1')
  maxPooling2dLayer(poolSize, 'Stride', strideSize, 'Name', 'MaxPool1')
  
  convolution2dLayer([7 2], 50, 'Padding', [1 0], 'Name', 'CNN2')
  batchNormalizationLayer('Name', 'BN2')
  leakyReluLayer('Name', 'LeakyReLu2')
  maxPooling2dLayer(poolSize, 'Stride', strideSize, 'Name', 'MaxPool2')
  
  fullyConnectedLayer(256, 'Name', 'FC1')
  leakyReluLayer('Name', 'LeakyReLu3')
  dropoutLayer(0.5, 'Name', 'DropOut1')
  
  fullyConnectedLayer(80, 'Name', 'FC2')
  leakyReluLayer('Name', 'LeakyReLu4')
  dropoutLayer(0.5, 'Name', 'DropOut2')
  
  fullyConnectedLayer(numKnownRouters+1, 'Name', 'FC3')
  softmaxLayer('Name', 'SoftMax')
  classificationLayer('Name', 'Output')
  ];

Настройте параметры обучения для использования оптимизатора ADAM с размером мини-пакета 128. Используйте тестовые кадры для проверки, поскольку оптимизация гиперпараметров была выполнена в [1].

По умолчанию ExecutionEnvironment имеет значение 'auto', который использует графический процессор для обучения, если он доступен. В противном случае trainNetwork (Deep Learning Toolbox) использует ЦП для обучения. Чтобы явно задать среду выполнения, установите ExecutionEnvironment одному из 'cpu', 'gpu', 'multi-gpu', или 'parallel'. Выбор 'cpu' может привести к очень длительной продолжительности обучения.

if trainNow
  miniBatchSize = 128;
  
  % Training options
  options = trainingOptions('adam', ...
    'MaxEpochs',30, ...
    'ValidationData',{xTestFrames, yTest}, ...
    'ValidationFrequency',floor((numTrainingFramesPerRouter*numKnownRouters + numUnknownTrainingFrames)/miniBatchSize/3), ...
    'Verbose',false, ...
    'L2Regularization', 0.0001, ...
    'InitialLearnRate', 0.0001, ...
    'MiniBatchSize', miniBatchSize, ...
    'ValidationPatience', 5, ...
    'Plots','training-progress', ...
    'Shuffle', 'every-epoch');
  
  % Train the network
  capturedDataNet = trainNetwork(xTrainingFrames, yTrain, layers, options);
else
  load('rfFingerprintingCapturedDataTrainedNN.mat','capturedDataNet','xTestFrames','yTest','MACAddresses')
end

На следующем графике показан обучающий прогресс работы сети на компьютере с одним GPU Nvidia Titan Xp, где сеть сошлась примерно за 10 эпох почти до 100% точности. Окончательная точность сети - 100%.

Создайте матрицу путаницы.

figure
yTestPred = classify(capturedDataNet,xTestFrames);
cm = confusionchart(yTest, yTestPred);
cm.Title = 'Confusion Matrix for Test Data';
cm.RowSummary = 'row-normalized';

Тестирование с использованием SDR

Проверьте работоспособность обученной сети на классе «Неизвестно». Формирование кадров маяка с MAC-адресами известных маршрутизаторов и одного неизвестного маршрутизатора. Передавайте эти кадры с помощью радиоблока ADALM-PLUTO и принимайте с помощью другого радиоблока ADALM-PLUTO. Поскольку нарушения канала и РЧ, созданные между этими двумя радиоприемниками, отличаются от нарушений, созданных между реальными маршрутизаторами и наблюдателем, нейронная сеть должна классифицировать все принятые сигналы как «неизвестные». Если принятый MAC-адрес известен, то система объявляет источник в качестве олицетворения маршрутизатора. Если принятый MAC-адрес неизвестен, то система объявляет источник неизвестным маршрутизатором. Для выполнения этого теста необходимо два радиоприемника ADALM-PLUTO для передачи и приема. Кроме того, необходимо установить пакет поддержки Communication Toolbox для ADALM-PLUTO Radio.

Генерация формы сигнала

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

chanBW='CBW20';     % Channel Bandwidth
osf = 2;            % Oversampling Factor
frameLength=160;    % Frame Length in samples
% Create Beacon frame-body configuration object
frameBodyConfig = wlanMACManagementConfig;

% Create Beacon frame configuration object
beaconFrameConfig = wlanMACFrameConfig('FrameType', 'Beacon');
beaconFrameConfig.ManagementConfig = frameBodyConfig;

% Create interpolation and decimation objects
decimator = dsp.FIRDecimator('DecimationFactor',osf);

% Save known MAC addresses
knownMACAddresses = MACAddresses;
MACAddressesToSimulate = [MACAddresses, "ABCDEFABCDEF"];

% Create WLAN waveform with the MAC addresses of known routers and an
% unknown router
txWaveform = zeros(1540,5);
for i = 1:length(MACAddressesToSimulate)
  
  % Set MAC Address
  beaconFrameConfig.Address2 = MACAddressesToSimulate(i);
  
  % Generate Beacon frame bits
  [beacon, mpduLength] = wlanMACFrame(beaconFrameConfig, 'OutputFormat', 'bits');
  
  nonHTcfg = wlanNonHTConfig(...
    'ChannelBandwidth', chanBW,...
    "MCS", 1,...
    "PSDULength", mpduLength);
  txWaveform(:,i) = [wlanWaveformGenerator(beacon, nonHTcfg); zeros(20,1)];
end

txWaveform = txWaveform(:);

% Get center frequency for channel 153 in 5 GHz band
fc = helperWLANChannelFrequency(153, 5);
fs = wlanSampleRate(nonHTcfg);

txSig  = resample(txWaveform,osf,1);

% Samples per frame in Burst Mode
spf = length(txSig)/length(MACAddressesToSimulate);

runSDRSection = false;
if helperIsPlutoSDRInstalled()  
  radios = findPlutoRadio();
  if length(radios) >= 2
    runSDRSection = true;
  else
    disp("Two ADALM-PLUTO radios are needed. Skipping SDR test.")
  end
else
    disp("Communications Toolbox Support Package for Analog Devices ADALM-PLUTO Radio not found.")
    disp("Click Add-Ons in the Home tab of the MATLAB toolstrip to install the support package.")
    disp("Skipping SDR test.")
end


if runSDRSection
  % Set up PlutoSDR transmitter
  deviceNameSDR = 'Pluto';
  txGain = 0;
  txSDR = sdrtx(deviceNameSDR);
  txSDR.RadioID = 'usb:0';
  txSDR.BasebandSampleRate = fs*osf;
  txSDR.CenterFrequency = fc;
  txSDR.Gain = txGain;
  
  % Set up PlutoSDR Receiver
  rxSDR = sdrrx(deviceNameSDR);
  rxSDR.RadioID = 'usb:1';
  rxSDR.BasebandSampleRate = txSDR.BasebandSampleRate;
  rxSDR.CenterFrequency = txSDR.CenterFrequency;
  rxSDR.GainSource ='Manual';
  rxSDR.Gain = 30;
  rxSDR.OutputDataType = 'double';
  rxSDR.EnableBurstMode=true;
  rxSDR.NumFramesInBurst = 20;
  rxSDR.SamplesPerFrame = osf*spf;
end

L-LTF для классификации

Последовательность L-LTF, присутствующая в преамбуле каждого кадра маяка, используется в качестве входных блоков для NN. Объект rfFingerprintingNonHTFrontEnd System используется для обнаружения пакетов WLAN, выполнения задач синхронизации и извлечения последовательностей L-LTF и данных. Кроме того, MAC-адрес также декодируется. Кроме того, данные предварительно обрабатываются и классифицируются с использованием обученной сети.

if runSDRSection
  numLLTF = 20;       % Number of L-LTF captured for Testing
  
  rxFrontEnd = rfFingerprintingNonHTFrontEnd('ChannelBandwidth', 'CBW20');
  
  disp("The known MAC addresses are:");
  disp(knownMACAddresses)
  
  % Set PlutoSDR to transmit repeatedly
  disp('Starting transmitter')
  transmitRepeat(txSDR, txSig);
  
  % Captured Frames counter
  numCapturedFrames = 0;
  
  disp('Starting receiver')
  % Loop until numLLTF frames are collected
  while numCapturedFrames < numLLTF
    
    % Receive data using PlutoSDR
    rxSig = rxSDR();
    rxSig = decimator(rxSig);
    
    % Perform front-end processing and payload buffering
    [payloadFull, cfgNonHT, rxNonHTData, chanEst, noiseVar, LLTF] = ...
      rxFrontEnd(rxSig);
    
    if payloadFull
      
      % Recover payload bits
      recBits = wlanNonHTDataRecover(rxNonHTData, chanEst, ...
        noiseVar, cfgNonHT, 'EqualizationMethod', 'ZF');
      
      % Decode and evaluate recovered bits
      [mpduCfg, ~, success] = wlanMPDUDecode(recBits, cfgNonHT);
      
      if success == wlanMACDecodeStatus.Success
        % Update counter
        numCapturedFrames = numCapturedFrames+1;
        
        % Create real-valued input
        LLTF = [real(LLTF), imag(LLTF)];
        LLTF = permute(reshape(LLTF,frameLength ,[] , 2, 1), [1 3 4 2]);
        
        ypred = classify(capturedDataNet, LLTF);
        
        if sum(contains(knownMACAddresses, mpduCfg.Address2)) ~= 0
          if categorical(convertCharsToStrings(mpduCfg.Address2))~=ypred
            disp(strcat("MAC Address ", mpduCfg.Address2," is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED"))
          else
            disp(strcat("MAC Address ", mpduCfg.Address2," is known, fingerprint match"))
          end
        else
          disp(strcat("MAC Address ", mpduCfg.Address2," is not recognized, unknown device"));
        end
      end
    end
  end
  release(txSDR)
end
The known MAC addresses are:
    "71B63A2D0B83"    "A3F8AC0F2253"    "EF11D125044A"    "F636A97E07E7"
Starting transmitter
## Establishing connection to hardware. This process can take several seconds.
## Waveform transmission has started successfully and will repeat indefinitely. 
## Call the release method to stop the transmission.
Starting receiver
## Establishing connection to hardware. This process can take several seconds.
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED

Дальнейшие исследования

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

Приложение: Вспомогательные функции

Приложение: Сбор данных известного и неизвестного маршрутизатора

Использовать rfFingerprintingRouterDataCollection для сбора данных от известных (т.е. доверенных) маршрутизаторов. Эта функция извлекает сигналы L-LTF, присутствующие в кадрах радиомаяков OFDM без HT 802.11a/g/n/ac, передаваемых от коммерческих аппаратных средств 802.11. Для получения дополнительной информации см. пример IEEE ® 802.11™ WLAN - OFDM Beacon Receiver with USRP ® Hardware (Communications Toolbox Support Package for USRP Radio). Сигналы L-LTF и соответствующие MAC-адреса маршрутизатора используются для обучения нейронной сети идентификации радиочастотных сигналов. Этот метод лучше всего работает, если маршрутизаторы и их антенны фиксированы и их трудно перемещать непреднамеренно. Например, в большинстве офисных сред маршрутизаторы монтируются на потолке. Выполните следующие действия.

  1. Подключите радиомодуль ADALM-PLUTO к компьютеру для использования в качестве радиомодуля наблюдателя.

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

  3. Определите номер канала маршрутизаторов. Чтобы узнать номера каналов, можно использовать приложение Wi-Fi analyzer на телефоне.

  4. Запустите сбор данных, запустив "rfFingerprintingRouterDataCollection(channel)"где channel - номер канала Wi-Fi

  5. Проконтролируйте значение «max (abs (LLTF))». Если оно превышает 1,2 или меньше 0,01, отрегулируйте коэффициент усиления приемника с помощью входного сигнала GAIN наrfFingerprintingRouterDataCollection функция.

Использовать вспомогательные функции rfFingerprintingUnknownClassDataCollectionTx и rfFingerprintingUnknownClassDataCollectionRx для сбора данных с неизвестных маршрутизаторов. Эти функции устанавливают два радиоблока ADALM-PLUTO для передачи и приема сигналов L-LTF. Принятые сигналы объединяются с известными сигналами маршрутизатора для обучения нейронной сети. Необходимо два радиоприемника ADALM-PLUTO, предпочтительно подключенных к двум отдельным ПК. Выполните следующие действия.

  1. Подключение радиоблока ADALM-PLUTO к стационарному ПК для работы в качестве неизвестного маршрутизатора

  2. Запуск передач с помощью запуска "rfFingerprintingUnknownClassDataCollectionTx"

  3. Подключите другой радиоприемник ADALM-PLUTO к мобильному ПК для работы в качестве наблюдателя

  4. Запустите сбор данных, запустив "rfFingerprintingUnknownClassDataCollectionRx". Эта функция по умолчанию собирает 200 кадров на местоположение. Каждое расположение представляет собой отдельный неизвестный маршрутизатор.

  5. Когда функция дает команду на перемещение в новое местоположение, переместите радиоблок наблюдателя в новое местоположение. По умолчанию эта функция собирает данные из 10 местоположений.

  6. Если наблюдатель не принимает какие-либо маяки или он редко принимает маяки, переместите наблюдателя ближе к передатчику.

  7. После завершения сбора данных вызовите "release(sdrTransmitter)"в сеансе MATLAB передающего радиоблока.

Избранная библиография

[1] К. Санхе, М. Белгиовине, Ф. Чжоу, С. Риязе, С. Иоаннидис и К. Чоудхури, «ORACLE: Оптимизированная радиоклассификация через сверточные сетевые сети», IEEE INFOCOM 2019 - IEEE конференция

Связанные темы