基于深度学习的无线电调制识别系统

基于深度学习的无线电调制识别系统

本项目实现了一个基于深度学习的无线电调制识别系统,使用LSTM(长短期记忆网络)模型对不同类型的
无线电信号进行自动分类识别。该系统能够在不同信噪比(SNR)条件下,准确识别多种调制类型,如BPSK、
QPSK、QAM16等。无线电调制识别是认知无线电、频谱监测和信号情报等领域的关键技术。传统方法依赖
专家设计的特征提取,而深度学习方法可以自动学习信号特征,提高识别准确率和鲁棒性。

在这里插入图片描述

数据集:本项目使用RadioML2016.10a数据集,这是一个广泛用于无线电调制识别研究的标准数据集。
数据集特点:包含10种调制类型,20种信噪比条件(从-20dB到18dB)
信号特征:每个样本包含128个时间步长,每个时间步长有I/Q两个通道
数据格式:输入形状为[样本数, 128, 2]
数据分割:数据集被分为训练集、验证集和测试集
在本项目中,选择以下调制类型进行识别:
GFSK (2FSK)、PAM4 (2ASK)、BPSK、QPSK、QAM16、QAM64、CPFSK、8PSK
模型架构
本项目使用了两层LSTM网络结构,具体如下:
CopyInsert
输入层: [128, 2](128个时间步长,每步2个特征:I/Q两个通道)
LSTM层1: 128个单元,return_sequences=True
LSTM层2: 128个单元
全连接层: 神经元数量等于调制类型数量
Softmax激活: 输出各调制类型的概率
LSTM模型的优势在于能够捕捉信号中的时序特征,这对于调制识别非常重要,因为不同调制方式的时域特征差异明显。

模型定义代码

CopyInsert
def LSTMModel(weights=None, input_shape=[128, 2], classes=11):if weights is not None and not os.path.exists(weights):raise ValueError('Invalid weights path.')
input_layer = Input(shape=input_shape, name='input')# 替代 CuDNNLSTM
x = LSTM(128, return_sequences=True, activation='tanh', recurrent_activation='sigmoid')(input_layer)
x = LSTM(128, activation='tanh', recurrent_activation='sigmoid')(x)output_layer = Dense(classes, activation='softmax', name='softmax')(x)model = Model(inputs=input_layer, outputs=output_layer)if weights:model.load_weights(weights)return model

5. 数据预处理
数据预处理是提高模型性能的关键步骤:
数据加载:从pickle文件加载RadioML2016.10a数据集
数据标准化:对每个样本进行L2归一化,提高模型的泛化能力

def norm_pad_zeros(X_train, nsamples):for i in range(X_train.shape[0]):X_train[i,:,0] = X_train[i,:,0]/la.norm(X_train[i,:,0],2)return X_train

幅度-相位转换:将I/Q数据转换为幅度和相位表示

def to_amp_phase(X_train, X_val, X_test, nsamples):X_train_cmplx = X_train[:,0,:] + 1j* X_train[:,1,:]X_train_amp = np.abs(X_train_cmplx)X_train_ang = np.arctan2(X_train[:,1,:], X_train[:,0,:]) / np.pi# ...

数据筛选:从所有调制类型中筛选出目标调制类型

selected_mods = ['GFSK', 'PAM4', 'BPSK', 'QPSK', 'QAM16', 'QAM64', 'CPFSK', '8PSK']
train_selected = [i for i in range(len(Y_train)) if mods[np.argmax(Y_train[i])] in selected_mods]
X_train_selected = X_train[train_selected]

标签重编码:将标签转换为独热编码(one-hot)形式

Y_train_selected_new = np.zeros((len(train_selected), len(selected_mods)))
for i, idx in enumerate(train_selected):mod = mods[np.argmax(Y_train[idx])]Y_train_selected_new[i, selected_mods_dict[mod]] = 1

6. 训练过程
损失函数:分类交叉熵(categorical_crossentropy)
优化器:Adam优化器
批量大小:400
训练轮数:最多100轮,配合早停策略
回调函数:
ModelCheckpoint:保存最佳模型
ReduceLROnPlateau:在验证损失停滞时降低学习率
EarlyStopping:在验证损失长时间不改善时提前停止训练
训练代码:

