声明:
本数据集不涉及任何机密,仅用于科研实验验证!!
数据集获取:
(方式一)联系微xin:cxw3020302521(需要50元作为劳动报酬,嫌贵勿扰!)
(方式二)联系邮箱:3020302521@qq.com(需要50元作为劳动报酬,嫌贵勿扰!)
数据集目录:
rfx_x中,第一个x表示第几个个体,第二个x表示第几种调制类型(0:二相编码/1:四相编码/2:单载频/3:二频编码/4:线性调频/5:非线性调频)
数据集详情:
为了满足不同功能雷达的性能需求,雷达发射机所发射的脉冲信号会经过不同的脉内调制后再通过信号放大链路及功放组件辐射到电磁空间。然而,除了用于初级雷 达信号产生的频率合成器会对雷达信号造成细微的个体差异外,信号放大链路及功率 放大器的非理想特性引入的信号指纹特征则最为明显。出于以上考虑,本文设计了如下图所示的基于 AD9910 直接数字频率合成器和 USRP-2954R 软件无线电设备的雷达辐射源信号模拟平台用于生成雷达辐射源识别信号数据集。
该信号模拟平台由信号发射机、信号接收机和信号处理机三部分组成,由信号处 理机中的通用计算机统一调度完成实验数据采集。信号发射机由 STM32f401ccu6 单 片机作为主控制器接收来自上位机软件的信号生成命令,然后通过 SPI 串行数据总线 控制 AD9910 直接数字频率合成器产生相应的已调雷达脉冲信号,最后通过单刀六掷 射频开关 HMC252 芯片选择相应的射频功放通道将经过放大后的脉冲信号发射出去,通过切换不同的功放通道实现不同雷达辐射源个体的模拟。信号接收机是一台 USRP-2954R 通用软件无线电设备,通过以太网接口与信号处理机中的通用计算机进行数据交互,负责将接收到的信号实时传输到信号处理机上。
系统硬件实物如上图所示,其中,AD9910 是一款内置 14 位 DAC 的直接数 字频率合成器(DDS),最高支持 1GSPS 采样速率,最高采样率下调谐分辨率约为 0.23Hz,可以在高达 400 MHz 的频率下生成频率捷变正弦波形,且内部集成静态 RAM, 支持信号频率、相位和震幅的多种组合调制。USRP-2954R 软件无线电设备中心频 率可以覆盖 10MHz 到 6GHz 的频段,最高收发瞬时带宽 160M。两者均被广泛应用于 雷达和通信等领域。 本文采用 AD9910 的 RAM 调制模式分别合成中心频率随机分布在 350MHz 到 400MHz 范围内的单载频(SF)、线性调频(LFM)、V 型非线性调频(NLFM)、二频编 码(BFSK)、二相编码(BPSK)和四相编码(QPSK)六种常用雷达辐射源脉冲信号,然后 经选定的射频功率放大器辐射出去。USRP-2954R 的中心频率对准 375MHz,采样率 设为 100MHz 对发射信号进行 I/Q 正交双通道采样。本文所选用的模拟雷达辐射源信 号频段及接收机频率设置如下图所示。
根据下表中所给出的参数范围,采集具有 6 个模拟辐射源个体,每个辐射源个体 6 种信号调制样式,每种调制样式 5000 个随机样本的,共计 18万个模拟雷达辐射源脉冲信号的数据集,供雷达辐射源识别算法模型的训练和有效性验证使用。
下图中展示了连续脉冲采样的情况,单个脉冲信号在整个采样序列中清晰可见,接收信号的信噪比较高。用户可以在拿到的脉冲数据中,通过 Matlab 软件仿真的方式,叠加高斯白噪声以模拟雷达辐射源信号在远距离传输过程中携带的信道噪声。
下图(a)到(f)中分别展示了加噪声之前六种不同调制类型的脉冲信号的实际采样效果,为了使得个体识别算法能够提取到脉冲信号的前后沿特征信息,本数据集在脉冲信号提取时保留了脉冲开始前和结束后的部分数据,保证单个脉冲信号的信息完整性。
在对原始采样信号进行脉冲提取和加噪处理后,为了使得雷达辐射源识别算法能够获取数值分布较为一致的输入,这里推荐一种采用平均包络幅值归一化的方法对所有硬件模拟数据进行预处理,该方法可表示为
式中 x 是未经归一化的雷达脉冲信号, mean( ) 是均值计算函数, abs( ) 是绝对值函数。
经过加噪和归一化预处理后的脉冲信号如上图所示,可以看出,信号有效部分的幅值被调整到了1左右。由于接收机在ADC采样前已经过滤了信号的直流分量, 所以信号基本满足零均值条件,故可以不再做特殊处理。
下面是数据集接口示例代码
# main.py提供了一个简单的数据集使用接口,以及一个示例CNN模型(仅用于数据集接口测试,没有实际算法参考价值)!!!!
# 1.拿到数据集后将全部数据解压到“data”文件夹下
# 2.将main.py放到“data”文件夹的上一级目录下
# 3.运行main.py
import os
import torch
import random
import scipy.io as scio
from torch.utils.data.dataset import Dataset
from torch.utils.data.dataloader import DataLoader
# ************************************数据集接口生成**************************
# 数据集列表生成
folder_path = './data/'
file_names = sorted([os.path.join('./data/', f) for f in os.listdir('./data/')], key=lambda x: (os.path.basename(x).lower(), os.path.basename(x).isdigit(), os.path.basename(x)))
#遍历36个mat文件,读取所有脉冲数据
rf_data_all=[]
for i in range(36):
data_file=scio.loadmat(file_names[i])
for j in range(5000):
#读取一个脉冲
S_org=data_file['data']['data'][0][j][0]
#将脉冲添加到数据集列表,列表每一项的结构为:【数据:[2,2049], 标签:[[1]]】
rf_data_all.append((torch.randn(2,len(S_org)), torch.tensor([[torch.tensor([[float(int(i/6))]])]])))#个体识别标签
# rf_data_all.append((torch.randn(2,len(S_org)), torch.tensor([[torch.tensor([[float(int(i%6))]])]])))#调制识别标签
rf_data_all[i*5000+j][0][0]=torch.from_numpy(S_org.real).float()
rf_data_all[i*5000+j][0][1]=torch.from_numpy(S_org.imag).float()
print(file_names[i],"read success")
print("rf_data_all_len=",len(rf_data_all))
# 重写collate_fn方法,获取一个batch的数据和标签
def collate_fn(data_seq):
# 数据
temp = [seq[0] for seq in data_seq]
data_out = torch.randn(len(temp), len(temp[0]), len(temp[0][0]))
for i in range(0, len(temp)):
for j in range(0, len(temp[0])):
data_out[i][j][0:len(temp[i][0])] = temp[i][j][0:len(temp[i][0])]
# 提取标签
label_out = torch.randn(len(temp)).long()
for i in range(0, len(temp)):
label_out[i] = data_seq[i][1][0]
return data_out, label_out
# 继承数据接口类
class dataset_cxw(Dataset):
def __init__(self, data_seq):
self.data_seq = data_seq
def __len__(self):
return len(self.data_seq)
def __getitem__(self, item):
return self.data_seq[item]
# 这里将所有数据按9:1分成训练集和测试集,用户可按照需求自行调整
random.shuffle(rf_data_all)#将总数据集随即打乱
train=rf_data_all[0 : int(0.9*len(rf_data_all))]#训练集列表
test =rf_data_all[int(0.9*len(rf_data_all)) : len(rf_data_all) ]#测试集列表
print("train_len=",len(train),"test_len=",len(test))
# 训练集数据接口生成
dataset_inst = dataset_cxw(train)
train_loader = DataLoader(dataset_inst, batch_size=5 , shuffle=True, collate_fn=collate_fn)
# 测试集数据接口生成
dataset_inst = dataset_cxw(test)
test_loader = DataLoader(dataset_inst, batch_size=1 , shuffle=True, collate_fn=collate_fn)
# *************************************示例CNN模型************************
# 定义模型结构(六分类示例)
class CNN (torch.nn.Module):
def __init__(self):
super().__init__()
# 一层卷积
self.conv1 = torch.nn.Conv1d(in_channels=2, out_channels=1, kernel_size=3, stride=1, padding=1, bias=True)
self.pool1 = torch.nn.MaxPool1d(kernel_size=2)
self.relu1 = torch.nn.ReLU()
# 一层全连接
self.flct1 = torch.nn.Linear(1024, 6)
def forward(self, x):
# 一层卷积
x = self.conv1(x)
x = self.pool1(x)
x = self.relu1(x)
# 一层全连接
x = torch.squeeze(x, dim=1)
x = self.flct1(x)
return x
# 模型例化
model= CNN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.00025, weight_decay=0)#优化器
loss_f = torch.nn.CrossEntropyLoss()#损失函数
#训练
for epoch in range(100):
for step, (x,y)in enumerate(train_loader):
# 前向计算
yp=model.forward(x)
#反向传播
loss = loss_f(yp, y) # 损失计算
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向梯度计算
optimizer.step() # 更新参数
print(loss)
#测试
for step, (x,y)in enumerate(test_loader):
yp=model.forward(x)
print("yp=",yp,"y=",y)