RadioML 2016.10a 调制方式识别

news2024/12/23 14:33:20

RadioML 2016.10a 调制方式识别 MLP、CNN、ResNet

image-20240619100129670

image-20240619100620198

X = [] 
lbl = []
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))
X = np.vstack(X)
file.close()

image-20240619100632708

上述论文的分类任务是识别和区分不同类型的无线电调制方式。

项目地址:https://github.com/daetz-coder/RadioML2016.10a_CNN

数据链接:https://pan.baidu.com/s/1sxyWf4M0ouAloslcXSJe9w?pwd=2016 
提取码:2016

下面介绍具体的处理方式,首先为了方便数据加载,根据SNR的不同划分为多个csv子文件

import pickle
import pandas as pd

# 指定pickle文件路径
pickle_file_path = './data/RML2016.10a_dict.pkl'

# 加载数据
with open(pickle_file_path, 'rb') as file:
    data_dict = pickle.load(file, encoding='latin1')

# 创建一个字典,用于按SNR组织数据
data_by_snr = {}

# 遍历数据字典,将数据按SNR分组
for key, value in data_dict.items():
    mod_type, snr = key
    if snr not in data_by_snr:
        data_by_snr[snr] = {}
    if mod_type not in data_by_snr[snr]:
        data_by_snr[snr][mod_type] = []
    # 只保留1000条数据
    data_by_snr[snr][mod_type].extend(value[:1000])

# 创建并保存每个SNR对应的CSV文件
for snr, mod_data in data_by_snr.items():
    combined_df = pd.DataFrame()
    for mod_type, samples in mod_data.items():
        for sample in samples:
            flat_sample = sample.flatten()
            temp_df = pd.DataFrame([flat_sample], columns=[f'Sample_{i}' for i in range(flat_sample.size)])
            temp_df['Mod_Type'] = mod_type
            temp_df['SNR'] = snr
            combined_df = pd.concat([combined_df, temp_df], ignore_index=True)
    
    # 保存到CSV文件
    csv_file_path = f'output_data_snr_{snr}.csv'
    combined_df.to_csv(csv_file_path, index=False)
    print(f"CSV file saved for SNR {snr}: {csv_file_path}")

print("Data processing complete. All CSV files saved.")

一、模型划分

0、Baseline

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset, random_split
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# 加载数据
csv_file_path = 'snr_data/output_data_snr_6.csv'
data_frame = pd.read_csv(csv_file_path)

# 提取前256列数据并转换为张量
vectors = torch.tensor(data_frame.iloc[:, :256].values, dtype=torch.float32)

# 划分训练集和测试集索引
train_size = int(0.8 * len(vectors))
test_size = len(vectors) - train_size
train_indices, test_indices = random_split(range(len(vectors)), [train_size, test_size])

# 使用训练集的统计量进行归一化
train_vectors = vectors[train_indices]
train_mean = train_vectors.mean(dim=0, keepdim=True)
train_std = train_vectors.std(dim=0, keepdim=True)

vectors = (vectors - train_mean) / train_std

# 转置和重塑为16x16 若MLP 无需重构
vectors = vectors.view(-1, 16, 16).unsqueeze(1).permute(0, 1, 3, 2)  # 添加通道维度并进行转置


# 提取Mod_Type列并转换为数值标签
mod_types = data_frame['Mod_Type'].astype('category').cat.codes.values
labels = torch.tensor(mod_types, dtype=torch.long)

# 创建TensorDataset
dataset = TensorDataset(vectors, labels)

# 创建训练集和测试集
train_dataset = TensorDataset(vectors[train_indices], labels[train_indices])
test_dataset = TensorDataset(vectors[test_indices], labels[test_indices])

# 创建DataLoader
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

这里需要加载具体模型

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 100
train_losses = []
test_losses = []
train_accuracies = []
test_accuracies = []

def calculate_accuracy(outputs, labels):
    _, predicted = torch.max(outputs, 1)
    total = labels.size(0)
    correct = (predicted == labels).sum().item()
    return correct / total

