Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

딥러닝을 사용한 변조 분류

이 예제에서는 변조 분류를 수행하는 컨벌루션 신경망(CNN)을 사용하는 방법을 보여줍니다. 여기서는 채널이 손상된 합성 파형을 생성해 봅니다. 생성된 파형을 훈련 데이터로 사용하여 변조 분류를 수행하는 CNN을 훈련시킵니다. 그런 다음 소프트웨어 정의 무선 통신(SDR) 하드웨어와 OTA 신호를 사용하여 CNN을 테스트합니다.

CNN을 사용하여 변조 유형 예측하기

이 예제의 훈련된 CNN은 다음과 같은 8개의 디지털 변조 유형과 3개의 아날로그 변조 유형을 인식합니다.

  • BPSK(이진 위상 편이 변조)

  • QPSK(직교 위상 편이 변조)

  • 8-PSK(8진 위상 편이 변조)

  • 16-QAM(16진 직교 진폭 변조)

  • 64-QAM(64진 직교 진폭 변조)

  • PAM4(4진 펄스 진폭 변조)

  • GFSK(가우스 주파수 편이 변조)

  • CPFSK(연속 위상 주파수 편이 변조)

  • B-FM(방송 FM)

  • DSB-AM(양측파대 진폭 변조)

  • SSB-AM(단측파대 진폭 변조)

modulationTypes = categorical(["BPSK", "QPSK", "8PSK", ...
  "16QAM", "64QAM", "PAM4", "GFSK", "CPFSK", ...
  "B-FM", "DSB-AM", "SSB-AM"]);

먼저 사전 훈련된 신경망을 불러옵니다. 신경망 훈련에 대한 자세한 내용은 CNN 훈련시키기 섹션을 참조하십시오.

load trainedModulationClassificationNetwork
trainedNet
trainedNet = 
  SeriesNetwork with properties:

         Layers: [28×1 nnet.cnn.layer.Layer]
     InputNames: {'Input Layer'}
    OutputNames: {'Output'}

훈련된 CNN은 1024개의 채널이 손상된 샘플을 받아서 각 프레임의 변조 유형을 예측합니다. 라이시안 다중 경로 페이딩, 중심 주파수와 샘플링 시간 변동 및 AWGN으로 손상된 몇 개의 PAM4 프레임을 생성합니다. 다음 함수를 사용해 합성 신호를 생성하여 CNN을 테스트합니다. 그런 다음 CNN을 사용하여 프레임의 변조 유형을 예측합니다.

% 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) 플랫폼을 사용하여 OTA 신호로 신경망 성능을 테스트합니다.

훈련을 위한 파형 생성

각 변조 유형에 대해 10,000개의 프레임을 생성합니다. 그중에서 80%는 훈련용으로, 10%는 검증용으로, 10%는 테스트용으로 사용됩니다. 신경망 훈련 단계에서 훈련 프레임과 검증 프레임을 사용합니다. 최종 분류 정확도는 테스트 프레임을 사용하여 획득합니다. 각 프레임의 길이는 1024개 샘플이고 샘플 레이트는 200kHz입니다. 디지털 변조 유형의 경우, 8개의 샘플이 하나의 기호를 나타냅니다. 이 신경망은 (비디오에서처럼) 여러 개의 연속 프레임이 아닌 단일 프레임을 기반으로 각각의 결정을 내립니다. 디지털 변조 유형의 중심 주파수는 902MHz이고 아날로그 변조 유형의 중심 주파수는 100MHz라고 가정합니다.

이 예제를 빠르게 실행하려면 훈련된 신경망을 사용하여 적은 수의 훈련 프레임을 생성하십시오. 신경망을 사용 중인 컴퓨터에서 훈련시키려면 "Train network now" 옵션을 선택합니다(즉, trainNow를 true로 설정).

trainNow = false;
if trainNow == true
  numFramesPerModType = 10000;
else
  numFramesPerModType = 200;
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

채널은 SNR이 30dB인 AWGN을 더합니다. awgn 함수를 사용하여 채널을 구현합니다.

라이시안 다중 경로

