【深度学习;信道均衡】基于深度学习的OFDM信道均衡方法对比
·









% SNR 代表 Es/N0, Es/N0 = Eb/N0 * log2(M)
% 计算噪声方差时忽略导频功率,导频与数据承受同等水平的噪声
% 由于应用了IFFT/FFT,功率是平衡的
% InsertDCNull 为 true,SNR_OFDM 中考虑了 DC 空子载波的影响
% 调整为 SNR + 10 * log(使用的子载波数量 / FFT长度)
% h_channel 每一帧都不同,存储在 H 中,或者从 h_set 读取
clear; clc; close all; % 清除工作区,避免变量干扰
%% 参数设置
SNR_Range = 5:5:25; % 修改要求:SNR范围改为 5, 10, 15, 20, 25
% 初始化结果数组
len_snr = length(SNR_Range);
BER_over_SNR = zeros(len_snr, 1);
SER_over_SNR = zeros(len_snr, 1);
DNN_BER_over_SNR = zeros(len_snr, 1);
DNN_SER_over_SNR = zeros(len_snr, 1);
% 导入训练好的深度神经网络
% 请确保 'DNN_Trained.mat' 文件在当前路径下
load('DNN_Trained_30.mat');
% load('DNNInfo.mat')
%% 主循环:遍历 SNR
snr_idx = 0; % 引入索引计数器
for SNR = SNR_Range
snr_idx = snr_idx + 1;
% 修改要求:显示当前循环进度
fprintf('当前进度: 正在处理 SNR = %d dB (%d/%d)...\n', SNR, snr_idx, len_snr);
Baseband_bandwidth = 20e6; % 基带带宽
M = 4; % QPSK 调制阶数
k = log2(M);
Num_of_subcarriers = 63; % 子载波数量
Num_of_FFT = Num_of_subcarriers + 1; % FFT点数
length_of_CP = 16; % 循环前缀长度
Num_of_frame = 2000; % 帧数 (如果运行太慢可适当减小)
Num_of_symbols = 1; % 每帧符号数
Num_of_pilot = 1; % 导频数量
Frame_size = Num_of_symbols + Num_of_pilot; % 帧大小
Pilot_interval = Frame_size / Num_of_pilot; % 导频间隔
Pilot_starting_location = 1; % 导频起始位置
length_of_symbol = Num_of_FFT + length_of_CP; % 符号总长度
% 计算比特数
Num_of_QPSK_symbols = Num_of_subcarriers * Num_of_symbols * Num_of_frame;
Num_of_bits = Num_of_QPSK_symbols * k;
% DNN 相关比特数设置
Num_of_QPSK_symbols_DNN = 8 * Num_of_symbols * Num_of_frame;
Num_of_bits_DNN = Num_of_QPSK_symbols_DNN * k;
% 初始化错误计数器
numErrs_sym = zeros(Num_of_frame, 1);
SER_in_frame = zeros(Num_of_frame, 1);
numErrs_bit = zeros(Num_of_frame, 1);
BER_in_frame = zeros(Num_of_frame, 1);
DNN_numErrs_sym = zeros(Num_of_frame, 1);
DNN_SER_in_frame = zeros(Num_of_frame, 1);
DNN_numErrs_bit = zeros(Num_of_frame, 1);
DNN_BER_in_frame = zeros(Num_of_frame, 1);
Rayleigh_h = zeros(Num_of_frame * Frame_size * length_of_symbol, 1);
Multipath_h = zeros(Num_of_frame * Frame_size * length_of_symbol, 1);
%% 帧循环
for Frame = 1:Num_of_frame
%% 1. 生成数据
N = Num_of_subcarriers * Num_of_symbols;
data = randi([0 1], N, k);
Data = reshape(data, [], 1);
dataSym = bi2de(data);
%% 2. QPSK 调制
QPSK_symbol = QPSK_Modualtor(dataSym); % 请确保此函数存在
QPSK_signal = reshape(QPSK_symbol, Num_of_subcarriers, Num_of_symbols);
%% 3. 插入导频 (Pilot Insertion)
Pilot_value = 1 - 1j;
Pilot_location = Pilot_starting_location : Pilot_interval : Frame_size;
Num_of_Pilot_per_Frame = length(Pilot_location) * Num_of_subcarriers;
data_location = 1 : Frame_size;
data_location(Pilot_location(:)) = [];
data_in_IFFT = zeros(Num_of_FFT - 1, Frame_size);
data_in_IFFT(:, Pilot_location(:)) = Pilot_value;
data_in_IFFT(:, data_location(:)) = QPSK_signal;
data_in_IFFT = [zeros(1, Frame_size); data_in_IFFT]; % 添加DC空子载波
%% 4. OFDM 发射机 (IFFT + CP)
Transmitted_signal = OFDM_Transmitter(data_in_IFFT, Num_of_FFT, length_of_CP); % 请确保此函数存在
%% 5. 信道模型 (Channel)
% AWGN 信道参数计算
Data_power = sum(power(abs(QPSK_symbol), 2)) / (length(QPSK_symbol));
SNR_OFDM = SNR + 10 * log10((Num_of_subcarriers / Num_of_FFT));
SNR_OFDM_HEX = 10 ^ (SNR_OFDM / 10);
Noise_power = Data_power / SNR_OFDM_HEX;
Nvariance = sqrt(Noise_power/2);
n = Nvariance * (randn(length(Transmitted_signal), 1) + 1j * randn(length(Transmitted_signal), 1)); % 生成噪声
% 纯 AWGN 信号 (未使用)
AWGN_Signal = Transmitted_signal + n;
%% 瑞利信道 (Rayleigh Channel)
Rayleigh_h_channel_OFDM_symbol = (1 / sqrt(2)) * randn(length_of_symbol, 1) + (1 / sqrt(2)) * 1j * randn(length_of_symbol, 1);
Rayleigh_h_channel = repmat(Rayleigh_h_channel_OFDM_symbol, Frame_size, 1);
Rayleigh_Fading_Signal = Rayleigh_h_channel .* Transmitted_signal + n;
Rayleigh_h(((Frame - 1) * Frame_size * length_of_symbol) + 1 : Frame * Frame_size * length_of_symbol, 1) = Rayleigh_h_channel;
% 已知 h 时的理想信号
Channel_signal_when_h_is_known = Rayleigh_Fading_Signal ./ Rayleigh_h_channel;
%% 多径瑞利衰落信道 (Multipath Rayleigh Fading Channel)
Multipath_Fading_h_channel_OFDM_symbol = ((randn + 1j * randn) / sqrt(2)) * ones(length_of_symbol, 1);
Multipath_Fading_h_channel = repmat(Multipath_Fading_h_channel_OFDM_symbol, Frame_size, 1);
% 存储多径 h
Multipath_h(((Frame - 1) * Frame_size * length_of_symbol) + 1 : Frame * Frame_size * length_of_symbol, 1) = Multipath_Fading_h_channel;
% 多径抽头 (5径)
Multitap_h = [(randn + 1j * randn);...
(randn + 1j * randn) / 2;...
(randn + 1j * randn) / 4;...
(randn + 1j * randn) / 8;...
(randn + 1j * randn) / 16] / (1.9375 * sqrt(pi/2));
%% 线性卷积 (模拟多径效应)
Multitap_Channel_Signal = conv(Transmitted_signal, Multitap_h);
% 截取有效部分并加噪
Multitap_Channel_Signal = Multitap_Channel_Signal(1 : length(Transmitted_signal)) + n;
%% 6. OFDM 接收机 (去CP + FFT)
[Unrecovered_signal, Unrecovered_signal_when_h_is_known] = OFDM_Receiver(Multitap_Channel_Signal, Num_of_FFT, length_of_CP, length_of_symbol, Channel_signal_when_h_is_known);
%% 7. 信道估计和均衡 (Channel estimation and equalization)
% 理想信道知识
Received_data_Perfect_knowledge = Unrecovered_signal_when_h_is_known(2:end, data_location(:));
%% 迫零均衡 (Zero-forcing) - LS估计
Received_pilot = Unrecovered_signal(:, Pilot_location(:));
H_LS = Received_pilot ./ Pilot_value;
Received_Signal_ZF = Unrecovered_signal(:, data_location(:)) ./ H_LS;
Received_data_ZF = Received_Signal_ZF(2:end, :); % 未使用
%% MMSE 均衡
% 需要确保 MMSE_Channel_Tap_Block_Pilot_Demo_1 函数可用
H_MMSE_h = MMSE_Channel_Tap_Block_Pilot_Demo_1(Received_pilot, Pilot_value, Num_of_FFT, Frame_size, SNR, Multitap_h');
H_MMSE = H_MMSE_h;
Received_Signal_MMSE = Unrecovered_signal ./ H_MMSE;
Received_data_MMSE = Received_Signal_MMSE(2:end, data_location(:));
%% 8. 深度学习均衡 (Deep Learning)
% 仅检测前8个QPSK符号用于演示/测试
[DNN_feature_signal, ~, ~] = Extract_Feature_OFDM(Unrecovered_signal, dataSym(1:2), M, QPSK_signal(1:8));
% 使用训练好的网络进行预测
Received_data_DNN = predict(DNN_Trained, DNN_feature_signal);
DNN_Received_data = Received_data_DNN(1:2:end, :) + 1j * Received_data_DNN(2:2:end, :);
% 设置当前主要对比的数据流 (这里选用 MMSE 结果作为基准)
Received_data = Received_data_ZF;
%% 9. 解调与误码率计算
% 常规 QPSK 解调
dataSym_Rx = QPSK_Demodulator(Received_data);
dataSym_Received = de2bi(dataSym_Rx, 2);
Data_Received = reshape(dataSym_Received, [], 1);
% DNN 数据 QPSK 解调
DNN_dataSym_Rx = QPSK_Demodulator(DNN_Received_data);
DNN_dataSym_Received = de2bi(DNN_dataSym_Rx, 2);
DNN_Data_Received = reshape(DNN_dataSym_Received, [], 1);
% 计算当前帧的误码率 (MMSE/LS)
numErrs_sym(Frame, 1) = sum(sum(round(dataSym) ~= round(dataSym_Rx)));
SER_in_frame(Frame, 1) = numErrs_sym(Frame, 1) / length(dataSym);
numErrs_bit(Frame, 1) = sum(sum(round(Data) ~= round(Data_Received)));
BER_in_frame(Frame, 1) = numErrs_bit(Frame, 1) / length(Data);
% 计算当前帧的误码率 (DNN)
DNN_numErrs_sym(Frame, 1) = sum(sum(round(dataSym(1:8)) ~= round(DNN_dataSym_Rx)));
DNN_SER_in_frame(Frame, 1) = DNN_numErrs_sym(Frame, 1) / length(DNN_dataSym_Rx);
DNN_numErrs_bit(Frame, 1) = sum(sum(round(reshape(de2bi(dataSym(1:8), 2),[],1)) ~= round(DNN_Data_Received)));
DNN_BER_in_frame(Frame, 1) = DNN_numErrs_bit(Frame, 1) / length(DNN_Data_Received);
end
%% 汇总当前 SNR 下的 BER/SER
BER = sum(numErrs_bit, 1) / Num_of_bits;
SER = sum(numErrs_sym, 1) / Num_of_QPSK_symbols;
% 使用 snr_idx 存储结果,确保数据紧凑
BER_over_SNR(snr_idx, 1) = BER;
SER_over_SNR(snr_idx, 1) = SER;
DNN_BER_over_SNR(snr_idx, 1) = sum(DNN_numErrs_bit, 1) / Num_of_bits_DNN;
DNN_SER_over_SNR(snr_idx, 1) = sum(DNN_numErrs_sym, 1) / Num_of_QPSK_symbols_DNN;
end
fprintf('仿真完成,开始绘图...\n');
%% 使用 plot 进行绘制
figure;
% 使用半对数坐标轴绘制 BER (通信系统常用)
semilogy(SNR_Range, BER_over_SNR, '-bo', 'LineWidth', 1.25, 'MarkerSize', 8, 'DisplayName', 'ZF BER');
hold on;
semilogy(SNR_Range, DNN_BER_over_SNR, '-r*', 'LineWidth', 1.25, 'MarkerSize', 8, 'DisplayName', 'DNN BER');
semilogy(SNR_Range, SER_over_SNR, '-b<', 'LineWidth', 1.25, 'MarkerSize', 8,'DisplayName', 'ZF SER');
hold on;
semilogy(SNR_Range, DNN_SER_over_SNR, '-rs','LineWidth', 1.25, 'MarkerSize', 8, 'DisplayName', 'DNN SER');
grid on;
xlabel('SNR (dB)');
ylabel('BER and SER');
title('OFDM系统信道均衡方法对比');
legend('show', 'Location', 'southwest');
xlim([0 30]);
ylim([10^(-3) 1])
% 如果需要绘制 SER,可以取消下面注释
% figure;
% semilogy(SNR_Range, SER_over_SNR, '-bo', 'DisplayName', 'MMSE SER');
% hold on;
% semilogy(SNR_Range, DNN_SER_over_SNR, '-r*', 'DisplayName', 'DNN SER');
% grid on; legend;
function [Xtraining_Cell, Xtraining_Array, Ytraining_categorical, Ytraining_regression_cell, Ytraining_regression_array, Xvalidation_Cell, Yvalidation_categorical, Yvalidation_regression] = Data_Generation(Training_set_ratio, SNR, Num_of_frame)
M = 4; % QPSK
k = log2(M);
Num_of_subcarriers = 63; %126
Num_of_FFT = Num_of_subcarriers + 1;
length_of_CP = 16;
Num_of_symbols = 1;
Num_of_pilot = 1;
Frame_size = Num_of_symbols + Num_of_pilot;
Pilot_interval = Frame_size / Num_of_pilot;
Pilot_starting_location = 1;
length_of_symbol = Num_of_FFT + length_of_CP;
Num_of_QPSK_symbols = Num_of_subcarriers * Num_of_symbols * Num_of_frame;
Num_of_bits = Num_of_QPSK_symbols * log2(M);
Xtraining_Cell = cell(Training_set_ratio * Num_of_frame, 1);
Xtraining_Array = zeros(Num_of_FFT * Frame_size * 2, 1, 1, Training_set_ratio * Num_of_frame);
Ytraining_categorical_double = zeros(Training_set_ratio * Num_of_frame, 1);
Ytraining_regression_cell = cell(Training_set_ratio * Num_of_frame, 1);
Ytraining_regression_array = zeros(Training_set_ratio * Num_of_frame, 16);
Xvalidation_Cell = cell(Num_of_frame - Training_set_ratio * Num_of_frame, 1);
Yvalidation_categorical_double = zeros(Num_of_frame - Training_set_ratio * Num_of_frame, 1);
Yvalidation_regression = cell(Num_of_frame - Training_set_ratio * Num_of_frame, 1);
for Frame = 1 : Num_of_frame
% Data generation
N = Num_of_subcarriers * Num_of_symbols;
data = randi([0 1], N, k);
dataSym = bi2de(data);
% QPSK modulator
QPSK_symbol = QPSK_Modualtor(dataSym);
QPSK_signal = reshape(QPSK_symbol, Num_of_subcarriers, Num_of_symbols);
% Pilot inserted
Pilot_value = 1 - 1j;
Pilot_location = Pilot_starting_location : Pilot_interval : Frame_size;
data_location = 1 : Frame_size;
data_location(Pilot_location(:)) = [];
data_in_IFFT = zeros(Num_of_FFT - 1, Frame_size);
data_in_IFFT(:, Pilot_location(:)) = Pilot_value;
data_in_IFFT(:, data_location(:)) = QPSK_signal;
data_in_IFFT = [zeros(1, Frame_size); data_in_IFFT];
% OFDM Transmitter
Transmitted_signal = OFDM_Transmitter(data_in_IFFT, Num_of_FFT, length_of_CP);
% Channel
% AWGN Channel
Data_power = sum(power(abs(QPSK_symbol), 2)) / (length(QPSK_symbol));
SNR_OFDM = SNR + 10 * log10((Num_of_subcarriers / Num_of_FFT));
SNR_OFDM_HEX = 10 ^ (SNR_OFDM / 10);
Noise_power = Data_power / SNR_OFDM_HEX;
Nvariance = sqrt(Noise_power/2); % QPSK has two paths of signal
n = Nvariance * (randn(length(Transmitted_signal), 1) + 1j * randn(length(Transmitted_signal), 1)); % Noise generation
% Multipath Rayleigh Fading Channel
Multitap_h = [(randn + 1j * randn);...
(randn + 1j * randn) / 2;...
(randn + 1j * randn) / 4;...
(randn + 1j * randn) / 8;...
(randn + 1j * randn) / 16] / (1.9375 * sqrt(pi/2));
% linear convolution
Multitap_Channel_Signal = conv(Transmitted_signal, Multitap_h);
% circular convolution
%Multitap_Channel_Signal = cconv(Transmitted_signal, Multitap_h, length(Transmitted_signal));
Multitap_Channel_Signal = Multitap_Channel_Signal(1 : length(Transmitted_signal)) + n;
% OFDM Receiver
Channel_signal_when_h_is_known = ones(160,1);
[Received_data, ~] = OFDM_Receiver(Multitap_Channel_Signal, Num_of_FFT, length_of_CP, length_of_symbol, Channel_signal_when_h_is_known);
[feature_of_OFDM_frame, label_of_OFDM_frame, label_of_regression] = Extract_Feature_OFDM(Received_data, dataSym(1:2), M, QPSK_signal(1:8));
if Frame <= fix(Training_set_ratio * Num_of_frame)
Xtraining_Cell{Frame, 1} = feature_of_OFDM_frame;
Xtraining_Array(:, :, 1, Frame) = feature_of_OFDM_frame;
Ytraining_categorical_double(Frame, 1) = label_of_OFDM_frame;
Ytraining_regression_cell{Frame, 1} = label_of_regression;
Ytraining_regression_array(Frame, :) = label_of_regression;
else
Xvalidation_Cell{Frame - Training_set_ratio * Num_of_frame, 1} = feature_of_OFDM_frame;
Yvalidation_categorical_double(Frame - Training_set_ratio * Num_of_frame, 1) = label_of_OFDM_frame;
Yvalidation_regression{Frame - Training_set_ratio * Num_of_frame, 1} = label_of_regression;
end
end
Ytraining_categorical = categorical(Ytraining_categorical_double);
Yvalidation_categorical = categorical(Yvalidation_categorical_double);
end
方法:ZF MMSE DNN 理想信道
性能指标:BER and SER
代码完好,一键运行即可
代码为虚拟产品,不支持退款,如有需要请仔细咨询!
更多推荐
所有评论(0)