关注我,追更更多通信仿真代码!
文章目录
-
- 摘要
- [1. 引言](#1. 引言)
- [2. OFDM信号模型与PAPR定义](#2. OFDM信号模型与PAPR定义)
-
- [2.1 OFDM基带信号](#2.1 OFDM基带信号)
- [2.2 峰均功率比(PAPR)](#2.2 峰均功率比(PAPR))
- [2.3 PAPR统计评估:CCDF](#2.3 PAPR统计评估:CCDF)
- [2.4 传统限幅滤波方法](#2.4 传统限幅滤波方法)
- [3. 基于神经网络的PAPR降低方法](#3. 基于神经网络的PAPR降低方法)
-
- [3.1 网络结构设计](#3.1 网络结构设计)
- [3.2 训练数据生成](#3.2 训练数据生成)
- [3.3 损失函数与优化器](#3.3 损失函数与优化器)
- [4 仿真设计与分析](#4 仿真设计与分析)
-
- [4.1 仿真参数设置](#4.1 仿真参数设置)
- [4.2 CCDF性能对比](#4.2 CCDF性能对比)
- [4.3 失真结果对比](#4.3 失真结果对比)
- [4.4 部分代码](#4.4 部分代码)
- [5 结论](#5 结论)
摘要
正交频分复用(OFDM)技术因其高频谱效率和抗多径衰落能力,在现代无线通信系统中得到广泛应用。然而,OFDM信号固有的高峰均功率比(PAPR)问题严重制约了功率放大器的工作效率。传统限幅滤波方法虽能有效降低PAPR,但会引入非线性失真和带外辐射。本文提出一种基于全连接神经网络的PAPR降低方法,通过训练网络学习原始OFDM信号与限幅滤波后信号之间的映射关系,实现低PAPR信号的智能生成。仿真结果表明,所提方法在PAPR抑制性能上可逼近传统限幅滤波方法,且具有降低信号失真的潜在优势。
1. 引言
-
正交频分复用(Orthogonal Frequency Division Multiplexing, OFDM)技术凭借其频谱利用率高、抗频率选择性衰落强等优点,已被广泛应用于4G/5G移动通信、数字电视广播及无线局域网等标准中。然而,OFDM符号由多个正交子载波叠加而成,其时域信号包络具有较大的动态范围,导致高峰均功率比(Peak-to-Average Power Ratio, PAPR。高PAPR要求发射端功率放大器具有较大的线性动态范围,否则信号会因进入非线性区而产生失真,降低系统性能。
-
为降低PAPR,研究者提出了多种技术,包括限幅(Clipping)、压缩扩展(Companding)、选择性映射(SLM)和部分传输序列等。其中,限幅滤波因实现简单且效果显著而备受关注,但其非线性操作会引入带内失真和带外辐射,需要在PAPR降低和信号质量之间折中。
-
近年来,深度学习在通信物理层中的应用日益广泛,已有研究将其用于信道估计、信号检测和波形设计等领域。本文尝试利用神经网络学习限幅滤波的映射关系,以期在保持PAPR降低效果的同时减少非线性失真。具体而言,我们构建了一个全连接神经网络(Fully Connected Neural Network, FCNN),以原始OFDM时域信号的实部和虚部为输入,以限幅滤波后的信号实部和虚部为输出,通过监督学习拟合该映射。
2. OFDM信号模型与PAPR定义
2.1 OFDM基带信号

2.2 峰均功率比(PAPR)

2.3 PAPR统计评估:CCDF

2.4 传统限幅滤波方法

3. 基于神经网络的PAPR降低方法
3.1 网络结构设计

3.2 训练数据生成

3.3 损失函数与优化器

4 仿真设计与分析
| 参数 | 符号 | 说明 |
|---|---|---|
| OFDM子载波数 | K K K | 根据系统带宽和频谱效率要求设定 |
| 循环前缀长度 | C P CP CP | 取 K / 4 K/4 K/4,以抵抗多径时延扩展 |
| 调制方式 | 16QAM | 每子载波携带 μ = 4 \mu = 4 μ=4 比特 |
| 数据子载波数 | N data N_{\text{data}} Ndata | K K K 减去导频子载波数 |
| 导频子载波数 | N pilot N_{\text{pilot}} Npilot | 用于信道估计,等间隔分布 |
| 限幅比 | C R \mathrm{CR} CR | 限幅门限与信号均方根值的比值 |
| 低通滤波器阶数 | n n n | 用于抑制限幅引入的带外辐射 |
| 训练符号数 | N sym N_{\text{sym}} Nsym | 生成足够数量的OFDM符号用于训练和测试 |
| 训练集比例 | ρ \rho ρ | 总样本中用于训练的比例 |
| 神经网络隐藏层神经元数 | N hidden N_{\text{hidden}} Nhidden | 全连接网络中间层神经元个数 |
| 激活函数 | tanh \tanh tanh | 隐藏层和输出层均使用双曲正切 |
| 损失函数 | MSE | 均方误差,定义为 L = 1 N ∑ i = 1 N ∣ y ( i ) − y ^ ( i ) ∣ 2 2 \mathcal{L} = \frac{1}{N} \sum_{i=1}^{N} | \mathbf{y}^{(i)} - \hat{\mathbf{y}}^{(i)} |_2^2 L=N1∑i=1N∣y(i)−y^(i)∣22 |
| 优化器 | Adam | 自适应矩估计优化算法 |
| 学习率 | η \eta η | 控制参数更新步长,通常设置为 10 − 3 10^{-3} 10−3 量级 |
| 批大小 | B B B | 每次迭代使用的样本数 |
| 训练轮数 | E E E | 完整遍历训练集的次数 |
4.1 仿真参数设置
4.2 CCDF性能对比


可以看到
- 原始信号具有最高的PAPR,限幅滤波信号显著降低了PAPR,验证了限幅滤波的有效性。神经网络预测信号的CCDF曲线与限幅滤波曲线较为接近,说明神经网络能够较好地学习限幅滤波的映射关系。该结果表明,所提出的神经网络方法在PAPR抑制性能上可接近传统限幅滤波,且具有无需迭代计算、一次前向传播即可生成低PAPR信号的优点。
4.3 失真结果对比


可以看到:
- 神经网络预测信号的 EVM 比限幅滤波信号低约 0.46 个百分点),在 20% 的尺度下,这个差异虽然相对小,但已可观测到趋势。更重要的是,在下面 SER 指标中差异更加明显。
- 无噪声神经网络预测信号的 SER 仅为限幅滤波信号的 29%(0.000446 / 0.001532 ≈ 0.29),误符号率降低了 70%。这充分证明了神经网络在降低 PAPR 的同时,显著减少了信号失真,展现出明显的信号质量优势。在 AWGN 信道下,由于噪声主导了误码的产生,神经网络预测信号的 BER 曲线与限幅滤波信号接近。
4.4 部分代码
c
# -*- coding: utf-8 -*-
"""
失真评估脚本
按 OFDM 符号分组,在频域计算 EVM 和 BER
"""
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import os
# ======================== 配置 ========================
K = 256 # 子载波数(必须与生成数据时一致)
trainingset_number = 9
filename_dataset_csv = f"training_data_{trainingset_number}.csv"
model_h5_file = f"saved_model_{trainingset_number}.h5"
# 16QAM 理想星座点(与 mapping_table 一致)
constellation = np.array([-3 - 3j, -3 - 1j, -3 + 3j, -3 + 1j,
-1 - 3j, -1 - 1j, -1 + 3j, -1 + 1j,
3 - 3j, 3 - 1j, 3 + 3j, 3 + 1j,
1 - 3j, 1 - 1j, 1 + 3j, 1 + 1j])
# ======================== 定义损失函数 ========================
def my_loss(y_true, y_pred):
return tf.reduce_mean(tf.square(y_pred - y_true))
# ======================== 加载数据 ========================
if not os.path.exists(filename_dataset_csv):
raise FileNotFoundError(f"数据文件不存在: {filename_dataset_csv}")
data = np.loadtxt(filename_dataset_csv, delimiter=',', skiprows=1)
total_samples = len(data)
num_symbols = total_samples // K
print(f"总采样点: {total_samples}, 可组成 {num_symbols} 个 OFDM 符号")
# 取完整符号数(截断尾部不足 K 个的点)
data = data[:num_symbols * K]
orig_complex = data[:, 0] + 1j * data[:, 1]
proc_complex = data[:, 2] + 1j * data[:, 3]
# ======================== 神经网络预测 ========================
if not os.path.exists(model_h5_file):
raise FileNotFoundError(f"模型文件不存在: {model_h5_file},请先训练。")
model = tf.keras.models.load_model(
model_h5_file,
custom_objects={'my_loss': my_loss}
)
print("模型加载成功!")
# 分批预测
batch_size = 1024
pred_list = []
for start in range(0, total_samples, batch_size):
end = min(start + batch_size, total_samples)
batch = data[start:end, 0:2]
pred = model.predict(batch, verbose=0)
pred_list.append(pred)
pred_array = np.vstack(pred_list)
pred_complex = pred_array[:, 0] + 1j * pred_array[:, 1]
print("神经网络预测完成。")
# ======================== 按符号分组,计算频域符号 ========================
def get_freq_symbols(time_signal, K):
"""
将时域信号按 K 个点分组,做 FFT,返回所有符号的频域子载波(复数矩阵)
形状: (num_symbols, K)
"""
num = len(time_signal) // K
time_signal = time_signal[:num * K]
freq = np.fft.fft(time_signal.reshape(num, K), axis=1)
return freq # shape (num, K)
# 获取三种信号的频域符号矩阵
freq_orig = get_freq_symbols(orig_complex, K)
freq_proc = get_freq_symbols(proc_complex, K)
freq_pred = get_freq_symbols(pred_complex, K)
# ======================== EVM 计算(频域) ========================
def compute_evm_freq(freq_symbols, constellation):
"""
输入: freq_symbols 形状 (num_symbols, K),每个子载波的复数值
计算所有符号、所有子载波的平均 EVM(百分比和 dB)
"""
all_symbols = freq_symbols.flatten() # 展平所有子载波
errors = []
for s in all_symbols:
# 找最近星座点
dists = np.abs(s - constellation)
idx = np.argmin(dists)
ideal = constellation[idx]
errors.append(s - ideal)
errors = np.array(errors)
rms_error = np.sqrt(np.mean(np.abs(errors) ** 2))
rms_ideal = np.sqrt(np.mean(np.abs(constellation) ** 2))
evm_percent = (rms_error / rms_ideal) * 100
evm_dB = 20 * np.log10(evm_percent / 100)
return evm_percent, evm_dB
# 计算三种信号的 EVM
evm_orig_per, evm_orig_dB = compute_evm_freq(freq_orig, constellation)
evm_proc_per, evm_proc_dB = compute_evm_freq(freq_proc, constellation)
evm_pred_per, evm_pred_dB = compute_evm_freq(freq_pred, constellation)
print("\n========== EVM 对比(频域) ==========")
print(f"原始信号 : {evm_orig_per:.2f}% ({evm_orig_dB:.2f} dB)")
print(f"限幅滤波信号 : {evm_proc_per:.2f}% ({evm_proc_dB:.2f} dB)")
print(f"神经网络预测信号 : {evm_pred_per:.2f}% ({evm_pred_dB:.2f} dB)")
# ======================== BER 仿真(频域) ========================
def demod_symbol(symbol, constellation):
"""硬判决,返回符号索引"""
dists = np.abs(symbol - constellation)
return np.argmin(dists)
def ser_compute(freq_symbols, constellation):
"""
计算误符号率(SER):相对于理想符号(直接对原始信号判决)
注意:由于原始信号本身有噪声,以原始信号的判决结果为参考可能不准确,
但这里我们假设原始信号是无失真的,故以原始信号的判决为参考。
"""
# 获取理想符号索引(从原始信号判决)
ideal_idx = np.array([demod_symbol(s, constellation) for s in freq_orig.flatten()])
# 对待测信号判决
test_idx = np.array([demod_symbol(s, constellation) for s in freq_symbols.flatten()])
return np.sum(test_idx != ideal_idx) / len(ideal_idx)
# 计算 SER
ser_orig = ser_compute(freq_orig, constellation)
ser_proc = ser_compute(freq_proc, constellation)
ser_pred = ser_compute(freq_pred, constellation)
print("\n========== 误符号率 (SER) 对比 ==========")
print(f"原始信号 : {ser_orig:.6f}")
print(f"限幅滤波信号 : {ser_proc:.6f}")
print(f"神经网络预测信号 : {ser_pred:.6f}")
# ======================== AWGN 下的 BER 曲线(频域加噪声) ========================
def add_awgn_freq(freq_symbols, snr_db):
"""在频域加 AWGN(保持符号功率)"""
# 计算平均符号功率
power = np.mean(np.abs(freq_symbols) ** 2)
noise_power = power * 10 ** (-snr_db / 10)
noise = np.sqrt(noise_power / 2) * (
np.random.randn(*freq_symbols.shape) + 1j * np.random.randn(*freq_symbols.shape))
return freq_symbols + noise
snr_range = np.arange(0, 25, 2)
ser_orig_list, ser_proc_list, ser_pred_list = [], [], []
# 以原始信号的判决为参考(无噪声理想判决)
ideal_idx = np.array([demod_symbol(s, constellation) for s in freq_orig.flatten()])
for snr in snr_range:
# 加噪声
rx_orig = add_awgn_freq(freq_orig, snr)
rx_proc = add_awgn_freq(freq_proc, snr)
rx_pred = add_awgn_freq(freq_pred, snr)
# 判决
idx_orig = np.array([demod_symbol(s, constellation) for s in rx_orig.flatten()])
idx_proc = np.array([demod_symbol(s, constellation) for s in rx_proc.flatten()])
idx_pred = np.array([demod_symbol(s, constellation) for s in rx_pred.flatten()])
ser_orig_list.append(np.sum(idx_orig != ideal_idx) / len(ideal_idx))
ser_proc_list.append(np.sum(idx_proc != ideal_idx) / len(ideal_idx))
ser_pred_list.append(np.sum(idx_pred != ideal_idx) / len(ideal_idx))
# ======================== 绘制 BER 曲线 ========================
plt.figure(figsize=(8, 6))
plt.semilogy(snr_range, ser_orig_list, 'b-o', label='原始信号')
plt.semilogy(snr_range, ser_proc_list, 'r-s', label='限幅滤波信号')
plt.semilogy(snr_range, ser_pred_list, 'g-^', label='神经网络预测')
plt.xlabel('SNR (dB)')
plt.ylabel('误符号率 (SER)')
plt.title('不同信号在 AWGN 下的抗噪声性能(频域)')
plt.grid(True, which='both', linestyle='--', alpha=0.6)
plt.legend()
plt.tight_layout()
plt.savefig('ber_comparison.png', dpi=300)
plt.show()
print("\nBER 曲线已保存为 ber_comparison.png")
print("\n结论:若神经网络预测信号的 EVM 和 BER 低于限幅滤波信号,则说明其具有降低信号失真的优势。")
5 结论
本文提出了一种基于全连接神经网络的 OFDM 信号 PAPR 降低方法。仿真结果表明,该方法在 PAPR 抑制性能上可逼近传统限幅滤波技术,同时能显低信号失真。展现出在保持 PAPR 抑制效果的同时提升信号质量的潜力。该方法为高功率效率的 OFDM 系统设计提供了一种可学习的非线性信号处理思路。
完整仿真代码可见往期文章文末VX公众号(包含往期博客所有代码),所见即所得