채널은 comm.RicianChannel System object™를 사용하여 신호를 라이시안 다중 경로 페이딩 채널에 통과시킵니다. 지연 프로파일을 [0 1.8 3.4] 샘플로 가정하고 이에 대응하는 평균 경로 이득이 [0 -2 -10]dB라고 가정합니다. K 인자는 4이고 최대 도플러 편이는 4Hz로, 이는 902MHz로 걷는 속도와 동일합니다. 다음 설정을 사용하여 채널을 구현합니다.

클록 오프셋

클록 오프셋은 송신기 및 수신기의 내부 클록 소스 간의 부정확성으로 인해 발생합니다. 클록 오프셋은 신호를 기저대역으로 낮게 변환하는 데 사용되는 중심 주파수와 디지털-아날로그 변환기 샘플링 레이트가 이상적인 값과 달라지는 원인이 됩니다. 채널 시뮬레이터는 C=1+Δclock106으로 표현되는 클록 오프셋 인자 C를 사용합니다. 여기서 Δclock은 클록 오프셋입니다. 각 프레임에 대해, 채널은 [-maxΔclock maxΔclock] 범위 내에 균일하게 분포된 값 집합으로부터 무작위 Δclock 값을 생성합니다. 여기서 maxΔclock은 최대 클록 오프셋입니다. 클록 오프셋은 ppm(parts per million) 단위로 측정됩니다. 이 예제에서는 최대 클록 오프셋이 5ppm이라고 가정하겠습니다.

maxDeltaOff = 5;
deltaOff = (rand()*2*maxDeltaOff) - maxDeltaOff;
C = 1 + (deltaOff/1e6);

주파수 오프셋

클록 오프셋 인자 C와 중심 주파수에 기반해 각 프레임에 주파수 오프셋을 적용합니다. comm.PhaseFrequencyOffset을 사용하여 채널을 구현합니다.

샘플링 레이트 오프셋

클록 오프셋 인자 C에 기반해 각 프레임에 샘플링 레이트 오프셋을 적용합니다. 새로운 레이트 C×fs로 프레임을 다시 샘플링하려면 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 파일에 저장하는 루프를 만듭니다. 데이터를 파일에 저장하면 이 예제를 실행할 때마다 데이터를 생성할 필요가 없습니다. 또한 데이터를 보다 효과적으로 공유할 수 있습니다.

각 프레임의 시작 부분에서 무작위 개수의 샘플을 제거하여 과도(Transient)를 제거하고, 프레임이 기호 경계에 대해 무작위 시작점을 갖는지 확인합니다.

% Set the random number generator to a known state to be able to regenerate
% the same frames every time the simulation is run
rng(12)

tic

numModulationTypes = length(modulationTypes);

channelInfo = info(channel);
transDelay = 50;
pool = getPoolSafe();
if ~isa(pool,"parallel.ClusterPool")
  dataDirectory = fullfile(tempdir,"ModClassDataFiles");
else
  dataDirectory = uigetdir("","Select network location to save data files");
