基于深度学习的数字调制信号盲辨认钻研概述信号调试形式辨认技术在军、民等畛域具备重要钻研价值,信号调制形式的正确辨认是通信接收机正确解调译码的前提。盲调制辨认技术旨在接管未知调制信号类型并主动分类辨认,此技术能在大量简单多样的调制信号中正确辨认调制格局,其对通信效率的晋升颇有好处。目前基于深度学习的盲调制辨认技术能施展深度学习在图像识别分类方面的极大劣势,其稳定性和准确率都达到了空前高度。本试验将应用不同信噪比调制信号、不同类型调制信号与不同网络匹配并选取分类成果杰出的 AlexNet 和 GoogLeNet 作为钻研网络,利用华为 MindSpore 框架搭建网络,使能网络高效运算,得出分类辨认成果。AlexNet2012 年 Hinton 团队提出 AlexNet 网络,其将分类准确率由传统的 70% 晋升至 80% 无余。AlexNet 构造由 5 个卷积层实现对数据卷积操作并连贯 3 个全连贯层展平数据参数,数据最终经 softmax 层输入分类。
AlexNet 采纳并行模式,应用 ReLu 激活函数,在最初 2 个全连贯层中随机失活 50% 神经元,防止模型过拟合的同时进步网络适应能力,升高网络复杂度,晋升运算速度和分类准确性,这是 AlexNet 解决图像分类问题的独特劣势。为保障网络的各层之间数据匹配和顺畅运行,计算卷积和池化后特色矩阵输入尺寸公式如下
其中,N 是矩阵卷积或者池化后输入特色矩阵尺寸的长和宽,输出图片尺寸为 W×W,F 是计算卷积核或者池化核尺寸为 F×F,S 为步长,P 是补零列数或行数。GoogLeNet2014 年 GoogLeNet 网络以 93.33% 的准确率在 ISLVRC 比赛上大放异彩,它应用翻新构造,在深度减少的同时,整个网络大小却小于 AlexNet 数倍,在肯定的计算资源下,GoogLeNet 体现出更好的性能劣势。
GoogLeNet 引入 Inception 模块、辅助分类器等。GoogLeNet 中 Inception 模块
Inception 模块引入并行构造,将特色矩阵并行输出四个分支解决,对解决后不同尺度特色矩阵按深度拼接。四个分支别离是 1×1 的卷积核,3×3 的卷积核,5×5 的卷积核和池化核大小为 3×3 的最大池化下采样。其中三个分支,应用 1×1 卷积核进行降维,缩小参数,升高计算复杂度。GoogLeNet 辅助分类器
减少的辅助分类器如,它有利于防止梯度隐没,并对中间层数据反馈,起到向前传导梯度的作用。两个辅助分类器构造雷同,均采纳均匀下采样解决,通过 1×1 卷积核和 ReLU 激活函数缩小参数。AlexNet 参数依据的参数计算公式和计算方法,失去特色矩阵尺寸,构建 AlexNet 网络结构参数如下
网络构建代码 ”””Alexnet.”””
import numpy as np
import mindspore.nn as nn
from mindspore.ops import operations as P
from mindspore.ops import functional as F
from mindspore.common.tensor import Tensor
import mindspore.common.dtype as mstype
def conv(in_channels, out_channels, kernel_size, stride=1, padding=0, pad_mode=”valid”, has_bias=True):
return nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding,
has_bias=has_bias, pad_mode=pad_mode)
def fc_with_initialize(input_channels, out_channels, has_bias=True):
return nn.Dense(input_channels, out_channels, has_bias=has_bias)
class DataNormTranspose(nn.Cell):
"""Normalize an tensor image with mean and standard deviation.
Given mean: (R, G, B) and std: (R, G, B),
will normalize each channel of the torch.*Tensor, i.e.
channel = (channel - mean) / std
Args:
mean (sequence): Sequence of means for R, G, B channels respectively.
std (sequence): Sequence of standard deviations for R, G, B channels
respectively.
"""
def __init__(self):
super(DataNormTranspose, self).__init__()
self.mean = Tensor(np.array([0.485 * 255, 0.456 * 255, 0.406 * 255]).reshape((1, 1, 1, 3)), mstype.float32)
self.std = Tensor(np.array([0.229 * 255, 0.224 * 255, 0.225 * 255]).reshape((1, 1, 1, 3)), mstype.float32)
def construct(self, x):
x = (x - self.mean) / self.std
x = F.transpose(x, (0, 3, 1, 2))
return x
class AlexNet(nn.Cell):
"""Alexnet"""
def __init__(self, num_classes=4, channel=3, phase='train', include_top=True, off_load=False):
super(AlexNet, self).__init__()
self.off_load = off_load
if self.off_load is True:
self.data_trans = DataNormTranspose()
self.conv1 = conv(channel, 64, 11, stride=4, pad_mode="same", has_bias=True)
self.conv2 = conv(64, 128, 5, pad_mode="same", has_bias=True)
self.conv3 = conv(128, 192, 3, pad_mode="same", has_bias=True)
self.conv4 = conv(192, 256, 3, pad_mode="same", has_bias=True)
self.conv5 = conv(256, 256, 3, pad_mode="same", has_bias=True)
self.relu = P.ReLU()
self.max_pool2d = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='valid')
self.include_top = include_top
if self.include_top:
dropout_ratio = 0.65
if phase == 'test':
dropout_ratio = 1.0
self.flatten = nn.Flatten()
self.fc1 = fc_with_initialize(6 * 6 * 256, 4096)
self.fc2 = fc_with_initialize(4096, 4096)
self.fc3 = fc_with_initialize(4096, num_classes)
self.dropout = nn.Dropout(dropout_ratio)
def construct(self, x):
"""define network"""
if self.off_load is True:
x = self.data_trans(x)
x = self.conv1(x)
x = self.relu(x)
x = self.max_pool2d(x)
x = self.conv2(x)
x = self.relu(x)
x = self.max_pool2d(x)
x = self.conv3(x)
x = self.relu(x)
x = self.conv4(x)
x = self.relu(x)
x = self.conv5(x)
x = self.relu(x)
x = self.max_pool2d(x)
if not self.include_top:
return x
x = self.flatten(x)
x = self.fc1(x)
x = self.relu(x)
x = self.dropout(x)
x = self.fc2(x)
x = self.relu(x)
x = self.dropout(x)
x = self.fc3(x)
return x
复制 AlexNet 配置参数(局部)
GoogLeNet 参数如下
GoogLeNet 网络结构,输出图像先通过卷积层和池化层后输出 inception 3、inception 4 和 inception 5 解决,并在 inception 4a 和 inception 4d 局部连贯辅助分类器,再经随机失活、展平和 softmax 失去输入概率分布。网络构建代码 ”””GoogleNet”””
import mindspore.nn as nn
from mindspore.common.initializer import TruncatedNormal
from mindspore.ops import operations as P
def weight_variable():
"""Weight variable."""
return TruncatedNormal(0.02)
class Conv2dBlock(nn.Cell):
"""
Basic convolutional block
Args:
in_channles (int): Input channel.
out_channels (int): Output channel.
kernel_size (int): Input kernel size. Default: 1
stride (int): Stride size for the first convolutional layer. Default: 1.
padding (int): Implicit paddings on both sides of the input. Default: 0.
pad_mode (str): Padding mode. Optional values are "same", "valid", "pad". Default: "same".
Returns:
Tensor, output tensor.
"""def __init__(self, in_channels, out_channels, kernel_size=1, stride=1, padding=0, pad_mode="same"):
super(Conv2dBlock, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride,padding=padding, pad_mode=pad_mode, weight_init=weight_variable())
self.bn = nn.BatchNorm2d(out_channels, eps=0.001)
self.relu = nn.ReLU()
def construct(self, x):
x = self.conv(x)
x = self.bn(x)
x = self.relu(x)
return x
class Inception(nn.Cell):
"""Inception Block"""
def __init__(self, in_channels, n1x1, n3x3red, n3x3, n5x5red, n5x5, pool_planes):
super(Inception, self).__init__()
self.b1 = Conv2dBlock(in_channels, n1x1, kernel_size=1)
self.b2 = nn.SequentialCell([Conv2dBlock(in_channels, n3x3red, kernel_size=1),Conv2dBlock(n3x3red, n3x3, kernel_size=3, padding=0)])
self.b3 = nn.SequentialCell([Conv2dBlock(in_channels, n5x5red, kernel_size=1),Conv2dBlock(n5x5red, n5x5, kernel_size=3, padding=0)])
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=1, pad_mode="same")
self.b4 = Conv2dBlock(in_channels, pool_planes, kernel_size=1)
self.concat = P.Concat(axis=1)
def construct(self, x):
branch1 = self.b1(x)
branch2 = self.b2(x)
branch3 = self.b3(x)
cell = self.maxpool(x)
branch4 = self.b4(cell)
return self.concat((branch1, branch2, branch3, branch4))
class GoogLeNet(nn.Cell):
"""Googlenet architecture"""
def __init__(self, num_classes, include_top=True):
super(GoogLeNet, self).__init__()
self.conv1 = Conv2dBlock(3, 64, kernel_size=7, stride=2, padding=0)
self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same")
self.conv2 = Conv2dBlock(64, 64, kernel_size=1)
self.conv3 = Conv2dBlock(64, 192, kernel_size=3, padding=0)
self.maxpool2 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same")
self.block3a = Inception(192, 64, 96, 128, 16, 32, 32)
self.block3b = Inception(256, 128, 128, 192, 32, 96, 64)
self.maxpool3 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same")
self.block4a = Inception(480, 192, 96, 208, 16, 48, 64)
self.block4b = Inception(512, 160, 112, 224, 24, 64, 64)
self.block4c = Inception(512, 128, 128, 256, 24, 64, 64)
self.block4d = Inception(512, 112, 144, 288, 32, 64, 64)
self.block4e = Inception(528, 256, 160, 320, 32, 128, 128)
self.maxpool4 = nn.MaxPool2d(kernel_size=2, stride=2, pad_mode="same")
self.block5a = Inception(832, 256, 160, 320, 32, 128, 128)
self.block5b = Inception(832, 384, 192, 384, 48, 128, 128)
self.dropout = nn.Dropout(keep_prob=0.8)
self.include_top = include_top
if self.include_top:
self.mean = P.ReduceMean(keep_dims=True)
self.flatten = nn.Flatten()
self.classifier = nn.Dense(1024, num_classes, weight_init=weight_variable(),bias_init=weight_variable())
def construct(self, x):
"""construct"""
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.maxpool2(x)
x = self.block3a(x)
x = self.block3b(x)
x = self.maxpool3(x)
x = self.block4a(x)
x = self.block4b(x)
x = self.block4c(x)
x = self.block4d(x)
x = self.block4e(x)
x = self.maxpool4(x)
x = self.block5a(x)
x = self.block5b(x)
if not self.include_top:
return x
x = self.mean(x, (2, 3))
x = self.flatten(x)
x = self.classifier(x)
return x
复制 GoogLeNet 网络训练参数(局部)
AlexNet 模型训练定义数据集函数 ”””Produce the dataset”””
import mindspore.dataset as ds
import mindspore.dataset.vision.c_transforms as CV
def create_dataset_imagenet(cfg, dataset_path, batch_size=32, repeat_num=1, training=True,
shuffle=True, sampler=None, class_indexing=None):
"""
create a train or eval imagenet2012 dataset for resnet50
Args:
dataset_path(string): the path of dataset.
do_train(bool): whether dataset is used for train or eval.
repeat_num(int): the repeat times of dataset. Default: 1
batch_size(int): the batch size of dataset. Default: 32
target(str): the device target. Default: Ascend
Returns:
dataset
"""
data_set = ds.ImageFolderDataset(dataset_path, shuffle=shuffle, sampler=sampler, class_indexing=class_indexing)
image_size = 224
# define map operations
transform_img = []
if training:
transform_img = [CV.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
CV.RandomHorizontalFlip(prob=0.5)
]
else:
transform_img = [CV.Decode(),
CV.Resize((256, 256)),
CV.CenterCrop(image_size)
]
data_set = data_set.map(input_columns="image", operations=transform_img)
data_set = data_set.batch(batch_size, drop_remainder=True)
# apply dataset repeat operation
if repeat_num > 1:
data_set = data_set.repeat(repeat_num)
return data_set
复制实例化模型 import time
import mindspore.nn as nn
from mindspore import Tensor
from mindspore.train import Model
from mindspore.nn.metrics import Accuracy
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor
from mindspore.train.loss_scale_manager import DynamicLossScaleManager, FixedLossScaleManager
from A_2AlexNet import AlexNet
from A_3CreatDs import create_dataset_imagenet
from A_4Generator_lr import get_lr
from A_5Get_param_groups import get_param_groups
from A_6Config import Config_Net as config
ds & net
_off_load = True
train_ds_path=’../datasets/train_10dB’
ds_train = create_dataset_imagenet(config, train_ds_path, config.batch_size,training=True)
network = AlexNet(config.num_classes, phase=’train’, off_load=_off_load)
metrics = {“Accuracy”: Accuracy()}
step_per_epoch = ds_train.get_dataset_size()
loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction=”mean”)
lr = get_lr(config)
opt = nn.Momentum(params=get_param_groups(network),
learning_rate=Tensor(lr),
momentum=config.momentum,
weight_decay=config.weight_decay,
loss_scale=config.loss_scale)
loss_scale_manager = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False)
model = Model(network,loss_fn=loss,optimizer=opt,metrics=metrics,loss_scale_manager=loss_scale_manager)
save ckpt
ckpt_save_dir = config.save_checkpoint_path
time_cb = TimeMonitor(data_size=step_per_epoch)
config_ck = CheckpointConfig(save_checkpoint_steps=config.save_checkpoint_epochs,
keep_checkpoint_max=config.keep_checkpoint_max)
ckpoint_cb = ModelCheckpoint(prefix=”alexnet”, directory=ckpt_save_dir, config=config_ck)
train
model.train(config.epoch_size, ds_train, callbacks=[time_cb, ckpoint_cb, LossMonitor()])
复制验证 import mindspore.nn as nn
from mindspore import Model,load_checkpoint,load_param_into_net
from A_2AlexNet import AlexNet
from A_3CreatDs import create_dataset_imagenet
from A_6Config import Config_Net as config
eval
eval_ds_path=’../datasets/5dB_eval’ #import eval_ds
eval_dataset = create_dataset_imagenet(cfg=config,dataset_path=eval_ds_path,batch_size=50,training=False)
net_eval = AlexNet(config.num_classes, phase=’test’, off_load=True)
ckpt_path=’../ckpt/A/5dB/alexnet-100_54_0.12973762.ckpt’ #import ckpt
eval_ds_dict = load_checkpoint(ckpt_path)
load_param_into_net(net_eval, eval_ds_dict)
net_eval.set_train(False)
loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction=”mean”)
metrics = {‘accuracy’: nn.Accuracy(),
'ConfusionMatrix':nn.ConfusionMatrix(config.num_classes)}#'2':nn.ConfusionMatrixMetric
model_eval=Model(network=net_eval,loss_fn=loss,metrics=metrics) #model ok
eval_result = model_eval.eval(eval_dataset)
print(“accuracy: “,eval_result)
复制 GoogLeNet 训练 import time
from mindspore.nn.optim.momentum import Momentum
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor
from mindspore.train.model import Model
from mindspore.train.loss_scale_manager import DynamicLossScaleManager, FixedLossScaleManager
from mindspore import Tensor
from G_2GoogLeNet import GoogLeNet
from G_3Dateset import create_dataset_imagenet
from G_4Lossfun import CrossEntropySmooth
from G_5Config import Config_Net as cfg
from G_6Get_lr import get_lr
def get_param_groups(network):
"""get param groups"""
decay_params = []
no_decay_params = []
for x in network.trainable_params():
parameter_name = x.name
if parameter_name.endswith('.bias'):
# all bias not using weight decay
no_decay_params.append(x)
elif parameter_name.endswith('.gamma'):
# bn weight bias not using weight decay, be carefully for now x not include BN
no_decay_params.append(x)
elif parameter_name.endswith('.beta'):
# bn weight bias not using weight decay, be carefully for now x not include BN
no_decay_params.append(x)
else:
decay_params.append(x)
return [{'params': no_decay_params, 'weight_decay': 0.0}, {'params': decay_params}]
ds & net
train_ds_path=’../datasets/2dB_train’
train_ds = create_dataset_imagenet(train_ds_path,training=True,batch_size=cfg.batch_size)
batch_num = train_ds.get_dataset_size()
net_train = GoogLeNet(num_classes=cfg.num_classes)
lr = get_lr(cfg)
opt = Momentum(params=get_param_groups(net_train),
learning_rate=Tensor(lr), #cfg.lr_init
momentum=cfg.momentum,
weight_decay=cfg.weight_decay,
loss_scale=cfg.loss_scale)
loss = CrossEntropySmooth(sparse=True,reduction=”mean”,smooth_factor=cfg.label_smooth_factor,num_classes=cfg.num_classes)
loss_scale_manager = FixedLossScaleManager(cfg.loss_scale, drop_overflow_update=False)
model = Model(net_train,loss_fn=loss,optimizer=opt,metrics={‘acc’},
keep_batchnorm_fp32=False,loss_scale_manager=loss_scale_manager)
save ckpt
ckpt_save_dir = cfg.save_checkpoint_path
config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_epochs, keep_checkpoint_max=cfg.keep_checkpoint_max)
ckpoint_cb = ModelCheckpoint(prefix=”googlenet”, directory=ckpt_save_dir, config=config_ck)
loss_cb = LossMonitor()
time_cb = TimeMonitor(data_size=batch_num)
cbs = [time_cb, ckpoint_cb, loss_cb]
train
model.train(cfg.epoch_size, train_ds, callbacks=cbs)
复制试验后果灰度图灰度图数据集类型
灰度图数据集下不同网络混同矩阵
灰度图数据集下,因为应用数据集 SNR 均为 10dB,加之网络模型参数通过试验微调,所以初始准确率整体别离达 81.27%、85.47% 和 86.00%,其中各网络均对 QPSK 辨认成果较好,而 16QAM、64QAM、8PSK 和 APSK 辨认成果较差,这与调制类型样本点数量和生成图像形态相干。灰度加强图进一步应用灰度加强图对 AlexNet 和 GoogLeNet 训练验证,察看联合间隔衰减模型后的灰度加强图对图像特色改良成果。灰度加强图数据集类型
灰度加强图数据集下不同网络混同矩阵
结果显示应用 AlexNet 时 8PSK、APSK 和 QPSK 辨认准确率达 90% 以上,但 16QAM 局部被谬误分类为 64QAM 和 APSK,一些 64QAM 被则谬误辨认为 QPSK 和 16QAM。应用 GoogLeNet 时 8PSK、APSK 和 QPSK 辨认成果较好,但 16QAM 和 64QAM 因图像类似而被局部辨认谬误。总体上看灰度加强图整体成果优于灰度图。三通道图试验后果鉴于 RGB 图更符合网络分类数据格式,对信噪比 2dB、5dB 和 10dB 的 RGB 数据集训练验证,察看成果。三通道图数据集类型
2dB RGB 数据集下不同网络混同矩阵
在低信噪比 2dB 时整体识别率较低,多种调制信号图像特色存在含糊和重叠,导致网络特征提取艰难。AlexNet 网络中 APSK 后果尤为显著,图像大部分被谬误辨认为 8PSK。GoogLeNet 因为不同特征提取形式并没有呈现这种情况,但总体的识别率也较低。5dB RGB 数据集下不同网络混同矩阵
在信噪比 5dB 时状况则大大改观,AlexNet 和 GoogLeNet 网络均匀识别率别离达 97.87% 和 98.13%,分类辨认成果极佳,这体现出了网络分类辨认成果的低劣性能,这时能对绝大多数盲调制信号正确辨认,具备很高实用价值和开发后劲。10dB RGB 数据集下不同网络混同矩阵
图像信噪比 10dB 时 AlexNet 和 GoogLeNet 网络的混同矩阵,网络对调制信号辨认精度均达到 100%。阐明 10dB 下网络能十分精确的提却不同调制信号图像的特色信息,对盲调制信号图像识别能无效利用深度学习网络参数模型对其精准分类。工夫复杂度剖析工夫复杂度是对网络以及试验设施能力的评估。经样本数据多轮试验,对每个网络的训练工夫统计平均值。本试验处理器为英特尔 Core i7-8700K CPU @ 3.70GHz,Windows 7 操作系统。网络均匀计算工夫统计如下
本试验基于 CPU 设施实现,若对速度和性能有更高的要求还可借助 GPU 或昇腾处理器对网络训练其对海量数据的计算解决有更大劣势,其中昇腾处理器除了计算能力的劣势还具备完满适配网络框架的能力。总结将试验过程所中得辨认准确率作图比照
在高信噪比状况下,AlexNet 对灰度图、灰度加强图和三通道图的辨认准确率由 80% 无余逐渐晋升至 100%,GoogLeNet 对灰度图、灰度加强图和三通道的识别率由 85% 逐渐晋升至 100%,这阐明图像处理过程对图像的无效特色产生了踊跃影响。对于 RGB 图像来说,两组网络在调制信号信噪比 2dB 时识别率别离约为 80% 和 90%,信噪比 10dB 时识别率均达到 100%,有了极大晋升。试验结果表明,三通道图比灰度图有更高的识别率,信噪比高的调制信号更容易被正确辨认,对于网络而言 AlexNet 运算速度更快,GoogLeNet 辨认准确率更高,在应用信噪比为 10dB 的三通道图像时,以上两种网络识别率均为 100%。