model = LSTMModel(weights=None, input_shape=[128, 2], classes=len(selected_mods))
model.compile(loss='categorical_crossentropy', metrics=['acc'], optimizer='adam')filepath = 'weights/weights.h5'
history = model.fit(X_train_selected,Y_train_selected_new,batch_size=batch_size,epochs=nb_epoch,verbose=2,validation_data=(X_val_selected, Y_val_selected_new),callbacks=[ModelCheckpoint(filepath, monitor='val_loss', save_best_only=True),ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6),EarlyStopping(monitor='val_loss', patience=50)])

7. 性能评估
模型评估采用多种方法:
混淆矩阵:直观展示各调制类型的识别准确率和错误类型

confnorm, _, _ = mltools.calculate_confusion_matrix(Y_test_selected_new, test_Y_hat, display_classes)
mltools.plot_confusion_matrix(confnorm, labels=display_classes, save_filename='picture/lstm_total_confusion.png')

不同信噪比下的性能:分析模型在不同信噪比条件下的表现

for i, snr in enumerate(snrs):indices = [j for j, s in enumerate(test_SNRs_selected) if s == snr]test_X_i = X_test_selected[indices]test_Y_i = Y_test_selected_new[indices]test_Y_i_hat = model.predict(test_X_i)confnorm_i, cor, ncor = mltools.calculate_confusion_matrix(test_Y_i, test_Y_i_hat, display_classes)acc[snr] = cor / (cor + ncor)
# 构建数据集
X = []
lbl = []
train_idx = []
val_idx = []
np.random.seed(2016)
a = 0# 遍历所有调制类型和信噪比
for mod in mods:for snr in snrs:X.append(Xd[(mod,snr)])for i in range(Xd[(mod,snr)].shape[0]):lbl.append((mod,snr))# 划分训练集和验证集train_idx += list(np.random.choice(range(a*1000,(a+1)*1000), size=600, replace=False))val_idx += list(np.random.choice(list(set(range(a*1000,(a+1)*1000))-set(train_idx)), size=200, replace=False))a += 1# 堆叠数据
X = np.vstack(X)
n_examples = X.shape[0]# 划分测试集
test_idx = list(set(range(0,n_examples))-set(train_idx)-set(val_idx))
np.random.shuffle(train_idx)
np.random.shuffle(val_idx)
np.random.shuffle(test_idx)# 提取数据子集
X_train = X[train_idx]
X_val = X[val_idx]
X_test = X[test_idx]# 转换为独热编码
def to_onehot(yy):yy1 = np.zeros([len(yy), len(mods)])yy1[np.arange(len(yy)), yy] = 1return yy1# 生成标签
Y_train = to_onehot(list(map(lambda x: mods.index(lbl[x][0]), train_idx)))
Y_val = to_onehot(list(map(lambda x: mods.index(lbl[x][0]), val_idx)))
Y_test = to_onehot(list(map(lambda x: mods.index(lbl[x][0]), test_idx)))# 转换为幅度-相位表示
X_train, X_val, X_test = to_amp_phase(X_train, X_val, X_test, 128)# 截断到最大长度
X_train = X_train[:,:maxlen,:]
X_val = X_val[:,:maxlen,:]
X_test = X_test[:,:maxlen,:]# 标准化
X_train = norm_pad_zeros(X_train, maxlen)
X_val = norm_pad_zeros(X_val, maxlen)
X_test = norm_pad_zeros(X_test, maxlen)return (mods, snrs, lbl), (X_train, Y_train), (X_val, Y_val), (X_test, Y_test), (train_idx, val_idx, test_idx)
selected_mods = ['GFSK', 'PAM4', 'BPSK', 'QPSK', 'QAM16', 'QAM64', 'CPFSK', '8PSK']
selected_mods_dict = {mod: i for i, mod in enumerate(selected_mods)}
display_classes = selected_mods

筛选与重新编码训练集

train_selected = [i for i in range(len(Y_train)) if mods[np.argmax(Y_train[i])] in selected_mods]
X_train_selected = X_train[train_selected]
Y_train_selected_new = np.zeros((len(train_selected), len(selected_mods)))
for i, idx in enumerate(train_selected):mod = mods[np.argmax(Y_train[idx])]Y_train_selected_new[i, selected_mods_dict[mod]] = 1