for epoch in range(num_epochs):
    # 训练阶段
    model.train()
    running_loss = 0.0
    correct = 0
    total = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        correct += (outputs.argmax(1) == labels).sum().item()
        total += labels.size(0)
    train_loss = running_loss / len(train_loader)
    train_accuracy = correct / total
    train_losses.append(train_loss)
    train_accuracies.append(train_accuracy)
    
    # 测试阶段
    model.eval()
    running_loss = 0.0
    correct = 0
    total = 0
    with torch.no_grad():
        for inputs, labels in test_loader:
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            running_loss += loss.item()
            correct += (outputs.argmax(1) == labels).sum().item()
            total += labels.size(0)
    test_loss = running_loss / len(test_loader)
    test_accuracy = correct / total
    test_losses.append(test_loss)
    test_accuracies.append(test_accuracy)
    
    print(f"Epoch [{epoch+1}/{num_epochs}], Train Loss: {train_loss:.4f}, Train Accuracy: {train_accuracy:.4f}, Test Loss: {test_loss:.4f}, Test Accuracy: {test_accuracy:.4f}")

print("Training complete.")

image-20240619123116251

# 计算混淆矩阵
all_labels = []
all_predictions = []

model.eval()
with torch.no_grad():
    for inputs, labels in test_loader:
        outputs = model(inputs)
        _, predicted = torch.max(outputs, 1)
        all_labels.extend(labels.numpy())
        all_predictions.extend(predicted.numpy())

# 绘制混淆矩阵
cm = confusion_matrix(all_labels, all_predictions)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=data_frame['Mod_Type'].astype('category').cat.categories)
disp.plot(cmap=plt.cm.Blues)
plt.show()

1、MLP

from torchinfo import summary
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(256, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 11)  # 有11种调制类型

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = SimpleNN()
# 打印模型结构和参数
summary(model, input_size=(1, 256))

image-20240619122355039

image-20240619122600032

image-20240619122623890

2、CNN

# 定义模型
from torchinfo import summary
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.bn1 = nn.BatchNorm2d(16)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm2d(32)
        self.dropout = nn.Dropout(0.3)
        self.fc1 = nn.Linear(32*4*4, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 11)  # 11种调制类型

    def forward(self, x):
        x = torch.relu(self.bn1(self.conv1(x)))
        x = torch.max_pool2d(x, 2)
        x = torch.relu(self.bn2(self.conv2(x)))
        x = torch.max_pool2d(x, 2)
        x = x.view(x.size(0), -1)
        x = torch.relu(self.fc1(x))
        x = self.dropout(x)
        x = torch.relu(self.fc2(x))
        x = self.dropout(x)
        x = self.fc3(x)
        return x

model = SimpleCNN()
summary(model, input_size=(1, 1,16,16))

image-20240619122341650

image-20240619122652005

image-20240619122657948

3、ResNet

# 定义ResNet基本块
from torchinfo import summary
class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, in_planes, planes, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.shortcut = nn.Sequential()
        if stride != 1 or in_planes != self.expansion * planes:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_planes, self.expansion * planes, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(self.expansion * planes)
            )

    def forward(self, x):
        out = torch.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)
        out = torch.relu(out)
        return out

