诺尔实验室研发的Sionna平台不管是对长码还是短码都有非常有帮助。
作为方向是Polar码的学习者,可以直接利用Sionna平台上的提供的开源代码直接搭建自己的encoder或者decoder。
下面是sionna平台的 网址:Polar Codes — Sionna 0.19.0 documentation
鉴于翻遍了全网也没找到sionna平台的指导手册,在此按照在自己的经验制作了一个手册。
此博客只针对我自己的方向(Polar码)编写了手册,如果要参考LDPC或者Turbo码,建议登录Sionna平台进行查看。
Let's Begin!
点击这个链接可以跳转sionna的产品介绍。此示例笔记本将指导大家了解基本原理并说明Sionna。
只需几个命令,我们就可以模拟许多 5G 兼容组件的 PHY 层链路级性能,包括轻松可视化结果。
加载所需的包
必须安装Sionna python 软件包。
如果有多个 GPU 可用,我们将这款笔记本电脑限制为单 GPU 使用。如果只有一个 GPU 可用,则可以忽略此命令。
此外,我们希望避免该笔记本在初始化并设置memory_growth为活动状态时实例化整个 GPU 内存。
备注:Sionna 不需要 GPU。一切都可以在您的 CPU 上运行 - 但您可能需要等待更长的时间。
Sionna 数据流和设计范式
Sionna 本质上(inherently)通过批处理(batchig)来并行化模拟(parrallelization),即批处理维度(batch dimention)中的每个元素(element)都是独立模拟的(is simulated independently)。
这意味着第一个张量维度(tensor dimention)始终用于帧间(inter-frame)并行化(parrallelization),类似于Matlab/NumPy 模拟中的外部for 循环。
为了保持数据流高效,Sionna 遵循一些简单的设计原则:
- 信号处理组件作为单独的Keras 层实现(信号处理组件 :siganl-processing complement)。
- tf.float32分别用作首选数据类型(prefrred datatype)和tf.complex64复值数据类型。这允许更简单地重用组件(例如,相同的加扰层(scrambling layer)可以用于二进制输入(binary input)和LLR值)。
- 模型可以在渴望模式(eagar made)下开发,允许简单(快速)地修改(modifacation)系统参数。
- 数字运算模拟(number crunching simulations )可以在更快的图形模式下执行,甚至大多数组件都可以使用XLA加速。
- 只要有可能,组件(components)就会通过自动分级(autogard)来自动微分(differentiable),以简化深度学习设计流程。
- 代码被构造成用于不同任务的子包(sub-packages),例如通道编码(channel coding)、映射(mapping)……(有关详细信息(detail),请参阅API 文档)。
划分(division)为各个块简化了部署(deployment),所有层和功能都带有单元测试(unittest)以确保其正确行为。
这些范例简化了我们组件的可重用性和可靠性,适用于各种通信相关应用。
让我们开始吧 - 第一层(渴望模式) (Eager Mode)
每层在使用之前都需要初始化(initialize)一次。
提示:使用API 文档来查找所有现有组件的概述(overview)。
我们现在想要通过 AWGN 信道传输一些符号。首先,我们需要初始化相应的层(corresponding layer)。
channel = sionna.channel.AWGN() # init AWGN channel layer
解释一下通过 AWGN 信道传输的符号包含什么:
将复杂的 AWGN 添加到具有一定方差的输入中。
该类继承自 Keras Layer类,可以用作 Keras 模型中的层。
该层no向输入添加具有方差的复杂 AWGN 噪声。噪声no/2在每个实际维度上都有方差。它可以是标量或张量,可以广播到输入的形状。
- Example
Setting-up:
awgn_channel = AWGN()
Running:
>>> # x is the channel input>>> # no is the noise variance>>>
y = awgn_channel((x, no))
在第一个示例中,我们希望将高斯噪声添加到的某些给定值中x。
请记住 - 第一个维度是批处理维度(batch dimention)。
我们模拟 2 个消息帧(message frames),每个消息帧包含 4 个符号(symbols)。
备注:AWGN 信道被定义为复值(complex-valued)。
# define a (complex-valued) tensor to be transmitted
x = tf.constant([[0., 1.5, 1., 0.],[-1., 0., -2, 3 ]], dtype=tf.complex64)
# let's have look at the shapeprint("Shape of x: ", x.shape)print("Values of x: ", x)
Shape of x: (2, 4)
Values of x: tf.Tensor(
[[ 0. +0.j 1.5+0.j 1. +0.j 0. +0.j]
[-1. +0.j 0. +0.j -2. +0.j 3. +0.j]], shape=(2, 4), dtype=complex64)
我们希望以 5 dB 的 SNR 模拟信道。为此,我们可以简单地调用之前定义的层channel。
如果您从未使用过Keras,您可以将层视为一个函数:它有一个输入并返回处理后的输出。
备注:每次执行此单元时都会绘制新的噪声实现。
ebno_db = 5
# calculate noise variance from given EbNono = sionna.utils.ebnodb2no(ebno_db = ebno_db,
num_bits_per_symbol=2, # QPSK
coderate=1)y = channel([x, no])
print("Noisy symbols are: ", y)
输出:
Noisy symbols are: tf.Tensor(
[[ 0.17642795-0.21076633j 1.540727 +0.2577709j 0.676615 -0.14763176j
-0.14807788-0.01961605j]
[-0.9018068 -0.04732923j -0.55583185+0.41312575j -1.8852113 -0.23232108j
3.3803759 +0.2269492j ]], shape=(2, 4), dtype=complex64)
批次和多维张量
Sionna 本身支持多维张量。
大多数层在最后一个维度上运行,并且可以具有任意输入形状(在输出时保留)。
假设我们想要向长度为 500 的 64 个码字(codewords)添加 CRC-24 校验(check)(例如,每个子载波(sub-carrier)不同的 CRC)。此外,我们希望对一批 100 个样本(a batch of 100 samples)进行并行模拟。
batch_size = 100 # outer level of parallelism
num_codewords = 64 # codewords per batch sample
info_bit_length = 500 # info bits PER codeword
source = sionna.utils.BinarySource() # yields random bits
u = source([batch_size, num_codewords, info_bit_length]) # call the source layerprint("Shape of u: ", u.shape)
# initialize an CRC encoder with the standard compliant "CRC24A" polynomial
encoder_crc = sionna.fec.crc.CRCEncoder("CRC24A")
decoder_crc = sionna.fec.crc.CRCDecoder(encoder_crc) # connect to encoder
# add the CRC to the information bits u
c = encoder_crc(u) # returns a list [c, crc_valid]
print("Shape of c: ", c.shape)
print("Processed bits: ", np.size(c.numpy()))
# we can also verify the results# returns list of [info bits without CRC bits, indicator if CRC holds]
u_hat, crc_valid = decoder_crc(c)
print("Shape of u_hat: ", u_hat.shape)
print("Shape of crc_valid: ", crc_valid.shape)
print("Valid CRC check of first codeword: ", crc_valid.numpy()[0,0,0])
输出:
u 的形状:(100, 64, 500)
c 的形状:(100, 64, 524)
已处理的位:3353600
u_hat 的形状:(100, 64, 500)
crc_valid 的形状:(100, 64, 1)
有效 CRC检查第一个码字:True
我们想要再进行一次模拟,但针对 5 个独立用户。
我们可以简单地添加另一个维度,而不是定义 5 个不同的张量。
num_users = 5
u = source([batch_size, num_users, num_codewords, info_bit_length])
print("New shape of u: ", u.shape)
# We can re-use the same encoder as beforec = encoder_crc(u)print("New shape of c: ", c.shape)print("Processed bits: ", np.size(c.numpy()))
输出:
u 的新形状:(100, 5, 64, 500)
c 的新形状:(100, 5, 64, 524)
已处理的位数:16768000
通常,良好的结果可视化有助于获得新的研究想法。因此,Sionna 具有内置绘图功能。
让我们看一下 16-QAM 星座图(constellation)。
constellation = sionna.mapping.Constellation("qam", num_bits_per_symbol=4)constellation.show();
输出的星座图:
目前我们已经了解了sionna平台的定义和基本的入门概念,下一篇文章我们将进行仿真。