创建模型

model = culstm.LSTMModel(weights=None, input_shape=[128, 2], classes=len(selected_mods))
model.compile(loss='categorical_crossentropy', metrics=['acc'], optimizer='adam')

训练模型

filepath = 'weights/weights.h5'
history = model.fit(X_train_selected,Y_train_selected_new,batch_size=batch_size,epochs=nb_epoch,verbose=2,validation_data=(X_val_selected, Y_val_selected_new),callbacks=[ModelCheckpoint(filepath, monitor='val_loss', save_best_only=True),ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6),EarlyStopping(monitor='val_loss', patience=50)])

模型评估

score = model.evaluate(X_test_selected, Y_test_selected_new, verbose=1, batch_size=batch_size)
print("测试集性能:", score)

预测与绘图函数

def predict(model):# 加载最佳模型权重model.load_weights(filepath)# 预测测试集test_Y_hat = model.predict(X_test_selected, batch_size=batch_size)# 计算总体混淆矩阵confnorm, _, _ = mltools.calculate_confusion_matrix(Y_test_selected_new, test_Y_hat, display_classes)mltools.plot_confusion_matrix(confnorm,labels=display_classes,save_filename='picture/lstm_total_confusion.png')# 计算每个信噪比下的性能acc = {}acc_mod_snr = np.zeros((len(selected_mods), len(snrs)))test_SNRs_selected = [lbl[test_idx[i]][1] for i in test_selected]for i, snr in enumerate(snrs):# 筛选特定信噪比的样本indices = [j for j, s in enumerate(test_SNRs_selected) if s == snr]test_X_i = X_test_selected[indices]test_Y_i = Y_test_selected_new[indices]# 预测test_Y_i_hat = model.predict(test_X_i)# 计算混淆矩阵和准确率confnorm_i, cor, ncor = mltools.calculate_confusion_matrix(test_Y_i, test_Y_i_hat, display_classes)acc[snr] = cor / (cor + ncor)# 保存准确率with open('acc111.csv', 'a', newline='') as f:csv.writer(f).writerow([acc[snr]])# 绘制混淆矩阵mltools.plot_confusion_matrix(confnorm_i,labels=display_classes,title="Confusion Matrix SNR={}".format(snr),save_filename="picture/Confusion(SNR={})(ACC={:.2f}).png".format(snr, 100.0 * acc[snr]))# 计算每种调制类型在当前信噪比下的准确率acc_mod_snr[:, i] = np.round(np.diag(confnorm_i) / np.sum(confnorm_i, axis=1), 3)# 绘制所有调制方式准确率曲线plt.figure(figsize=(12, 8))for i in range(len(selected_mods)):plt.plot(snrs, acc_mod_snr[i], marker='o', label=display_classes[i])for x, y in zip(snrs, acc_mod_snr[i]):plt.text(x, y, '{:.2f}'.format(y), fontsize=8, ha='center', va='bottom')plt.xlabel("SNR (dB)")plt.ylabel("Accuracy")plt.title("Per-Modulation Classification Accuracy vs SNR (All Mods)")plt.legend(loc='best')plt.grid(True)plt.tight_layout()plt.savefig("picture/all_mods_acc.png", dpi=300)plt.close()# 保存结果数据with open('predictresult/acc_for_mod_on_lstm.dat', 'wb') as f:pickle.dump(acc_mod_snr, f)with open('predictresult/lstm.dat', 'wb') as f:pickle.dump(acc, f)# 绘制总体准确率曲线plt.plot(snrs, [acc[snr] for snr in snrs])plt.xlabel("SNR")plt.ylabel("Overall Accuracy")plt.title("Overall Classification Accuracy on RadioML2016.10a")plt.grid()plt.tight_layout()plt.savefig('picture/each_acc.png')

主要贡献:

使用深度学习方法自动提取信号特征,避免了传统方法中复杂的特征工程在不同信噪比条件下对多种调制类型进行识别,并分析了各调制类型的识别难度提供了完整的数据处理、模型训练和评估流程,便于后续研究和应用通过本项目,我们可以看到深度学习在信号处理领域的巨大潜力,它不仅简化了传统的特征工程过程,还能在复杂环境下取得更好的性能。随着深度学习技术的不断发展,我们可以期待更多创新应用在无线通信领域涌现。
https://pan.baidu.com/s/16FN0BR0LUkfpcxZizn43xw

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 爬虫之requests 模块的应用

