2016-11-25

In a previous article I explained the way I see neural networks and gave some basic examples. Personally I believe in ‘simple examples’ as a way to comprehend crucial principles and this article continues in this fashion. By looking at a single cell the activation functions are highlighted and it’s shown that picking the most appropriate one can be done using grid-search. Along the way you can see that simple feedforward networks are a way to dissipate noise and that neural networks are really just functions.

Like the previous article, the examples are on top of the Keras framework but you can recreate all of this in TensorFlow, Caffe or any other neural framework.

Feedforward networks are fairly easy but can nevertheless produce great results. One would sometimes forget, considering what the internet is buzzing about, that not everything needs to be casted in convolutional and/or recurrent topologies.

None of the examples require GPU or datacenters, the synthetic or artificial data is designed to highlight a particular aspect and not a real-world case.

This article is also available as a Jupyter notebook on Gist.

Counting from 0 to 9

Let’s start with learning a network to count from 0 to 9. The code predicts the next number for a given sequence of the previous numbers. The number 9 is followed by 0 in cycles.

Note that the data is partitioned in buckets so the to-be-predicted number is not based on a single digit but on a bucket of digits. When data has some time-like ordering one typically uses networks with memories aka recurrence but this bucket approach works just as well in simple situations (i.e. no variations and few features). You should try to make the same prediction network with only a single number. The bucket approach is useful as a preparation for recurrent networks where one typically has this step-backward situation.

Bit shift operator

Like the counting example we take some binary buckets and shift the 1-bits to the right.

The output is not precise but you can truncate it and plot it to see it more clearly.

Using the score you can see that all solutions give accuracy 100% but the loss differs:

single: 20.62%

one extra: 4.05%

two extra: 5.82%

one (20): 0.24%

two (20): 0.00%

So, you don’t need to increase complexity in order to achieve accuracy but the signal will be more sharp if you do.

The truncation to integers can also be achieved by means of custom layers. Below you can find the Round layer which does precisely this.

Neurons as functions

A single neuron, node or cell is just a function and if you play a bit with the API you can also visualize the various activation functions.

Let’s explicitly assign weights to a single cell thus preventing this to affect the output:

Note that if no activation is specified it will default to linear and that compiling a network will typically assign random weights to the nodes. Details of how the activations are effectively implemeted (really straightforward) can be found here but you can also easily plot the activation functions by using the single cell as a functions:

If you want a custom activation function you can simply plug in your own function instead of a name (string). Whether something like the sine below makes sense is of course another matter, but you can indeed use anything you like:

Note that activation can be added separately to the model like so

Finally, there are also advanced activation functions in Keras which are there for specific tasks. Though you can use them like any other activation function, they work well for image-oriented learning. For instance, the parametric rectified linear unit or PReLu function was invented to surpass human-level performance on ImageNet classification.

Picking the most appropriate activation functions

