You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将.sigmf-data文件中的IQ样本输入至CNN分类器

基于IQ样本的CNN分类器数据输入解决方案

问题背景

正在构建针对解调IQ样本的CNN分类器,架构要求如下:

  • 包含2个卷积层、2个全连接层,共4层核心网络
  • 输入为加有功率<-13dB高斯噪声的窗化解调IQ序列,每个复数IQ由实部、虚部两个实数表示,单样本长度128,维度为2×128
  • 第一个卷积层:50个1×7尺寸的滤波器,后接ReLU激活
  • 第二个卷积层:50个2×7尺寸的滤波器,后接ReLU激活
  • 第一个全连接层:256个神经元,Dropout率50%,L2正则化参数0.0001
  • 第二个全连接层:80个神经元,Dropout率50%,L2正则化参数0.0001
  • 输出层:Softmax分类器,输出16类样本的概率
  • 优化器:Adam,学习率0.0001;损失函数:交叉熵;基于TensorFlow Keras实现

现有16个.sigmf-data格式的IQ样本文件,单文件加载代码如下,但不清楚如何将IQ数据适配CNN输入格式:

signal = sigmffile.fromfile("Demod_WiFi_cable_X310_3123D76_IQ#1_run1.sigmf-data")
samples = temp_signal.read_samples()

现有代码问题

原模型定义中输入形状((1,128,2,1))存在冗余维度,且未完成IQ样本的预处理流程,导致数据无法匹配模型输入要求。

完整解决方案

1. 数据加载与预处理

将复数IQ样本转换为CNN可接受的格式,同时生成对应类别标签:

import numpy as np
from sigmf import sigmffile
from tensorflow import keras
from sklearn.model_selection import train_test_split

def load_and_preprocess_iq_file(file_path, window_size=128, step_size=64):
    # 加载复数IQ样本
    signal = sigmffile.fromfile(file_path)
    samples = signal.read_samples()
    
    # 拆分实部与虚部,得到(N, 2)形状的数组
    iq_data = np.column_stack((samples.real, samples.imag))
    total_samples = len(iq_data)
    
    # 滑动窗口生成固定长度的样本
    windowed_samples = []
    for start_idx in range(0, total_samples - window_size + 1, step_size):
        window = iq_data[start_idx:start_idx+window_size]
        windowed_samples.append(window)
    
    # 扩展通道维度,适配Conv2D输入格式:(样本数, 128, 2, 1)
    windowed_samples = np.array(windowed_samples)
    return np.expand_dims(windowed_samples, axis=-1)

# 加载16个文件并生成标签
file_paths = [f"Demod_WiFi_cable_X310_3123D76_IQ#{i}_run1.sigmf-data" for i in range(1, 17)]
X = []
y = []

for class_idx, file_path in enumerate(file_paths):
    # 处理当前文件的IQ样本
    processed_samples = load_and_preprocess_iq_file(file_path)
    X.append(processed_samples)
    
    # 生成one-hot标签(16类)
    class_labels = np.zeros((len(processed_samples), 16))
    class_labels[:, class_idx] = 1
    y.append(class_labels)

# 合并所有数据并划分训练/测试集
X = np.concatenate(X, axis=0)
y = np.concatenate(y, axis=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

2. 修正后的模型定义

调整输入形状与预处理后的数据匹配,确保卷积层正确处理IQ样本:

# 定义CNN模型
model = keras.Sequential([
    # 输入形状对应(128个IQ点, 实部/虚部2个特征, 1个通道)
    layers.Conv2D(filters=50, kernel_size=(7, 1), activation='relu', input_shape=(128, 2, 1)),
    layers.Conv2D(filters=50, kernel_size=(7, 2), activation='relu'),
    layers.Flatten(),
    layers.Dropout(rate=0.5),
    layers.Dense(units=256, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001)),
    layers.Dropout(rate=0.5),
    layers.Dense(units=80, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001)),
    layers.Dense(units=16, activation='softmax')
])

model.summary()

# 编译模型
optimizer = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])

# 训练模型
history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.1)

# 评估模型性能
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"测试集准确率: {test_acc:.4f}")

关键说明

  • 数据适配:将复数IQ拆分为实部+虚部的二维特征,通过滑动窗口生成固定长度(128)的样本,扩展通道维度后匹配Conv2D的输入格式
  • 模型修正:移除原输入形状中的冗余维度,确保卷积核尺寸(1×7、2×7)能在IQ序列的时间轴(128点)和特征轴(实部/虚部)上正确滑动
  • 标签处理:16个文件对应16个类别,生成one-hot标签与Softmax输出、交叉熵损失函数匹配

内容的提问来源于stack exchange,提问作者Sourabh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 21:12:14