Add Gaussian channel model
This commit is contained in:
parent
d0af8fc3da
commit
3b40e27070
|
@ -1 +1,2 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import torch.nn as nn
|
import torch.nn as nn
|
||||||
|
from .GaussianChannel import GaussianChannel
|
||||||
|
|
||||||
|
|
||||||
class ConstellationNet(nn.Module):
|
class ConstellationNet(nn.Module):
|
||||||
|
@ -6,7 +7,8 @@ class ConstellationNet(nn.Module):
|
||||||
self,
|
self,
|
||||||
order=2,
|
order=2,
|
||||||
encoder_layers_sizes=(),
|
encoder_layers_sizes=(),
|
||||||
decoder_layers_sizes=()
|
decoder_layers_sizes=(),
|
||||||
|
channel_model=GaussianChannel()
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Create an encoder-decoder network to automatically shape a
|
Create an encoder-decoder network to automatically shape a
|
||||||
|
@ -14,13 +16,15 @@ class ConstellationNet(nn.Module):
|
||||||
fiber channel.
|
fiber channel.
|
||||||
|
|
||||||
:param order: Order of the constellation, i.e. the number of messages
|
:param order: Order of the constellation, i.e. the number of messages
|
||||||
that are to be transmitted or equivalently the number of symbols whose
|
that are to be transmitted, or equivalently the number of symbols whose
|
||||||
placements in the constellation have to be learned.
|
placements in the constellation have to be learned.
|
||||||
:param encoder_layers_sizes: Shape of the encoder’s hidden layers. The
|
:param encoder_layers_sizes: Shape of the encoder’s hidden layers. The
|
||||||
size of this sequence is the number of hidden layers, with each element
|
size of this sequence is the number of hidden layers, with each element
|
||||||
being a number which specifies the number of neurons in its channel.
|
being a number which specifies the number of neurons in its channel.
|
||||||
:param decoder_layers_sizes: Shape of the decoder’s hidden layers. Uses
|
:param decoder_layers_sizes: Shape of the decoder’s hidden layers. Uses
|
||||||
the same convention as `encoder_layers_sizes` above.
|
the same convention as `encoder_layers_sizes` above.
|
||||||
|
:param channel_model: Instance of the channel model to use between the
|
||||||
|
encoder and decoder network.
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -41,9 +45,7 @@ class ConstellationNet(nn.Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
self.encoder = nn.Sequential(*encoder_layers)
|
self.encoder = nn.Sequential(*encoder_layers)
|
||||||
|
self.channel = channel_model
|
||||||
# TODO: Add real channel model
|
|
||||||
self.channel = nn.Identity()
|
|
||||||
|
|
||||||
# Build the decoder network taking the noisy I/Q vector received from
|
# Build the decoder network taking the noisy I/Q vector received from
|
||||||
# the channel as input and outputting a probability vector for each
|
# the channel as input and outputting a probability vector for each
|
||||||
|
@ -60,7 +62,7 @@ class ConstellationNet(nn.Module):
|
||||||
# Softmax is not used at the end of the network because the
|
# Softmax is not used at the end of the network because the
|
||||||
# CrossEntropyLoss criterion is used for training, which includes
|
# CrossEntropyLoss criterion is used for training, which includes
|
||||||
# LogSoftmax
|
# LogSoftmax
|
||||||
decoder_layers.append(nn.Linear(prev_layer_size, order),)
|
decoder_layers.append(nn.Linear(prev_layer_size, order))
|
||||||
|
|
||||||
self.decoder = nn.Sequential(*decoder_layers)
|
self.decoder = nn.Sequential(*decoder_layers)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def channel_OSNR():
|
||||||
|
Sys_rate = 32e9
|
||||||
|
r = 0.05
|
||||||
|
Dispersion = 16.48e-6
|
||||||
|
B_2 = Dispersion
|
||||||
|
Non_linear_index = 1.3e3
|
||||||
|
Gam = Non_linear_index
|
||||||
|
Loss = 10**20
|
||||||
|
Alpha = Loss
|
||||||
|
Span_count = 20
|
||||||
|
N_s = Span_count
|
||||||
|
Span_length = 10e5 # (km)
|
||||||
|
L_s = Span_length
|
||||||
|
Noise_figure = 10**0.5 # (dB)
|
||||||
|
h = 6.6261e-34
|
||||||
|
v = 299792458
|
||||||
|
B_WDM = Sys_rate*(1+r)
|
||||||
|
B_N = 0.1
|
||||||
|
|
||||||
|
P_ASE_1 = h*v*B_N*(Loss*Span_length*Noise_figure-1)
|
||||||
|
P_ASE = P_ASE_1 * Span_count
|
||||||
|
L_eff = 1-np.exp(-Loss*Span_length)/2/Alpha
|
||||||
|
|
||||||
|
eps = 0.3*np.log(1+(6/L_s)*(L_eff/np.arcsinh((np.pi**2/3)*B_2*L_eff*B_WDM**2)))
|
||||||
|
b = P_ASE_1/(2*(N_s**eps)*B_N*(Gam**2)*L_eff*np.arcsinh((np.pi**2/3)*B_2*L_eff*B_WDM**2))
|
||||||
|
P_ch = Sys_rate*(((27*np.pi*B_2/16)*b)**(1/3))
|
||||||
|
OSNR = (2*P_ch/3/P_ASE)
|
||||||
|
|
||||||
|
OSNR_dB = 10*np.log10(OSNR)
|
||||||
|
return OSNR_dB
|
||||||
|
|
||||||
|
|
||||||
|
def Const_Points_Pow(IQ):
|
||||||
|
"""
|
||||||
|
Calculate the average power of a set of vectors.
|
||||||
|
"""
|
||||||
|
p_enc_avg = (torch.norm(IQ, dim=1) ** 2).mean()
|
||||||
|
p_enc_avg_dB = 10 * torch.log10(p_enc_avg)
|
||||||
|
return p_enc_avg_dB
|
||||||
|
|
||||||
|
|
||||||
|
def Pow_Noise(CH_OSNR, CPP):
|
||||||
|
"""
|
||||||
|
Calculate the power of channel noise.
|
||||||
|
"""
|
||||||
|
P_N_dB = CPP - CH_OSNR
|
||||||
|
p_N_watt = 10**(P_N_dB/10)
|
||||||
|
Var_Noise = p_N_watt
|
||||||
|
return Var_Noise
|
||||||
|
|
||||||
|
|
||||||
|
def Channel_Noise_Model(NV, S):
|
||||||
|
"""
|
||||||
|
Compute the Gaussian noise to be added to each vector to simulate passing
|
||||||
|
through a channel.
|
||||||
|
"""
|
||||||
|
return torch.distributions.normal.Normal(
|
||||||
|
0, torch.sqrt(NV*5000)
|
||||||
|
).sample(S)
|
||||||
|
|
||||||
|
|
||||||
|
class GaussianChannel(nn.Module):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
Noise_Variance = Pow_Noise(channel_OSNR(), Const_Points_Pow(x))
|
||||||
|
Noise_Volts = Channel_Noise_Model(Noise_Variance, [len(x), 2])
|
||||||
|
return x + Noise_Volts
|
|
@ -1,2 +1,3 @@
|
||||||
from constellation.ConstellationNet import ConstellationNet
|
from constellation.ConstellationNet import ConstellationNet
|
||||||
|
from constellation.GaussianChannel import GaussianChannel
|
||||||
import constellation.util
|
import constellation.util
|
||||||
|
|
14
plot.py
14
plot.py
|
@ -3,17 +3,23 @@ from constellation import util
|
||||||
import torch
|
import torch
|
||||||
from matplotlib import pyplot
|
from matplotlib import pyplot
|
||||||
from mpl_toolkits.axisartist.axislines import SubplotZero
|
from mpl_toolkits.axisartist.axislines import SubplotZero
|
||||||
import math
|
|
||||||
import numpy
|
|
||||||
|
|
||||||
# Number learned symbols
|
# Number learned symbols
|
||||||
order = 4
|
order = 4
|
||||||
|
|
||||||
# File in which the trained model is saved
|
# File in which the trained model is saved
|
||||||
input_file = 'output/constellation-order-{}.tc'.format(order)
|
input_file = 'output/constellation-order-{}.pth'.format(order)
|
||||||
|
|
||||||
|
# Restore model from file
|
||||||
|
model = constellation.ConstellationNet(
|
||||||
|
order=order,
|
||||||
|
encoder_layers_sizes=(4,),
|
||||||
|
decoder_layers_sizes=(4,),
|
||||||
|
channel_model=constellation.GaussianChannel()
|
||||||
|
)
|
||||||
|
|
||||||
model = constellation.ConstellationNet(order=order)
|
|
||||||
model.load_state_dict(torch.load(input_file))
|
model.load_state_dict(torch.load(input_file))
|
||||||
|
model.eval()
|
||||||
|
|
||||||
# Compute encoded vectors
|
# Compute encoded vectors
|
||||||
with torch.no_grad():
|
with torch.no_grad():
|
||||||
|
|
9
train.py
9
train.py
|
@ -15,9 +15,14 @@ num_epochs = 20000
|
||||||
loss_report_epoch_skip = 500
|
loss_report_epoch_skip = 500
|
||||||
|
|
||||||
# File in which the trained model is saved
|
# File in which the trained model is saved
|
||||||
output_file = 'output/constellation-order-{}.tc'.format(order)
|
output_file = 'output/constellation-order-{}.pth'.format(order)
|
||||||
|
|
||||||
model = constellation.ConstellationNet(order=order)
|
model = constellation.ConstellationNet(
|
||||||
|
order=order,
|
||||||
|
encoder_layers_sizes=(4,),
|
||||||
|
decoder_layers_sizes=(4,),
|
||||||
|
channel_model=constellation.GaussianChannel()
|
||||||
|
)
|
||||||
|
|
||||||
# Train the model with random data
|
# Train the model with random data
|
||||||
model.train()
|
model.train()
|
||||||
|
|
Loading…
Reference in New Issue