The activation functions seem to be only slightly different but they actually do make a big difference. In the example below we have some artificial data consisting of a line with a bump in the middle together with some noise and try to make the neural network learn the shape of the curve. You can see from the plot below that relu does a much lesser job than the hyperbolic tangent activation.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXMAAAEACAYAAABBDJb9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz%20AAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xd8zdcbwPHPkYXYo9SmVu1N+anYNWrVqllqVlGjqFLR%20FlVtUbVX7a1G1Saqduy9R2yCCCLz/P74RuxI3Jv7vffmeb9eXned77lPInly7plKa40QQgjHlsDs%20AIQQQlhOkrkQQjgBSeZCCOEEJJkLIYQTkGQuhBBOQJK5EEI4Aaskc6VUD6XUEaXUIaXUHKWUuzXq%20FUIIETMWJ3OlVAagK1BMa10IcAWaWlqvEEKImHO1Uj0ugKdSKgJIDFy1Ur1CCCFiwOKWudb6KvAr%20cAm4AtzTWm+wtF4hhBAxZ41ulhRAXSArkAFIopRqZmm9QgghYs4a3SxVgHNa6zsASqmlQFlg7rOF%20lFKyCYwQQrwFrbV6UxlrzGa5BJRRSiVUSimgMnD8NQHZ/b9BgwaZHoPEKTFKnBLnk38xZY0+893A%20YmA/cBBQwCRL6xVCCBFzVpnNorUeDAy2Rl1CCCFiT1aAvsDLy8vsEGJE4rQeR4gRJE5rc5Q4Y0rF%20pk/GojdSStvqvYQQwlkopdA2GgAVQghhMknmQgjhBCSZCyGEE5BkLoQQTkCSuRBCOAFJ5kIIYaGf%20foJ168yNQZK5EEK8pZQp4epV+OYbzZ/V53J6733TYrHWfuZCCBHv3LsHJTJeZSUdyMhlbh4rQ67i%20yUyJRVrmQggRC1rDqlUwdYqmJTM5QBHupUtOkuEPKFPDvJa5rAAVQog3ePgQPD0hKAi6dIHV068x%20kY7kcjnN9U/TkanoFf488jtDptWw+nvLClAhhLCSJEngt98gcWJNyPTZHKAIyfLeJ+3om6y/X40C%20fY/w41TrJ/LYkD5zIYSIgZ97XWcZHSmY8DAhnd3xj0hNsUH7SZc9CyFhoN7Ydo5bksyFEOI18uSB%20tGk0nzKP0ao7N4q/g2oSQcfZE1l9sCapUxtTEvv0MTtS6WYRQogo7u5w+rRxXym4d+oGvbbX5xfP%203rj2DWXle3XI/+0xGn9VE4DFi43piZMnmxh0JGmZCyFEpNBQyJ0bfvxB05T5jEnQleByHpwvn42O%20Mydx9HIB+vWD+vWhYEEoVszsiJ+S2SxCCAE8eABJk0JabjI5QXvKJd1Ggo7h9Nk9gmlb2qK10ZFh%206zQW09ks0jIXQgigUSNoxEImunYkgVcEK7J+TM/xIxk3NS2dRsCZM3DypNlRvp5VWuZKqeTAFKAA%20EAG01VrveqGMtMyFEKbSGi5cgOzZnz63bx9UL36Lqa6fUyGpDwGtktN6/Ux8jlWMusZMtp5nPhr4%20R2v9PlAYOG6leoUQwmpWr4YcOeD6dWOA8/hxGFZ8IafdclG54kYmVe5AnnGn8DlWkTFj4Px5syOO%20OYu7WZRSyYDyWuvPALTWYYB5a1qFEOI1AgKM23ffhTTcIqBqG6an8uFq43f5dM189l0oTv/+ULIk%201KtnbqyxZXE3i1KqMDAJOIbRKvcFumutg14oJ90sQghTRETAli1QqZLx+BMWMdW9HW4VQvjJvR/D%201vTnzxluDBgAJ06Ah4e58T7Llt0srkAxYKzWuhjwCOhnhXqFEMIqxo83EnlqbvN3wlrMTN2Kiy2y%20UuzIfn5YNYiwcDfKlTO6VewpkceGNWazXAb8tNa+kY8XA31fVdDb2zvqvpeXF15eXlZ4eyGEeL2w%20MPjyS/gkwSKmuX2O6/9C+TZiCKOnfxU13XDtWsia1eRAI/n4+ODj4xPr66w1m2UL0F5rfUopNQhI%20rLXu+0IZ6WYRQtjU5s3QsJI/sz1bUDHhJvZXL0rTdQtIkSErWsOhQ2ZH+Ga2nmfeDZijlHIDzgFt%20rFSvEELE2vXr8M03EDhzMRcStiFB6XC6BI1l2tzPKVpU4esLCZxsMxNZASqEcCpKQUruMNuzBZUT%20bmRX5VI0XruIGwHpOX0acuY0O8LYkRWgQoh4Z98+qJdgKTPcP8O1VBidHo3nz4VtAEV4uPO1xp/l%20xF+aECI+OHMmsjWu7nLlw9rMT/Eph+sWIOf+M/y5qy2gmDnTuRM5SDIXQjgwpeDAAaiTYBkXEmal%20cslNdMnzB/9bsI2PG2cAjNdbtjQ5UBuQZC6EcChKwfDhxm1y7uHWui4LkzfheN33yXXwNFN3tAcU%20nToZ5QsXNjVcm5E+cyGE3Vu1CrZtg7x5jcf9+kFttZJZHi3wKBnCV+EjmbCgM2CME1arZiTxVavM%20i9nWZDaLEMLueXkZy/HBaI1PS9yGWu7/cOijQjRYt5TLdzLTvj1MmQKPHxsnBjmLmM5mkWQuhLB7%20OXPC2bNQU61ijkdzPEoF87X+mbFbv+RJa/zKFciQwdw444Ktt8AVQgiriYiA4GAIDIT06eHW2QAW%20JW7IkuQNOFs/B3mPnaBKz67MmaPQGvbscc5EHhvSMhdC2J1vv4WhQ4371VnNvITNSFjyMf0SDOP3%20Ld0BZfqhEbYii4aEEA5n1y5wdTWOZ0vKfSYnak9d9+WcqJWH+uuXceFWdvbtg/feMztS+yMtcyGE%203VCR7c9qrGFewmYkLvGIAW4/8JtPL7ROQLVqxg6H8Ym0zIUQdu/AAXBzg3z5jBWaSQhkUqL21Hdf%20xulauai3YRnnbhrN8IkToUMHkwO2Y5LMhRCmKVoUkiSBCROgMutZkLApnsUeMsjDmxHz+qB1AmrW%20hAoVJJG/iSRzIYTNKQUZM0Y+eBCIbteZv5Mt5vzH2am7cTmnr+cmUyZYuBA++MDUUB2GJHMhhE09%20OUTnyhWoyEYWJmyCZ7EHDE36DUPmDiBCuwDg52dejI5IkrkQIs6Fhhp943fvQsWK4MkD/vDoQhP3%20hVyul4kKm7Zw7Er+qPJXr5oYrIOSRUNCiDjl728sr69dG1Klggps5pxHDpoUXcBv5XuQb+4x3NLk%20JywMjhyBsmXh3XfNjtrxyNREIUScOXMGcuUy7ifmIb+7d6OZ+1yuf5KOBj5/ceBiUTp1giJFoGNH%20c2O1V7I3ixDCNCEhEB5uLMW/fx/K8y8LPRqRvMh9xqb/gv5/DyM03J1HjyBRIrOjtW8235tFKZVA%20KbVPKbXCWnUKIRzH1q3GLJVRoyBHDkicGMLuP2SCWwfWeFYn5FN3Prz1L18v/5Wu3d3RWhK5NVlz%20ALQ7cAxIZsU6hRAOYsEC47ZHD+P2f2xloUdjkhcKYGrmz/l6zi8EhyYEoEQJk4J0YlbpZlFKZQKm%20A0OAnlrrOq8oI90sQjihU6cgWbKng5aJeMQvrr34zGMG9xqnoN3hhaz2/V9U+aAg8PB4unRfRM/W%20y/lHAl8Dya1UnxDCQeTJ8/R+WbaxwL0xqQrdZU6OZtzKNpoJ3p7kzg3Jk8PNm5AwoXmxOjOLk7lS%20qhZwQ2t9QCnlxZOd4l/B29s76r6XlxdeXl6Wvr0QwkQDBhi3CQniZ9c+tHWfxoOmntTauQqfhRWj%20tql9/Bh++ME4YEJEz8fHB58nK6tiweJuFqXUUKAFEAYkApICS7XWrV4oJ90sQjiJmTON039q14a8%20d7ezwL0JKfPfYUm+T/hyyVgePE7KvXtGa1xYxpSpiUqpCkAv6TMXwrkpZbTGh7l8Q3v3yQQ1S0SL%20PbNZe+gjxo+Htm2d6xxOM8kWuEIIq7t921iSX5qdLHBrQqr8d1hZqDad5k0k4FEKvvwSOnUyO8r4%20yarL+bXWW17VKhdCOL5atSBT2sesyNuLDQmrkLTVfZonmMOnMxcw5OcUAHz5pclBxmOyAlQIEa2u%20XY3bXX/sZoFbE1K/78/GkpVov2AK/g/SAMYBzAEBkCKFiYE6KVnOL4Sw2KlTUCjPY35QA+nsMZ6w%20Zq60PzKZxHkb0b69kbyzZDHmmYu4IX3mQohYCw8HrY3tagFKsIejbk1Jnec2W8p+SNv50/nPNx3Z%20sj0tI+yDbIErhADg3DlwdTW2qXUnmGGqL5s8KpKm5S2+TPYHtSetYubCdOTKJYncHknLXAgBPJ2F%20kjvQl3mun5Im9y12eZWm9byZXL2bkWLFoHp1c2MUryctcxFnPv4YBg82OwrxJufPG/PGt6wPZgj9%208XH3Il3L63yddgRVx22gzRfGYZ05c5ocqIiWDICKOBERAS4ukDUr/PorVK5sDJZ98IGxVaqrfCa0%20C0OHwrffQlH2Md+1CWlz3uJA5SK0nj8TP/8sPH5sbIoVEGDcyr4qtiezWYRp9u2D4sVf//q1a8ah%20BcL2IiJg+nTYtAnmzAF3FcJ3fM9X7qOIaKboef43pm5pR/78il69oE0bsyMWMptFmGbKlOhf37cP%20ata0TSzieQMGwLBhkQ8O7OewW1PS5bjBniololrjAQEy1dARSctcWN2TfapTJ7lNl2pjqVn4H1In%208efszfeYva0Fc7c1o1t3FxYvBj8/c2ONT+7fNza+ciOEgfxAD/eRz7XGQSG/ovZHulmEzXXrBpMm%20QXAw1Cyyimkd2rJ8b11mb2vB9XvpKZj5MD1qjMTVJYxGoxdx+U5mQkOl/9wW1q0zZqIU4iAL3JqQ%20Pvt1DlQpTKsFs/DzzxJVTn5F7Y/NzwAVYvp0I5E3LzebKe3aUX/kX2RqMIkjNz4kX+ncLN3zCRPP%20bWWZbz22fleeLGkucveu2VE7r86djT+UoaFQq3oo3moQ29zLkeHTK/R+dwQVx/ng55+FQ4fg0SPY%20vt3siIUlpGUurEYpqPC+Dwu6NqH/Rh+69H+fYsWM19avhxUrYMwYGDECLm8cTecq4yn13W6u3UqG%20p6e5sTuTPXugZMmn3V0FOcR8t6ZkzHaF/VWL0GrBLJq0yULmzJA/vzHTSNgv6WYRNuXrCzUr3+Tg%200MK0GD+bjUdenyECA40BtomfdyB54gC+WzufkyflQEhLaQ0bN0LVqsZjV0Lpr4bytdsIIpooel4y%20+saHD1f06WNurCLmJJkLmwkKgsSJYWG3Rpy7mYMraYfz++/RX6MUeLg9Zu+PxfFe4s2iXY1sE6wT%208/U1WuQABTjMfLcmZMp2hQNVC9NywWz8/LOQLh1cvGjMGReOQfrMhc1cuwY1Cv9DocyHOJ908BsT%20+RPBoQnpMHUSo1p+xUHfgLgNMh5o2BBcCGOA+oGd7mXI0sSP3hlH4DVuS9Qg5+XLksidlcwjEBY7%20fy6c4Z/25et5I1ixN2ZLBC9ehEyZwMWlHKsP1uDu9h/JO32EJJq3kCgR+PiA58WjHHBrQuasfvhW%20Kx7VGtfaGLN45x2ZOeTMpGUuLHLwIMz+YSb3HqbAPfvHMb4uSxZIkMDo4/1u8fe0rTCN9zJc5tGj%20OAzWiRw/Djt2QP36EPo4jBUfDGG3eymyNr5I70zPt8bB6EcvXNjEgEWck7/TwiLNm4Wz7PMhtJk0%20nY4DYj+I+f77cO1eBiZvbs939b8nJGQSiRPHQaBO5Pp1yJfPuP8+x9jv1oSsWS6yt1oxWiycg59/%20Fh4+NMpcvGhurMJ2LG6ZK6UyKaU2KaWOKqUOK6W6WSMw4RhyJ17OrcC0/HfyfxQtGvvrtYY03OLA%20siJ8UnIJg3pL9olOcLCxeZkLYfRTw9jjXpJsjS7QK/MvfDznX3oNNFrjiRMbG5z99pvJAQubsXg2%20i1IqPZBea31AKZUE2AvU1VqfeKGczGZxMuHhsPOHcoxc3YPFuxq+XR1BIfjlqcK7fruYVaslD1N5%200n3maCtH6vi0NrqlAPJynAVuTciW+QIHqhWmxSKjNd6gASxZYm6cwvpsNptFa31da30g8v4D4DiQ%200dJ6hf1bMmk376a4hmee+m9dh0vP7mQrkoLv+J4M667S8n+z2LTa34pROofQUEhAOH3UT/i6lyB7%20w3OMKf8LFSb8i59/FrJmhYoVzY5SmMmqfeZKqWxAEWCXNesV9une3ilMvtWeNj1c3q6CCRNgyxbY%20uZN6e93JUGkc21aW42LGP6hUY5B1g3Uwd+8ax7fduQP//Qdf1znBfo/GZM94nt2VS9JqySwOncnM%20hI3GdMMLF8yOWJjNask8sotlMdA9soX+Em9v76j7Xl5eeHl5WevthY3duPKQRqUXkb/PUZp+/xYV%20/PsvfPcdbNsGyZLxQUVY3uAHMq8cSalRuyC8L7jEz5MQgoKMRA6QJlU4vROMYJ/H94TXc6HL5T+Y%20NbkVoEiWTHaddEY+Pj74+PjE+jqrrABVSrkCfwOrtdav7PCUPnPn0vrDGTQqvYiPf/mbgwehUKFY%20XHzxIpQpAzNmQLVqUU+vWRVO+trFiainSNm1B9krtbJ+4HZuwwaoXdsY6MzFKRYnbMh7Gc6wtUJ5%20Pls6gxsB6fH0hAevbC4JZ2TrFaDTgGOvS+TC+bStMI2pPp/TpQsULBiLCx8+hHr14Ouvn0vkAB/V%20cqEPP/PO6lv4/zs6Xu3HWrgwjB9vHNoRGhzO1y7DOeBRhKwfX6BN6unUmL6GGwHG8Uz375scrLBL%201pjNUg74FzgM6Mh//bXWa14oJy1zJ/H4jh8PFxXh3S7XCAlzj/mFWkPTpsZ68hkznm7r94wVKyBx%203SoU/uQgCYasJHWeMlaM3D496R8HyMlpliZqQM53z7C2TDXarZhK4VJpqFgRPv8cpk0zzuwU8Yds%20tCXizOIfR3H/0iGajpoWuwU+Q4fCsmXGoGeiRK8tVlTtZ4tHBQLGf0TmNgstD9iOHTwIRYqAIoI+%20bj8zKMFggmt70OrsDFYeqAvEqw8o4hVkoy0RJx4/hgxhC1m0u1HsEvnKlTB2LPz1V7SJHCCiUFFW%20h9UgzdIVhNy/blnAdujuXSNBd+hgJPL3OMNBz8J4Z/ZmZZ2Pybb6AisP1GXCBDh82OxohcPQWtvk%20n/FWwtFN+PWSvj0hlXZzCY75RUePap02rdY7dsSo+MqVWmflvA7y8NAbB/R+y0jtF2idJ4/WinDd%20x22YDvLw0LfrpdRV86/RRprX+sEDs6MU9iIyd74xx0rLXMRKisDFLN9bl3MXYthXfvcu1K0Lw4cb%20M1hioHZtuEg25rs3ofTmcdy/F2JBxPYp5OQ5DiUpxPeZB7GwRiOaBVzi84HVAWNqopy8JGJLkrmI%20lYwRS1i0uxGZMsWgcFiYMeBZqxa0aROr9zl3DnoGjsRtXyibBo4mMPDt4jXb4sXQv//T5fjtP4+g%20r8dPHEuYj3cq3qC62xryD5jF2k1JaNwY/P0hYfycXi8sJAOgIsauXbxLkg1ZSNv5Fo9DYpBxeveG%20AwdgzZpYb6T9JPlNy/gZ9ZItJ9XxO8RgDMiuPHgAlSoZZ3K+8w543jzLymR1yJX6NDPztaTb+jEE%20hSSWAU4RLRkAFVa36I+NbD1ZngWLYpDIZ80yBjsXLHirExGezFrscmUsSa4/oEOmibGuw2xJkxqL%20fxQRtHv4I8cT5SPV//ypoHxov2oqoRGJcXMzO0rhLCSZixjZvx8S31vD2kPVqVXrDYX37IGePWH5%20ckid+q3f8/RpCMKT+ZmaMiRsAAH37L8Jq7Xxd+zJMvvAQ2c5njIv3u8MZnzZTmRde4md58pSvjxs%202gQhzjccIEwiyVzEyF9/aaoXWsvaQ9Wjb2hfuwYNGsDkyVCggEXvmTOncdvl1B+kcL1HyMxJFtVn%20CzduQKtWkDVLBIOTD+Rk4ry4FwulcNABemwcTWi4O3//bWxNU7682dEKZyLJXMSI68PjhEe4cPJa%20ntcXCg42Enn79saSfSsJDE7O8tx1cRnwDbeuhlqtXmtZsgT69IE0aeDddyGnyynOpM3JNyl/Ykih%20/qysc5ZDfvlJnNjYweCNn2yEeAsyACpiZL73bwT4naRox4mUKvWKAlob683v34eFC5+epGChJ33n%202dKe52SaPMz2GEZr315ERGA3/c0FC8KRIwCa4e/0oefDkZwsmocaR/7B715WTpyAPHmMWZoeHsix%20eCJWZABUWFXKx2vxOVn91YkcYMwY8PWFP/+0WiIHo9emd2+4cCs7a/NVo9Fxb1K4BpIundXe4q1o%20DevWGX9sHj6E9z2OcilDFr5KOJre2X+hwH9H8LuXlYYNjUQOkDKlJHIRd6RlLt7oql8QSde9Q7Ye%20l/G/n/zlAhs3QvPmxnHx2bPHSQxdu8KaRac5nK0Ao/Z+xTdhw02d0rd9O5QrB6AZk+VLOvtPYO/7%20xal5dBX+QWkBY5q9y1ue2yHEE9IyF1YzdegWDlwswg7fVyTyc+eMRD5vXpwlcjAa/tU+ycWqnLXo%20psaQnmtx9l7RCQ6GwYPh7FkonXIH17Omo13EVNq9M4XSvrujEnnz5pLIhW1JMhfRevQIkjxYy9rD%201cmd+4UXAwOhTh0YMMAmB1COHQuq6nCoAD+59XvVDrpxbt8++PH7EBL90pDtoeU4lLgQqa/d5s/z%20xgrXjh1h1CiYPdv2sYn4TbpZRLR27YKk/+aj1fiZ+J4r8fSFiAj45BNjHvnkya/cmzyu/NGwC5+v%20mkaxx/s4GPw+7rHYUv1tffghbN0KDd5bzJ8unxER4ELTkPmsuVuDVKmMfdiNbhchrEu6WYRVNKp1%20ibRJb9GuT7HnX/j+e7h5M7K5bNsmctneQwn9yI3xiTvh4QG7d8ft+7VsCcf332RrhXIsvNGEvx/W%20Js2NW6y5WwOAZMkkkQvzSTIX0apeaC3rj1SlU6dnflSWLjWOvFmyxJhrZ2PFyiRnU5nRlHXfQUWX%20jfz8s3Xrf/TImCqvFLi7hpDzyiAuZ8tE7kOnKRfyH82uzCcM4+PA7NnGBxMhzCbdLCJai79qyIq9%20dZi5NfJw5cOHjd2jVq+GEiWivzguac2u6mXIvN+PjLevcP++ImnS2FXx99/GmG3+/MbjbNngxAlj%20g8f58zUfF13BpDwdSLn8HpNcOtDzwW+E4cakScb5Gi1byilAIu7FtJtFDqcQr9WxQ6i+MymFTpf8%20mvHErVtaZ8+u9ezZ5gYWafM/N3VQDg+96t2PNEToEydidz1o7eGhdUiI1tu26aiDIYpl89VbupTX%209/Mm0WcS5tCF2R/1mvwYC1vDlodTKKU+UkqdUEqdUkr1tUadwnyHfXZx8XZWEiROD6Gh0LgxNGxo%20zLuzA1410lIjYiNVXTYwK01L8uY1ukb27jU2a4yIePV1gYHGlwPGVEN3d6PPu2DmQyztXo/15atS%20dNJ+Rp78ivcfH+cgRaKuvXTJBl+YEG/B4mSulEoA/AFUB/IDnyql8lparzDfR4XWsObgR8Y5lL16%20Gf3jw4aZHdZzEuYtRwOPpTR1nc+czM0Ao/enadOnfdmbNhmrMJ+0rXPl4pkZMJqyubexuGsDNjet%20SK65Z7gyKyMfhv7LxvI/MG6yUXD/fuPazJlt/zUKESMxab5H9w8oA6x+5nE/oO8rysX95xFhNSdO%20aL3r+5LaK98mradM0Tp3bq3v3jU7rJfcvGkcL1o14xodktpVbytbRqdLfu25bpEn/2rXfno

Show more