end
disp("Data file directory is " + dataDirectory)
Data file directory is C:\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
    elapsedTime = seconds(toc);
    elapsedTime.Format = 'hh:mm:ss';
    fprintf('%s - Generating %s frames\n', ...
      elapsedTime, 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
Generating data and saving in data files...
00:00:00 - Generating BPSK frames
00:00:01 - Generating QPSK frames
00:00:02 - Generating 8PSK frames
00:00:03 - Generating 16QAM frames
00:00:04 - Generating 64QAM frames
00:00:05 - Generating PAM4 frames
00:00:07 - Generating GFSK frames
00:00:08 - Generating CPFSK frames
00:00:09 - Generating B-FM frames
00:00:10 - Generating DSB-AM frames
00:00:11 - Generating SSB-AM frames
% 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 객체를 사용하여, 생성된 복합 파형을 포함하는 파일을 관리합니다. 데이터저장소는 각 개별 파일은 메모리에 맞지만 전체 모음은 메모리에 맞지 않을 수 있는 경우 특히 유용합니다.

frameDS = signalDatastore(dataDirectory,'SignalVariableNames',["frame","label"]);

복소 신호를 실수형 배열로 변환하기

이 예제의 딥러닝 신경망에는 실수 입력이 필요하지만 수신된 신호는 복소 기저대역 샘플을 갖습니다. 복소 신호를 실수 값으로 구성된 4차원 배열로 변환하십시오. 출력 프레임은 크기가 1×spf×2×N입니다. 여기서 첫 번째 페이지(세 번째 차원)는 동위상 샘플이고 두 번째 페이지는 직교위상 샘플입니다. 컨벌루션 필터의 크기가 1×spf인 경우 이 방법은 컨벌루션 계층에서도 I와 Q의 정보가 혼합되도록 하여 위상 정보를 보다 잘 사용합니다. 자세한 내용은 helperModClassIQAsPages를 참조하십시오.

frameDSTrans = transform(frameDS,@helperModClassIQAsPages);

훈련, 검증, 테스트로 분할하기

다음으로, 프레임을 훈련 데이터, 검증 데이터 및 테스트 데이터로 나눕니다. 자세한 내용은 helperModClassSplitData를 참조하십시오.

splitPercentages = [percentTrainingSamples,percentValidationSamples,percentTestSamples];
[trainDSTrans,validDSTrans,testDSTrans] = helperModClassSplitData(frameDSTrans,splitPercentages);

데이터를 메모리로 가져오기

신경망 훈련은 반복적인 작업입니다. 매회 반복에서 데이터저장소가 파일에서 데이터를 읽어 들이고 데이터를 변환한 후에 신경망 계수를 업데이트합니다. 데이터가 컴퓨터의 메모리에 들어갈 경우 파일의 데이터를 메모리로 가져올 때 이 반복된 파일 읽기 및 변환 과정이 필요 없으므로 훈련 속도를 더 높일 수 있습니다. 대신에, 파일에서 데이터를 읽어 들이고 변환하는 작업이 한 번만 수행됩니다.

파일의 모든 데이터를 메모리로 가져옵니다. 파일에는 두 변수 framelabel이 있으며, 데이터저장소에 대해 read를 호출할 때마다 셀형 배열이 반환됩니다. 이 셀형 배열에서 첫 번째 요소는 frame이고 두 번째 요소는 label입니다. transform 함수 helperModClassReadFramehelperModClassReadLabel을 사용하여 프레임과 레이블을 읽어 들입니다. Parallel Computing Toolbox™ 라이선스가 있는 경우 readall 항목을 true로 설정된 "UseParallel" 옵션 세트와 함께 사용하여 변환 함수에 대한 병렬 처리를 활성화하십시오. readall 함수는 기본적으로 첫 번째 차원에 대해 read 함수의 출력값을 결합하므로, 프레임을 셀형 배열로 반환하고 네 번째 차원에 대해 수동으로 결합합니다.

% Read the training and validation frames into the memory
pctExists = parallelComputingLicenseExists();
trainFrames = transform(trainDSTrans, @helperModClassReadFrame);
rxTrainFrames = readall(trainFrames,"UseParallel",pctExists);
rxTrainFrames = cat(4, rxTrainFrames{:});
validFrames = transform(validDSTrans, @helperModClassReadFrame);
rxValidFrames = readall(validFrames,"UseParallel",pctExists);
rxValidFrames = cat(4, rxValidFrames{:});

% Read the training and validation labels into the memory
trainLabels = transform(trainDSTrans, @helperModClassReadLabel);
rxTrainLabels = readall(trainLabels,"UseParallel",pctExists);
validLabels = transform(validDSTrans, @helperModClassReadLabel);
rxValidLabels = readall(validLabels,"UseParallel",pctExists);

CNN 훈련시키기

이 예제에서는 6개의 컨벌루션 계층과 1개의 완전 연결 계층으로 구성된 CNN을 사용합니다. 마지막 계층을 제외한 각 컨벌루션 계층은 뒤에 배치 정규화 계층, ReLU(Rectified Linear Unit) 활성화 계층 및 최댓값 풀링 계층이 옵니다. 마지막 컨벌루션 계층에서 최댓값 풀링 계층은 평균값 풀링 계층으로 대체됩니다. 출력 계층에는 소프트맥스 활성화가 있습니다. 신경망 설계에 대한 안내는 딥러닝 팁과 요령 (Deep Learning Toolbox) 항목을 참조하십시오.

modClassNet = helperModClassCNN(modulationTypes,sps,spf);

다음으로, 미니 배치 크기가 1024인 SGDM 솔버를 사용하도록 TrainingOptionsSGDM (Deep Learning Toolbox)을 구성합니다. Epoch 횟수가 크더라도 추가적인 훈련 이점이 창출되지 않으므로 최대 Epoch 횟수를 20으로 설정합니다. 기본적으로 'ExecutionEnvironment' 속성은 'auto'로 설정되어 있습니다. 이 경우 trainNetwork 함수는 GPU를 사용할 수 있으면 GPU를 사용하고, 그렇지 않으면 CPU를 사용합니다. GPU를 사용하려면 Parallel Computing Toolbox 라이선스가 있어야 합니다. 초기 학습률을 3x10-1으로 설정합니다. Epoch 6회마다 학습률을 0.75배만큼 줄입니다. 'Plots'를 'training-progress'로 설정하여 훈련 진행 상황을 플로팅합니다. NVIDIA® GeForce RTX 3080 GPU에서는 이 신경망을 훈련시키는 데 약 3분 정도 소요됩니다.

maxEpochs = 20;
miniBatchSize = 1024;
options = helperModClassTrainingOptions(maxEpochs,miniBatchSize,...
  numel(rxTrainLabels),rxValidFrames,rxValidLabels);

신경망을 훈련시키거나 이미 훈련된 신경망을 사용할 수 있습니다. 기본적으로 이 예제에서는 훈련된 신경망을 사용합니다.

if trainNow == true
  elapsedTime = seconds(toc);
  elapsedTime.Format = 'hh:mm:ss';
  fprintf('%s - Training the network\n', elapsedTime)
  trainedNet = trainNetwork(rxTrainFrames,rxTrainLabels,modClassNet,options);
else
  load trainedModulationClassificationNetwork
end

훈련 진행 상황 플롯에서 볼 수 있듯이 신경망은 약 20회의 Epoch 만에 97%가 넘는 정확도로 수렴됩니다.

테스트 프레임에 대한 분류 정확도를 구하여 훈련된 신경망을 평가합니다. 결과를 보면 신경망이 이 파형 그룹에 대해 약 95%의 정확도를 달성함을 알 수 있습니다.

elapsedTime = seconds(toc);
elapsedTime.Format = 'hh:mm:ss';
fprintf('%s - Classifying test frames\n', elapsedTime)
00:00:25 - Classifying test frames
% Read the test frames into the memory
testFrames = transform(testDSTrans, @helperModClassReadFrame);
rxTestFrames = readall(testFrames,"UseParallel",pctExists);
rxTestFrames = cat(4, rxTestFrames{:});

% Read the test labels into the memory
testLabels = transform(testDSTrans, @helperModClassReadLabel);
rxTestLabels = readall(testLabels,"UseParallel",pctExists);

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의 부분 집합이므로 이는 예상 가능한 문제입니다. 또한 SSB-AM 신호에는 DSB-AM 신호 스펙트럼의 정확히 절반이 포함되어 있기 때문에 신경망은 DSB-AM 프레임과 SSB-AM 프레임도 혼동합니다.

figure
cm = confusionchart(rxTestLabels, rxTestPred);
cm.Title = 'Confusion Matrix for Test Data';
cm.RowSummary = 'row-normalized';
cm.Parent.Position = [cm.Parent.Position(1:2) 950 550];

SDR을 사용하여 테스트하기

helperModClassSDRTest 함수를 사용하여, 훈련된 신경망의 성능을 OTA 신호로 테스트합니다. 이 테스트를 수행하려면 송신 및 수신 전용 SDR이 있어야 합니다. 2개의 ADALM-PLUTO 라디오를 사용할 수도 있고, 송신용으로 하나의 ADALM-PLUTO 라디오를 사용하고 수신용으로 하나의 USRP® 라디오를 사용할 수도 있습니다. Install Support Package for Analog Devices ADALM-PLUTO Radio 작업을 수행해야 합니다. USRP® 라디오를 사용하는 경우, Install Communications Toolbox Support Package for USRP Radio 작업도 수행해야 합니다. helperModClassSDRTest 함수는 훈련 신호를 생성하는 데 사용되는 것과 동일한 변조 함수를 사용하고, ADALM-PLUTO 라디오를 사용하여 이를 송신합니다. 채널을 시뮬레이션하는 대신, 신호 수신용으로 구성된 SDR(ADALM-PLUTO 또는 USRP® 라디오)을 사용하여 채널이 손상된 신호를 캡처하십시오. 앞에서 변조 유형을 예측하는 데 사용된 것과 동일한 classify 함수를 이용해 훈련된 신경망을 사용합니다. 다음 코드를 실행하면 혼동행렬이 생성되고 테스트 정확도가 출력됩니다.

radioPlatform = "ADALM-PLUTO";

switch radioPlatform
  case "ADALM-PLUTO"
    if helperIsPlutoSDRInstalled() == true
      radios = findPlutoRadio();
      if length(radios) >= 2
        helperModClassSDRTest(radios);
      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 = contains({rxRadio.Platform}, {'B200','B210'});
        case "USRP X3xx"
          idx = contains({rxRadio.Platform}, {'X300','X310'});
        case "USRP N2xx"
          idx = contains({rxRadio.Platform}, 'N200/N210/USRP2');
      end
      rxRadio = rxRadio(idx);
      if (length(txRadio) >= 1) && (length(rxRadio) >= 1)
        helperModClassSDRTest(rxRadio);
      else
        disp('Selected radios not found. Skipping over-the-air test.')
      end
    end
end

약 2피트만큼 떨어진 2개의 고정 ADALM-PLUTO 라디오를 사용할 경우, 신경망은 다음과 같은 혼동행렬과 함께 99%의 전체적인 정확도를 달성합니다. 결과는 실험 환경에 따라 달라집니다.

심층 탐구

필터 개수나 필터 크기와 같은 하이퍼파라미터를 최적화하거나 계층을 추가하거나 다른 활성화 계층을 사용하는 등의 방법으로 신경망 구조를 최적화하여 정확도를 개선할 수 있습니다.

Communication Toolbox는 이외에도 많은 변조 유형과 채널 손상을 제공합니다. 자세한 내용은 변조전파 및 채널 모델 섹션을 참조하십시오. LTE Toolbox, WLAN Toolbox5G Toolbox를 사용하여 특정 표준 신호를 추가할 수도 있습니다. Phased Array System Toolbox를 사용하여 레이다 신호를 추가할 수도 있습니다.

헬퍼 파일

helperModClassGetModulator 함수는 변조된 신호를 생성하는 데 사용된 MATLAB® 함수를 제공합니다. 다음과 같은 함수와 System object에서도 더 자세한 내용을 살펴볼 수 있습니다.

로컬 함수

function pool = getPoolSafe()
if exist("gcp","file") && license('test','distrib_computing_toolbox')
  pool = gcp;
  if isempty(pool)
    pool = parpool;
  end
else
  pool = [];
end
end

참고 문헌

  1. O'Shea, T. J., J. Corgan, and T. C. Clancy. "Convolutional Radio Modulation Recognition Networks." Preprint, submitted June 10, 2016. https://arxiv.org/abs/1602.04105

  2. O'Shea, T. J., T. Roy, and T. C. Clancy. "Over-the-Air Deep Learning Based Radio Signal Classification." IEEE Journal of Selected Topics in Signal Processing. Vol. 12, Number 1, 2018, pp. 168–179.

  3. Liu, X., D. Yang, and A. E. Gamal. "Deep Neural Network Architectures for Modulation Classification." Preprint, submitted January 5, 2018. https://arxiv.org/abs/1712.00443v3

관련 항목