Этот пример показывает, как обучить сверточную нейронную сеть (CNN) для оценки канала с помощью Deep Learning Toolbox™ и данных, сгенерированных с помощью 5G Toolbox™. Используя обученный CNN, вы выполняете оценку канала в режиме single-input single-output (SISO), используя физический опорный сигнал демодуляции совместно используемого канала нисходящей линии связи (PDSCH) (DM-RS).
Общий подход к оценке канала заключается во вставке известных опорных пилот-символов в передачу и затем интерполяции остальной части отклика канала при помощи этих пилот-символов.
Для примера, показывающего, как использовать этот подход оценки канала, смотрите NR PDSCH Пропускная способность.
Можно также использовать методы глубокого обучения, чтобы выполнить оценку канала. Для примера путем просмотра ресурсной сетки PDSCH в качестве 2-D изображения можно превратить задачу оценки канала в задачу обработки изображений, подобное шумоподавление или суперразрешению, где CNN эффективны.
Используя 5G Toolbox, можно настроить и сгенерировать совместимые со стандартом формы волны и модели канала для использования в качестве обучающих данных. Используя Deep Learning Toolbox, можно использовать эти обучающие данные для обучения оценки канала CNN. Этот пример показывает, как сгенерировать такие обучающие данные и как обучить оценку канала CNN. Пример также показывает, как использовать CNN оценки канала для обработки изображений, которые содержат линейно интерполированные принятые пилотные символы. Пример завершается визуализацией результатов оценки канала нейронной сети по сравнению с практичными и совершенными оценщиками.
Обучение нейронной сети состоит из следующих шагов:
Генерация данных
Разделение сгенерированных данных на наборы для обучения и валидации
Определение архитектуры CNN
Определение опций обучения, оптимизатора и скорости обучения
Обучение сети
Из-за большого количества сигналов и возможных сценариев обучение может занять несколько минут. По умолчанию обучение отключено, используется предварительно обученная модель. Вы можете включить обучение, установив trainModel
к true.
trainModel = false;
Если установлены Parallel Computing Toolbox™ и поддерживается графический процессор NVIDIA ® с поддержкой CUDA, в сетевом обучении по умолчанию используется ускорение графического процессора. The trainNetwork
(Deep Learning Toolbox) функция позволяет вам переопределить это поведение по умолчанию. Список поддерживаемых графических процессоров см. в разделе Поддержка GPU по версии (Parallel Computing Toolbox).
Генерация данных предназначена для получения 256 обучающих примеров или обучающих наборов данных. Такого объема данных достаточно, чтобы обучить сеть оценки функционального канала на центральном процессоре за разумное время. Для сравнения, предварительно обученная модель основана на 16 384 примерах обучения.
Обучающие данные модели CNN имеют фиксированную размерность, сеть может принимать только сетки 612 на 14 на 1, то есть 612 поднесущих, 14 символов OFDM и 1 антенну. Поэтому модель может работать только с фиксированным выделением полосы пропускания, длиной циклического префикса и одной приемной антенной.
CNN рассматривает ресурсные сетки как 2-D изображения, поэтому каждый элемент сетки должен быть реальным числом. В сценарии оценки канала ресурсные сетки имеют комплексные данные. Поэтому реальная и мнимая части этих сеток вводятся отдельно в CNN. В этом примере обучающие данные преобразуются из комплексной матрицы 612 на 14 в действительную матрицу 612 на 14 на 2, где третья размерность обозначает действительные и мнимые компоненты. Поскольку вы должны вводить действительные и мнимые сетки в нейронную сеть отдельно при выполнении предсказаний, пример преобразует обучающие данные в 4-D массивы 612-by-14-by-1-by-2N вида, где N - количество примеров обучения.
Чтобы убедиться, что CNN не перегружает обучающие данные, обучающие данные разделяются на валидацию и наборы обучающих данных. Данные валидации используются для мониторинга эффективности обученной нейронной сети с регулярными интервалами, как определено valFrequency
, приблизительно 5 за эпоху. Остановите обучение, когда потеря валидации перестанет улучшаться. В этом случае размер данных валидации совпадает с размером одного мини-пакета из-за небольшого размера набора данных.
CNN оценки возвращенного канала обучается на различных строениях канала на основе различных расширений задержки, доплеровских сдвигов и областей значений ОСШ от 0 до 10 дБ.
% Set the random seed for reproducibility (this has no effect if a GPU is % used) rng(42) if trainModel % Generate the training data [trainData,trainLabels] = hGenerateTrainingData(256); % Set the number of examples per mini-batch batchSize = 32; % Split real and imaginary grids into 2 image sets, then concatenate trainData = cat(4,trainData(:,:,1,:),trainData(:,:,2,:)); trainLabels = cat(4,trainLabels(:,:,1,:),trainLabels(:,:,2,:)); % Split into training and validation sets valData = trainData(:,:,:,1:batchSize); valLabels = trainLabels(:,:,:,1:batchSize); trainData = trainData(:,:,:,batchSize+1:end); trainLabels = trainLabels(:,:,:,batchSize+1:end); % Validate roughly 5 times every epoch valFrequency = round(size(trainData,4)/batchSize/5); % Define the CNN structure layers = [ ... imageInputLayer([612 14 1],'Normalization','none') convolution2dLayer(9,64,'Padding',4) reluLayer convolution2dLayer(5,64,'Padding',2,'NumChannels',64) reluLayer convolution2dLayer(5,64,'Padding',2,'NumChannels',64) reluLayer convolution2dLayer(5,32,'Padding',2,'NumChannels',64) reluLayer convolution2dLayer(5,1,'Padding',2,'NumChannels',32) regressionLayer ]; % Set up a training policy options = trainingOptions('adam', ... 'InitialLearnRate',3e-4, ... 'MaxEpochs',5, ... 'Shuffle','every-epoch', ... 'Verbose',false, ... 'Plots','training-progress', ... 'MiniBatchSize',batchSize, ... 'ValidationData',{valData, valLabels}, ... 'ValidationFrequency',valFrequency, ... 'ValidationPatience',5); % Train the network. The saved structure trainingInfo contains the % training progress for later inspection. This structure is useful for % comparing optimal convergence speeds of different optimization % methods. [channelEstimationCNN,trainingInfo] = trainNetwork(trainData, ... trainLabels,layers,options); else % Load pretrained network if trainModel is set to false load('trainedChannelEstimationNetwork.mat') end
Проверьте состав и отдельные слои модели. Модель имеет 5 сверточных слоев. Уровень входа ожидает матрицы размера 612 на 14, где 612 - количество поднесущих, а 14 - количество символов OFDM. Каждый элемент является вещественным числом, поскольку действительная и мнимая части сложных сеток вводятся отдельно.
channelEstimationCNN.Layers
ans = 11x1 Layer array with layers: 1 'imageinput' Image Input 612x14x1 images 2 'conv_1' Convolution 64 9x9x1 convolutions with stride [1 1] and padding [4 4 4 4] 3 'relu_1' ReLU ReLU 4 'conv_2' Convolution 64 5x5x64 convolutions with stride [1 1] and padding [2 2 2 2] 5 'relu_2' ReLU ReLU 6 'conv_3' Convolution 64 5x5x64 convolutions with stride [1 1] and padding [2 2 2 2] 7 'relu_3' ReLU ReLU 8 'conv_4' Convolution 32 5x5x64 convolutions with stride [1 1] and padding [2 2 2 2] 9 'relu_4' ReLU ReLU 10 'conv_5' Convolution 1 5x5x32 convolutions with stride [1 1] and padding [2 2 2 2] 11 'regressionoutput' Regression Output mean-squared-error with response 'Response'
Установите уровень шума симуляции в дБ.
SNRdB = 10;
Загрузите предопределенные параметры симуляции, включая параметры PDSCH и строение DM-RS. Возвращенный объект carrier
является допустимым объектом строения поставщика услуг связи и pdsch
является структурой строения PDSCH, установленной для передачи SISO.
[gnb,carrier,pdsch] = hDeepLearningChanEstSimParameters();
Создайте модель канала TDL и установите параметры канала. Чтобы сравнить различные канальные отклики оценщиков, можно изменить эти параметры позже.
channel = nrTDLChannel; channel.Seed = 0; channel.DelayProfile = 'TDL-A'; channel.DelaySpread = 3e-7; channel.MaximumDopplerShift = 50; % This example supports only SISO configuration channel.NumTransmitAntennas = 1; channel.NumReceiveAntennas = 1; waveformInfo = nrOFDMInfo(carrier); channel.SampleRate = waveformInfo.SampleRate;
Получите максимальное количество задержанных выборок компонентом многолучевого распространения канала. Это число вычисляется из пути с наибольшей задержкой и задержкой реализации фильтра канала. Это число необходимо для промывки фильтра канала при получении принятого сигнала.
chInfo = info(channel); maxChDelay = ceil(max(chInfo.PathDelays*channel.SampleRate))+chInfo.ChannelFilterDelay;
Симулируйте передачу PDSCH путем выполнения следующих шагов:
Сгенерируйте ресурсную сетку PDSCH
Вставка символов DM-RS
Выполните OFDM модуляцию
Отправьте модулированную форму волны через модель канала
Добавьте белый Гауссов шум
Выполните идеальную временную синхронизацию
Выполните демодуляцию OFDM
% Generate DM-RS indices and symbols [~,dmrsIndices,dmrsSymbols,pdschIndicesInfo] = hPDSCHResources(gnb,pdsch); % Create PDSCH resource grid pdschGrid = nrResourceGrid(carrier); % Map PDSCH DM-RS symbols to the grid pdschGrid(dmrsIndices) = pdschGrid(dmrsIndices)+dmrsSymbols; % OFDM-modulate associated resource elements txWaveform = nrOFDMModulate(carrier,pdschGrid);
Чтобы промыть содержимое канала, добавьте нули в конце переданной формы волны. Эти нули учитывают любую задержку, введенную в канал, такую как многолучевой канал и задержка реализации. Количество нулей зависит от частоты дискретизации, профиля задержки и разброса задержки.
txWaveform = [txWaveform; zeros(maxChDelay,size(txWaveform,2))];
Отправляйте данные через модель канала TDL.
[rxWaveform,pathGains,sampleTimes] = channel(txWaveform);
Добавьте аддитивный белый Гауссов шум (AWGN) к полученной форме волны во временной области. Чтобы учесть частоту дискретизации, нормализуйте степень шума. ОСШ определяется для каждого ресурсного элемента (RE) для каждой приемной антенны (3GPP TS 38.101-4).
SNR = 10^(SNRdB/20); % Calculate linear noise gain
N0 = 1/(sqrt(2.0*gnb.NRxAnts*double(waveformInfo.Nfft))*SNR);
noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform)));
rxWaveform = rxWaveform + noise;
Выполните идеальную синхронизацию. Чтобы найти самый сильный многолучевой компонент, используйте информацию, предоставленную каналом.
% Get path filters for perfect channel estimation
pathFilters = getPathFilters(channel);
[offset,~] = nrPerfectTimingEstimate(pathGains,pathFilters);
rxWaveform = rxWaveform(1+offset:end, :);
OFDM-демодулируйте полученные данные, чтобы воссоздать ресурсную сетку.
rxGrid = nrOFDMDemodulate(carrier,rxWaveform); % Pad the grid with zeros in case an incomplete slot has been demodulated [K,L,R] = size(rxGrid); if (L < carrier.SymbolsPerSlot) rxGrid = cat(2,rxGrid,zeros(K,carrier.SymbolsPerSlot-L,R)); end
Можно выполнить и сравнить результаты идеальных, практичных и нейронных оценок одной и той же модели канала.
Чтобы выполнить идеальную оценку канала, используйте nrPerfectChannelEstimate
функция, использующая значение коэффициентов усиления пути, обеспечиваемых каналом.
estChannelGridPerfect = nrPerfectChannelEstimate(carrier,pathGains, ...
pathFilters,offset,sampleTimes);
Для выполнения практической оценки канала используйте nrChannelEstimate
функция.
[estChannelGrid,~] = nrChannelEstimate(carrier,rxGrid,dmrsIndices, ... dmrsSymbols,'CDMLengths',pdschIndicesInfo.CDMLengths);
Чтобы выполнить оценку канала с помощью нейронной сети, необходимо интерполировать полученную сетку. Затем разделите интерполированное изображение на его реальную и мнимую части и вводите эти изображения вместе в нейронную сеть как один пакет. Используйте predict
(Deep Learning Toolbox) функция, чтобы делать предсказания на реальных и мнимых изображениях. Наконец, конкатенируйте и преобразуйте результаты обратно в комплексные данные.
% Interpolate the received resource grid using pilot symbol locations interpChannelGrid = hPreprocessInput(rxGrid,dmrsIndices,dmrsSymbols); % Concatenate the real and imaginary grids along the batch dimension nnInput = cat(4,real(interpChannelGrid),imag(interpChannelGrid)); % Use the neural network to estimate the channel estChannelGridNN = predict(channelEstimationCNN,nnInput); % Convert results to complex estChannelGridNN = complex(estChannelGridNN(:,:,:,1),estChannelGridNN(:,:,:,2));
Вычислите среднюю квадратичную невязку (MSE) каждого метода оценки.
neural_mse = mean(abs(estChannelGridPerfect(:) - estChannelGridNN(:)).^2); interp_mse = mean(abs(estChannelGridPerfect(:) - interpChannelGrid(:)).^2); practical_mse = mean(abs(estChannelGridPerfect(:) - estChannelGrid(:)).^2);
Постройте график оценок отдельных каналов и фактической реализации каналов, полученных из отводов фильтра каналов. И практическая оценка, и оценка нейронной сети превосходят линейную интерполяцию.
plotChEstimates(interpChannelGrid,estChannelGrid,estChannelGridNN,estChannelGridPerfect,...
interp_mse,practical_mse,neural_mse);
ван де Бик, Ян-Яап, Ове Эдфорс, Магнус Сэнделл, Сара Кейт Уилсон, и Пер Ола Борджессон. «Об оценке канала в системах OFDM». В 1995 году IEEE 45-я конференция по автомобильным технологиям. Обратный отсчет к беспроводному XXI веку, 2: 815-19, июль 1995.
Йе, Хао, Джеффри Е Ли и Бин-Хван Цзюан. Степень глубокого обучения для оценки канала и обнаружения сигналов в системах OFDM. IEEE Wireless Communications Letters 7, № 1 (февраль 2018): 114-17.
Солтани, Мехран, Вахид Пурахмади, Али Мирзаеи и Хамид Шейхзаде. Оценка канала на основе глубокого обучения. Препринт, представленный 13 октября 2018 года.
function hest = hPreprocessInput(rxGrid,dmrsIndices,dmrsSymbols) % Perform linear interpolation of the grid and input the result to the % neural network This helper function extracts the DM-RS symbols from % dmrsIndices locations in the received grid rxGrid and performs linear % interpolation on the extracted pilots. % Obtain pilot symbol estimates dmrsRx = rxGrid(dmrsIndices); dmrsEsts = dmrsRx .* conj(dmrsSymbols); % Create empty grids to fill after linear interpolation [rxDMRSGrid, hest] = deal(zeros(size(rxGrid))); rxDMRSGrid(dmrsIndices) = dmrsSymbols; % Find the row and column coordinates for a given DMRS configuration [rows,cols] = find(rxDMRSGrid ~= 0); dmrsSubs = [rows,cols,ones(size(cols))]; [l_hest,k_hest] = meshgrid(1:size(hest,2),1:size(hest,1)); % Perform linear interpolation f = scatteredInterpolant(dmrsSubs(:,2),dmrsSubs(:,1),dmrsEsts); hest = f(l_hest,k_hest); end function [trainData,trainLabels] = hGenerateTrainingData(dataSize) % Generate training data examples for channel estimation % Run dataSize number of iterations to create random channel configurations % and pass an OFDM-modulated fixed PDSCH grid with only the DM-RS symbols % inserted. Perform perfect timing synchronization and OFDM demodulation, % extracting the pilot symbols and performing linear interpolation at each % iteration. Use perfect channel information to create the % label data. The function returns 2 arrays - the training data and labels. fprintf('Starting data generation...\n') % List of possible channel profiles delayProfiles = {'TDL-A', 'TDL-B', 'TDL-C', 'TDL-D', 'TDL-E'}; [simParameters, carrier, pdsch] = hDeepLearningChanEstSimParameters(); % Create the channel model object nTxAnts = simParameters.NTxAnts; nRxAnts = simParameters.NRxAnts; channel = nrTDLChannel; % TDL channel object channel.NumTransmitAntennas = nTxAnts; channel.NumReceiveAntennas = nRxAnts; % Use the value returned from <matlab:edit('nrOFDMInfo') nrOFDMInfo> to % set the channel model sample rate waveformInfo = nrOFDMInfo(carrier); channel.SampleRate = waveformInfo.SampleRate; % Get the maximum number of delayed samples by a channel multipath % component. This number is calculated from the channel path with the largest % delay and the implementation delay of the channel filter, and is required % to flush the channel filter to obtain the received signal. chInfo = info(channel); maxChDelay = ceil(max(chInfo.PathDelays*channel.SampleRate)) + chInfo.ChannelFilterDelay; % Return DM-RS indices and symbols [~,dmrsIndices,dmrsSymbols,~] = hPDSCHResources(simParameters,pdsch); % PDSCH mapping in grid associated with PDSCH transmission period pdschGrid = nrResourceGrid(carrier,nTxAnts); % PDSCH DM-RS precoding and mapping [~,dmrsAntIndices] = nrExtractResources(dmrsIndices,pdschGrid); pdschGrid(dmrsAntIndices) = pdschGrid(dmrsAntIndices) + dmrsSymbols; % OFDM modulation of associated resource elements txWaveform_original = nrOFDMModulate(carrier,pdschGrid); % Acquire linear interpolator coordinates for neural net preprocessing [rows,cols] = find(pdschGrid ~= 0); dmrsSubs = [rows, cols, ones(size(cols))]; hest = zeros(size(pdschGrid)); [l_hest,k_hest] = meshgrid(1:size(hest,2),1:size(hest,1)); % Preallocate memory for the training data and labels numExamples = dataSize; [trainData, trainLabels] = deal(zeros([612 14 2 numExamples])); % Main loop for data generation, iterating over the number of examples % specified in the function call. Each iteration of the loop produces a % new channel realization with a random delay spread, doppler shift, % and delay profile. Every perturbed version of the transmitted % waveform with the DM-RS symbols is stored in trainData, and the % perfect channel realization in trainLabels. for i = 1:numExamples % Release the channel to change nontunable properties channel.release % Pick a random seed to create different channel realizations channel.Seed = randi([1001 2000]); % Pick a random delay profile, delay spread, and maximum doppler shift channel.DelayProfile = string(delayProfiles(randi([1 numel(delayProfiles)]))); channel.DelaySpread = randi([1 300])*1e-9; channel.MaximumDopplerShift = randi([5 400]); % Send data through the channel model. Append zeros at the end of % the transmitted waveform to flush channel content. These zeros % take into account any delay introduced in the channel, such as % multipath delay and implementation delay. This value depends on % the sampling rate, delay profile, and delay spread txWaveform = [txWaveform_original; zeros(maxChDelay, size(txWaveform_original,2))]; [rxWaveform,pathGains,sampleTimes] = channel(txWaveform); % Add additive white Gaussian noise (AWGN) to the received time-domain % waveform. To take into account sampling rate, normalize the noise power. % The SNR is defined per RE for each receive antenna (3GPP TS 38.101-4). SNRdB = randi([0 10]); % Random SNR values between 0 and 10 dB SNR = 10^(SNRdB/20); % Calculate linear noise gain N0 = 1/(sqrt(2.0*nRxAnts*double(waveformInfo.Nfft))*SNR); noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))); rxWaveform = rxWaveform + noise; % Perfect synchronization. Use information provided by the channel % to find the strongest multipath component pathFilters = getPathFilters(channel); % Get path filters for perfect channel estimation [offset,~] = nrPerfectTimingEstimate(pathGains,pathFilters); rxWaveform = rxWaveform(1+offset:end, :); % Perform OFDM demodulation on the received data to recreate the % resource grid, including padding in case practical % synchronization results in an incomplete slot being demodulated rxGrid = nrOFDMDemodulate(carrier,rxWaveform); [K,L,R] = size(rxGrid); if (L < carrier.SymbolsPerSlot) rxGrid = cat(2,rxGrid,zeros(K,carrier.SymbolsPerSlot-L,R)); end % Perfect channel estimation, using the value of the path gains % provided by the channel. This channel estimate does not % include the effect of transmitter precoding estChannelGridPerfect = nrPerfectChannelEstimate(carrier,pathGains, ... pathFilters,offset,sampleTimes); % Linear interpolation dmrsRx = rxGrid(dmrsIndices); dmrsEsts = dmrsRx .* conj(dmrsSymbols); f = scatteredInterpolant(dmrsSubs(:,2),dmrsSubs(:,1),dmrsEsts); hest = f(l_hest,k_hest); % Split interpolated grid into real and imaginary components and % concatenate them along the third dimension, as well as for the % true channel response rx_grid = cat(3, real(hest), imag(hest)); est_grid = cat(3, real(estChannelGridPerfect), ... imag(estChannelGridPerfect)); % Add generated training example and label to the respective arrays trainData(:,:,:,i) = rx_grid; trainLabels(:,:,:,i) = est_grid; % Data generation tracker if mod(i,round(numExamples/25)) == 0 fprintf('%3.2f%% complete\n',i/numExamples*100); end end fprintf('Data generation complete!\n') end function plotChEstimates(interpChannelGrid,estChannelGrid,estChannelGridNN,estChannelGridPerfect,... interp_mse,practical_mse,neural_mse) % Plot the different channel estimates and display the measured MSE figure subplot(1,4,1) imagesc(abs(interpChannelGrid)); xlabel('OFDM Symbol'); ylabel('Subcarrier'); title({'Linear Interpolation', ['MSE: ', num2str(interp_mse)]}); subplot(1,4,2) imagesc(abs(estChannelGrid)); xlabel('OFDM Symbol'); ylabel('Subcarrier'); title({'Practical Estimator', ['MSE: ', num2str(practical_mse)]}); subplot(1,4,3) imagesc(abs(estChannelGridNN)); xlabel('OFDM Symbol'); ylabel('Subcarrier'); title({'Neural Network', ['MSE: ', num2str(neural_mse)]}); subplot(1,4,4) imagesc(abs(estChannelGridPerfect)); xlabel('OFDM Symbol'); ylabel('Subcarrier'); title({'Actual Channel'}); end
nrChannelEstimate
| nrPerfectChannelEstimate
| predict
(Deep Learning Toolbox) | trainNetwork
(Deep Learning Toolbox)