# 定义ResNet
class ResNet(nn.Module):
    def __init__(self, block, num_blocks, num_classes=11):
        super(ResNet, self).__init__()
        self.in_planes = 16

        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(16)
        self.layer1 = self._make_layer(block, 16, num_blocks[0], stride=1)
        self.layer2 = self._make_layer(block, 32, num_blocks[1], stride=2)
        self.linear = nn.Linear(32*4*4*4, num_classes)

    def _make_layer(self, block, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []
        for stride in strides:
            layers.append(block(self.in_planes, planes, stride))
            self.in_planes = planes * block.expansion
        return nn.Sequential(*layers)

    def forward(self, x):
        out = torch.relu(self.bn1(self.conv1(x)))
        out = self.layer1(out)
        out = self.layer2(out)
        out = torch.flatten(out, 1)
        out = self.linear(out)
        return out

def ResNet18():
    return ResNet(BasicBlock, [2, 2])

model = ResNet18()
summary(model, input_size=(1, 1,16,16))

image-20240619122312714

image-20240619122714985

image-20240619122722813

可以发现在三种模型下非常容易过拟合,为了探究是否是SNR的造成的影响,故修改SNR数值,进行下述实验

二、SNR划分

根据SNR的计算公式来看,-20db表示噪声的功率是信号的100倍,其余以此类推

image-20240619125247448

1、SNR(-20) min

image-20240619125210047

image-20240619125216547

image-20240619125223002

2、SNR(-6)

image-20240619125029174

image-20240619124938229

image-20240619124944334

3、SNR(0)

image-20240619125019091

image-20240619124959152

image-20240619125006416

4、SNR(6)

image-20240619125047770

image-20240619125110720

image-20240619125117493

5、SNR(18) max

image-20240619125138169

image-20240619125145635

image-20240619125151302

从实验结果来看,趋势还是比较符合预期,总体上SNR越大检测的性能越好,尤其是当SNR=-20db时无法区分任何一种类型

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

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

相关文章

深度解析ISO9001质量管理体系认证的核心优势

ISO9001质量管理体系认证是一项全球通用的标准,旨在帮助企业优化质量管理,提升市场竞争力。本文将详细解析ISO9001认证为企业带来的多重核心优势。 首先,ISO9001认证显著提升了企业的产品和服务质量。通过建立和实施系统化的质量管理流程&…

一个简单、快速用于训练和微调中等规模GPT模型的开源项目

大家好,今天给大家分享的是一个简单、快速用于训练和微调中等规模GPT模型的开源项目,该项目旨在拓宽深度学习领域的应用,特别是为深度学习的入门者提供便利。 Nano GPT是一个基于PyTorch的开源项目,由前特斯拉AI负责人Andrej Ka…

【Windows】一键设置默认浏览器

最近,有人向我求助,希望我能帮助他们实现一键设置Chrome为默认浏览器。我心想,这有何难?改个注册表不就搞定了嘛。很多软件不都是这么做的吗?找到对应的注册表项,快速、准确地修改,然后…结果却…

24计算机应届生的活路是什么

不够大胆❗ 很多小伙伴在找工作时觉得自己没有竞争力,很没有自信,以至于很害怕找工作面试,被人否定的感觉很不好受。 其实很多工作并没有想象中的高大上,不要害怕,计算机就业的方向是真的广,不要走窄了&…

用android如何实现计算机计算功能

一.新建一个项目 步骤&#xff1a; 1.新建项目 2.选择 二.用户界面构建 找到项目的res的下面layout里面的activity.xml文件进行约束布局界面构建。 activity.xml代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.c…

Word页码设置,封面无页码,目录摘要阿拉伯数字I,II,III页码,正文开始123为页码

一、背景 使用Word写项目书或论文时&#xff0c;需要正确插入页码&#xff0c;比如封面无页码&#xff0c;目录摘要阿拉伯数字I&#xff0c;II&#xff0c;III为页码&#xff0c;正文开始以123为页码&#xff0c;下面介绍具体实施方法。 所用Word版本&#xff1a;2021 二、W…

【机器学习】第3章 K-近邻算法

一、概念 1.K-近邻算法&#xff1a;也叫KNN 分类 算法&#xff0c;其中的N是 邻近邻居NearestNeighbor的首字母。 &#xff08;1&#xff09;其中K是特征值&#xff0c;就是选择离某个预测的值&#xff08;例如预测的是苹果&#xff0c;就找个苹果&#xff09;最近的几个值&am…

Ollama(docker)+ Open Webui(docker)+Comfyui

Windows 系统可以安装docker desktop 相对比较好用一点&#xff0c;其他的应该也可以 比如rancher desktop podman desktop 安装需要windows WSL 安装ollama docker docker run -d --gpusall -v D:\ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama 这里…

AI视频智能监管赋能城市管理:打造安全有序的城市环境

一、方案背景 随着城市化进程的加速和科技的飞速发展&#xff0c;街道治安问题日益凸显&#xff0c;治安监控成为维护社会稳定和保障人民安全的重要手段。当前&#xff0c;许多城市已经建立了较为完善的治安监控体系&#xff0c;但仍存在一些问题。例如&#xff0c;监控设备分…

20240619在飞凌OK3588-C的Linux R4系统下查找MIPI YUV摄像头的csi size err

20240619在飞凌OK3588-C的Linux R4系统下查找MIPI YUV摄像头的csi size err 2024/6/19 14:00 缘起&#xff0c;公司使用LVDS OUT的机芯&#xff0c;4LANE的LVDS输出。1920x108030分辨率&#xff08;1080p/30&#xff09; 通过FPGA转换为2LANE的MIPI OUT之后进RK3588/OK3588-C。…

加油团油卡密优惠系统开发之多平台兼容性及适配(二)

一、引言 随着科技的快速发展和设备的多样化&#xff0c;确保软件系统在不同平台上的兼容性及适配变得越来越重要。加油团油卡密优惠系统作为一款面向广大用户的在线服务系统&#xff0c;其多平台兼容性及适配的优劣直接影响到用户的体验和使用效果。本文将进一步探讨如何提升…

红队实战宝典之内网渗透测试

本文源自《红队实战宝典之内网渗透测试》一书前言。 近年来&#xff0c;随着计算机网络技术的发展和应用范围的扩大&#xff0c;不同结构、不同规模的局域网和广域网迅速遍及全球。 以互联网为代表的计算机网络技术在短短几十年内经历了从0到1、从简单到复杂的飞速发展&#…

重磅!首个跨平台的通用Linux端间互联组件Klink在openKylin开源

随着智能终端设备的普及&#xff0c;多个智能终端设备之间的互联互通应用场景日益丰富&#xff0c;多设备互联互通应用场景需要开发者单独实现通讯协议。因此&#xff0c;为解决跨平台互联互通问题&#xff0c;由openKylin社区理事单位麒麟软件旗下星光麒麟团队成立的Connectiv…

Python微磁学磁倾斜和西塔规则算法

&#x1f4dc;有限差分-用例 &#x1f4dc;离散化偏微分方程求解器和模型定型 | &#x1f4dc;三维热传递偏微分方程解 | &#x1f4dc;特定资产期权价值偏微分方程计算 | &#x1f4dc;三维波偏微分方程空间导数计算 | &#x1f4dc;应力-速度公式一阶声波方程模拟二维地震波…

tkinter实现一个GUI界面-快速入手

目录 一个简单界面输出效果其他功能插入进度条文本框内容输入和删除标签内容显示和删除 一个简单界面 含插入文本、文本框、按钮、按钮调用函数 # -*- coding: UTF-8 -*-import tkinter as tk from tkinter import END from tkinter import filedialog from tkinter impor…

3d模型有个虚拟外框怎么去除?---模大狮模型网

在3D建模和渲染过程中&#xff0c;虚拟外框(Bounding Box)是一个常见的显示元素&#xff0c;用于表示模型的包围盒或选择状态。尽管虚拟外框在一些情况下有其作用&#xff0c;但在最终渲染或呈现阶段&#xff0c;我们通常希望清除这些辅助显示&#xff0c;以展示纯粹的模型效果…

[图解]企业应用架构模式2024新译本讲解14-服务层2

1 00:00:01,070 --> 00:00:01,820 我们来看案例 2 00:00:02,600 --> 00:00:06,620 案例也同样是之前跟事务脚本 3 00:00:07,030 --> 00:00:09,400 领域模型等等用过的案例是一样的 4 00:00:10,480 --> 00:00:12,700 这里译文改了一些 5 00:00:16,200 --> 00…

ai创作是什么?分享ai创作的方法

ai创作是什么&#xff1f;在当今这个信息爆炸的时代&#xff0c;文字的力量愈发显得重要。无论是日常沟通还是专业创作&#xff0c;我们都需要用文字来表达自己&#xff0c;传递思想。然而&#xff0c;面对海量的信息和快速变化的世界&#xff0c;如何高效地生成高质量的文字内…

高效、智能、稳定,LoRa监测终端为光伏跟踪支架系统保驾护航

在光伏发电领域&#xff0c;光伏跟踪支架作为提高光伏系统发电效率的关键技术之一&#xff0c;已经得到了广泛的应用。然而&#xff0c;如何有效地监测光伏跟踪支架的状态&#xff0c;确保其稳定、高效地运行&#xff0c;一直是业界关注的焦点。近年来&#xff0c;随着物联网技…

基础模型服务商SiliconCloud,新注册用户赠送 14 元的配额(约 1 亿 token)

注册链接&#xff1a;https://cloud.siliconflow.cn?referrerclx1f2kue00005c599dx5u8dz 开源模型可以自己部署&#xff0c;对服务器的要求还是挺高&#xff0c;以及学习成本、部署过程成本都是比较高&#xff0c;硅基流动SiliconFlow提供了另一个方式&#xff0c;可以像使用…