基于深度学习的调制分类
这个例子展示了如何使用卷积神经网络(CNN)进行调制分类。你产生合成的,信道受损的波形。使用生成的波形作为训练数据,训练CNN进行调制分类。然后使用软件定义无线电(SDR)硬件和无线信号测试CNN。
利用CNN预测调制类型
本例中经过训练的CNN可以识别这8种数字调制类型和3种模拟调制类型:
二进制相移键控(BPSK)
正交相移键控(QPSK)
8元相移键控(8-PSK)
16元正交调幅(16-QAM)
64元正交调幅(64-QAM)
四元脉冲调幅(PAM4)
高斯频移键控
连续相位频移键控(CPFSK)
广播调频(B-FM)
双边带调幅(DSB-AM)
单边带调幅(SSB-AM)
调制类型=分类的([“BPSK”,“正交相移编码”,“8相移键控”,...“16 qam”,“64 qam”,“PAM4”,“GFSK”,“CPFSK”,...“B-FM”,“DSB-AM”,“SSB-AM”]);
首先,加载训练好的网络。关于网络培训的详细信息,请参见培训CNN部分。
负载trainedModulationClassificationNetworktrainedNet
trainedNet = SeriesNetwork with properties: Layers: [28×1 nnet.cnn.layer.Layer] InputNames:{'输入层'}OutputNames:{'输出'}
训练后的CNN取1024个信道受损样本,并预测每帧的调制类型。生成若干PAM4帧,这些帧受专家多径衰落、中心频率和采样时间漂移以及AWGN的影响。使用下面的函数生成合成信号来测试CNN。然后利用CNN预测帧的调制类型。
兰迪
:生成随机比特pammod
pam4 -调制位rcosdesign
:设计一个平方根凸起余弦脉冲整形滤波器过滤器
:脉冲形状的符号comm.RicianChannel
:应用专家级多路径通道comm.PhaseFrequencyOffset
:由于时钟偏移,应用相位和/或频率偏移interp1
:由于时钟偏移而应用时序漂移情况下
:添加AWGN
将随机数生成器设置为已知状态,以便能够重新生成%相同的帧,每次模拟运行rng (123456)%随机比特D = randi([0 3], 1024,1);% PAM4调制Syms = pammod(d,4);%平方根凸起余弦滤波器filterCoeffs = rcosdesign(0.35,4,8);tx = filter(filterCoeffs,1,upsample(syms,8));%的通道信噪比= 30;maxOffset = 5;Fc = 902e6;Fs = 200e3;multipathChannel = com . ricianchannel (...“SampleRate”fs,...“PathDelays”, [0 1.8 3.4] / 200e3,...“AveragePathGains”, [0 -2 -10],...“KFactor”4...“MaximumDopplerShift”4);frequencyShifter = com . phasefrequencyoffset (...“SampleRate”fs);应用独立的多路径通道reset(multipathChannel) outMultipathChan = multipathChannel(tx);确定时钟偏移因子clockOffset = (rand() * 2*maxOffset) - maxOffset;C = 1 + clockOffset / 1e6;添加频率偏移frequencyShifter。FrequencyOffset = -(C-1)*fc;outFreqShifter = frequencyShifter(outMultipathChan);增加采样时间漂移T =(0:长度(tx)-1)' / fs;newFs = fs * C;tp = (0:length(tx)-1)' / newFs;outTimeDrift = interp1(t, outFreqShifter, tp);%添加噪音rx = awgn(outTimeDrift,SNR,0);用于分类的帧生成unknownFrames = helpermodclassgetnframes (rx);%的分类[prediction1,score1] = category (trainedNet,unknownFrames);
返回分类器预测,这类似于艰难的决策。网络正确识别该帧为PAM4帧。调制信号的产生请参见helperModClassGetModulator函数。
prediction1
prediction1 =7×1分类Pam4 Pam4 Pam4 Pam4 Pam4 Pam4 Pam4 Pam4
分类器还为每一帧返回一个分数向量。分数对应于每个帧具有预测调制类型的概率。把分数画出来。
helperModClassPlotScores (score1 modulationTypes)
在我们可以使用CNN进行调制分类或任何其他任务之前,我们首先需要用已知(或标记)数据训练网络。本示例的第一部分展示了如何使用Communications Toolbox™功能(如调制器、滤波器和信道损伤)来生成合成训练数据。第二部分着重于定义、训练和测试CNN以完成调制分类任务。第三部分利用软件定义无线电(SDR)平台对无线信号进行网络性能测试。
用于训练的波形生成
为每种调制类型生成10,000帧,其中80%用于训练,10%用于验证,10%用于测试。我们在网络训练阶段使用训练和验证框架。通过测试帧获得最终的分类精度。每个帧有1024个采样长,采样率为200khz。对于数字调制类型,八个样本代表一个符号。该网络基于单个帧而不是多个连续帧(如视频)做出每个决策。假设数字和模拟调制类型的中心频率分别为902 MHz和100 MHz。
为了快速运行这个例子,使用经过训练的网络并生成少量的训练帧。要在计算机上训练网络,请选择“train network now”选项(即将trainNow设置为true)。
trainNow =假;如果numFramesPerModType = 10000;其他的numFramesPerModType = 200;结束percentTrainingSamples = 80;percentValidationSamples = 10;percentTestSamples = 10;SPS = 8;每个符号的样本百分比SPF = 1024;每帧样本百分比symbolsPerFrame = spf / sps;Fs = 200e3;%抽样率Fc = [902e6 100e6];%中心频率
创造渠道障碍
通过通道传递每个帧
情况下
瑞尔斯多径衰落
时钟偏移,导致中心频率偏移和采样时间漂移
由于本例中的网络基于单个帧做出决策,因此每个帧必须通过一个独立的通道。
情况下
信道添加AWGN,信噪比为30 dB。使用情况下
函数。
Rician多路径
该信道通过一个瑞斯多径衰落信道传递信号comm.RicianChannel
系统对象™。假设[0 1.8 3.4]样本的延迟分布,对应的平均路径增益为[0 -2 -10]dB。k因子为4,最大多普勒频移为4hz,相当于902 MHz的步行速度。使用以下设置实现通道。
时钟偏移量
由于发射机和接收机的内部时钟源不准确而产生时钟偏移。时钟偏移导致中心频率(用于将信号下转换到基带)和数模转换器采样率与理想值不同。信道模拟器使用时钟偏移因子 ,表示为 ,在那里 是时钟偏移量。对于每一帧,信道生成一个随机的 值从范围内的均匀分布的值集中[ ), 最大时钟偏移量。时钟偏移量以百万分之一(ppm)为单位。对于本例,假设最大时钟偏移量为5ppm。
maxDeltaOff = 5;deltaOff = (rand()*2*maxDeltaOff) - maxDeltaOff;C = 1 + (deltaOff/1e6);
频率偏移
根据时钟偏移因子,将每一帧设置为频率偏移
和中心频率。使用comm.PhaseFrequencyOffset
.
采样率偏移
根据时钟偏移因素,使每一帧的采样速率偏移
.方法实现通道interp1
函数以新的速率重新采样帧
.
综合频道
使用helperModClassTestChannel对象将所有三个通道损伤应用于帧。
channel = helperModClassTestChannel(...“SampleRate”fs,...“信噪比”信噪比,...“PathDelays”, [0 1.8 3.4] / fs,...“AveragePathGains”, [0 -2 -10],...“KFactor”4...“MaximumDopplerShift”4...“MaximumClockOffset”5,...“CenterFrequency”902 e6)
channel = helperModClassTestChannel with properties: SNR: 30 CenterFrequency: 902000000 SampleRate: 200000 pathdelay: [0 9.0000 -06 1.7000e-05] averagepath增益:[0 -2 -10]KFactor: 4 MaximumDopplerShift: 4 MaximumClockOffset: 5
通过info object函数可以查看通道的基本信息。
chInfo =信息(频道)
chInfo =带字段的结构:ChannelDelay: 6 MaximumFrequencyOffset: 4510 MaximumSampleRateOffset: 1
波形的一代
创建一个循环,为每种调制类型生成信道受损帧,并将具有相应标签的帧存储在MAT文件中。通过将数据保存到文件中,您无需在每次运行此示例时生成数据。您还可以更有效地共享数据。
从每个帧的开始移除随机数量的样本,以去除瞬态,并确保帧相对于符号边界有一个随机起点。
将随机数生成器设置为已知状态,以便能够重新生成%相同的帧,每次模拟运行rng(1235) tic numModulationTypes = length(modulationTypes);channelInfo =信息(通道);transDelay = 50;dataDirectory = fullfile(tempdir,“ModClassDataFiles”);disp ("数据文件目录为"+ dataDirectory)
数据文件路径为C:\Users\kkearney\AppData\Local\Temp\ModClassDataFiles
fileNameRoot =“帧”;检查数据文件是否存在dataFilesExist = false;如果存在(dataDirectory“dir”) files = dir(fullfile(dataDirectory,sprintf(“% s *”, fileNameRoot)));如果length(files) == numModulationTypes*numFramesPerModType dataFilesExist = true;结束结束如果~ dataFilesExist disp (“生成数据并保存在数据文件中……”) [success,msg,msgID] = mkdir(dataDirectory);如果味精~成功错误(是否)结束为modType = 1:numModulationTypes elapsedTime = seconds(toc);elapsedTime。格式=“hh: mm: ss”;流('%s -生成%s帧\n',...elapsedTime, modulationTypes(modType)) label = modulationTypes(modType);numSymbols = (numFramesPerModType / sps);dataSrc = helperModClassGetSource(modulationTypes(modType), sps, 2*spf, fs);modulator = helperModClassGetModulator(modulationTypes(modType), sps, fs);如果包含(char (modulationTypes (modType)) {“B-FM”,“DSB-AM”,“SSB-AM”})模拟调制类型使用100 MHz的中心频率通道。CenterFrequency = 100e6;其他的数字调制类型使用902 MHz的中心频率通道。CenterFrequency = 902e6;结束为p = 1: numFramesPerModType生成随机数据x = dataSrc();%调节Y =调制器(x);通过独立渠道rxSamples =通道(y);从开始删除瞬变,修剪到大小,并归一化。frame = helperModClassFrameGenerator(rxSamples, spf, spf, transDelay, sps);保存数据文件文件名= fullfile(数据目录,...sprintf (“% s % s % 03 d”、fileNameRoot modulationTypes (modType)、p));保存(文件名,“帧”,“标签”)结束结束其他的disp (“数据文件存在。跳过数据生成。”)结束
生成数据并保存在数据文件中…
00:00:00 -生成BPSK帧00:00:01 -生成QPSK帧00:00:03 -生成8PSK帧00:00:04 -生成16QAM帧00:00:06 -生成64QAM帧00:00:07 -生成PAM4帧00:00:09 -生成GFSK帧00:00:10 -生成CPFSK帧00:00:11 -生成B-FM帧00:00:26 -生成DSB-AM帧00:00:27 -生成SSB-AM帧
绘制示例帧的实部和虚部的振幅%相对于样品数量helperModClassPlotTimeDomain (dataDirectory modulationTypes fs)
绘制示例帧的光谱图helperModClassPlotSpectrogram (dataDirectory modulationTypes fs, sps)
创建数据存储
使用一个signalDatastore
对象来管理包含生成的复杂波形的文件。当每个单独的文件都适合内存,但整个集合并不一定适合内存时,数据存储特别有用。
frameDS = signalDatastore“SignalVariableNames”, (“帧”,“标签”]);
将复杂信号转换为实数组
本例中的深度学习网络期望真实输入,而接收到的信号具有复杂的基带样本。将复杂信号转换为实值4-D数组。输出帧的大小为1-by-spf-by-2-by-N,其中第一页(第三维)是同相样本,第二页是正交样本。当卷积滤波器的大小为1 by spf时,这种方法确保I和Q中的信息即使在卷积层中也能混合,并更好地利用相位信息。看到helperModClassIQAsPages获取详细信息。
frameDSTrans = transform(frameDS,@helperModClassIQAsPages);
分为培训、验证和测试
接下来,将帧划分为训练数据、验证数据和测试数据。看到helperModClassSplitData获取详细信息。
splitpercentage = [percentTrainingSamples,percentValidationSamples,percentTestSamples];[trainDSTrans,validDSTrans,testDSTrans] = helperModClassSplitData(frameDSTrans, splitpercentage);
使用“本地”配置文件启动并行池(parpool)…连接到并行池(工人数:6)。
将数据导入内存
神经网络训练是迭代的。在每次迭代中,数据存储从文件中读取数据并在更新网络系数之前转换数据。如果数据适合计算机的内存,将数据从文件导入到内存中可以通过消除从文件中重复读取和转换过程来实现更快的训练。相反,从文件中读取数据并转换一次。使用磁盘上的数据文件训练这个网络大约需要110分钟,而使用内存中的数据训练大约需要50分钟。
将文件中的所有数据导入内存。文件有两个变量:框架
而且标签
和每个读
调用数据存储返回一个单元格数组,其中第一个元素是框架
第二个元素是标签
.使用变换
功能helperModClassReadFrame而且helperModClassReadLabel阅读框架和标签。使用readall
与“UseParallel”
选项设置为真正的
以启用转换函数的并行处理并行计算工具箱™许可证。自readall
方法的输出进行连接读
函数在第一个维度上,返回单元格数组中的帧,并在第四个维度上手动连接。
将训练和验证帧读入内存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{:});将训练和验证标签读入内存trainLabels = transform(trainDSTrans, @helperModClassReadLabel);rxTrainLabels = readall(训练标签,“UseParallel”, pctExists);validLabels = transform(validDSTrans, @helperModClassReadLabel);rxValidLabels = readall(validLabels,“UseParallel”, pctExists);
训练CNN
本例使用的CNN由六个卷积层和一个全连接层组成。除最后一个卷积层外,每个卷积层后面都有一个批量归一化层、整流线性单元(ReLU)激活层和最大池化层。在最后一个卷积层中,最大池化层被平均池化层取代。输出层具有softmax激活。有关网络设计指导,请参见深度学习技巧和技巧(深度学习工具箱).
modClassNet = helperModClassCNN(modulationTypes,sps,spf);
下一个配置TrainingOptionsSGDM
(深度学习工具箱)使用小型批处理大小为256的SGDM求解器。将最大epoch数设置为12,因为更大的epoch数不会提供进一步的训练优势。默认情况下,“ExecutionEnvironment”
属性设置为“汽车”
,在那里trainNetwork
函数使用GPU(如果有)或CPU(如果没有)。要使用GPU,您必须有一个并行计算工具箱许可证。设置初始学习速率为
.每9个周期将学习率降低10倍。集“阴谋”
“训练进步”
规划培训进度。在NVIDIA®Titan Xp GPU上,网络训练大约需要25分钟。
maxEpochs = 12;miniBatchSize = 256;选项= helperModClassTrainingOptions(maxEpochs,miniBatchSize,...元素个数(rxTrainLabels)、rxValidFrames rxValidLabels);
要么训练网络,要么使用已经训练好的网络。默认情况下,本例使用经过训练的网络。
如果trainNow = true elapsedTime = seconds(toc);elapsedTime。格式=“hh: mm: ss”;流('%s -训练网络\n', elapsedTime) trainedNet = trainNetwork(rxTrainFrames,rxTrainLabels,modClassNet,options);其他的负载trainedModulationClassificationNetwork结束
正如训练进度图所示,该网络在大约12个周期内收敛,准确率超过95%。
通过获得测试帧的分类精度来评估训练网络。结果表明,该网络对这组波形的准确率约为94%。
elapsedTime = seconds(toc);elapsedTime。格式=“hh: mm: ss”;流('%s -分类测试帧\n'elapsedTime)
00:02:22 -分类测试帧
将测试帧读入内存testFrames = transform(testDSTrans, @helperModClassReadFrame);rxTestFrames = readall(testFrames,“UseParallel”, pctExists);rxTestFrames = cat(4, rxTestFrames{:});将测试标签读入内存testLabels = transform(testDSTrans, @helperModClassReadLabel);rxTestLabels = readall(testLabels,“UseParallel”, pctExists);rxTestPred =分类(trainedNet,rxTestFrames);testAccuracy = mean(rxTestPred == rxTestLabels);disp (“测试精度:”+测试精度*100 +“%”)
试验精度:94.5455%
绘制测试帧的混淆矩阵。如矩阵所示,网络混淆了16-QAM和64-QAM帧。这个问题是意料之中的,因为每帧只携带128个符号,而16-QAM是64-QAM的子集。该网络还混淆了QPSK和8-PSK帧,因为由于衰落信道和频率偏移,这些调制类型的星座在相位旋转后看起来相似。
figure cm = confusionchart(rxTestLabels, rxTestPred);厘米。Title =“测试数据的混淆矩阵”;厘米。RowSummary =“row-normalized”;cm.Parent.Position = [cm.Parent.Position(1:2) 740 424];
SDR测试
使用无线信号测试训练网络的性能helperModClassSDRTest函数。要执行此测试,必须有用于传输和接收的专用sdr。您可以使用两个ADALM-PLUTO无线电,或者一个ADALM-PLUTO无线电用于传输,一个USRP®无线电用于接收。你必须安装模拟设备AD金宝appALM-PLUTO无线电支持包(模拟设备ADALM-Pluto无线电通信工具箱金宝app支持包).如果您正在使用USRP®无线电,您还必须安装USRP无线电的通信工具箱支持包金宝app(USRP无线电通信工具箱支持包)金宝app.的helperModClassSDRTest
函数使用与生成训练信号相同的调制函数,然后使用ADALM-PLUTO无线电传输它们。不模拟信道,而是使用为信号接收(ADALM-PLUTO或USRP®无线电)配置的SDR捕获信道受损的信号。使用训练过的网络分类
以前用来预测调制类型的函数。运行下一个代码段产生一个混淆矩阵,并打印出测试精度。
radioPlatform =“ADALM-PLUTO”;开关radioPlatform情况下“ADALM-PLUTO”如果helperIsPlutoSDRInstalled() == true收音机= findPlutoRadio();如果length(收音机)>= 2 helperModClassSDRTest(收音机);其他的disp (“选定的收音机未找到。跳过空中测试。”)结束结束情况下{“USRP B2xx”,“USRP X3xx”,“USRP N2xx”}如果(helperIsUSRPInstalled() == true) && (helperIsPlutoSDRInstalled() == true) txRadio = findPlutoRadio();rxRadio = findsdru();开关radioPlatform情况下“USRP B2xx”idx = contains({rxRadio。平台},{“B200”,“B210”});情况下“USRP X3xx”idx = contains({rxRadio。平台},{“×”,“X310”});情况下“USRP N2xx”idx = contains({rxRadio。平台},“N200 / N210 / USRP2”);结束rxRadio = rxRadio(idx);如果(length(txRadio) >= 1) && (length(rxRadio) >= 1) helperModClassSDRTest(rxRadio);其他的disp (“选定的收音机未找到。跳过空中测试。”)结束结束结束
当使用两个相距约2英尺的固定ADALM-PLUTO无线电时,网络通过以下混淆矩阵达到99%的总体精度。结果将根据实验设置而有所不同。
进一步的探索
可以通过优化超参数参数,如滤波器数量、滤波器大小,或者优化网络结构,如增加更多的层数、使用不同的激活层等来提高精度。
通信工具箱提供了更多的调制类型和信道损害。有关更多信息,请参阅调制而且传播和信道模型部分。您还可以添加标准的特定信号LTE工具箱,WLAN的工具箱,5 g的工具箱.还可以添加雷达信号相控阵系统工具箱.
helperModClassGetModulator函数提供了MATLAB®函数用于生成调制信号。您还可以探索以下函数和系统对象以了解更多详细信息:
参考文献
奥谢,t。J。柯根,t。c。克兰西。卷积无线电调制识别网络。预印本,2016年6月10日提交。https://arxiv.org/abs/1602.04105
奥谢,t。J。t。罗伊和t。c。克兰西。基于空中深度学习的无线电信号分类IEEE信号处理专题杂志。Vol. 12, no . 1, 2018, pp. 168-179。
刘旭,杨德华,贾迈勒。调制分类的深度神经网络体系结构预印本,2018年1月5日提交。https://arxiv.org/abs/1712.00443v3
相关的话题
- MATLAB深度学习(深度学习工具箱)