requests 是用 python 语言编写的一个开源的HTTP库,可以通过 requests 库编写 python 代码发送网络请求,其简单易用,是编写爬虫程序时必知必会的一个模块。 requests 模块的作用 发送网络请求,获取响应数据。 中文文档&#xf…

随机森林(Random Forest)学习

随机森林是一种基于集成学习的机器学习算法,属于Bagging(Bootstrap Aggregating)方法的一种扩展。它通过组合多个决策树来提升模型的泛化能力和鲁棒性,广泛用于分类、回归和特征选择任务。 1.随机森林核心思想 1.1少数服从多数 在…

从 0 到 1!Java 并发编程基础全解析,零基础入门必看!

写在前面 博主在之前写了很多关于并发编程深入理解的系列文章,有博友反馈说对博主的文章表示非常有收获但是对作者文章的某些基础描述有些模糊,所以博主再根据最能接触到的基础,为这类博友进行扫盲!当然,后续仍然会接…

el-input宽度自适应方法总结

使用 style 或 class 直接设置宽度 可以通过内联样式或 CSS 类来直接设置 el-input 的宽度为 100%&#xff0c;使其自适应父容器的宽度 <template><div style"width: 100%;"><el-input style"width: 100%;" v-model"input">…

解决 Supabase “permission denied for table XXX“ 错误

解决 Supabase “permission denied for table” 错误 问题描述 在使用 Supabase 开发应用时&#xff0c;你可能会遇到以下错误&#xff1a; [Nest] ERROR [ExceptionsHandler] Object(4) {code: 42501,details: null,hint: null,message: permission denied for table user…

java每日精进 5.20【MyBatis 联表分页查询】

1. MyBatis XML 实现分页查询 1.1 实现方式 MyBatis XML 是一种传统的 MyBatis 使用方式&#xff0c;通过在 XML 文件中编写 SQL 语句&#xff0c;并结合 Mapper 接口和 Service 层实现分页查询。分页需要手动编写两条 SQL 语句&#xff1a;一条查询分页数据列表&#xff0c;…

linux taskset 查询或设置进程绑定CPU

1、安装 taskset larkubuntu&#xff1a;~$ sudo apt-get install util-linux larkubuntu&#xff1a;~$ taskset --help 用法&#xff1a; taskset [选项] [mask | cpu-list] [pid|cmd [args...]] 显示或更改进程的 CPU 关联性。 选项&#xff1a; -a&#xff0c; --all-tasks…

Python应用字符串格式化初解

大家好!在 Python 编程中&#xff0c;字符串格式化是一项基础且实用的技能。它能让你更灵活地拼接字符串与变量&#xff0c;使输出信息更符合需求。本文将为和我一样的初学者详细介绍 Python 字符串格式化的常用方法。 定义: 字符串格式化就是将变量或数据插入到字符串中的特定…

EasyRTC嵌入式音视频通信SDK一对一音视频通信,打造远程办公/医疗/教育等场景解决方案

一、方案概述​ 数字技术发展促使在线教育、远程医疗等行业对一对一实时音视频通信需求激增。传统方式存在低延迟、高画质及多场景适配不足等问题&#xff0c;而EasyRTC凭借音视频处理、高效信令交互与智能网络适配技术&#xff0c;打造稳定低延迟通信&#xff0c;满足基础通信…

SEO长尾词优化精准布局

内容概要 长尾关键词作为SEO策略的核心要素&#xff0c;其价值在于精准捕捉细分需求与低竞争流量入口。相较于短尾词的高泛化性&#xff0c;长尾词通过语义扩展与场景化组合&#xff0c;能够更高效地匹配用户搜索意图&#xff0c;降低优化成本的同时提升转化潜力。本文将从词库…

【MySQL】第7节|Mysql锁机制与优化实践以及MVCC底层原理剖析

