├── AutoEncoderFiber.ipynb
├── LICENSE
└── README.md
/AutoEncoderFiber.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "AutoEncoderFibercopy.ipynb",
7 | "version": "0.3.2",
8 | "provenance": [],
9 | "collapsed_sections": [],
10 | "include_colab_link": true
11 | },
12 | "kernelspec": {
13 | "display_name": "Python 3",
14 | "language": "python",
15 | "name": "python3"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | "
"
27 | ]
28 | },
29 | {
30 | "metadata": {
31 | "id": "GuDJI6Q5meSB",
32 | "colab_type": "text"
33 | },
34 | "cell_type": "markdown",
35 | "source": [
36 | "# Auto-encoder for a memoryless fiber-optic channel\n",
37 | "\n",
38 | "This script uses an auto-encoder (AE) for end-to-end learning of a non-linear memoryless fiber channel. The determines a good constellation and a good receiver. The achievable information rate is also computed. \n",
39 | "\n",
40 | "The system is of the form:\n",
41 | "$$\n",
42 | "x_{k+1}=x_k \\exp (j \\gamma L / K |x_k|^2) + n_k, k=0,..,K-1\n",
43 | "$$\n",
44 | "where $x_0$ is the input (a complex symbol), $\\gamma$ is the fiber nonlinearity parameter (typically around 1.2), $L$ is the fiber length, and $K$ is the number of amplification stages. The channel output is $x_K$. Finally, $n_k$ is white Gaussian noise. \n",
45 | "\n",
46 | "\n",
47 | "This code was is based on the paper\n",
48 | "\n",
49 | "Shen Li, Christian Häger, Nil Garcia, and Henk Wymeersch, \"Achievable Information Rates for Nonlinear Fiber Communication via End-to-end Autoencoder Learning,\" in *Proc. European Conference on Optical Communication* (2018) [arXiv:1804.07675](https://arxiv.org/pdf/1804.07675.pdf). \n",
50 | "\n",
51 | "The code was written by Christian Häger. Parts were provided by Shen Li. Integration and polishing by Henk Wymeersch. \n",
52 | "\n",
53 | "Remaining issues:\n",
54 | "* returns NaN for too high input power\n",
55 | "\n",
56 | "\n"
57 | ]
58 | },
59 | {
60 | "metadata": {
61 | "id": "DTSyKzaDmeSN",
62 | "colab_type": "code",
63 | "colab": {}
64 | },
65 | "cell_type": "code",
66 | "source": [
67 | "import tensorflow as tf\n",
68 | "import numpy as np\n",
69 | "import matplotlib.pyplot as plt\n",
70 | "import scipy.io as sio\n",
71 | "import math\n",
72 | "import time\n",
73 | "import sys\n",
74 | "import matplotlib.cm as cm"
75 | ],
76 | "execution_count": 0,
77 | "outputs": []
78 | },
79 | {
80 | "metadata": {
81 | "id": "IzWYJH3lmeSp",
82 | "colab_type": "code",
83 | "colab": {}
84 | },
85 | "cell_type": "code",
86 | "source": [
87 | "def tf_print(tmp_var):\n",
88 | " init = tf.global_variables_initializer()\n",
89 | " sess = tf.Session()\n",
90 | " sess.run(init)\n",
91 | " print(sess.run(tmp_var))\n"
92 | ],
93 | "execution_count": 0,
94 | "outputs": []
95 | },
96 | {
97 | "metadata": {
98 | "id": "sQzoQ8lumeS3",
99 | "colab_type": "code",
100 | "colab": {}
101 | },
102 | "cell_type": "code",
103 | "source": [
104 | "## START: these are the main parameters to set\n",
105 | "P_in_dBm=-2 # input power in dBm\n",
106 | "gamma = 1.27 # fiber nonlinearity (set to 0 zero for AWGN or 1.27 for a nonlinear channel)\n",
107 | "M = 16 # constellation size\n",
108 | "\n",
109 | "# main network parameters and optimization parameters (to be modified for performance improvements)\n",
110 | "neurons_per_layer = 50 \n",
111 | "tx_layers = 2\n",
112 | "rx_layers = 3\n",
113 | "learning_rate = 0.001\n",
114 | "iterations = 50000\n",
115 | "stacks = 20\n",
116 | "minibatch_size = stacks*M\n",
117 | "## END: these are the main parameters to set\n",
118 | "\n",
119 | "\n",
120 | "# derived channel parameters\n",
121 | "channel_uses = 2 # this should be 2: the fiber code will break otherwise\n",
122 | "assert(channel_uses==2), \"channel uses should be 2\"\n",
123 | "L=2000 # fiber total length\n",
124 | "K=20 # number of amplification stages (more layers requires more time)\n",
125 | "sigma = 3.8505e-4*np.sqrt(2) # N0= h*v*nsp*(G-1) sigma**2 = BW*N0 \n",
126 | "sigma2tot=K*sigma**2\n",
127 | "P_in=10**(P_in_dBm/10)*0.001\n",
128 | "Ess=np.sqrt(P_in)\n",
129 | "SNR=Ess**2/(sigma2tot)\n",
130 | "SNR_dB=10*np.log(SNR)"
131 | ],
132 | "execution_count": 0,
133 | "outputs": []
134 | },
135 | {
136 | "metadata": {
137 | "id": "8RbjEuy4LNYG",
138 | "colab_type": "code",
139 | "colab": {}
140 | },
141 | "cell_type": "code",
142 | "source": [
143 | "#=====================================================#\n",
144 | "# Define the components of the computation graph\n",
145 | "#=====================================================#\n",
146 | "initializer = tf.contrib.layers.xavier_initializer()\n",
147 | "# transmitter\n",
148 | "W_tx = {}\n",
149 | "b_tx = {}\n",
150 | "for NN in range(tx_layers):\n",
151 | " if NN == 0:\n",
152 | " in_neurons = M\n",
153 | " else:\n",
154 | " in_neurons = neurons_per_layer\n",
155 | " if NN == tx_layers - 1:\n",
156 | " out_neurons = channel_uses\n",
157 | " else:\n",
158 | " out_neurons = neurons_per_layer\n",
159 | " W_tx[NN] = tf.Variable(initializer([in_neurons, out_neurons]))\n",
160 | " b_tx[NN] = tf.Variable(initializer([1, out_neurons]))\n",
161 | " \n",
162 | "# receiver\n",
163 | "W_rx = {}\n",
164 | "b_rx = {}\n",
165 | "for NN in range(rx_layers):\n",
166 | " if NN == 0:\n",
167 | " in_neurons = channel_uses+1\n",
168 | " else:\n",
169 | " in_neurons = neurons_per_layer\n",
170 | " if NN == rx_layers - 1:\n",
171 | " out_neurons = M\n",
172 | " else:\n",
173 | " out_neurons = neurons_per_layer\n",
174 | " W_rx[NN] = tf.Variable(initializer([in_neurons, out_neurons]))\n",
175 | " b_rx[NN] = tf.Variable(initializer([1, out_neurons])) \n",
176 | "\n",
177 | "# the encoder\n",
178 | "def encoder(x):\n",
179 | " for NN in range(tx_layers-1):\n",
180 | " x = tf.nn.tanh(tf.matmul(x, W_tx[NN]) + b_tx[NN])\n",
181 | " x = tf.matmul(x, W_tx[tx_layers-1]) + b_tx[tx_layers-1]\n",
182 | " return x\n",
183 | "\n",
184 | "# the decoder\n",
185 | "def decoder(x):\n",
186 | " for NN in range(rx_layers-1):\n",
187 | " x = tf.nn.tanh(tf.matmul(x, W_rx[NN]) + b_rx[NN])\n",
188 | " x = tf.nn.softmax(tf.matmul(x, W_rx[rx_layers-1]) + b_rx[rx_layers-1])\n",
189 | " return x\n",
190 | "\n",
191 | "# the non-dispersive fiber channel \n",
192 | "def fiber_channel(x):\n",
193 | " xr=x[:,0]\n",
194 | " xi=x[:,1]\n",
195 | " for segments in range(1,K+1): \n",
196 | " s=gamma*(xr**2+xi**2)*L/K \n",
197 | " xr=xr*tf.cos(s)-xi*tf.sin(s)\n",
198 | " xi=xi*tf.cos(s)+xr*tf.sin(s)\n",
199 | " xr=tf.add(xr,tf.random_normal(tf.shape(xr), mean=0.0, stddev=sigma))\n",
200 | " xi=tf.add(xi,tf.random_normal(tf.shape(xi), mean=0.0, stddev=sigma)) \n",
201 | " z=tf.stack([xr,xi,xr**2+xi**2]) \n",
202 | " z=tf.transpose(z) \n",
203 | " return z\n",
204 | "\n",
205 | "# average transmit power constraint\n",
206 | "def normalization(x): # E[|x|^2] = Es\n",
207 | " return Ess*x / tf.sqrt(2*tf.reduce_mean(tf.square(x)))"
208 | ],
209 | "execution_count": 0,
210 | "outputs": []
211 | },
212 | {
213 | "metadata": {
214 | "id": "_rlBVxfWmeTH",
215 | "colab_type": "code",
216 | "colab": {}
217 | },
218 | "cell_type": "code",
219 | "source": [
220 | "#=====================================================#\n",
221 | "# build the computation graph\n",
222 | "#=====================================================#\n",
223 | "X_tilde = tf.placeholder('float', [minibatch_size, M]) # one-hot vectors\n",
224 | "\n",
225 | "#grid coordinates for visulazing decision regions\n",
226 | "resolution=1000\n",
227 | "G = tf.placeholder('float', [resolution**2, channel_uses+1])\n",
228 | "\n",
229 | "X1=encoder(X_tilde)\n",
230 | "X = normalization(X1) # minibatch_size x channel_uses\n",
231 | "Y = fiber_channel(X)\n",
232 | "Z = decoder(Y)\n",
233 | "D = decoder(G)\n",
234 | "epsilon = 0.000001\n",
235 | "loss = -tf.reduce_mean(X_tilde*tf.log(Z+epsilon))\n",
236 | "MI=(np.log(M)-loss*M)/np.log(2)\n",
237 | "optimizer = tf.train.AdamOptimizer(learning_rate)\n",
238 | "train = optimizer.minimize(loss)"
239 | ],
240 | "execution_count": 0,
241 | "outputs": []
242 | },
243 | {
244 | "metadata": {
245 | "id": "cYP38e2pmeTa",
246 | "colab_type": "code",
247 | "outputId": "fd6864b6-6478-4bba-8b1a-99fb70d925e8",
248 | "colab": {
249 | "base_uri": "https://localhost:8080/",
250 | "height": 920
251 | }
252 | },
253 | "cell_type": "code",
254 | "source": [
255 | "#=====================================================#\n",
256 | "# parameter training\n",
257 | "#=====================================================#\n",
258 | "start_time = time.time()\n",
259 | "unitmatrix = np.eye(M) \n",
260 | "training_set = np.tile(unitmatrix, [stacks, 1])\n",
261 | "init_op = tf.global_variables_initializer()\n",
262 | "sess = tf.Session()\n",
263 | "sess.run(init_op)\n",
264 | "MI_tmp=0\n",
265 | "totalloss=[]\n",
266 | "for i in range(1, iterations+1):\n",
267 | " _, loss_tmp, MI_tmp = sess.run([train, loss, MI], feed_dict={X_tilde: training_set})\n",
268 | " totalloss=np.append(totalloss, loss_tmp)\n",
269 | " if i%1000==0 or i==1:\n",
270 | " print('iteration ', i, ': loss = ', loss_tmp, '; Mutual information [bits] = ', MI_tmp) \n",
271 | "elapsed = time.time() - start_time\n",
272 | "print(\"{0:.2f} seconds\".format(elapsed))"
273 | ],
274 | "execution_count": 6,
275 | "outputs": [
276 | {
277 | "output_type": "stream",
278 | "text": [
279 | "iteration 1 : loss = 0.17885368 ; Mutual information [bits] = -0.12850097\n",
280 | "iteration 1000 : loss = 0.028006202 ; Mutual information [bits] = 3.3535295\n",
281 | "iteration 2000 : loss = 0.011281811 ; Mutual information [bits] = 3.7395804\n",
282 | "iteration 3000 : loss = 0.0055578933 ; Mutual information [bits] = 3.8717065\n",
283 | "iteration 4000 : loss = 0.005900917 ; Mutual information [bits] = 3.8637884\n",
284 | "iteration 5000 : loss = 0.004730115 ; Mutual information [bits] = 3.890814\n",
285 | "iteration 6000 : loss = 0.005254518 ; Mutual information [bits] = 3.878709\n",
286 | "iteration 7000 : loss = 0.0032975976 ; Mutual information [bits] = 3.923881\n",
287 | "iteration 8000 : loss = 0.0026089507 ; Mutual information [bits] = 3.9397771\n",
288 | "iteration 9000 : loss = 0.001929207 ; Mutual information [bits] = 3.9554677\n",
289 | "iteration 10000 : loss = 0.0034735291 ; Mutual information [bits] = 3.9198198\n",
290 | "iteration 11000 : loss = 0.0020205784 ; Mutual information [bits] = 3.9533587\n",
291 | "iteration 12000 : loss = 0.0019302426 ; Mutual information [bits] = 3.955444\n",
292 | "iteration 13000 : loss = 0.0027602636 ; Mutual information [bits] = 3.9362845\n",
293 | "iteration 14000 : loss = 0.001349867 ; Mutual information [bits] = 3.9688408\n",
294 | "iteration 15000 : loss = 0.0029932146 ; Mutual information [bits] = 3.9309072\n",
295 | "iteration 16000 : loss = 0.0007508879 ; Mutual information [bits] = 3.9826672\n",
296 | "iteration 17000 : loss = 0.0019698858 ; Mutual information [bits] = 3.9545288\n",
297 | "iteration 18000 : loss = 0.0018588252 ; Mutual information [bits] = 3.9570923\n",
298 | "iteration 19000 : loss = 0.0028716298 ; Mutual information [bits] = 3.9337137\n",
299 | "iteration 20000 : loss = 0.002332374 ; Mutual information [bits] = 3.9461615\n",
300 | "iteration 21000 : loss = 0.00052453595 ; Mutual information [bits] = 3.9878922\n",
301 | "iteration 22000 : loss = 0.0005966529 ; Mutual information [bits] = 3.9862273\n",
302 | "iteration 23000 : loss = 0.00065423944 ; Mutual information [bits] = 3.984898\n",
303 | "iteration 24000 : loss = 0.0022190292 ; Mutual information [bits] = 3.9487777\n",
304 | "iteration 25000 : loss = 0.0005131921 ; Mutual information [bits] = 3.9881537\n",
305 | "iteration 26000 : loss = 0.001012143 ; Mutual information [bits] = 3.9766364\n",
306 | "iteration 27000 : loss = 0.0011796795 ; Mutual information [bits] = 3.9727693\n",
307 | "iteration 28000 : loss = 0.0016018931 ; Mutual information [bits] = 3.9630234\n",
308 | "iteration 29000 : loss = 0.0016618859 ; Mutual information [bits] = 3.9616385\n",
309 | "iteration 30000 : loss = 0.00021583195 ; Mutual information [bits] = 3.995018\n",
310 | "iteration 31000 : loss = 0.0019067747 ; Mutual information [bits] = 3.9559858\n",
311 | "iteration 32000 : loss = 0.0012141239 ; Mutual information [bits] = 3.9719744\n",
312 | "iteration 33000 : loss = 0.0009799392 ; Mutual information [bits] = 3.9773798\n",
313 | "iteration 34000 : loss = 0.0015597316 ; Mutual information [bits] = 3.9639964\n",
314 | "iteration 35000 : loss = 0.0021589745 ; Mutual information [bits] = 3.9501643\n",
315 | "iteration 36000 : loss = 0.0018438756 ; Mutual information [bits] = 3.9574378\n",
316 | "iteration 37000 : loss = 0.0011696611 ; Mutual information [bits] = 3.9730003\n",
317 | "iteration 38000 : loss = 0.0013336143 ; Mutual information [bits] = 3.969216\n",
318 | "iteration 39000 : loss = 0.00085040426 ; Mutual information [bits] = 3.9803698\n",
319 | "iteration 40000 : loss = 0.0018855694 ; Mutual information [bits] = 3.9564753\n",
320 | "iteration 41000 : loss = 0.0006585914 ; Mutual information [bits] = 3.9847977\n",
321 | "iteration 42000 : loss = 0.0019125761 ; Mutual information [bits] = 3.9558516\n",
322 | "iteration 43000 : loss = 0.0027832282 ; Mutual information [bits] = 3.9357545\n",
323 | "iteration 44000 : loss = 0.000286943 ; Mutual information [bits] = 3.9933765\n",
324 | "iteration 45000 : loss = 0.0020027482 ; Mutual information [bits] = 3.9537704\n",
325 | "iteration 46000 : loss = 0.001009146 ; Mutual information [bits] = 3.9767056\n",
326 | "iteration 47000 : loss = 0.0018047865 ; Mutual information [bits] = 3.95834\n",
327 | "iteration 48000 : loss = 0.0005892061 ; Mutual information [bits] = 3.9863992\n",
328 | "iteration 49000 : loss = 0.002877311 ; Mutual information [bits] = 3.9335828\n",
329 | "iteration 50000 : loss = 0.0008200977 ; Mutual information [bits] = 3.9810696\n",
330 | "132.48 seconds\n"
331 | ],
332 | "name": "stdout"
333 | }
334 | ]
335 | },
336 | {
337 | "metadata": {
338 | "id": "jasr9ooGmeTw",
339 | "colab_type": "code",
340 | "outputId": "6da1268b-b77f-4168-eef8-338c2a80d7cf",
341 | "colab": {
342 | "base_uri": "https://localhost:8080/",
343 | "height": 660
344 | }
345 | },
346 | "cell_type": "code",
347 | "source": [
348 | "#=====================================================#\n",
349 | "# Visualization\n",
350 | "#=====================================================#\n",
351 | "#x,y grids\n",
352 | "x = np.arange(-0.1, 0.1, 0.0002)\n",
353 | "xx, yy = np.meshgrid(x, x)\n",
354 | "xg = xx.reshape(1000000,1)\n",
355 | "yg = yy.reshape(1000000,1)\n",
356 | "r = xg**2+yg**2\n",
357 | "xygrids = np.concatenate((xg, yg, r), axis=1)\n",
358 | "\n",
359 | "\n",
360 | "[constellation,receive_points,decision_regions] = sess.run([X,Y,D],feed_dict={X_tilde:training_set, G: xygrids})\n",
361 | "x = constellation[:, 0]\n",
362 | "y = constellation[:, 1]\n",
363 | "\n",
364 | "receive_x = receive_points[:, 0]\n",
365 | "receive_y = receive_points[:, 1]\n",
366 | "\n",
367 | "# plotting\n",
368 | "fig=plt.figure(figsize=(7, 7))\n",
369 | "ax = fig.add_subplot(2, 1, 1)\n",
370 | "plt.plot(totalloss)\n",
371 | "plt.xlabel('iteration')\n",
372 | "plt.ylabel('loss')\n",
373 | "\n",
374 | "fig = plt.figure(figsize=(7, 7))\n",
375 | "ax1 = fig.add_subplot(111)\n",
376 | "plt.xlabel('X')\n",
377 | "plt.ylabel('Y')\n",
378 | "ax1.scatter(x, y, c='b', marker='o')\n",
379 | "plt.axis('equal')\n",
380 | "xmax = max(abs(x))\n",
381 | "ymax = max(abs(y))\n",
382 | "max_axis = 1.2 * max(xmax, ymax)\n",
383 | "plt.xlim(-max_axis, max_axis)\n",
384 | "plt.ylim(-max_axis, max_axis)\n",
385 | "plt.show()\n"
386 | ],
387 | "execution_count": 7,
388 | "outputs": [
389 | {
390 | "output_type": "display_data",
391 | "data": {
392 | "image/png": "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\nq995uHQAAAAASUVORK5CYII=\n",
393 | "text/plain": [
394 | ""
395 | ]
396 | },
397 | "metadata": {
398 | "tags": []
399 | }
400 | },
401 | {
402 | "output_type": "display_data",
403 | "data": {
404 | "image/png": "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\nm+TxePTNb35TwWBQ//Vf/6XBwUE1NDQ4WTYAIMO5rHtduJum7DyXz7UCe9BXe9BXe9BXe6TqmiEz\n0AAAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgC\nAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCM\nRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjEcYAgCMRxgCAIxHGAIAjOdo\nGA4NDamurk7V1dWqqalRJBK54z1Hjx7V2rVrFQgE1NbWljQWj8e1YsUKvfnmm06VDAAwgKNh+Oqr\nr2rWrFk6ePCgNm7cqGeeeSZpfGBgQI2Njdq/f79aWlrU3NysS5cuJcZ37typefPmOVkyAMAAjoZh\nOBxWWVmZJGnVqlXq7u5OGu/p6dHixYvl8XiUm5ur4uLixHvC4bDy8vL0mc98xsmSAQAGyHHyy+Lx\nuLxeryQpKytLLpdLg4ODcrvdd4xLktfrVSwW0+DgoBobG/X8889r+/bt9/VdBQUzlZOTPfV/xAif\nz2Pbtk1GX+1BX+1BX+2Rir7aFoZtbW13XPPr6elJWrYsa8xt3Brfu3evAoGAZs2add/f39s7cN/v\nHS+fz6NY7Kpt2zcVfbUHfbUHfbWHnX0dK2RtC8NAIKBAIJC0LhgMKhaLadGiRRoaGpJlWYmjQkny\n+/2Kx+OJ5Wg0qqVLl+rll1/WzZs39eKLL+r8+fM6efKkdu3apU9/+tN2lQ8AMIij1wxLSkp07Ngx\nSVJnZ6dWrlyZNL5kyRKdOnVKV65cUX9/v7q7u7V8+XIdOnRIhw8f1uHDh/Xwww+rvr6eIAQATBlH\nrxlWVFSoq6tL1dXVcrvdCoVCkoZPg65YsULLli1TXV2dnnjiCblcLm3atEkeD+fkAQD2cln3unA3\nTdl5Lp9rBfagr/agr/agr/ZI1TVDZqABABiPMAQAGI8wBAAYjzAEABiPMAQAGI8wBAAYjzAEABiP\nMAQAGI8wBAAYjzAEABiPMAQAGI8wBAAYL2Mn6gYA4H5xZAgAMB5hCAAwHmEIADAeYQgAMB5hCAAw\nHmEIADAeYQgAMB5hOIqhoSHV1dWpurpaNTU1ikQid7zn6NGjWrt2rQKBgNra2pLG4vG4VqxYoTff\nfNOpkqeFifb1+vXr+uEPf6jq6mo9/vjjeuutt5wuPW1t375dlZWVqqqq0smTJ5PGurq69Nhjj6my\nslKNjY339RkMm0hfd+7cqcrKSq1du1a/+tWvnC55WphIXyXp2rVrKi0tVXt7uz2FWbir9vZ2q6Gh\nwbIsy3rjjTesJ598Mmm8v7/3Ai4CAAAFWElEQVTf+uIXv2hduXLF+vDDD60vf/nLVm9vb2L8+9//\nvrVmzRrrf/7nfxytO91NtK9Hjhyx6uvrLcuyrHfeecdau3at06WnpTfffNPasGGDZVmWdebMGevx\nxx9PGv/Sl75kvfvuu9aNGzes6upq6/e///09P4OJ9TUcDlv/8A//YFmWZX3wwQfW6tWrnS477U2k\nr7c8++yz1t///d9bL730ki21cWQ4inA4rLKyMknSqlWr1N3dnTTe09OjxYsXy+PxKDc3V8XFxYn3\nhMNh5eXl6TOf+Yzjdae7ifb1kUce0ebNmyVJXq9Xly5dcrz2dBQOh1VaWipJWrhwoS5fvqy+vj5J\nUiQS0ezZs1VYWKisrCytXr1a4XB4zM9g2ET6umLFCu3atUuSNGvWLH344Ye6ceNGyv6GdDSRvkrS\n2bNndebMGT388MO21UYYjiIej8vr9UqSsrKy5HK5NDg4eNdxafh/0LFYTIODg2psbNR3vvMdx2ue\nDiba1xkzZuhjH/uYJKm5uVlf+cpXnC08TcXjcRUUFCSWb/VLkmKx2F17OdZnMGwifc3OztbMmTMl\nSUeOHNFDDz2k7OxsZwtPcxPpqyTt2LFDwWDQ1tpybN36NNHW1nbHNb+enp6kZeseU7jeGt+7d68C\ngYBmzZo1tUVOQ1PZ11tefPFFnT59Wnv27JmaIjPMvfo5VZ8xzXh69Nprr+nIkSNqamqysaLMcD99\nfeWVV7R06VLNmzfP1loIQ0mBQECBQCBpXTAYVCwW06JFizQ0NCTLsuR2uxPjfr9f8Xg8sRyNRrV0\n6VK9/PLLunnzpl588UWdP39eJ0+e1K5du/TpT3/asb8nXUxlX6XhcH399df1/PPPa8aMGc78EWnu\nbv3y+Xx3Hbt48aL8fr9mzJgx6mcwbCJ9laQ33nhDe/bs0c9//nN5PB5ni54GJtLX48ePKxKJ6Pjx\n43r//ffldrv14IMPatWqVVNaG6dJR1FSUqJjx45Jkjo7O7Vy5cqk8SVLlujUqVO6cuWK+vv71d3d\nreXLl+vQoUM6fPiwDh8+rIcfflj19fVGBuFoJtrXSCSiQ4cO6bnnnkucLsVwPzs6OiRJp0+flt/v\nV35+viRp7ty56uvr04ULF3T9+nV1dnaqpKRkzM9g2ET6evXqVe3cuVM/+9nP9MADD6Sy/LQ1kb7+\n27/9m1566SUdPnxYgUBA3/zmN6c8CCWODEdVUVGhrq4uVVdXy+12KxQKSRo+DbpixQotW7ZMdXV1\neuKJJ+RyubRp0yb2BO/DRPv6wgsv6NKlS9qwYUNiW/v27Us6qjRRcXGxioqKVFVVJZfLpfr6erW3\nt8vj8aisrEwNDQ2qq6uTNNz7BQsWaMGCBXd8Bskm0tfW1lb19vbq29/+dmI7O3bs0Cc+8YlU/Rlp\nZyJ9dQrPMwQAGI/TpAAA4xGGAADjEYYAAOMRhgAA4xGGAADjEYZABjp16pRKS0uT5hz9yU9+oh07\ndqSwKiB9EYZABlq8eLEeffTRxH2cb731lk6cOJF0DxyA/0cYAhlq48aNevvtt/Xaa6+poaFBTz/9\nNLP3AKPgpnsgg/3hD3/Qo48+qq9//ev67ne/m+pygLTFkSGQwd555x3NnTtX3d3dPJ0CGANhCGSo\nWCymZ599Vr/4xS/k9/v17//+76kuCUhbnCYFMtSGDRv0pS99SWvWrNEHH3ygtWvXav/+/frUpz6V\n6tKAtMORIZCBDh06JElas2aNpOGnhn/nO9/R5s2bdfPmzVSWBqQljgwBAMbjyBAAYDzCEABgPMIQ\nAGA8whAAYDzCEABgPMIQAGA8whAAYLz/A1QSHmuizjvgAAAAAElFTkSuQmCC\n",
405 | "text/plain": [
406 | ""
407 | ]
408 | },
409 | "metadata": {
410 | "tags": []
411 | }
412 | }
413 | ]
414 | },
415 | {
416 | "metadata": {
417 | "id": "ATtx6VedmeUY",
418 | "colab_type": "code",
419 | "outputId": "72aa76c9-3f60-4307-cc85-8e1ac55cbedb",
420 | "colab": {
421 | "base_uri": "https://localhost:8080/",
422 | "height": 428
423 | }
424 | },
425 | "cell_type": "code",
426 | "source": [
427 | "#=====================================================#\n",
428 | "# Decision regions\n",
429 | "#=====================================================#\n",
430 | "import matplotlib.cm as cm\n",
431 | "fig=plt.figure(figsize=(7, 7))\n",
432 | "plt.xlim(-max_axis, max_axis)\n",
433 | "plt.ylim(-max_axis, max_axis)\n",
434 | "z = np.argmax(decision_regions, axis=1).reshape(1000, 1000)\n",
435 | "plt.pcolormesh(xx, yy, z)\n",
436 | "cmap = cm.rainbow(np.linspace(0.0, 1.0, M))\n",
437 | "\n",
438 | "for k in range(minibatch_size):\n",
439 | " index = k % M\n",
440 | " plt.scatter(receive_x[k], receive_y[k], c=cmap[index], marker='.',s=50)\n",
441 | "\n",
442 | "plt.show()"
443 | ],
444 | "execution_count": 8,
445 | "outputs": [
446 | {
447 | "output_type": "display_data",
448 | "data": {
449 | "image/png": "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\neXkoLCzU5foSKblel8uF4uJiAMD69etx2WWX6fbvhJLrjZo3bx7uvPNOLFq0SJdrzeZ6H3nkESxc\nuFDVa8lT9dN0tG7dugF7Yol7S0KGsZbR51esWIH6+nqUlZWpe5Eial4vAFRVVeHVV1/FO++8g3vu\nuQfPP/+8ehcL9a8XAF5++WXs3bsXzz77rDoXmUCLazaKkusw8trN8nuTSs71/ulPf8L69etV/29M\nDjnXu3r1auzbtw933XUXNm7cCIfDoeGVJSflev/whz9gwoQJGDFihKrf27KhVl9fj/r6+rivLVy4\nED6fD2PHjkUgEIAgCHC73bHnvV4v/H5/7HFLSwsmTJiA1157DeFwGC+//DIOHz6MDz/8EE8++STO\nP/98U17vjh07MGbMGJSXl2PatGm4++67VbtOLa4XiATOli1b8PTTTyM/P1/169XimvWU7DqqqqqS\nPnfixAl4vV7k5+enfI8Zr9dISq/33XffxbPPPov//M//1G0pWun17tmzB4MHD0Z1dTVqamoQCoXQ\n2tqKwYMHm/J6t27diubmZmzduhXHjx+H2+3GsGHDMHXq1KyuxVbLj3V1ddi0aRMAoLGxEVOmTIl7\n/qKLLsJHH32E9vZ2dHV1YdeuXZg8eTJWr16NtWvXYu3atZg+fToWL16saqCpfb2bN2/Ga6+9BgD4\n9NNPUV1drfm1ZnO9zc3NWL16NZ566qnYMqRelF6z3urq6vDWW28BAPbu3Quv14vS0lIAwPDhw9HZ\n2YkjR44gGAyisbERdXV1ad9jxus1kpLr7ejowKOPPorf/e53qKioMP317ty5M1ZN+v1+dHd3xy0J\nmu16n3jiCbz66qtYu3Yt6uvrcdttt2UdaIDNbj0TCoVw33334eDBg3C73Xj44YdRXV2NFStWoLa2\nFhMnTsSmTZuwcuVKOBwONDQ04Oqrr477jIULF+Kaa64Z8Iefma63tbUVCxcuRFdXF/r7+3Hvvffq\nUl0ovd7HH38cb7zxBs4666zYZ61cuTKuYjLbNW/duhUrV67EF198gcrKSlRVVWm+/LR06VLs3LkT\nDocDixcvxscffwyPx4OZM2figw8+wNKlSwEAs2bNws0335z0PWPHjtX0GrO53j179uCRRx7Bl19+\niby8PAwdOhTLli3TLTDkXu+aNWuwbNkyjBw5MvYZjzzySNy/x2a63t7eXtx77704duwYent78fOf\n/xxXXHGFLteq5HrFli1bhrPPPhvXXntt1tdhq1AjIqLcZqvlRyIiym0MNSIisg2GGhER2QZDjYiI\nbIOhRkREtsFQIyIi22CoERGRbfw/pFC/qOneuhQAAAAASUVORK5CYII=\n",
450 | "text/plain": [
451 | ""
452 | ]
453 | },
454 | "metadata": {
455 | "tags": []
456 | }
457 | }
458 | ]
459 | }
460 | ]
461 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Henk Wymeersch
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Auto-encoder for a memoryless fiber-optical channel
2 |
3 | This script uses an auto-encoder (AE) for end-to-end learning of a non-linear memoryless fiber channel. The determines a good constellation and a good receiver. The achievable information rate is also computed.
4 |
5 | This code was is based on the paper
6 |
7 | Shen Li, Christian Häger, Nil Garcia, and Henk Wymeersch, "Achievable Information Rates for Nonlinear Fiber Communication via End-to-end Autoencoder Learning," in *Proc. European Conference on Optical Communication* (2018) [arXiv:1804.07675](https://arxiv.org/pdf/1804.07675.pdf).
8 |
--------------------------------------------------------------------------------