Этот пример показывает, как использовать сверточную нейронную сеть (CNN) для классификации модуляции. Вы генерируете синтетические, ослабленные по каналам формы волны. Используя сгенерированные формы волны в качестве обучающих данных, вы обучаете CNN для классификации модуляции. Затем тестируйте CNN с программно определяемым радио (SDR) оборудованием и беспроводными сигналами.
Обученный CNN в этом примере распознает эти восемь типов цифровой и три типа аналоговой модуляции:
Двоичная клавиша фазы сдвига (BPSK)
Квадратурная манипуляция фазы сдвига (QPSK)
8-арная фаза сдвига манипуляция (8-PSK)
16-арная квадратурная амплитудная модуляция (16-QAM)
64-арная квадратурная амплитудная модуляция (64-QAM)
4-арная импульсная амплитудная модуляция (PAM4)
Гауссовая манипуляция со сдвигом частоты (GFSK)
Непрерывная манипуляция фазы сдвига частотой (CPFSK)
Широковещательная FM (B-FM)
Двойная амплитудная модуляция боковой полосы (DSB-AM)
Однополосная амплитудная модуляция (SSB-AM)
modulationTypes = categorical(["BPSK", "QPSK", "8PSK", ... "16QAM", "64QAM", "PAM4", "GFSK", "CPFSK", ... "B-FM", "DSB-AM", "SSB-AM"]);
Во-первых, загрузите обученную сеть. Для получения дополнительной информации о сетевом обучении смотрите раздел Training a CNN.
load trainedModulationClassificationNetwork
trainedNet
trainedNet = SeriesNetwork with properties: Layers: [28×1 nnet.cnn.layer.Layer] InputNames: {'Input Layer'} OutputNames: {'Output'}
Обученный CNN принимает 1024 выборки с нарушением канала и предсказывает тип модуляции каждой системы координат. Сгенерируйте несколько системы координат PAM4, которые нарушаются с многолучевым замиранием Райса, дрейфом времени центральной частоты и дискретизации и AWGN. Используйте следующую функцию для генерации синтетических сигналов для тестирования CNN. Затем используйте CNN, чтобы предсказать тип модуляции систем координат.
randi
: Сгенерируйте случайные биты
pammod
(Communications Toolbox) PAM4-modulate биты
rcosdesign
(Signal Processing Toolbox): Создайте квадратный корневой фильтр формирования косинусоидных импульсов
filter
: Импульсная форма символов
comm.RicianChannel
(Communications Toolbox): Применить многолучевой канал Райса
comm.PhaseFrequencyOffset
(Communications Toolbox): Применить сдвиг фазы и/или частоты из-за смещения синхроимпульса
interp1
: Применить дрейф синхронизации из-за смещения синхроимпульса
awgn
(Communications Toolbox): Добавление AWGN
% Set the random number generator to a known state to be able to regenerate % the same frames every time the simulation is run rng(123456) % Random bits d = randi([0 3], 1024, 1); % PAM4 modulation syms = pammod(d,4); % Square-root raised cosine filter filterCoeffs = rcosdesign(0.35,4,8); tx = filter(filterCoeffs,1,upsample(syms,8)); % Channel SNR = 30; maxOffset = 5; fc = 902e6; fs = 200e3; multipathChannel = comm.RicianChannel(... 'SampleRate', fs, ... 'PathDelays', [0 1.8 3.4] / 200e3, ... 'AveragePathGains', [0 -2 -10], ... 'KFactor', 4, ... 'MaximumDopplerShift', 4); frequencyShifter = comm.PhaseFrequencyOffset(... 'SampleRate', fs); % Apply an independent multipath channel reset(multipathChannel) outMultipathChan = multipathChannel(tx); % Determine clock offset factor clockOffset = (rand() * 2*maxOffset) - maxOffset; C = 1 + clockOffset / 1e6; % Add frequency offset frequencyShifter.FrequencyOffset = -(C-1)*fc; outFreqShifter = frequencyShifter(outMultipathChan); % Add sampling time drift t = (0:length(tx)-1)' / fs; newFs = fs * C; tp = (0:length(tx)-1)' / newFs; outTimeDrift = interp1(t, outFreqShifter, tp); % Add noise rx = awgn(outTimeDrift,SNR,0); % Frame generation for classification unknownFrames = helperModClassGetNNFrames(rx); % Classification [prediction1,score1] = classify(trainedNet,unknownFrames);
Верните предсказания классификатора, которые аналогичны жестким решениям. Сеть правильно идентифицирует системы координат как PAM4 системы координат. Для получения дополнительной информации о генерации модулированных сигналов смотрите функцию helperModClassGetModulator.
prediction1
prediction1 = 7×1 categorical
PAM4
PAM4
PAM4
PAM4
PAM4
PAM4
PAM4
Классификатор также возвращает вектор счетов для каждой системы координат. Счет соответствует вероятности того, что каждая система координат имеет предсказанный тип модуляции. Постройте счета.
helperModClassPlotScores(score1,modulationTypes)
Прежде чем мы сможем использовать CNN для классификации модуляции или любой другой задачи, нам сначала нужно обучить сеть с известными (или маркированными) данными. В первой части этого примера показано, как использовать функции Communications Toolbox, такие как модуляторы, фильтры и нарушения канала, для генерации синтетических обучающих данных. Вторая часть посвящена определению, обучению и проверке CNN для задачи классификации модуляций. Третья часть тестирует сетевую эффективность с беспроводными сигналами с помощью программно определяемого радио (SDR) платформ.
Сгенерируйте 10 000 системы координат для каждого типа модуляции, где 80% используется для обучения, 10% используется для валидации и 10% используется для проверки. Мы используем системы координат обучения и валидации на фазе сетевого обучения. Окончательная точность классификации получается с помощью тестовых систем координат. Каждая система координат имеет длину 1024 выборки и частоту дискретизации 200 кГц. Для типов цифровой модуляции восемь выборок представляют символ. Сеть принимает каждое решение на основе одиночных систем координат, а не на нескольких последовательных системах координат (как в видео). Предположим, что центральная частота 902 МГц и 100 МГц для цифрового и аналогового типов модуляции, соответственно.
Чтобы запустить этот пример быстро, используйте обученную сеть и сгенерируйте небольшое количество систем координат. Чтобы обучить сеть на вашем компьютере, выберите опцию «Обучить сеть сейчас» (т.е. установите trainNow на true).
trainNow = false; if trainNow = = true numFramesPerModType = 10000; else numFramesPerModType = 500; end percentTrainingSamples = 80; percentValidationSamples = 10; percentTestSamples = 10; sps = 8; % Samples per symbol spf = 1024; % Samples per frame symbolsPerFrame = spf/sps; fs = 200e3; % Sample rate fc = [902e6 100e6]; % Center frequencies
Пропустите каждую систему координат через канал с
AWGN
Райс многолучевой канал с замираниями
Смещение синхроимпульса, в результате чего смещение центральной частоты и временной дрейф дискретизации
Поскольку сеть в этом примере принимает решения на основе одиночных систем координат, каждая система координат должен проходить через независимый канал.
Канал добавляет AWGN с ОСШ 30 дБ. Реализуйте канал с помощью awgn
(Communications Toolbox) функцию.
Канал передает сигналы через многолучевой канал Райса с замираниями, используя comm.RicianChannel
(Communications Toolbox) Системный объект. Предположим, что профиль задержки [0 1.8 3.4] выборок с соответствующим средним коэффициентом усиления пути [0 -2 -10] дБ. Коэффициент К равен 4, а максимальный доплеровский сдвиг равен 4 Гц, что эквивалентно скорости ходьбы на 902 МГц. Реализуйте канал со следующими настройками.
Смещение синхроимпульса происходит из-за неточностей внутренних источников синхроимпульса передатчиков и приемников. Смещение синхроимпульса заставляет центральную частоту, которая используется для преобразования сигнала вниз в полосу модулирующих частот, и частоту дискретизации цифроаналогового преобразователя отличаться от идеальных значений. Симулятор канала использует коэффициент смещения синхроимпульса , выраженная как , где - смещение синхроимпульса. Для каждой системы координат канал генерирует случайный значение из равномерно распределенного множества значений в области значений [ ], где - максимальное смещение синхроимпульса. Смещение часов измеряется в частях на миллион (ppm). В данном примере примите максимальное смещение синхроимпульса 5 ppm.
maxDeltaOff = 5; deltaOff = (rand()*2*maxDeltaOff) - maxDeltaOff; C = 1 + (deltaOff/1e6);
Смещение Частоты
Подвергайте каждую систему координат смещению частоты на основе коэффициента смещения синхроимпульса и центральную частоту. Реализуйте канал с помощью comm.PhaseFrequencyOffset
(Communications Toolbox).
Смещение частоты дискретизации
Подвергайте каждую систему координат смещению частоты дискретизации на основе коэффициента смещения синхроимпульса . Реализуйте канал с помощью interp1
функция для повторной выборки системы координат с новой скоростью .
Используйте объект helperModClassTestChannel, чтобы применить все три нарушения канала к системам координат.
channel = helperModClassTestChannel(... 'SampleRate', fs, ... 'SNR', SNR, ... 'PathDelays', [0 1.8 3.4] / fs, ... 'AveragePathGains', [0 -2 -10], ... 'KFactor', 4, ... 'MaximumDopplerShift', 4, ... 'MaximumClockOffset', 5, ... 'CenterFrequency', 902e6)
channel = helperModClassTestChannel with properties: SNR: 30 CenterFrequency: 902000000 SampleRate: 200000 PathDelays: [0 9.0000e-06 1.7000e-05] AveragePathGains: [0 -2 -10] KFactor: 4 MaximumDopplerShift: 4 MaximumClockOffset: 5
Просмотреть базовую информацию о канале можно с помощью функции объекта info.
chInfo = info(channel)
chInfo = struct with fields:
ChannelDelay: 6
MaximumFrequencyOffset: 4510
MaximumSampleRateOffset: 1
Создайте цикл, который генерирует системы координат с нарушением канала для каждого типа модуляции и хранит системы координат с соответствующими метками в файлах MAT. Путем сохранения данных в файлы вы устраняете необходимость генерировать данные каждый раз, когда вы запускаете этот пример. Можно также более эффективно обмениваться данными.
Удалите случайное число отсчетов из начала каждого кадра, чтобы удалить переходные процессы и убедиться, что системы координат имеют случайную начальную точку относительно контуров символа.
% Set the random number generator to a known state to be able to regenerate % the same frames every time the simulation is run rng(1235) tic numModulationTypes = length(modulationTypes); channelInfo = info(channel); transDelay = 50; dataDirectory = fullfile(tempdir,"ModClassDataFiles"); disp("Data file directory is " + dataDirectory)
Data file directory is C:\Users\esozer\AppData\Local\Temp\ModClassDataFiles
fileNameRoot = "frame"; % Check if data files exist dataFilesExist = false; if exist(dataDirectory,'dir') files = dir(fullfile(dataDirectory,sprintf("%s*",fileNameRoot))); if length(files) == numModulationTypes*numFramesPerModType dataFilesExist = true; end end if ~dataFilesExist disp("Generating data and saving in data files...") [success,msg,msgID] = mkdir(dataDirectory); if ~success error(msgID,msg) end for modType = 1:numModulationTypes fprintf('%s - Generating %s frames\n', ... datestr(toc/86400,'HH:MM:SS'), modulationTypes(modType)) label = modulationTypes(modType); numSymbols = (numFramesPerModType / sps); dataSrc = helperModClassGetSource(modulationTypes(modType), sps, 2*spf, fs); modulator = helperModClassGetModulator(modulationTypes(modType), sps, fs); if contains(char(modulationTypes(modType)), {'B-FM','DSB-AM','SSB-AM'}) % Analog modulation types use a center frequency of 100 MHz channel.CenterFrequency = 100e6; else % Digital modulation types use a center frequency of 902 MHz channel.CenterFrequency = 902e6; end for p=1:numFramesPerModType % Generate random data x = dataSrc(); % Modulate y = modulator(x); % Pass through independent channels rxSamples = channel(y); % Remove transients from the beginning, trim to size, and normalize frame = helperModClassFrameGenerator(rxSamples, spf, spf, transDelay, sps); % Save data file fileName = fullfile(dataDirectory,... sprintf("%s%s%03d",fileNameRoot,modulationTypes(modType),p)); save(fileName,"frame","label") end end else disp("Data files exist. Skip data generation.") end
Data files exist. Skip data generation.
% Plot the amplitude of the real and imaginary parts of the example frames % against the sample number helperModClassPlotTimeDomain(dataDirectory,modulationTypes,fs)
% Plot the spectrogram of the example frames
helperModClassPlotSpectrogram(dataDirectory,modulationTypes,fs,sps)
Использование signalDatastore
объект для управления файлами, которые содержат сгенерированные сложные формы волны. Datastores особенно полезны, когда каждый отдельный файл помещается в памяти, но весь набор не обязательно помещается.
frameDS = signalDatastore(dataDirectory,'SignalVariableNames',["frame","label"]);
Нейронная сеть для глубокого обучения в этом примере ожидает реальных входов, в то время как принятый сигнал имеет сложные дискретизации основной полосы частот. Преобразуйте комплексные сигналы в действительные массивы 4-D. У выхода систем координат быть 1-by-spf-by-2-by-N размера, где первая страница (3-и размерности) является синфазными выборками, а вторая страница - квадратурными выборками. Когда сверточные фильтры имеют размер 1 на spf, этот подход гарантирует, что информация в I и Q смешивается даже в сверточных слоях, и лучше использует информацию фазы. Для получения дополнительной информации см. helperModClassIQAsPages.
frameDSTrans = transform(frameDS,@helperModClassIQAsPages);
Затем разделите системы координат на обучающие, валидационные и тестовые данные. Для получения дополнительной информации см. helperModClassSplitData.
splitPercentages = [percentTrainingSamples,percentValidationSamples,percentTestSamples]; [trainDSTrans,validDSTrans,testDSTrans] = helperModClassSplitData(frameDSTrans,splitPercentages);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 2: Completed in 11 sec - Pass 2 of 2: Completed in 11 sec Evaluation completed in 25 sec
Обучение нейронной сети итеративно. При каждой итерации datastore считывает данные из файлов и преобразует данные перед обновлением сетевых коэффициентов. Если данные помещаются в память вашего компьютера, импорт данных из файлов в память позволяет быстрее обучаться, устраняя этот процесс повторного чтения из файла и преобразования. Вместо этого данные считываются из файлов и трансформируются один раз. Обучение этой сети с использованием файлов данных на диске занимает около 110 минут, в то время как обучение с использованием данных в памяти занимает около 50 минут.
Импортируйте все данные в файлах в память. Файлы имеют две переменные: frame
и label
и каждый read
вызов datastore возвращает массив ячеек, где первым элементом является frame
и второй элемент является label
. Используйте transform
функции helperModClassReadFrame и helperModClassReadLabel для чтения систем координат и меток. Использование tall
массивы для параллельной обработки функций преобразования, в случае если у вас есть лицензия Parallel Computing Toolbox. Начиная с gather
функция по умолчанию конкатенирует выход read
функция по первой размерности, возвращает системы координат в массив ячеек и вручную конкатенируется по 4-ой размерности.
% Gather the training and validation frames into the memory
trainFramesTall = tall(transform(trainDSTrans, @helperModClassReadFrame));
rxTrainFrames = gather(trainFramesTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 4.3 sec Evaluation completed in 4.3 sec
rxTrainFrames = cat(4, rxTrainFrames{:}); validFramesTall = tall(transform(validDSTrans, @helperModClassReadFrame)); rxValidFrames = gather(validFramesTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 0.76 sec Evaluation completed in 0.78 sec
rxValidFrames = cat(4, rxValidFrames{:});
% Gather the training and validation labels into the memory
trainLabelsTall = tall(transform(trainDSTrans, @helperModClassReadLabel));
rxTrainLabels = gather(trainLabelsTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 2: Completed in 4.6 sec - Pass 2 of 2: Completed in 7 sec Evaluation completed in 12 sec
validLabelsTall = tall(transform(validDSTrans, @helperModClassReadLabel)); rxValidLabels = gather(validLabelsTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 2: Completed in 0.7 sec - Pass 2 of 2: Completed in 0.85 sec Evaluation completed in 1.8 sec
Этот пример использует CNN, который состоит из шести слоев свертки и одного полносвязного слоя. Каждый слой свертки, кроме последнего, сопровождается слоем нормализации партии ., слоем активации выпрямленных линейных модулей (ReLU) и слоем максимального объединения. В последнем слое свертки максимальный слой объединения заменяется средним слоем объединения. Слой выхода имеет активацию softmax. Для руководства по проекту сетей смотрите Советы по глубокому обучению и трюки.
modClassNet = helperModClassCNN(modulationTypes,sps,spf);
Следующая настройка TrainingOptionsSGDM
использовать решатель SGDM с мини-пакетом размером 256. Установите максимальное количество эпох равным 12, так как большее количество эпох не обеспечивает дополнительных преимуществ обучения. По умолчанию в 'ExecutionEnvironment'
для свойства задано значение 'auto'
, где trainNetwork
функция использует графический процессор, если он доступен, или использует центральный процессор, если нет. Чтобы использовать графический процессор, вы должны иметь лицензию Parallel Computing Toolbox. Установите начальную скорость обучения равным . Уменьшите скорость обучения в 10 раз каждые 9 эпох. Задайте 'Plots'
на 'training-progress'
для построения графика процесса обучения. На графическом процессоре NVIDIA Titan Xp сеть занимает примерно 25 минут.
maxEpochs = 12;
miniBatchSize = 256;
options = helperModClassTrainingOptions(maxEpochs,miniBatchSize,...
numel(rxTrainLabels),rxValidFrames,rxValidLabels);
Либо обучите сеть, либо используйте уже обученную сеть. По умолчанию в этом примере используется обученная сеть.
if trainNow == true fprintf('%s - Training the network\n', datestr(toc/86400,'HH:MM:SS')) trainedNet = trainNetwork(rxTrainFrames,rxTrainLabels,modClassNet,options); else load trainedModulationClassificationNetwork end
Как показывает график процесса обучения, сеть сходится примерно за 12 эпох до более чем 95% точности.
Оцените обученную сеть путем получения точности классификации для тестовых систем координат. Результаты показывают, что сеть достигает около 94% точности для этой группы осциллограмм.
fprintf('%s - Classifying test frames\n', datestr(toc/86400,'HH:MM:SS'))
00:02:18 - Classifying test frames
% Gather the test frames into the memory
testFramesTall = tall(transform(testDSTrans, @helperModClassReadFrame));
rxTestFrames = gather(testFramesTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 0.68 sec Evaluation completed in 0.69 sec
rxTestFrames = cat(4, rxTestFrames{:});
% Gather the test labels into the memory
testLabelsTall = tall(transform(testDSTrans, @helperModClassReadLabel));
rxTestLabels = gather(testLabelsTall);
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 2: Completed in 0.7 sec - Pass 2 of 2: Completed in 0.86 sec Evaluation completed in 1.8 sec
rxTestPred = classify(trainedNet,rxTestFrames); testAccuracy = mean(rxTestPred == rxTestLabels); disp("Test accuracy: " + testAccuracy*100 + "%")
Test accuracy: 95.4545%
Постройте график матрицы неточностей для тестовых систем координат. Как показывает матрица, сеть запутывает 16-QAM и 64-QAM системы координат. Эта проблема ожидается, поскольку каждая система координат содержит только 128 символов, и 16-QAM является подмножеством 64-QAM. Сеть также путает QPSK и 8-PSK системы координат, поскольку созвездия этих типов модуляции выглядят сходными после поворота фазы из-за затухания канала и смещения частоты.
figure cm = confusionchart(rxTestLabels, rxTestPred); cm.Title = 'Confusion Matrix for Test Data'; cm.RowSummary = 'row-normalized'; cm.Parent.Position = [cm.Parent.Position(1:2) 740 424];
Проверьте эффективность обученной сети с беспроводными сигналами с помощью функции helperModClassSDRTest. Для выполнения этого теста необходимо иметь выделенные SDR для передачи и приема. Можно использовать две радиостанции ADALM-PLUTO или одну радиостанцию ADALM-PLUTO для передачи и одну радиостанцию USRP ® для приема. Необходимо установить пакет поддержки Communications Toolbox для радио ADALM-PLUTO. Если вы используете радио USRP ®, необходимо также установить пакет поддержки Communications Toolbox для радио USRP ®. The helperModClassSDRTest
функция использует те же функции модуляции, что и для генерации обучающих сигналов, а затем передает их с помощью радио ADALM-PLUTO. Вместо симуляции канала, захватывайте сигналы с нарушением канала с помощью SDR, который сконфигурирован для приема сигнала (ADALM-PLUTO или USRP ® radio). Используйте обученную сеть с теми же classify
функция, используемая ранее для предсказания типа модуляции. Выполнение следующего сегмента кода создает матрицу неточностей и распечатывает точность теста.
radioPlatform = "ADALM-PLUTO"; switch radioPlatform case "ADALM-PLUTO" if helperIsPlutoSDRInstalled () = = true радио = findPlutoRadio (); if длина (радиостанции) > = 2 helperModClassSDRTest (радиостанции); else disp ('Selected radios not found. Skipping over-the-air test.') end end case {"USRP B2xx","USRP X3xx","USRP N2xx"} if (helperIsUSRPInstalled () = true) & & (helperIsPlutoSDRInstalled () = true) txRadio = findPlutoRadio (); rxRadio = findsdru (); switch radioPlatform case "USRP B2xx" idx = содержит ({rxRadio.Platform}, {'B200','B210'}); case "USRP X3xx" idx = содержит ({rxRadio.Platform}, {'X300','X310'}); case "USRP N2xx" idx = содержит ({rxRadio.Platform },'N200/N210/USRP2'); end rxRadio = rxRadio (idx); if (длина (txRadio) > = 1) & & (длина (rxRadio) > = 1) helperModClassSDRTest (rxRadio); else disp ('Selected radios not found. Skipping over-the-air test.') end end end
При использовании двух стационарных радиостанций ADALM-PLUTO, разделенных примерно на 2 фута, сеть достигает 99% общей точности со следующей матрицей путаницы. Результаты будут варьироваться в зависимости от экспериментальной настройки.
Возможно оптимизировать параметры гиперпараметров, такие как количество фильтров, размер фильтра или оптимизировать структуру сети, такие как добавление большего количества слоев, использование различных слоев активации и т.д., чтобы улучшить точность.
Communication Toolbox обеспечивает намного больше типов модуляции и нарушений канала. Для получения дополнительной информации смотрите разделы Modulation (Communications Toolbox) и Propagation and Channel Models (Communications Toolbox). Можно также добавить стандартные конкретные сигналы с помощью LTE Toolbox, WLAN Toolbox и 5G Toolbox. Можно также добавить радиолокационные сигналы с помощью Phased Array System Toolbox.
функция helperModClassGetModulator обеспечивает функции MATLAB, используемые для генерации модулированных сигналов. Для получения дополнительной информации можно также изучить следующие функции и системные объекты.
О'Ши, Т. Дж., Дж. Корган и Т. К. Клэнси. «Сверточные сети распознавания радиомодуляции». Препринт, представленный 10 июня 2016 года. https://arxiv.org/abs/1602.04105
О'Ши, Т. Дж., Т. Рой и Т. К. Клэнси. Классификация радиосигналов на основе глубокого обучения по воздуху. Журнал IEEE по выбранным темам в обработке сигналов. Том 12, № 1, 2018, с. 168-179.
Лю, X., Д. Ян, и А. Э. Гамаль. «Архитектуры глубоких нейронных сетей для классификации модуляций». Препринт, представленный 5 января 2018 года. https://arxiv.org/abs/1712.00443v3
trainingOptions
| trainNetwork