锁等待分析 我们通过检查InnoDB_row_lock相关的状态变量来分析系统上的行锁的争夺情况 示例场景 假设有两个用户同时操作账户表 accounts&#xff08;主键为 id&#xff09;&#xff1a; 1. 用户A&#xff1a;执行转账&#xff0c;锁定账户 id1 并等待3秒&#xff1a; BEG…

基于规则引擎与机器学习的智能Web应用防火墙设计与实现

基于规则引擎与机器学习的智能Web应用防火墙设计与实现 引言&#xff1a;智能防御的必然选择 在2023年OWASP最新报告中&#xff0c;传统Web应用防火墙&#xff08;WAF&#xff09;对新型API攻击的漏报率高达67%&#xff0c;而误报导致的正常业务拦截损失每年超过2.3亿美元。面…

GIM发布新版本了 (附rust CLI制作brew bottle流程)

GIM 发布新版本了&#xff01;现在1.3.0版本可用了 可以通过brew upgrade git-intelligence-message升级。 初次安装需要先执行 brew tap davelet/gim GIM 是一个根据git仓库内文件变更自动生成git提交消息的命令行工具&#xff0c;参考前文《GIM: 根据代码变更自动生成git提交…

PyQt5高效布局指南:QTabWidget与QStackedWidget实战解析

&#x1f50d; 问题背景 当界面控件过多时&#xff0c;直接平铺会导致窗口拥挤、用户体验下降。PyQt5提供了两种高效容器控件&#xff1a; QTabWidget&#xff1a;选项卡式布局&#xff0c;支持直接切换不同功能模块QStackedWidget&#xff1a;堆栈式布局&#xff0c;需配合导…

《2.2.1顺序表的定义|精讲篇》

上一节学习了线性表的逻辑结构&#xff0c;线性表需要实现哪些基本运算/操作&#xff1f;在本节中&#xff0c;我们将学习顺序表的定义、顺序表的特性&#xff0c;以及如何用代码来实现顺序表。下个小节我们会介绍基于顺序存储&#xff08;这种存储结构&#xff09;如何用代码具…

【 大模型技术驱动智能网联汽车革命:关键技术解析与未来趋势】

大模型技术驱动智能网联汽车革命&#xff1a;关键技术解析与未来趋势 关键词总结&#xff1a; 大模型技术&#xff1a;LLM、VLM、MLLM、Transformer架构核心场景&#xff1a;智能驾驶、智能座舱、智能网联关键技术&#xff1a;端到端系统、BEVOCC网络、多模态融合、强化学习挑…

Rocketmq broker 是主从架构还是集群架构,可以故障自动转移吗

RocketMQ Broker的架构与故障转移机制 RocketMQ的Broker架构同时采用了主从架构和集群架构&#xff0c;并且支持故障自动转移。下面详细说明&#xff1a; 一、架构类型 1. 集群架构 RocketMQ天然支持分布式集群部署 一个RocketMQ集群包含多个Broker组(每组有主从) 不同Bro…

从零开始建立个人品牌并验证定位变现性的方法论——基于开源AI大模型、AI智能名片与S2B2C商城生态的实证研究

摘要&#xff1a;本文提出一种融合开源AI大模型、AI智能名片与S2B2C商城小程序源码的"最小测试闭环"方法论&#xff0c;通过技术赋能实现个人品牌定位的精准验证与变现路径优化。以某美妆领域自由职业者为例&#xff0c;其通过开源AI大模型完成能力图谱构建与资源匹配…

SQL进阶之旅 Day 2:高效的表设计与规范:从基础到实战

【SQL进阶之旅 Day 2】高效的表设计与规范&#xff1a;从基础到实战 开篇 在数据库开发中&#xff0c;一个良好的表设计不仅能够提高查询效率&#xff0c;还能避免冗余数据和一致性问题。本文作为"SQL进阶之旅"系列的第2天&#xff0c;将重点介绍高效的表设计与规范…

Java—— IO流的应用

带权重的点名系统 案例要求 文件中有学生的信息&#xff0c;每个学生的信息独占一行。包括学生的姓名&#xff0c;性别&#xff0c;权重 要求每次被抽中的学生&#xff0c;再次被抽中的概率在原先的基础上降低一半。 本题的核心就是带权重的随机 分析 权重&#xff0c;权重和…