<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[AI Society - Medium]]></title>
        <description><![CDATA[Artificial Intelligence Hacking Group - Medium]]></description>
        <link>https://medium.com/ai-society?source=rss----bc8767f5d170---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>AI Society - Medium</title>
            <link>https://medium.com/ai-society?source=rss----bc8767f5d170---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 21:01:09 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/ai-society" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[GANs from Scratch 1: A deep introduction. With code in PyTorch and TensorFlow]]></title>
            <link>https://medium.com/ai-society/gans-from-scratch-1-a-deep-introduction-with-code-in-pytorch-and-tensorflow-cb03cdcdba0f?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/cb03cdcdba0f</guid>
            <category><![CDATA[generative-model]]></category>
            <category><![CDATA[pytorch]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[gans-explained]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Diego Gomez Mosquera]]></dc:creator>
            <pubDate>Fri, 02 Feb 2018 15:03:50 GMT</pubDate>
            <atom:updated>2023-03-07T21:27:36.090Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://medium.com/tag/gans-explained">Generative Networks Explained</a></h4><h4>“The coolest idea in deep learning in the last 20 years.” — Yann LeCun on GANs.</h4><ul><li><a href="https://github.com/diegoalejogm/gans">TL;DR #ShowMeTheCode</a></li></ul><p>In this blog post we will explore <strong>Generative Adversarial Networks (GANs)</strong>. If you haven’t heard of them before, this is your opportunity to learn all of what you’ve been missing out until now. If you’re not familiar with GANs, they’ve been hype during the last few years, specially the last semester. Though they’ve existed since 2014, GANs have already become widely known for their application versatility and their outstanding results in generating data.</p><p>They have been used in real-life applications for text/image/video generation, drug discovery and text-to-image synthesis. Just to give you an idea of their potential, here’s a short list of incredible projects created with GANs that you should definitely check out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nKe_kwZoefrELGHh06sbuw.jpeg" /><figcaption>Image-to-Image Translation using GANs. [1]</figcaption></figure><ul><li><a href="https://www.theverge.com/2017/10/30/16569402/ai-generate-fake-faces-celebs-nvidia-gan">AI Generates Fake Celebrity Faces</a> (<a href="http://research.nvidia.com/publication/2017-10_Progressive-Growing-of">Paper</a>)</li><li><a href="https://www.technologyreview.com/s/609469/this-ai-learns-your-fashion-sense-and-invents-your-next-outfit/">AI Learns Fashion Sense</a> (<a href="https://arxiv.org/pdf/1711.02231.pdf">Paper</a>)</li><li><a href="https://junyanz.github.io/CycleGAN/">Image to Image Translation using Cycle-Consistent Adversarial Neural Networks</a></li><li><a href="https://www.technologyreview.com/s/608195/machine-creativity-beats-some-modern-art/">AI Creates Modern Art</a> (<a href="https://arxiv.org/abs/1706.07068">Paper</a>)</li><li><a href="https://motherboard.vice.com/en_us/article/a3dn9j/this-deep-learning-ai-generated-thousands-of-creepy-cat-pictures">This Deep Learning AI Generated Thousands of Creepy Cat Pictures</a></li><li><a href="https://qz.com/817604/mits-nightmare-machine-uses-artificial-intelligence-to-create-horrific-images-of-ghoulish-faces-and-scary-places/">MIT is using AI to create pure horror</a></li><li><a href="https://www.theverge.com/2017/8/24/16195858/amazon-ai-fashion-designer">Amazon’s new algorithm designs clothing by analyzing a bunch of pictures</a></li><li><a href="https://www.inverse.com/article/39018-these-neutral-networks-can-generate-realistic-photos">AI creates Photo-realistic Images</a> (<a href="https://arxiv.org/pdf/1711.11585.pdf">Paper</a>)</li></ul><p>In this blog post we’ll start by describing Generative Algorithms and why GANs are becoming increasingly relevant. An overview and a detailed explanation on how and why GANs work will follow. Finally, we’ll be programming a Vanilla GAN, which is the <a href="https://arxiv.org/abs/1406.2661">first GAN model</a> ever proposed! Feel free to read this blog in the order you prefer.</p><p>For demonstration purposes we’ll be using PyTorch, although a TensorFlow implementation can also be found in my GitHub Repo <a href="github.com/diegoalejogm/gans">github.com/diegoalejogm/gans</a>. You can check out some of the advanced GAN models (e.g. DCGAN) in the same GitHub repository if you’re interested, which by the way will also be explained in the series of posts that I’m starting, so make sure to stay tuned.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*XO7aeFzFj1sxQsSq0y8J6Q.gif" /><figcaption>Output of a GAN through time, learning to Create Hand-written digits. We’ll code this example!</figcaption></figure><h3>1. Introduction</h3><p><a href="https://arxiv.org/abs/1406.2661">Generative Adversarial Networks</a> (or <strong>GANs</strong> for short) are one of the most popular Machine Learning algorithms developed in recent times.</p><p>For those new to the field of <strong>Artificial Intelligence </strong>(AI), we can briefly describe <strong>Machine Learning </strong>(ML)<strong> </strong>as the sub-field of AI that uses data to “teach” a machine/program how to perform a new task. A simple example of this would be using images of a person’s face as input to the algorithm, so that a program learns to recognize that same person in any given picture (it’ll probably need negative samples too). For this purpose, we can describe Machine Learning as applied mathematical optimization, where an algorithm can represent data (e.g. a picture) in a multi-dimensional space (remember the Cartesian Plane? That’s a 2 dimensional field), and then learns to distinguish new multi-dimensional vector samples as belonging to the target distribution or not. For a visual understanding on <strong>how machines learn</strong> I recommend this <a href="https://www.youtube.com/watch?v=R9OHn5ZF4Uo">broad video explanation</a> and this other video on <a href="https://www.youtube.com/watch?v=WSKi8HfcxEk">the rise of machines</a>, which I were very fun to watch. Though this is a very fascinating field to explore and discuss, I’ll leave the in-depth explanation for a later post, <strong>we’re here for GANs!</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Xwzif0xi1oeXk5jBE75-Xg.png" /><figcaption>Google Trend’s Interest over time for term “Generative Adversarial Networks”</figcaption></figure><h3><strong>What’s so magical about GANs?</strong></h3><p>In short, they belong to the set of algorithms named <a href="https://en.wikipedia.org/wiki/Generative_model"><strong>generative models</strong></a>. These algorithms belong to the field of <a href="https://en.wikipedia.org/wiki/Unsupervised_learning"><strong>unsupervised learning</strong></a>, a sub-set of ML which aims to study algorithms that learn the <strong>underlying structure</strong> of the given data, without specifying a target value. Generative models learn the intrinsic distribution function of the input data <strong><em>p(x) </em></strong>(or <strong><em>p(x,y) </em></strong>if there are multiple targets/classes in the dataset), allowing them to generate both synthetic inputs <strong><em>x’</em></strong> and outputs/targets <strong><em>y’</em></strong>, typically given some <a href="https://en.wikipedia.org/wiki/Latent_variable">hidden parameters</a>.</p><p>In contrast, <a href="https://en.wikipedia.org/wiki/Supervised_learning"><strong>supervised learning algorithms</strong></a> learn to map a function <strong><em>y’=f(x)</em></strong>, given labeled data <strong><em>y</em></strong>. An example of this would be <em>classification</em>, where one could use customer purchase data (<strong><em>x</em></strong><em>)</em><strong><em> </em></strong>and the customer respective age (<strong><em>y</em></strong>) to classify new customers. Most of the supervised learning algorithms are inherently <strong>discriminative</strong>, which means they learn how to model the conditional probability distribution function (p.d.f) <strong><em>p(y|x)</em></strong> instead, which is the probability of a target (<em>age=35</em>) given an input (<em>purchase=milk</em>). Despite the fact that one could make predictions with this probability distribution function, one is not allowed to sample new instances (<em>simulate customers with ages</em>) from the input distribution directly. <br><strong><em>Side-note</em></strong><em>: It is possible to use discriminative algorithms which are not probabilistic, they are called discriminative functions.</em></p><p>GANs they have proven to be really succesfull in modeling and generating high dimensional data, which is why they’ve become so popular. Nevertheless they are not the only types of Generative Models, others include Variational Autoencoders (<a href="https://arxiv.org/abs/1312.6114">VAEs</a>) and <a href="https://arxiv.org/abs/1606.05328">pixelCNN</a>/<a href="https://arxiv.org/abs/1601.06759">pixelRNN</a> and <a href="https://arxiv.org/abs/1605.08803">real NVP</a>. Each model has its own tradeoffs.</p><p>Some of the most relevant GAN pros and cons for the are:</p><ul><li>They currently generate the sharpest images</li><li>They are easy to train (since no statistical inference is required), and only back-propogation is needed to obtain gradients</li><li>GANs are difficult to optimize due to unstable training dynamics.</li><li>No statistical inference can be done with them (<a href="https://ishmaelbelghazi.github.io/ALI/">except here</a>):<br>GANs belong to the class of <strong><em>direct implicit</em></strong> density models; they model <strong><em>p(x)</em></strong> without explicitly defining the p.d.f.</li></ul><h3><strong><em>So.. why generative models?</em></strong></h3><p>Generative models are one of the most promising approaches to understand the vast amount of data that surrounds us nowadays. According to <a href="https://blog.openai.com/generative-models/">OpenAI</a>, algorithms which are able to create data might be substantially better at understanding intrinsically the world. The idea that generative models hold a better potential at solving our problems can be illustrated using the quote of one of my favourite physicists.</p><blockquote>“What I cannot create, I do not understand.” — Richard P. Feynman</blockquote><p>(I strongly suggest reading his book <a href="https://www.amazon.com/Surely-Feynman-Adventures-Curious-Character/dp/0393316041">“Surely You’re Joking Mr. Feynman”</a>)</p><p>Generative models can be thought as containing more information than their discriminative counterpart/complement, since they also be used for <em>discriminative tasks</em> such as <em>classification</em> or <em>regression </em>(where the target is a continuous value such as<em> ℝ</em>). One could calculate the conditional p.d.f <strong><em>p(y|x) </em></strong>needed most of the times for such tasks, by using statistical inference on the joint p.d.f. <strong><em>p(x,y) </em></strong>if it is available in the generative model.</p><p>Though generative models work for classification and regression, fully discriminative approaches are usually more successful at discriminative tasks in comparison to generative approaches <a href="http://www.cs.cmu.edu/~aarti/Class/10701/readings/NgJordanNIPS2001.pdf">in some scenarios</a>.</p><h3>Use Cases</h3><p>Among several use cases, generative models may be applied to:</p><ul><li>Generating realistic artwork samples (video/image/audio).</li><li><a href="https://en.wikipedia.org/wiki/Reinforcement_learning">Simulation</a> and planning using time-series data.</li><li>Statistical inference.</li><li>Machine Learning Engineers and Scientists reading this article may have already realized that generative models can also be used to generate inputs which may expand small datasets.</li></ul><p>I also found a very long and interesting curated list of awesome GAN applications <a href="https://github.com/nashory/gans-awesome-applications">here</a>.</p><h3><strong>2. Understanding a GAN: Overview</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5rMmuXmAquGTT-odw-bOpw.jpeg" /><figcaption>Global concept of a GAN</figcaption></figure><p>Generative Adversarial Networks are composed of two models:</p><ul><li>The first model is called a <strong>Generator </strong>and it aims to generate new data similar to the expected one. The Generator could be asimilated to a human art forger, which creates fake works of art.</li><li>The second model is named the <strong>Discriminator</strong>. This model’s goal is to recognize if an input data is ‘<em>real’ — </em>belongs to the original dataset — or if it is ‘<em>fake’</em> — generated by a forger. In this scenario, a Discriminator is analogous to an art expert, which tries to detect artworks as truthful or fraud.</li></ul><p><strong>How do these models interact?</strong><a href="https://arxiv.org/abs/1406.2661"><strong> </strong>Paraphrasing the original paper which proposed this framework</a>, it can be thought of the Generator as having an adversary, the Discriminator. The Generator (forger) needs to learn how to create data in such a way that the Discriminator isn’t able to distinguish it as fake anymore. The competition between these two teams is what improves their knowledge, until the Generator succeeds in creating realistic data.</p><h3>Mathematically Modeling a GAN</h3><p>Though the GANs framework could be applied to any two models that perform the tasks described above, it is easier to understand when using <a href="https://en.wikipedia.org/wiki/Universal_approximation_theorem">universal approximators</a> such as <a href="https://en.wikipedia.org/wiki/Artificial_neural_network">artificial neural networks</a>.</p><p>A neural network <em>G(</em><strong><em>z, θ₁</em></strong><em>)</em> is used to model the Generator mentioned above. It’s role is mapping input noise variables <strong>z</strong> to the desired data space <strong><em>x</em> </strong>(say images). Conversely, a second neural network <em>D(</em><strong><em>x</em></strong><em>, </em><strong><em>θ₂</em></strong><em>)</em> models the discriminator and outputs the<strong> probability that the data came from the real dataset, </strong>in the range (0,1). In both cases, <strong><em>θᵢ</em></strong> represents the weights or parameters that define each neural network.</p><p>As a result, the Discriminator is trained to correctly classify the input data as either real or fake. This means it’s weights are updated as to<strong> maximize</strong> the probability that any real data input <strong><em>x</em></strong><em> </em>is classified as belonging to the real dataset, while <strong>minimizing</strong> the probability that any fake image is classified as belonging to the real dataset. In more technical terms, the loss/error function used <strong>maximizes the function <em>D(x)</em>, and it also minimizes <em>D(G(z))</em></strong><em>.</em></p><p>Furthermore, the Generator is trained to fool the Discriminator by generating data as realistic as possible, which means that <strong>the Generator’s weight’s are optimized to maximize the probability that any fake image is classified as belonging to the real dataset</strong>. Formally this means that the loss/error function used for this network <strong>maximizes <em>D(G(z))</em></strong><em>.</em></p><p>In practice, the logarithm of the probability (e.g. <em>log D(…)</em>) is used in the loss functions instead of the raw probabilies, since using a log loss heavily penalises classifiers that are confident about an incorrect classification.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*9Sflt97Rk7T4jQI4oic3BA.png" /><figcaption>Log Loss Visualization: Low probability values are highly penalized</figcaption></figure><p>After several steps of training, if the Generator and Discriminator have enough capacity (if the networks can approximate the objective functions), they will reach a point at which both cannot improve anymore. At this point, the generator generates realistic synthetic data, and the discriminator is unable to differentiate between the two types of input.</p><p>Since during training both the Discriminator and Generator are trying to optimize opposite loss functions, they can be thought of two agents playing a <a href="https://en.wikipedia.org/wiki/Minimax">minimax game</a> with value function V(G,D). In this minimax game, the generator is trying to maximize it’s probability of having it’s outputs recognized as real, while the discriminator is trying to minimize this same value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ldvqzz6C5n_nByobuB0P5g.png" /><figcaption>Value Function of Minimax Game played by Generator and Discriminator</figcaption></figure><h3>Training a GAN</h3><p>Since both the generator and discriminator are being modeled with neural, networks, agradient-based optimization algorithm can be used to train the GAN. In our coding example we’ll be using stochastic gradient descent, as it has proven to be succesfull in multiple fields.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OZ62_qvC6GAIH7CdajSRqg.png" /><figcaption>Algorithm on how to train a GAN using stochastic gradient descent [2]</figcaption></figure><p>The fundamental steps to train a GAN can be described as following:</p><ol><li>Sample a <strong>noise </strong>set and a<strong> real-data</strong> set, each with size <em>m.</em></li><li>Train the <strong>Discriminator</strong> on this data.</li><li>Sample a different noise <strong>subset </strong>with size <em>m</em>.</li><li>Train the <strong>Generator</strong> on this data.</li><li><strong>Repeat </strong>from<strong> </strong>Step 1.</li></ol><h3>3. Coding a GAN</h3><p>Finally, the moment several of us were waiting for has arrived. 🙌</p><p>We’ll implement a GAN in this tutorial, starting by downloading the required libraries.</p><p>pip install torchvision tensorboardx jupyter matplotlib numpy</p><p>In case you haven’t downloaded PyTorch yet, check out their <a href="http://pytorch.org/#pip-install-pytorch">download helper here</a>. Remember that you can also find a <a href="https://github.com/diegoalejogm/gans/blob/master/1.%20Vanilla%20GAN%20TensorFlow.ipynb">TensorFlow example here.</a></p><p>We’ll proceed by creating a file/notebook and importing the following dependencies.</p><pre>import torch<br>from torch import nn, optim<br>from torch.autograd.variable import Variable<br>from torchvision import transforms, datasets</pre><p>To log our progress, we will import an additional file I’ve created, which will allow us to visualize the training process in console/<a href="http://jupyter.org">Jupyter</a>, and at the same time store it in TensorBoard for those who already know how to use it.</p><pre>from utils import Logger</pre><p>You need to download the file and put it in the same folder where your GAN file will be. It is not necessary that you understand the code in this file, as it is only used for visualization purposes.</p><p>The file can be found in any of the following links:</p><ul><li><a href="https://github.com/diegoalejogm/gans/blob/master/utils.py">GitHub Repo Link</a></li><li><a href="https://raw.githubusercontent.com/diegoalejogm/gans/master/utils.py">GitHub Raw Content Link</a></li></ul><figure><a href="https://raw.githubusercontent.com/diegoalejogm/gans/master/utils.py"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eusN-QAIdGIwQPCiWxKhEA.png" /></a><figcaption>Preview of the file we will use for logging.</figcaption></figure><p><strong>Dataset</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/1*7HmSJOABTcRzWMVOB3fJlA.png" /><figcaption>MNIST Dataset Samples</figcaption></figure><p>The dataset we’ll be using here is LeCunn’s <a href="http://yann.lecun.com/exdb/mnist/">MNIST dataset</a>, consisting of about 60.000 black and white images of handwritten digits, each with size 28x28 pixels². This dataset will be preprocessed according to some <a href="https://github.com/soumith/ganhacks">useful ‘hacks’ proven to be useful for training GANs</a>.</p><p>**Specifically, the input values which range in between [0, 255] will be normalized between -1 and 1. This means the value 0 will be mapped to -1, the value 255 to 1, and similarly all values in between will get a value in the range [-1, 1].</p><pre><strong>def</strong> mnist_data():<br>    compose = transforms.Compose(<br>        [transforms.ToTensor(),<br>         transforms.Normalize((.5, .5, .5), (.5, .5, .5))<br>        ])<br>    out_dir = &#39;./dataset&#39;<br>    return datasets.MNIST(root=out_dir, train=True, transform=compose, download=True)</pre><pre># Load data<br>data = mnist_data()</pre><pre># Create loader with data, so that we can iterate over it<br>data_loader = torch.utils.data.DataLoader(data, batch_size=100, shuffle=True)<br># Num batches<br>num_batches = len(data_loader)</pre><p><strong>Networks</strong></p><p>Next, we’ll define the neural networks, starting with the <strong>Discriminator</strong>. This network will take a <a href="https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.flatten.html">flattened</a> image as its input, and return the probability of it belonging to the real dataset, or the synthetic dataset. The input size for each image will be 28x28=784. Regarding the structure of this network, it will have three hidden layers, each followed by a <a href="http://pytorch.org/docs/master/nn.html#torch.nn.LeakyReLU"><em>Leaky-ReLU</em></a> nonlinearity and a <a href="http://pytorch.org/docs/master/nn.html#torch.nn.Dropout"><em>Dropout</em></a> layer to prevent overfitting. A <a href="https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Sigmoid_function.html"><em>Sigmoid/Logistic</em> <em>function</em></a><em> </em>is applied to the real-valued output to obtain a value in the open-range (0, 1):</p><pre><strong>class</strong> <strong>DiscriminatorNet</strong>(torch.nn.Module):<br>    <em>&quot;&quot;&quot;</em><br><em>    A three hidden-layer discriminative neural network</em><br><em>    &quot;&quot;&quot;</em><br>    <strong>def</strong> __init__(self):<br>        super(DiscriminatorNet, self).__init__()<br>        n_features = 784<br>        n_out = 1<br>        <br>        self.hidden0 = nn.Sequential( <br>            nn.Linear(n_features, 1024),<br>            nn.LeakyReLU(0.2),<br>            nn.Dropout(0.3)<br>        )<br>        self.hidden1 = nn.Sequential(<br>            nn.Linear(1024, 512),<br>            nn.LeakyReLU(0.2),<br>            nn.Dropout(0.3)<br>        )<br>        self.hidden2 = nn.Sequential(<br>            nn.Linear(512, 256),<br>            nn.LeakyReLU(0.2),<br>            nn.Dropout(0.3)<br>        )<br>        self.out = nn.Sequential(<br>            torch.nn.Linear(256, n_out),<br>            torch.nn.Sigmoid()<br>        )<br><br>    <strong>def</strong> forward(self, x):<br>        x = self.hidden0(x)<br>        x = self.hidden1(x)<br>        x = self.hidden2(x)<br>        x = self.out(x)<br>        <strong>return</strong> x</pre><pre>discriminator = DiscriminatorNet()</pre><p>We also need some additional functionality that allows us to convert a flattened image into its 2-dimensional representation, and another one that does the opposite.</p><pre><strong>def</strong> images_to_vectors(images):<br>    <strong>return</strong> images.view(images.size(0), 784)<br><br><strong>def</strong> vectors_to_images(vectors):<br>    <strong>return</strong> vectors.view(vectors.size(0), 1, 28, 28)</pre><p>On the other hand, the <strong>Generative Network</strong> takes a latent variable vector as input, and returns a 784 valued vector, which corresponds to a flattened 28x28 image. Remember that the purpose of this network is to learn how to create <strong>undistinguishable images of hand-written digits</strong>, which is why its output is itself a new image.</p><p>This network will have three hidden layers, each followed by a <a href="http://pytorch.org/docs/master/nn.html#torch.nn.LeakyReLU"><em>Leaky-ReLU</em></a> nonlinearity. The output layer will have a <a href="http://mathworld.wolfram.com/HyperbolicTangent.html">TanH activation function</a>, which maps the resulting values into the (-1, 1) range, which is the same range in which our preprocessed MNIST images is bounded.</p><pre><strong>class</strong> <strong>GeneratorNet</strong>(torch.nn.Module):<br>    <em>&quot;&quot;&quot;</em><br><em>    A three hidden-layer generative neural network</em><br><em>    &quot;&quot;&quot;</em><br>    <strong>def</strong> __init__(self):<br>        super(GeneratorNet, self).__init__()<br>        n_features = 100<br>        n_out = 784<br>        <br>        self.hidden0 = nn.Sequential(<br>            nn.Linear(n_features, 256),<br>            nn.LeakyReLU(0.2)<br>        )<br>        self.hidden1 = nn.Sequential(            <br>            nn.Linear(256, 512),<br>            nn.LeakyReLU(0.2)<br>        )<br>        self.hidden2 = nn.Sequential(<br>            nn.Linear(512, 1024),<br>            nn.LeakyReLU(0.2)<br>        )<br>        <br>        self.out = nn.Sequential(<br>            nn.Linear(1024, n_out),<br>            nn.Tanh()<br>        )<br><br>    <strong>def</strong> forward(self, x):<br>        x = self.hidden0(x)<br>        x = self.hidden1(x)<br>        x = self.hidden2(x)<br>        x = self.out(x)<br>        <strong>return</strong> x</pre><pre>generator = GeneratorNet()</pre><p>We also need some additional functionality that allows us to create the random noise. The random noise will be sampled from a normal distribution with mean 0 and variance 1 as proposed in <a href="https://github.com/soumith/ganhacks">this link</a>.</p><pre><strong>def</strong> noise(size):<br>    &#39;&#39;&#39;<br>    Generates a 1-d vector of gaussian sampled random values<br>    &#39;&#39;&#39;<br>    n = Variable(torch.randn(size, 100))<br>    <strong>return</strong> n</pre><p><strong>Optimization</strong></p><p>Here we’ll use <a href="https://arxiv.org/abs/1412.6980">Adam</a> as the optimization algorithm for both neural networks, with a learning rate of 0.0002. The proposed learning rate was obtained after testing with several values, though it isn’t necessarily the optimal value for this task.</p><pre>d_optimizer = optim.Adam(discriminator.parameters(), lr=0.0002)<br>g_optimizer = optim.Adam(generator.parameters(), lr=0.0002)</pre><p>The <strong>loss function</strong> we’ll be using for this task is named <strong>Binary Cross Entopy Loss (BCE Loss)</strong>, and it will be used for this scenario as it resembles the log-loss for both the Generator and Discriminator defined earlier in the post (see <em>Modeling Mathematically a GAN</em>). Specifically we’ll be taking the average of the loss calculated for each minibatch.</p><pre>loss = nn.BCELoss()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IcuF1_TXjngF2VHQjdwzjg.png" /><figcaption>Binary Cross Entropy Log. Mean is calculated by computing sum(L) / N.</figcaption></figure><p>In this formula the values <em>y </em>are named targets, <em>v </em>are the inputs, and <em>w </em>are the weights. Since we don’t need the weight at all, it’ll be set to <em>wᵢ=1</em> for all <em>i</em>.</p><p><strong>Discriminator Loss:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vh9PN7ktJMs7FH71yAnKKg.png" /><figcaption>Discriminator’s Loss.</figcaption></figure><p>If we replace <em>vᵢ = D(xᵢ) and yᵢ=1 ∀ i (for all i) </em>in the BCE-Loss definition, we obtain the loss related to the real-images. Conversely if we set <em>vᵢ = D(G(zᵢ)) and yᵢ=0 ∀ i, </em>we obtain the loss related to the fake-images. In the mathematical model of a GAN I described earlier, the gradient of this had to be ascended, but <strong>PyTorch</strong> and most other Machine Learning frameworks usually minimize functions instead. Since maximizing a function is equivalent to minimizing it’s negative, and the BCE-Loss term has a minus sign, we don’t need to worry about the sign.</p><p>Additionally, we can observe that the real-images targets are always ones, while the fake-images targets are zero, so it would be helpful to define the following functions:</p><pre><strong>def</strong> ones_target(size):<br>    <em>&#39;&#39;&#39;</em><br><em>    Tensor containing ones, with shape = size</em><br><em>    &#39;&#39;&#39;</em><br>    data = Variable(torch.ones(size, 1))<br>    <strong>return</strong> data<br><br><strong>def</strong> zeros_target(size):<br>    <em>&#39;&#39;&#39;</em><br><em>    Tensor containing zeros, with shape = size</em><br><em>    &#39;&#39;&#39;</em><br>    data = Variable(torch.zeros(size, 1))<br>    <strong>return</strong> data</pre><p>By summing up these two discriminator losses we obtain the total mini-batch loss for the Discriminator. In practice, we will calculate the gradients separately, and then update them together.</p><pre><strong>def</strong> train_discriminator(optimizer, real_data, fake_data):<br>    N = real_data.size(0)<br>    <em># Reset gradients</em><br>    optimizer.zero_grad()<br>    <br><strong>    <em># 1.1 Train on Real Data</em><br></strong>    prediction_real = discriminator(real_data)<br>    <em># Calculate error and backpropagate</em><br>    error_real = loss(prediction_real, ones_target(N) )<br>    error_real.backward()<br><br><strong>    <em># 1.2 Train on Fake Data</em></strong><br>    prediction_fake = discriminator(fake_data)<br>    <em># Calculate error and backpropagate</em><br>    error_fake = loss(prediction_fake, zeros_target(N))<br>    error_fake.backward()<br>    <br><strong>    <em># 1.3 Update weights with gradients</em><br></strong>    optimizer.step()<br>    <br>    <em># Return error and predictions for real and fake inputs</em><br>    <strong>return</strong> error_real + error_fake, prediction_real, prediction_fake</pre><p><strong>Generator Loss:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*77HB-XBWpCc-ZIGbyaOisA.png" /><figcaption>Generator’s Loss</figcaption></figure><p>Rather than minimizing <em>log(1- D(G(z))), </em>training the Generator to maximize <strong><em>log D(G(z))</em></strong><em> </em><strong>will</strong> <strong>provide much stronger gradients early in training</strong>. Both losses may be swapped interchangeably since they result in the same dynamics for the Generator and Discriminator.</p><p>Maximizing <em>log D(G(z)) </em>is equivalent to minimizing it’s negative and since the BCE-Loss definition has a minus sign, we don’t need to take care of the sign. Similarly to the Discriminator, if we set <em>vᵢ = D(G(zᵢ)) and yᵢ=1 ∀ i, </em>we obtain the desired loss to be minimized.</p><pre><strong>def</strong> train_generator(optimizer, fake_data):<br>    N = fake_data.size(0)</pre><pre><strong>    <em># Reset gradients</em><br></strong>    optimizer.zero_grad()</pre><pre><strong>    <em># Sample noise and generate fake data</em><br></strong>    prediction = discriminator(fake_data)</pre><pre><strong>    <em># Calculate error and backpropagate</em><br></strong>    error = loss(prediction, ones_target(N))<br>    error.backward()</pre><pre><strong>    <em># Update weights with gradients</em><br></strong>    optimizer.step()</pre><pre>    <em># Return error</em><br>    <strong>return</strong> error</pre><p><strong>Testing</strong></p><p>Last thing before we run our algorithm, we want to visualize how the training process develops while our GAN learns. To do so, we will create a static batch of noise, every few steps we will visualize the batch of images the generator outputs when using this noise as input.</p><pre>num_test_samples = 16<br>test_noise = noise(num_test_samples)</pre><p><strong>Training</strong></p><p>Now that we’ve defined the dataset, networks, optimization and learning algorithms we can train our GAN. This part is really simple, since the only thing we’ve got to do is to code in python the pseudocode shown earlier on traning a GAN (see <a href="#Training a GAN"><em>Training a GAN</em></a>).</p><p>We’ll be using all the pieces we’ve coded already, plus the logging file I asked you to download earlier for this procedure:</p><pre># Create logger instance<br>logger = Logger(model_name=&#39;VGAN&#39;, data_name=&#39;MNIST&#39;)</pre><pre># Total number of epochs to train<br>num_epochs = 200</pre><pre><strong>for</strong> epoch <strong>in</strong> range(num_epochs):<br>    <strong>for</strong> n_batch, (real_batch,_) <strong>in</strong> enumerate(data_loader):<br>        N = real_batch.size(0)</pre><pre><strong>        <em># 1. Train Discriminator</em><br></strong>        real_data = Variable(images_to_vectors(real_batch))</pre><pre>        <em># Generate fake data and detach <br>        # (so gradients are not calculated for generator)<br></em>        fake_data = generator(noise(N)).detach()</pre><pre>        <em># Train D</em><br>        d_error, d_pred_real, d_pred_fake = \<br>              train_discriminator(d_optimizer, real_data, fake_data)<br><br><strong>        <em># 2. Train Generator</em></strong></pre><pre>        <em># Generate fake data</em><br>        fake_data = generator(noise(N))</pre><pre>        <em># Train G</em><br>        g_error = train_generator(g_optimizer, fake_data)</pre><pre>        <strong># Log batch error</strong><br>        logger.log(d_error, g_error, epoch, n_batch, num_batches)</pre><pre><strong><em>        # Display Progress every few batches</em></strong><br>        <strong>if</strong> (n_batch) % 100 == 0: <br>            test_images = vectors_to_images(generator(test_noise))<br>            test_images = test_images.data</pre><pre>            logger.log_images(<br>                test_images, num_test_samples, <br>                epoch, n_batch, num_batches<br>            );<br>            # Display status Logs<br>            logger.display_status(<br>                epoch, num_epochs, n_batch, num_batches,<br>                d_error, g_error, d_pred_real, d_pred_fake<br>            )</pre><p><strong>And that’s it, we’ve made it! 🎊</strong></p><h3>Results</h3><p>In the beginning the images generated are pure noise:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vdSdhjsKBp3sKTmuEw60og.png" /></figure><p>But then they improve,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6xo1lGYdPj5Rd2UHN1tFHA.png" /></figure><p>Until you get pretty good syntethic images,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9SgC7rruLilakoZVOFlIHg.png" /></figure><p>It is also possible to visualize the learning process. As you can see in the next figures, the discriminator error is very high in the beginning, as it doesn’t know how to classify correctly images as being either real or fake. As the discriminator becomes better and its error decreases to about .5 at step 5k, the generator error increases, proving that the discriminator outperforms the generator and it can correctly classify the fake samples. As time passes and training continues, the generator error lowers, implying that the images it generates are better and better. While the generator improves, the discriminator’s error increases, because the synthetic images are becoming more realistic each time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*30XhKJBFsnqAAhsWNsNDJQ.png" /><figcaption>Generator’s Error through Time</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NcFXFcj9x3Fp7u5tNcEQfg.png" /><figcaption>Discriminator’s Error through Time</figcaption></figure><p>You can also check out the notebook named Vanilla Gan PyTorch in this <a href="https://github.com/diegoalejogm/gans/blob/master/1.%20Vanilla%20GAN%20PyTorch.ipynb">link</a> and run it online. You may also <a href="https://www.floydhub.com/diegoalejogm/projects/gans/10/output">download the output data</a>.</p><ul><li><a href="https://www.floydhub.com/diegoalejogm/projects/gans/10/output/runs"><strong>runs</strong>/</a> folder contains the tensor board data.</li><li><a href="https://www.floydhub.com/diegoalejogm/projects/gans/10/output/data"><strong>data/</strong></a> folder contains the images generated through time and the already trained neural network models.</li></ul><h3>Conclusions</h3><p>In this blog post I have introduced Generative Adversarial Networks. We started by learning what kind of algorithms they are, and why they’re so relevant nowadays. Next we explored the parts that conform a GAN and how they work together. Finally we finished linking the theory with the practice by programming with a fully working implementation of a GAN that learned to create synthetic examples of the MNIST dataset.</p><p>Now that you’ve learned all of this, next steps would be to keep on reading and learning about the more advanced GAN methods that I listed in the Further Reading Section. As mentioned earlier, I’ll keep writing these kind of tutorials to make it easier for enthusiasts to learn Machine Learning in a practical way, and learning required maths in the way.</p><h3><strong>Further Reading/Watching</strong></h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FhnT-P3aALVE%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DhnT-P3aALVE&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FhnT-P3aALVE%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/db058a657ff7226cf747469bb6a93960/href">https://medium.com/media/db058a657ff7226cf747469bb6a93960/href</a></iframe><ul><li><a href="https://arxiv.org/abs/1511.06434">DCGAN</a>, <a href="https://arxiv.org/abs/1703.05192">DiscoGAN</a> and <a href="https://arxiv.org/abs/1703.10593">CycleGAN</a> (GAN variations with better performance on specific tasks).</li><li>Google DeepMind’s<a href="http://www.gatsby.ucl.ac.uk/~balaji/Understanding-GANs.pdf"> slides on Understanding Generative Adversarial Networks</a> by Balaji Lakshminarayanan.</li><li><a href="https://arxiv.org/abs/1511.06434">Deep Convolutional Generative Adversarial Networks Paper</a> by Radford, Metz and Chintala.</li><li><a href="http://www.cedar.buffalo.edu/~srihari/CSE574/Discriminative-Generative.pdf">University at Buffalo’s Slides on Generative and Discriminative Models</a> by Sargur N. Srihari.</li><li><a href="https://medium.com/u/592ce2a67248">Andrew Ng</a> <a href="http://www.cs.cmu.edu/~aarti/Class/10701/readings/NgJordanNIPS2001.pdf">and Michael I. Jordan’s Paper on Generative vs. Discriminative Classifiers</a>.</li><li>Stanford’s CS229: <a href="http://cs229.stanford.edu/notes/cs229-notes2.pdf">Machine Learning Lecture Notes on Generative Learning algorithms</a> by <a href="https://medium.com/u/592ce2a67248">Andrew Ng</a>.</li><li>Stanford’s CS231n: <a href="http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture13.pdf">Convolutional Neural Networks for Visual Recognition Lecture 13 Notes on Generative Models</a> by Fei-Fei Li, Justin Johnson and Serena Yeung.</li><li>My <a href="https://github.com/diegoalejogm/gans">GitHub’s repository on Generative Adversarial Networks in TensorFlow and Pytorch</a>.</li><li>Ian GoodFellow’s <a href="https://www.reddit.com/r/MachineLearning/comments/40ldq6/generative_adversarial_networks_for_text/">Reddit Thread on Generative Adversarial Networks for Text.</a></li><li><a href="https://lilianweng.github.io/lil-log/2017/08/20/from-GAN-to-WGAN.html">Deeper Maths on GANs</a></li></ul><p>Thanks for reading this post until the end, I’m really glad to find people who’re as motivated as I am about science (specifically CS and AI).</p><p>Make sure to <strong>like</strong>/<strong>share</strong> this post 😊 , and comment your experience reading it!</p><p>Feel free to leave any questions and subscribe for future state-of-the-art ML explanations.</p><p>GitHub: <a href="http://GitHub.com/diegoalejogm">diegoalejogm</a><br>LinkedIn: <a href="http://linkedin.com/in/diegoalejogm">diegoalejogm</a></p><h3>References</h3><p>[1] Jun-Yan Zhu, Taesung Park, Phillip Isola, Alexei A. Efros, <em>Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks</em>, 2018, <a href="https://arxiv.org/abs/1703.10593">https://arxiv.org/abs/1703.10593</a></p><p>[2] Ian J. Goodfellow, Jean Pouget-Abadie, Mehdi Mirza, Bing Xu, David Warde-Farley, Sherjil Ozair, Aaron Courville, Yoshua Bengio, <em>Generative Adversarial Networks</em>, 2014, <a href="https://arxiv.org/abs/1406.2661">https://arxiv.org/abs/1406.2661</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cb03cdcdba0f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/gans-from-scratch-1-a-deep-introduction-with-code-in-pytorch-and-tensorflow-cb03cdcdba0f">GANs from Scratch 1: A deep introduction. With code in PyTorch and TensorFlow</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What happens next? (an opinion on AI and jobs)]]></title>
            <link>https://medium.com/ai-society/what-happens-next-on-ai-and-jobs-ad327a2f2d90?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/ad327a2f2d90</guid>
            <category><![CDATA[jobs]]></category>
            <category><![CDATA[money]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[future]]></category>
            <dc:creator><![CDATA[Diego Montoya Sefair]]></dc:creator>
            <pubDate>Tue, 27 Jun 2017 19:28:21 GMT</pubDate>
            <atom:updated>2020-01-02T04:56:00.615Z</atom:updated>
            <content:encoded><![CDATA[<p>When you actually sit to think about it, it turns out to be really complex, especially as the effects are starting to be visible right now. I&#39;m talking about Artificial Intelligence (AI) and its effects on jobs.</p><p>Being immersed in these kinds of topics makes you realize that it’s not insane to come to the following conclusion: Sooner or later, a machine will be able to perform <em>any </em>job better than a human. A machine could become a better doctor, a better chef, a better psychologist —yes, a better psychologist — , a better lawyer, or a better programmer.</p><p>The reason I believe this is relatively simple. Firstly, it is worth mentioning the remarkable success that AI has had recently in a large number of fields. <a href="https://waymo.com">Cars can now drive themselves</a>, <a href="http://www.wired.co.uk/article/google-deepmind-atari">computers are learning to play some Atari games better than humans</a>, and even <a href="https://www.technologyreview.com/s/602949/ai-has-beaten-humans-at-lip-reading/">read lips better than humans</a>. Moreover, computers are very good at doing mathematical computations, and a lot of the core of machine learning is mathematics. An optimization problem. And while brains are incredible biological machines, a computer really has the potential to take every single variable into account and calculate outputs that are closer to a global optimum than the brain would.</p><p>Now, the key difference between yesterday’s and today’s techniques is that instead of explicitly writing programs to solve a problem, we are writing programs that learn to solve the problem. Instead of explicitly designing a program to recognize handwritten digits we design a program which, by seeing examples of a lot of different pictures and what the number is, l<em>earns a</em> method (a-priori unknown to the programmer) to recognize them with near-perfect accuracy. This is an incredibly remarkable achievement. Computers are l<em>earning t</em>o solve problems, rather than following a pre-crafted recipe for solving them. This resembles the way our brains learn, and it’s producing absolutely impressive results so far.</p><p>But the purpose of this article is not to convince you that computers will most likely surpass humans at almost every task. So if you are not convinced yet about this there are plenty of other resources than could help. You could also take a look at the following good video from <a href="https://www.youtube.com/channel/UC2C_jShtL725hvbm1arSV9w">CGP Grey</a> to have a broader view of the situation. Either way, I would also recommend watching it since it complements this article&#39;s introduction.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F7Pq-S557XQU%3Fstart%3D33%26feature%3Doembed%26start%3D33&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D7Pq-S557XQU&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F7Pq-S557XQU%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/bb25538df5ca862ff143e95d613f674d/href">https://medium.com/media/bb25538df5ca862ff143e95d613f674d/href</a></iframe><p>In summary, I see no reason to doubt that AI will continue to evolve at an ever increasing (exponential) pace. In fact, AI can also help the very research of AI since Machine Learning is becoming one of the core components of Data Science, the art of processing and making sense of data.</p><h4>The ultimate industrial revolution</h4><p>As AI evolves and becomes more capable it starts to displace humans at the tasks where they start to do better (or comparatively good). Why? For one, machines work 24 hours, 365 days a year, without complaining. And, if they do the job better and faster than humans, it&#39;s the perfect combination for it to be a huge deal for companies. From their point of view they are being a lot more profitable, they reduce costs and increase their quality (and quantity if applicable). Overall, they are offering better products or services at lower prices. This is not a new thing, as the Industrial Revolution showed us. However, now it&#39;s the time for intelectual jobs rather than technical ones.</p><p>This, by itself, is not bad. We are producing better things, and even better knowledge. Just imagine putting machines to think about the most difficult problems humanity has right now, 24/7. The largest and most efficient research center driven by machines that don&#39;t sleep, working for the well-being of us and asking nothing in return. We would just set them and wait to see what they discover. Physics, chemistry, medicine, mathematics. In general, any area of knowledge. Envision AI super-computers dedicated to finding the cure to cancer, or to solving the most challenging questions of the universe.</p><p>Due to these amazing possibilities I would say research on AI is not going to stop. We are approaching (and already began) a phase of profound change. We already went through the phase of seeing how machines can perform a lot of <em>repetitive</em> jobs better or as good as humans during the Industrial Revolution. But now we are beginning to see how machines can also outperform humans (or do equally or sufficiently good) at tasks we wouldn’t have ever thought, intellectual tasks. As this process happens we start loosing jobs, only this time the new jobs that replace <em>(temporarily) t</em>he lost ones will requiere a high level of knowledge, education.</p><p>In the beginning new jobs emerge, as we are seeing today and as we saw during the Industrial Revolution. New jobs in the fields of data science and machine learning have been created recently. However, as progress is made more and more jobs also disappear (exponentially), and at a faster rate than the ones emerging. And this is not something that <em>will</em> happen, it&#39;s something that <em>is</em> happening right now as you have probably seen in the news and in your everyday life. Eventually, and as we have discussed earlier, we can get to the point where there are little to no jobs a machine cannot perform better than a human. If that happens, that would be it: the ultimate revolution.</p><h4>The collapse of the monetary system</h4><p>Independently of what happens —i.e. if machines outperform humans in any intellectual task— the economic system is going to suffer. <a href="https://www.thevenusproject.com/the-venus-project/jacque-fresco/">Jacque Fresco</a>, the proposer of something big he called <a href="https://www.thevenusproject.com">The Venus Project</a> —we’ll get to this later—, had a position on this. In <a href="https://www.youtube.com/watch?v=dBkFeA2pOQY">one of his talks</a> he remarked precisely on how machines are replacing jobs in multiple sectors of the industry. As we discussed earlier, he said this is going to happen naturally since industries find it far more profitable to have as less humans as possible. No wages or any other legal requirement attached to regular contracts, much faster (and usually better) work, and to add to that, no 9–5 journeys during weekdays but 24/7 ones 365 days a year.</p><p>As jobs get replaced humans start to make their way out, and as this happens productivity will rise substantially while purchasing power falls drastically: the collapse of the money system. Production is off the charts, but no one has money to buy things. What should we do then? This is my big question and is what gives this article it’s title. It’s almost certain that the economy will collapse, what happens next? We are clearly not prepared for this, and if you think about it, any attempt to prevent it would probably not get very far.</p><p>One option would be to implement laws to regulate companies and force them to hire people. How should we handle jobs that are no longer doable by humans because of their effort or their precision? How to be fair to all companies? Maybe we come up with some solution to make this work, but, what are we accomplishing? Does it even make sense to force companies to be more inefficient? In the end, machines give companies the potential to produce better products and services —also at a lower price but that&#39;s irrelevant since costumers wouldn&#39;t be able to afford it.</p><p>Maybe another solution then is to stop research, literally make research on AI illegal. This could certainly stop progress and probably save the economic system. But again, what would we be accomplishing? What is it worth more to us, money, or progress? Should we stop the potential of discovering the cure for cancer in order to save the economic system? Should we agree to let people die in countless driving accidents caused by human error in order to prevent driverless vehicles from taking over the transportation industry? Should we make people waste time in lines in supermarkets to preserve human cashiers? Should we reduce the potential of understanding the biggest mysteries of the universe to prevent AI from evolving?</p><p>So, we will be faced with some controversial decisions, and this is the main point I want to make here. A crisis will come, but this will not be like the rest of the economic crises of the past. This time we will reach a point where money itself stops making sense. Money rewards work, but if there are few to no humans doing work then money loses its very reason of existence. Machines work for us and they don’t ask for anything in return — hopefully we are smart enough so this doesn’t change.</p><p>If we continue with things as they are today research will be made, technology will improve, and so will services, products, and health. But many jobs will cease to exist and we are already seeing the effect. Naturally, repetitive jobs will be the first to suffer. Technology like Google&#39;s <a href="https://waymo.com">Waymo</a> project (Google&#39;s version of a self-driving car) and autopilots will displace every human from the transportation industry. And those are not technologies far in the future. We are talking 1–2 years before we see comercial, fully autonomous vehicles out there, and you guessed it, they are very profitable for the transportation industry. If you are not convinced, you might take a look at <a href="https://www.wired.com/2016/09/self-driving-autonomous-uber-pittsburgh/">what Uber has already in the works</a>.</p><p>Just taking away transportation jobs from humans is enough to create a giant disruption in the system. Where are these people going to go? During the economic crisis that is beginning to happen new, <em>temporary</em>, jobs will be created (temporary since they’ll most likely be replaced later as well). The difference is that these jobs will all have a common denominator: they will be intellectual and require education. Repetitive jobs will come to an end and people will be forced to seek education if they want to survive.</p><p>If you ask me, stopping progress is not a very clever solution, and I would think governments will probably agree. If that is so, an economic crisis will happen, and it will be the <em>ultimate</em> crisis since it will take the monetary system down. I will not disagree, the transition will be very hard, specially for those doing the jobs that will disappear in the first wave. I&#39;m eager to see what people figure out to ease this transition, but something big is about to happen.</p><h4>What happens next?</h4><p>And so we get to our ultimate question. What happens next? What happens after the crisis? I can&#39;t answer this question since only time will tell, but I would say our way of living will see a dramatic change in the coming decades. I think money will lose all of its fundamental value, and that&#39;s when we can remove it altogether and start to give things away for free.</p><p>If you want an idea of a solution, Jacque Fresco thought about one for some time during his life. His response was <a href="https://www.thevenusproject.com">The Venus Project</a>, a <em>resource-driven economy</em>. He focuses precisely on the idea of removing money from the system and moving on to a way of life in which we are given things for free. Everyone would have a very high standard of life, and this would be possible since machines do mostly everything. In fact, one of Fresco’s points is that after removing money we remove most of the problems humanity faces right now: poverty, corruption, most forms of violence and war, among many other problems which derive from money. We could stop worrying about work and focus on doing other things. Is this the right path? Who knows, but what is? We would have to take a lot of care, for example, with respect to the psychological implications this would have on people.</p><p>But my point isn&#39;t to discuss The Venus Project in detail. I just referenced it so you could get an idea of what could be next. In summary, the point that I want to make could be summarized as follows. Something big will happen in the coming decades, and this is because it doesn&#39;t make much sense to even try to prevent progress. If we have the potential to save lives, shouldn&#39;t we? If we can make key advances in medicine, shouldn&#39;t we? If we have the potential to solve the most challenging mysteries of the universe, shouldn&#39;t we? As a side-effect, money will most certainly stop making sense, and yes, the transition to a money-less system will be hard. Humanity will probably undergo the biggest change in history, and in some decades from now life will be nothing like it currently is. In my humble opinion, this is something worth thinking from now since something big is about to happen, and its going to happen sooner than we realize.</p><h4>Other Links</h4><ul><li><a href="https://www.youtube.com/watch?v=WSKi8HfcxEk"><strong>The Rise of the Machines — Why Automation is Different this Time</strong></a><strong><br></strong>A video series (in development) by the great <a href="https://www.youtube.com/channel/UCsXVk37bltHxD1rDPwtNM8Q">Kurzgesagt</a> team</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ad327a2f2d90" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/what-happens-next-on-ai-and-jobs-ad327a2f2d90">What happens next? (an opinion on AI and jobs)</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Convolutional Neural Networks are a Great Architecture for Machine Translation]]></title>
            <link>https://medium.com/ai-society/why-convolutional-neural-networks-are-a-great-architecture-for-machine-translation-9258ca1263a8?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/9258ca1263a8</guid>
            <category><![CDATA[language-translation]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[naturallanguageprocessing]]></category>
            <category><![CDATA[machine-translation]]></category>
            <dc:creator><![CDATA[Esteban Vargas]]></dc:creator>
            <pubDate>Wed, 07 Jun 2017 22:48:35 GMT</pubDate>
            <atom:updated>2017-06-07T22:48:34.937Z</atom:updated>
            <content:encoded><![CDATA[<p>Facebook AI Research recently posted <a href="https://code.facebook.com/posts/1978007565818999/a-novel-approach-to-neural-machine-translation/">a paper</a> in which a Convolutional Neural Network architecture is proposed for machine translation instead of a <a href="https://medium.com/ai-society/how-language-translators-will-work-c85a70cc4f3a">Recurrent Neural Network architecture</a>, which has been the convention until now. In this post we will explain why a CNN-based architecture might become the standard for machine translation (and even other NLP tasks) in the feature.</p><p><strong>Convolutional Neural Networks basics<br></strong>Let’s first understand how CNNs work in order to explain why they have certain advantages over RNNs. <br>The basic concept underlying CNNs is that we compute a vector for every possible phrase. For instance take the string <em>“my favorite AI blog”</em>. Then we compute the <a href="https://medium.com/ai-society/jkljlj-7d6e699895c4">word vector representation</a> for: <em>“my favorite, favorite AI, AI blog, my favorite AI, favorite AI blog”. </em>Once we have that, we compute all the bigram vectors until we reach a top vector.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/325/1*9CbWzH9O9iWOfWc5bEeLjw.png" /><figcaption>Example of the computation of the bigram vectors for a very simple sentence until the top vector is reached. Retrieved from the Association for Computational Linguistics.</figcaption></figure><p>The computation of these bigrams (or n-grams in more complex but convenient CNN architectures) can be parallelized, the time-step-based computations in a RNN architecture can’t. This data structure has been really successful in classifying images; for instance let’s take the image of a cat as an example; it first processes clusters of pixels, then recognizes shapes, then recognizes parts of the image (ears, legs, tail, etc.) and it finally recognizes there is a cat in the picture.</p><p><strong>Convolutional Sequence to Sequence Learning<br></strong>Gehring et al., (2017)proposed using CNNs because contrary to RNNs computation can be parallelized, optimization is easier since the number of non-linearities is fixed and independent of the input length and last because they outperform the LSTM accuracy in <a href="https://arxiv.org/abs/1609.08144">Wu et al., (2016).</a> In addition to that the algorithm for capturing these dependencies scales in O(n/k) instead of O(n) due to the hierarchical structure.</p><p>Despite being known that convolutions have several advantages since the early days, such as the ones presented by Waibel et al., (1989) and LeCun &amp; Bengio, (1995), they solely create representations for fixed sized contexts. RNNs allowed to create representations for variable sized contexts and LSTMs and GRUs tackled the problem of RNNs not capturing long-range dependencies. These were the reasons why RNNs became the standard for machine translation and CNNs became more widely adopted in fixed sized contexts such as image processing. But the convolutional architecture presented by Gehring tackles these problems and outperforms RNNs.</p><p><strong>Convolutional Architecture<br></strong>In this section of the article we’ll explain in a summarized way what the fully convolutional architecture proposed by Gehring consists of; the first step is embedding input elements in a distributional space and giving a sense of order to the model by embedding the absolute position of input elements, then both vectors are combined and we proceed similarly for the output elements that were already generated by the decoder network.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/203/1*9dXKrIGHJHtKtAtdlfSncw.gif" /><figcaption>This linear combination represents the input embeddings in the source language.</figcaption></figure><p>Based on these input elements, intermediate states are computed both for the encoder and decoder networks. The computation of each of these states is called a block, and each block contains a one-dimensional convolution followed by a non-linearity. Gated Linear Units, as proposed by Dauphin et al., 2016, are the non-linearity that implement a gating mechanism over the output of the convolution. Ultimately, the softmax activation function is used to compute a distribution over the T possible next target elements.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/137/1*-aVW1kUgXxgUWIp4vGwcIA.gif" /><figcaption>Each convolution kernel takes X (a concatenation of k input elements embedded in d dimensions) as an input and outputs Y which has twice the dimensionality of the input elements.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/356/1*8XvWPG8junY4PQuser4RUQ.gif" /><figcaption>The top decoder output is transformed with a linear layer with weights Wo and bias bo respectively.</figcaption></figure><p>Then we proceed to compute attention. We combine the current decoder state with an embedding of the previous target element to get the current decoder state summary. The current attention for the current decoder layer, state, and source element is computed by taking the dot-product between the decoder state summary and each output of the last encoder block.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/178/1*HlLsarUtWD0JM9m64ZA_Ag.gif" /></figure><p>Next, the conditional input for the current decoded layer is computed with a weighted sum of the encoder outputs and the input element embeddings. Once this is computed, it’s added to the output of the corresponding decoder layer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/154/1*ocTQ_rmNbO4IA6qKLGtnqw.gif" /></figure><p>Finally, a normalization strategy and a careful weight initialization are applied in order to ensure that the variance across the network doesn’t change dramatically which results in a stabilized learning. This way we lastly reach our desired translation in the target language.</p><p><strong>Experimental Setup and Results<br></strong>3 major WMT translation tasks were used by Facebook AI Research to compare both architectures. The <a href="https://en.wikipedia.org/wiki/BLEU">BLEU</a> algorithm, which is used to evaluate how much correspondence a machine-translated text has with a professional human translation, was used to benchmark translations. For English-Romanian, the convolutional architecture surpassed by 1.8 BLEU. For English-French the difference was 1.5 BLEU. For English-German it was 0.5 BLEU.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9258ca1263a8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/why-convolutional-neural-networks-are-a-great-architecture-for-machine-translation-9258ca1263a8">Why Convolutional Neural Networks are a Great Architecture for Machine Translation</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recurrent Neural Networks for Language Translation]]></title>
            <link>https://medium.com/ai-society/how-language-translators-will-work-c85a70cc4f3a?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/c85a70cc4f3a</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Esteban Vargas]]></dc:creator>
            <pubDate>Mon, 13 Mar 2017 13:35:31 GMT</pubDate>
            <atom:updated>2017-03-29T15:39:40.616Z</atom:updated>
            <content:encoded><![CDATA[<p>Tools that allow any person to communicate with any other person truly make the world a better place. <a href="https://en.wikipedia.org/wiki/Rosetta_Stone">The Rosetta Stone</a> was the first of such tools, evolving to dictionaries and eventually to sophisticated systems such as a language translator that you’ve probably used before, Google Translate. Deep Learning will soon change how these systems work, and the models that will enable such thing have all kinds of applications in NLP even outside the realm of machine translation (such as building an opinion generator, which part of the AI-Society team will actually hack on, so stay tuned).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/1*VctmIaRL3OGLSnBhiAILlg.jpeg" /><figcaption>The Rosetta Stone is considered the first language translator</figcaption></figure><p>Let’s first talk about recurrent neural network (RNN) based language models. Yoshua Bengio proposed using artificial neural network based statistical modeling for computing the probability of a sequence of words occurring. This approach proved to be successful; however, feedforward neural networks don’t allow to receive variable length sequences as an input which limits the power of the model. Since RNNs allow variable length sequences both as an input and as an output, they are naturally the next step in statistical language modeling. [1] The RNN architecture is presented in the diagram below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/221/1*kJpD7AjKSNQ8yuczFiaFQA.png" /><figcaption>Simple Recurrent Neural Network architecture model presented by Mikolov et al.</figcaption></figure><p>In this model we are given a set of <a href="https://medium.com/ai-society/jkljlj-7d6e699895c4#.vklpntyqm">word vectors</a> as an input, we have <em>t </em>time-steps which are equivalent to the number of hidden layers, these layers have neurons (each performing a linear matrix operation on its inputs followed by a non-linear operation). Time-steps generate the output of the previous step and the next word vector in the text corpus is passed as an input to the hidden layer to generate the prediction of a sequence (conditioning the neural network on all previous words).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/211/1*FUGkJFY0RsRN8fT7O8Tzug.gif" /><figcaption>Equation for computing the hidden state with a linear neural network at each time-step</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/167/1*Zd7iFwt2B1b5_HoV9d5XSw.gif" /><figcaption>Equation for the softmax classifier</figcaption></figure><p>These are the basics of RNNs. However simple RNN architectures have problems which were explored by <a href="http://www-dsi.ing.unifi.it/~paolo/ps/tnn-94-gradient.pdf">Bengio et al.</a> In practice, simple RNNs aren’t able to learn “long-term dependencies”. Let’s analyze the following example in which we try to predict the last word in a sentence:</p><p><em>“I prefer writing my code in Node JS because I am fluent in ______.”</em></p><p>The blank could probably be filled with a programming language, and if you know about backend development you might know that the answer is <em>JavaScript. </em>In order for a program to know this the program needs some context about Node JS and JavaScript from somewhere else in the text. Two fancy types of RNNs solve this problem, Long Short-Term Memories (LSTMs) and Gated Recurrent Units (GRUs). <a href="https://www.tensorflow.org/tutorials/recurrent">The TensorFlow documentation has an amazing tutorial on language modeling with LSTMs</a> so for the purpose of this blog post we will do the same thing with GRUs.</p><p><strong>Gated Recurrent Units</strong></p><p>GRUs were introduced by <a href="https://arxiv.org/pdf/1502.02367v3.pdf">Cho et al.</a> The main idea behind this architecture is to keep around memories to capture long distance dependencies and to allow error messages to flow at different strengths depending on the inputs.</p><p>Instead of computing a hidden layer at the next time-step, GRU first computes an update gate (which is another layer) taking the current word vector and hidden state as parameters.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/1*AJ1VADUY2OsLlIn_NuKigQ.gif" /><figcaption>Update gate</figcaption></figure><p>Then a reset gate is computed with the same equation but with different weights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/199/1*wyDRJ25ONhDP3opZHL-MJA.gif" /><figcaption>Reset gate</figcaption></figure><p>If the reset gate is 0, it only stores the new word information in the memory (reset).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/223/1*wk3JtR_Q9xiS9DFGo8kXMQ.gif" /><figcaption>Memory (reset)</figcaption></figure><p>The current time-step combines current and previous time-steps to compute the final memory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/215/1*LQG_cBb1bE--mr_8fgY2tg.gif" /><figcaption>Final memory</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/1*1eXNttQ9x34kiAADUh8hqw.png" /><figcaption>Clean illustration of the architecture by Richard Socher</figcaption></figure><p>Now that you understand the architecture of a GRU cell, you can do some really interesting things. For instance you could train <a href="https://www.tensorflow.org/tutorials/recurrent">this model</a> and compare the <a href="https://en.wikipedia.org/wiki/Perplexity#Perplexity_per_word">perplexity</a> that an LSTM yields in comparison with a GRU. You could also modify <a href="https://www.tensorflow.org/tutorials/seq2seq">this piece of code</a> and build your own language translator using GRUs instead of LSTMs.</p><p><strong>Final Thoughts</strong></p><p>Traditional machine translation models are bayesian and at a very broad scope what they do is that they align the source language corpus with the target language corpus (usually at a sentence or paragraph level), after many repetitions of the alignment process each block (sentence or paragraph) has many possible translations, and finally the best hypothesis is searched with Bayes’ Theorem.</p><p><strong>EDIT: The papers cited in this post are from 2015 and before. On March 2017 -date in which this post was written- we’ve been told that these systems are already used in production, replacing the mentioned bayesian systems.</strong></p><p>[1] There are other reasons. For example, the RAM requirement only scales with the number of words.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c85a70cc4f3a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/how-language-translators-will-work-c85a70cc4f3a">Recurrent Neural Networks for Language Translation</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Lisp approach to AI (Part 1)]]></title>
            <link>https://medium.com/ai-society/the-lisp-approach-to-ai-part-1-a48c7385a913?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/a48c7385a913</guid>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[lisp]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Sebastian Valencia]]></dc:creator>
            <pubDate>Tue, 28 Feb 2017 16:48:05 GMT</pubDate>
            <atom:updated>2017-02-28T16:46:39.955Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pecVF01CD2MYurZSvxboGw.png" /><figcaption>Common Lisp code to create an n-inputs m-units one layer perceptron. Taken from the code of <a href="https://www.amazon.com/Artificial-Intelligence-Modern-Approach-3rd/dp/0136042597">AIMA</a>, a classic textbook in Artificial Intelligence. The whole code <a href="http://aima.cs.berkeley.edu/lisp/learning/algorithms/perceptron.lisp">here</a>.</figcaption></figure><p>If you are a programmer that reads about the history and random facts of this lovely craft, and practice it <em>ad honorem — </em>just for fun — , you have found yourself reading about a programming language called Lisp. Some praise it as a software miracle, as the best tool for programming. Some even dare to call Lisp one of the best programming languages ever invented (even if that doesn’t make sense at all). After all, before Python, Scala, Haskell, there was programming, and before Deep Learning there was Artificial Intelligence. Great hackers that love Lisp:</p><ul><li>Paul Graham, co-founder of Y-Combinator is a big Lisp evangelist. He <a href="http://www.paulgraham.com/avg.html">wrote his startup’s code in Lisp</a>. Viaweb — the startup — was co-founded along with Robert Tappan Morris, a legendary hacker who allegedly released the first computer worm accidentally. After being a rehabilitated worm writer (written in C), <a href="http://www.dailydot.com/via/paul-graham-hacker-to-half-billion-dollar-man/">Robert Tappan wrote the server code of the small company in Common Lisp</a>. Viaweb was sold to Yahoo! in 1998 for $48 million dollars. Of course there’s not enough evidence yet to said that C lead you to jail while Lips makes you a millionaire.</li><li>Alan Kay, a pioneer in the practical aspects of OOP and the lead developer of the original Smalltalk (another software miracle?), has called Lisp the greatest single programming language ever designed. <a href="http://www.michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/">He has also compared Lisp with Maxwell’s equations.</a></li><li>Edsger Wybe Dijkstra, a pioneer in the field of formal verification and specification, concurrency theory, and operating systems design, whose most famous work is a greedy one, once said:</li></ul><blockquote>Lisp has jokingly been called the most intelligent way to misuse a computer. I think that description is a great compliment because it transmits the full flavor of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts.</blockquote><ul><li>Robert Floyd, a Stanford professor without a PhD — I’m just joking , but that’s true— , the designer of Floyd-Warshall algorithm, a pioneer in axiomatic semantics, and the author of the <a href="https://www.amazon.com/Language-Machines-Introduction-Computability-Languages/dp/0716782669">best book to learn mathematical induction from as a hacker</a>, once said:</li></ul><blockquote><em>Although my own previous enthusiasm has been for syntactically rich languages, like the Algol family, I now see clearly and concretely the force of Minsky’s 1970 Turing Lecture, in which he argued that Lisp’s uniformity of structure and power of self reference gave the programmer capabilities whose content was well worth the sacrifice of visual form.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j9xadR0s77ajIAysJSBxmg.png" /><figcaption>Some CS celebrities that have treated Lisp as a miracle (sometimes). A venture capitalist, a musician, Dijkstra’s algorithm inventor, and Robert Floyd (he <a href="http://www-cs-faculty.stanford.edu/~uno/papers/floyd.ps.gz">was highly appreciated by Donald Knuth</a>).</figcaption></figure><p>Three of our luminaries, along with Marvin Minsky (the guy referred by Floyd), and John McCarthy (the inventor of Lisp), were awarded with the Turing Award. So why do many CS celebrities <em>talk</em> so good about a simple programming language? Lisp is famous nowadays because of the things others have said about it, but in the early days of AI, Lisp was the <em>de facto</em> language to express ideas related to natural language processing, computer assisted geometry, text generation, AI planning, and automated theorem proving. Yes, there was AI before Machine Learning, indeed, there was an AI winter before the boom of neural networks and statistical approaches to AI, but that’s a topic that deserves an entire single post.</p><h3>The Lisp approach to AI</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7Bb4u7_ECKJ-0I5ysiF3hA.png" /><figcaption>John McCarthy, the inventor of the term “Artificial Intelligence”, the inventor of garbage collection, and the inventor of Lisp. Marvin Minsky, the founder of the AI lab at MIT.</figcaption></figure><p>The progress, development, and evolution of Lisp was tightly related to the early progress, development, and evolution of Artificial Intelligence. Two of the guys mentioned before were pioneers in AI. <a href="https://www.youtube.com/watch?v=Ozipf13jRr4">John McCarthy</a>, the creator of Lisp, coined the term <em>Artificial Intelligence</em>, while <a href="https://www.webofstories.com/play/marvin.minsky/49">Marvin Minsky shaped the content of the new field by founding the AI lab at MIT</a>. Many of their students were the developers of the first digital milestones of artificial intelligence.</p><p>Programs for <a href="https://www.csail.mit.edu/videoarchive/history/aifilms/robot-26">natural language understanding and generation</a>, <a href="https://www.cs.virginia.edu/~evans/greatworks/samuel1959.pdf">game playing</a> (the link contains a paper from the man who introduced the term <em>Machine Learning</em>), <a href="http://dl.acm.org/citation.cfm?id=888956">theorem proving</a>, <a href="ftp://publications.ai.mit.edu/ai-publications/pdf/AITR-228.pdf">early computer vision</a>, <a href="http://inst.cs.berkeley.edu/~cs282/sp02/readings/moses-int.pdf">symbolic mathematics</a> (specially <a href="https://www.cs.purdue.edu/cs47100/saint.pdf">integration</a>), <a href="https://dspace.mit.edu/handle/1721.1/6894">problem-solving</a> and <a href="http://www.aclweb.org/anthology/J80-3004">knowledge representation</a>, were produced at Stanford and MIT using different dialects of Lisp as a tool to express those ideas in. Was it just a coincidence, or is there something special with the idea (not just the language) of Lisp? This is a list of some classic AI programs that were <em>expressed</em> in Lisp.</p><ul><li>ELIZA was a natural language processing computer program originally written by <a href="https://en.wikipedia.org/wiki/Joseph_Weizenbaum">Joseph Weizenbaum</a> at MIT. The program was a simple therapist to interact with, showing a trivial and superficial communication between a human and a machine. It <a href="http://dl.acm.org/citation.cfm?id=364057">was implemented in a pre-processor of Fortran that mimics Lisp features for list processing and composition of nested expressions.</a> <a href="http://www.codersatwork.com/bernie-cosell.html">It was later written in Lisp by Bernie Cosell</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/1*os3l7BfP4ZcVq_Q1Q8Vhrg.png" /><figcaption>A typical conversation between a human and ELIZA. The <a href="http://kameken.clique.jp/Lectures/Lectures2010/NLP2010/relatedDocuments/Eliza-weizenabaum.pdf">paper</a> that introduced the program is called <strong>ELIZA — A Computer Program for the Study of Natural Language Communication between Man and Machine</strong></figcaption></figure><ul><li>MACSYMA (MAC’s symbolic manipulator) was one of the first computer algebra systems originally developed at MIT’s project MAC. MACSYMA was written in a dialect of Lisp called MacLisp, and at that time it was one of the biggest Lisp programs out there. In 1982, MACSYMA was licensed to <a href="https://en.wikipedia.org/wiki/Symbolics">Symbolics</a>, a computer hardware company whose main focus was the production of <a href="https://www.quora.com/What-is-a-lisp-machine-and-what-is-so-great-about-them">machines whose architecture was optimized for the development and interpretation of Lisp programs</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/1*ZH0Oe8-rQRKQKjMI2PuyPA.png" /><figcaption>A very simple session in MACSYMA.</figcaption></figure><ul><li>SHRDLU, was the dissertation of Terry Winograd (the PhD advisor of Larry Page at Stanford University) at MIT. It was written in the AI lab created by Minsky to demonstrate a dialog with the machine that could lead to actions taken by the machine in a virtual environment both agents (the human, and the machine) were capable to understand. As MACSYMA, SHRDLU was written in MacLisp.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hSsXVAFwBhf3E9YuQjlezA.jpeg" /><figcaption>A <a href="http://edoc.hu-berlin.de/dissertationen/link-david-2004-07-27/HTML/chapter11.html">sample session</a> in SHRDLU. The program was supposed to understand and execute actions told by a human in natural language.</figcaption></figure><p>The progress of AI in its early days was not because of Lisp, I do think CS subjects should be agnostic of the language they express their ideas in. Lisp was used on the early days of AI because it was flexible enough to allow quick experimentation and prototyping (<em>REPL</em>), and it introduced fundamental ideas that were cool and fresh at the moment (<a href="http://www.paulgraham.com/diff.html"><em>IF-THEN-ELSE</em> construct, recursion, and <em>Garbage Collection</em></a>). Those features proved themselves to be useful to express the kind of the ideas AI people needed to express. This innovation, and the rapid adoption of Lisp for AI (in labs and projects) helped the language grow and become a standard AI language.</p><p>Of course all these programs could have been written in other languages, but Lisp was an accepted and highly praised vehicle to explore and implement these kind of ideas at the moment.</p><h3>Lisp in the real world</h3><p>At this point, you may think that Lisp was just an academic invention to teach and implement symbolic AI programs. But the rapid adoption of Lisp in academia, implied a massive effort to embrace Lisp (or any of its descendants) in real-world production ready software. The following is a collection of some of those programs; most of the programs included in this list are still running on production environments, while the other part of it used to backup large pieces of software in well-known projects or companies.</p><p>You need to know that Lisp and its dialects have evolved a lot since McCarthy defined it for the first time, but most of the original idea of Lisp has been preserved in its descendants. Most of the semantics of Lisp has been an invariant in most Lisp’s implementations that were capable to power or support, in one way or another, the operation of the following projects.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lWzxU-h4NTBqOoecqBhWIg.png" /><figcaption>Some of the projects/companies whose stack has included Lisp.</figcaption></figure><ul><li>After the pain found by Bernie Greenberg and Richard Stallman while implementing a language to manipulate text in the <a href="https://en.wikipedia.org/wiki/TECO_(text_editor)">TECO</a> text-editor, Bernie decided to implement a whole new editor (written in MacLisp) and an interpreter that allowed users to manipulate the text being edited. Due to poor portability offered by MacLisp, <a href="https://www.gnu.org/gnu/rms-lisp.en.html">Richard Stallman decided to implement it in C keeping the interpreted language to customize both the text and the editor, this language is called EmacsLisp</a>.</li><li><a href="https://www.youtube.com/watch?v=2w_ekB08ohU">Douglas Lenat,</a> a persistent believer in the power of symbolic AI, has worked on three famous AI programs through his lifetime. The first one, Automated Mathematician (AM) made heavy use of the Lisp property to represent programs as data (you’ll understand this later) to define a bunch of mathematical concepts that could serve as a basis to solve math problems. Its sequel, <a href="http://aliciapatterson.org/stories/eurisko-computer-mind-its-own">Eurisko</a>, written in RLL-1, a language written in Lisp, was looking to extend AM’s potential to other fields by working with heuristics (an abstract concept that’s hard to define using a programming language). The frustration of Lenat, acquired while working on Eurisko, <a href="http://www.businessinsider.com/cycorp-ai-2014-7">lead Lenat to start his own company</a>, <strong>Cycorp, Inc</strong>. In 1984 the company started a project to introduce <a href="https://www.wired.com/2016/03/doug-lenat-artificial-intelligence-common-sense-engine/">common sense</a> to machines, that was supposed to enable computers to perform human-like reasoning. This effort, often qualified as impractical, <a href="https://www.technologyreview.com/s/600984/an-ai-with-30-years-worth-of-knowledge-finally-goes-to-work/">was launched in 2014</a>.</li><li>Some of our favorite sources to get information from: Reddit and Hacker News were/are at websites powered by Lisp. Reddit was originally written in Common Lisp, the “standard” Lisp dialect, <a href="https://redditblog.com/2005/12/05/on-lisp/">but it was rewritten in Python by 2005</a>. Hacker News is itself powered by <a href="http://arclanguage.org/install">Arc</a>, a programming language written by Paul Graham using the Racket programming language (another descendant of Lisp).</li><li>Planning and logistics are hard problems due to the size and the number of variables involved in. AI has been capable to deal with those problems by finding “clever” ways to optimize search in complex data structures. With this fact in mind, the U.S. Military choose to simulate the feasibility of strategies for supply or personnel transportation using the DART program written in Common Lisp; DART was used in the Gulf War, where it represented large budget savings.</li><li>Besides military usage, <a href="https://kuomarc.wordpress.com/2012/03/05/the-uncommon-lisp-approach-to-operations-research/">planning and scheduling with AI</a>, have found space in industrial software. <a href="https://routific.com/">Routific</a> is a Route Optimization as a Service startup whose routing engine — entirely written in Common Lisp — plans optimal routes for delivery companies optimizing the time and spent fuel. ITA Software, a company acquired by Google 5 years ago, offers to their customers a <a href="http://franz.com/success/customer_apps/data_mining/itastory.php3">simple travel search engine</a> to search for cheap air trips taking into account several variables. <a href="http://www.paulgraham.com/carl.html">ITA Software makes use of sophisticated algorithms expressed in Common Lisp</a>.</li></ul><p>One of Lisp’s main virtues, is that it enables a programmer to create new linguistic abstractions with ease. So there should be not surprise in the fact that Lisp has <strong>influenced</strong> many popular programming languages; two of them — very close to the AI/Data Science/ML community (besides from Lisp itself) — , which are R and Julia.</p><ul><li>R was originally written as a very simple Lisp interpreter using as reference a chapter of a <a href="https://mitpress.mit.edu/sicp/full-text/book/book.html">very popular introductory textbook on computer science</a>, and a really good but surprisingly unknown <a href="https://www.amazon.com/Programming-Languages-Samuel-N-Kamin/dp/0201068249">book on Programming Languages</a>. Lisp held an enormous influence in the development and conception of the first R implementation as documented by Ross Ihaka (the creator of R) many times:</li></ul><ol><li><a href="https://www.stat.auckland.ac.nz/~ihaka/downloads/Interface98.pdf">R : Past and Future History</a></li><li><a href="https://www.stat.auckland.ac.nz/~ihaka/downloads/Compstat-2008.pdf">Back to the Future: Lisp as a Base for a Statistical Computing System</a></li><li><a href="https://www.stat.auckland.ac.nz/~ihaka/downloads/R-paper.pdf">R: A Language for Data Analysis and Graphics</a></li></ol><ul><li>Julia development was heavily inspired by the same Lisp dialect that inspired R. That influence was so big, that the language developers decided to write some parts of the language pipeline in it. The Julia parser is written entirely in Scheme and it’s evaluated using a Lisp dialect written by one of the language designers (femtolisp).</li><li>Another language that’s worth mentioning is Lush, a scientific object-oriented programming language designed to prototype numerical analysis, computer vision and machine learning programs. It was designed and implemented by <a href="https://www.youtube.com/watch?v=Gwad1cWMcC0&amp;t=234s">Yann LeCun</a>, the man behind the introduction of <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q">Convolutional Neural Networks to Computer Vision</a> (along with <a href="http://www.cs.princeton.edu/courses/archive/spr08/cos598B/Readings/Fukushima1980.pdf">Kunihiko Fukushima</a>), and the current director of Facebook’s AI lab.</li></ul><h3>If Lisp if so great, Why TensorFlow’s main language isn’t Lisp?</h3><p>Most of the programs mentioned earlier made heavy use of symbolic manipulation. As mentioned by <a href="https://medium.com/u/1928cbd0e69c">Carlos E. Perez</a> in his post <a href="https://medium.com/intuitionmachine/the-many-tribes-problem-of-artificial-intelligence-ai-1300faba5b60#.svtdwt6tl"><em>The Many Tribes of Artificial Intelligence</em></a>, before ML and the Neural Network boom, there were symbolic based approaches to AI that combined symbolic manipulation of some elements, following a collection of rules that were modeled with the purpose to encapsulate the behavior of an intelligent system. The problem those days was not the efficient computation of numerical problems, but the manipulation and synthesis of symbols.</p><p>Just as C, C++, and Fortran shine in numerical computation where performance matters the most, Lisp shines in symbolic manipulation. One of Lisp’s greatest strengths is being able to handle efficiently symbols and lists<strong>.</strong></p><p>Lisp is not a perfect language, it has many flaws (lots of dialects, lack of well-known libraries, weird syntax that does not contribute to attract people in, dynamic typing, etc.), but it was a well-suited tool for the problems AI pioneers were trying to tackle at those days, just the same way C/C++, or Fortran are a perfect choice to implement the underpins of a Deep Learning system (TensorFlow is implemented both in C++ and Python). There’s not a single Swiss army knife programming language, we do need to pick a language that suits the most the particular task we’re approaching.</p><h3>Exploring AI with Lisp</h3><p>The whole idea of this series is to use Lisp, more specifically, its dialect Scheme to explore Artificial Intelligence (AI is much more than programming, and AI programming is much more than Lisp) related ideas. The goal is to learn together about classical AI concepts such as general problem solving, text generation, symbolic mathematics problems, knowledge representation, expert systems, search, NLP, logical and stochastic reasoning, game playing, and even “<a href="http://cs.stanford.edu/people/eroberts/courses/soco/projects/neural-networks/History/history1.html">contemporary</a>” stuff such as neural networks using the Scheme programming language to express those ideas.</p><p>Let’s begin our journey exploring Artificial Intelligence using Lisp. Your homework for the next post in the series is to install <a href="https://www.gnu.org/software/mit-scheme/">MIT-Scheme</a> on your machine.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*KNyXCTXJ6TDC6-AYhrN2Fw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a48c7385a913" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/the-lisp-approach-to-ai-part-1-a48c7385a913">The Lisp approach to AI (Part 1)</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My first experience with deep reinforcement learning]]></title>
            <link>https://medium.com/ai-society/my-first-experience-with-deep-reinforcement-learning-1743594f0361?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/1743594f0361</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[pacman]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[reinforcement-learning]]></category>
            <dc:creator><![CDATA[Diego Montoya Sefair]]></dc:creator>
            <pubDate>Tue, 21 Feb 2017 17:10:04 GMT</pubDate>
            <atom:updated>2018-09-23T03:27:53.054Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/637/1*D7JNcbvhP5UOR6_Ul-WJaw.gif" /><figcaption>Image from <a href="http://ai.berkeley.edu">http://ai.berkeley.edu</a></figcaption></figure><p><em>Note: This article assumes previous knowledge on the basics behind neural networks and Q-learning</em></p><p>About six months ago I saw myself in the need of deciding a topic for my undergraduate thesis project. Since there wasn’t much of AI in my major’s curriculum I chose to do research in that field to gain some knowledge. Now, I had to decide which AI subtopic I wanted to work on and it quickly became clear to me which one it should be.</p><p>I have always been fascinated by neural networks and their ability to learn to approximate any function at all. I have always thought that this is an absolutely remarkable feature since many (if not all) problems can be modeled as a function (i.e. something that takes some input, does some processing, and produces some output). It seems to me that, while we are still far from getting there, neural networks could play a very important role in the path toward the ultimate goal of reaching a general AI.</p><p>On the other side, in the last years a small company called DeepMind — now owned by Google — had shown great advances in reinforcement learning, and specifically what it is calling <em>deep</em> reinforcement learning (i.e. combining neural networks with reinforcement learning). In the case of Q-learning the principle behind this is that since neural networks are very good function approximators then, why not use them to approximate the Q-function? Deep learning with Q-learning is a very cool concept since other techniques that were used before to approximate the Q-function quickly became unfeasible once the state representation grew in dimensionality. Using the described technique enabled DeepMind to make an algorithm capable of playing many Atari games better than professional human players while not explicitly coding the logic and rules of each game [1]. In other words, the algorithm learned by itself what it was best to do by just looking at the pixels of the game, the score, and given the ability to choose an action (i.e. manipulate the controls of the game) like any human player would be able to.</p><p>But more than this, reinforcement learning is another of the fascinating sides of machine learning since it resembles the way we humans learn. Everything we do in life gets us a reward in return, be it positive or negative. Doing a good job will get us the approval of our colleagues, our boss, money, or even a smile from who we benefited with the job. Those things <em>feel</em> good, our brains release dopamine so we want to do them again, a positive reward. But getting into a car crash doesn’t feel good, so the next time we will try to be more careful since we don’t want that to happen again. We want to maximize our rewards, we <em>learn</em>,<em> </em>and we do it by reinforcement. With experience we get better at doing something, just as reinforcement learning algorithms do.</p><p>That said, with both deep learning and reinforcement learning we can model a huge variety of the problems we as humans face every day, and this is what makes them very interesting. These techniques are what power systems like autonomous cars for example. Could they be <em>the </em>answer to achieving a general AI? Only time will tell, but they are certainly getting us to interesting things.</p><h3>Now, for the project…</h3><p>From the results that DeepMind published in one of its papers, one of the graphs looked like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/478/0*AYmBDq3Yyojhm6ap." /><figcaption>Comparison of DeepMind&#39;s DQN with the best reinforcement learning algorithms in the literature [1]</figcaption></figure><p>The above graph shows how DeepMind’s algorithm performed with respect to “the best reinforcement learning methods in the literature”. However, the interesting part is the line in the middle which shows how the algorithm performed in comparison to professional human players. The performance of the algorithms were normalized with respect to the performance of the human players (100% level). As you can see the performance of the algorithm with games like Ms. PacMan was really low. They don’t specifically mention the reason behind this but it seems to be related to the relatively long-term planning that the game requires, combined with the fact that Q-learning as it is commonly implemented is known to have these kinds of temporal limitations.</p><p>After reading the publication some questions came to me from the approach that DeepMind was having, specifically with the fact that they were were using the very pixels of the game as the state representation. This is remarkable since it is the same information that our brains receive as input, and it is also very good in the sense that it generalizes very well for other games. However, I had the doubt about what would happen if we gave the agent more “calculated” information, i.e. a state representation composed of information other than the pixels. What kind of impact did the state representation have in the learning process and result? This is when I decided to work with a game (PacMan), write a deep Q-learning agent in Python and look for answers.</p><p>To clarify, I wasn’t pretending to improve the performance that DeepMind achieved in the games below the human line. What I’m trying to show is how the questions that turned into my senior thesis came to be, and it was that “human-level” line that sparked those questions in me.</p><p>Now, finding what was the impact of changing the state representation was the main objective of the research at first, however, one more question arose during the process that I thought was worth investigating, namely: how did (or if) both, varying the topology of the neural network and having a persisted experience replay file before beginning training affected the learning process and the result of the algorithm.</p><p>To expand a little on the second part, experience replay is one of the tricks that has been discovered to be one of the most important optimizations to make that will enable the neural network to learn in a reasonable time (or even converge). This is because this technique breaks the concept of continuity between any two transitions while giving the network a chance to also reinforce its knowledge of previous experiences more efficiently. What I wanted to know was, given that experience replay is helpful, could it be also helpful to have a large pre-populated (persisted) experience replay memory right from the start? Could this help the algorithm to get to convergence faster than having to populate the replay memory each time from zero?</p><p>At this point I would be telling you much of what is written in the <a href="https://github.com/diegomontoyas/DeepLearning-PacMan/blob/master/Thesis%20Document.pdf">report</a> [2], so I would encourage you to read the paper if you find the research interesting. In a nutshell though, I discovered that all three aspects affect the learning process considerably. Firstly, I could see that the state representation should be as simple as possible (but complete) since simpler state representations are considerably easier to train on. Secondly, I found that having a pre-calculated, large, persisted replay memory has the potential to improve learning speed notably but one should take some precautions so having one does not bias what the agent learns (e.g. when past experiences greatly outnumber new experiences). Lastly, I could also see that changing the topology of the neural network does have an important impact in the learning result. The hypothesis that I could extract is that larger networks take considerably longer to train and were not able to train on time, so one should choose an appropriate topology (i.e. one that is complex enough to be able to approximate the Q-function for the particular problem, but not more complex than that).</p><h3>The experience</h3><p>I had a lot of fun with this project, but what’s more, I learned a lot. Now, from my experience, I think reinforcement learning has the potential to be very powerful, especially in combination with neural networks. However, this combination is what can make the process a little frustrating if you are expecting your model to learn in a matter of a couple of hours and then win every game you play against it. The reality is that neural networks, while very powerful, can require very fine tuning to actually learn something. But more than this, you have to be very careful, for example, with the parameters you choose, the topology, and the activation functions as some of these aspects can represent the difference between a neural network that does a very good job in a reasonable time and a neural network that doesn’t learn anything. In summary, getting a good model can require many optimizations and dedication, however when you achieve one the results can be very surprising (as groups like DeepMind have shown us).</p><p>Another aspect that can get difficult to handle is the computational complexity of training a model of this kind. If you have a good GPU sitting on your desk you can improve training time by quite<em> a lot, </em>since neural networks are really benefitted by massive parallelism. However, not many have a GPU to spare, so testing can become a little tedious as each training session can take several hours or even days depending on the problem.</p><p>To sum up, you will learn a lot from doing different experiments. Nonetheless, if you plan to get immersed in deep reinforcement learning (puns not initially intended) I would recommend to first have a good understanding of neural networks, some patience, and a good machine / GPU could also be very helpful depending on the problem.</p><h3>Finally, why PacMan?</h3><p>Since it’s a game I really like — I mean, who doesn’t?</p><h4><strong>References</strong></h4><p>[1] <a href="https://storage.googleapis.com/deepmind-media/dqn/DQNNaturePaper.pdf">V. Mnih <em>et al.</em>, “Human-level control through deep reinforcement learning,” <em>Nature</em>, vol. 518, no. 7540, pp. 529–533, Feb. 2015</a></p><p>[2] <a href="https://goo.gl/PT5a1m">D. Montoya, “Exploring how different state representations and configurations affect the learning process and outcome of deep Q-learning algorithms,” Universidad de los Andes, 2016.</a></p><h4>Interesting links</h4><ul><li><strong>Great how-to on deep reinforcement learning: </strong><a href="https://www.nervanasys.com/demystifying-deep-reinforcement-learning/">T. Matiisen, “Guest Post (Part I): Demystifying Deep Reinforcement Learning,” <em>Nervana</em></a></li><li><strong>Great book on neural networks: </strong><a href="http://neuralnetworksanddeeplearning.com">M. A. Nielsen, <em>Neural Networks and Deep Learning</em>.</a></li><li><strong><em>(Video)</em> </strong><a href="https://www.youtube.com/watch?v=V1eYniJ0Rnk"><strong>DeepMind&#39;s algorithm playing Atari Breakout</strong></a></li><li><strong><em>(Video)</em> </strong><a href="https://www.youtube.com/watch?v=xN1d3qHMIEQ&amp;t=15s"><strong>A short introduction to DeepMind</strong></a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1743594f0361" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/my-first-experience-with-deep-reinforcement-learning-1743594f0361">My first experience with deep reinforcement learning</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hello, Gradient Descent]]></title>
            <link>https://medium.com/ai-society/hello-gradient-descent-ef74434bdfa5?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/ef74434bdfa5</guid>
            <category><![CDATA[gradient-descent]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Juan Camilo Bages Prada]]></dc:creator>
            <pubDate>Thu, 16 Feb 2017 21:00:13 GMT</pubDate>
            <atom:updated>2017-02-19T16:47:54.363Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/703/1*t4aYsxpCqz2eymJ4zkUS9Q.png" /><figcaption>Gradient Descent. Image taken from <a href="http://blog.datumbox.com/wp-content/uploads/2013/10/gradient-descent.png">http://blog.datumbox.com/wp-content/uploads/2013/10/gradient-descent.png</a></figcaption></figure><p>Hi there! This article is part of a series called <strong><em>“Hello, &lt;algorithm&gt;”</em></strong>. In this series we will give some insights about how different AI algorithms work, and we will have fun by implementing them. Today we are gonna talk about <em>Gradient Descent</em>, a simple yet powerful optimization algorithm for finding the (local) minimum of a given function.</p><h3>Getting some insight</h3><p>The inspiration behind <em>Gradient Descent</em> comes directly from calculus. Basically, it states that if we’ve a <a href="https://en.wikipedia.org/wiki/Differentiable_function"><em>differentiable function</em></a>, the fastest way to decrease is by taking steps proportional to the opposite direction of the function’s <a href="https://en.wikipedia.org/wiki/Gradient"><em>gradient</em></a> at any given point. This happens because the gradient points to the steepest direction of the function’s generated surface at the current point.</p><p>In other words, think about the function’s surface as a mountain that you are hiking down. You know that your goal is to reach the bottom, and you may think that the fastest way to accomplish this is by proceeding through the path that makes you descend the most. In this case, that path points to the opposite of the steepest mountain direction upwards.</p><p>With this in mind, we can repeatedly perform these steps in the appropriate direction and we should eventually converge into the (local) minimum. Following our analogy, this is the equivalent of arriving to the bottom of our mountain.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DLtfEc-igaDCIdiqqsJvCg.jpeg" /><figcaption>Hiking down a mountain. Image taken from <a href="https://raftrek.com/wp-content/uploads/2015/10/Hiking-down-mountain-ridge.jpg">https://raftrek.com/wp-content/uploads/2015/10/Hiking-down-mountain-ridge.jpg</a></figcaption></figure><h3>Calculating the next step</h3><p>So we’ve been talking about taking steps in the right direction, but how can we calculate them? Well, the answer is in the following equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/422/1*I57tMkWx3tjn8byb46KNzw.png" /><figcaption>Gradient Descent Step.</figcaption></figure><p>This formula needs some clarification. Let’s say we are currently in a position Θ⁰, and we want to get to a position Θ¹. As we said previously, every step is gonna be proportional to the opposite direction of the function’s gradient at any given point. So this definition of step for a given function <em>J</em>(Θ) will be equal to −α∇<em>J</em>(Θ).</p><h4>Why minus and not plus?</h4><p>Remember that we take steps in the <strong><em>opposite</em></strong> direction of the gradient. So in order to achieve this, we subtract the step value to our current position.</p><h4>Okay that sounds good, but what do you mean with α?</h4><p>The symbol α is called the <strong><em>Learning Rate</em></strong>. This is a value that will force us to take little steps so we don’t overshoot the (local) minimum. A bad choice for α would trap us into one of the following possibilities:</p><ul><li>If α is too small, our learning algorithm is gonna take too much time to converge.</li><li>If α is too large, our learning algorithm might overshoot the bottom, and even diverge because of an infinite loop.</li></ul><p>Take a look at the following examples to see what happens when we make a bad choice for the <strong><em>Learning Rate</em></strong> α:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/396/1*_EEOl5h56T2ZcXzH-Egahg.png" /><figcaption>Bad choices for Learning Rate α. Image taken from <a href="https://storage.googleapis.com/supplemental_media/udacityu/315142919/Gradient%20Descent.pdf">https://storage.googleapis.com/supplemental_media/udacityu/315142919/Gradient%20Descent.pdf</a></figcaption></figure><h3>Calculating the gradient</h3><p>The gradient of a function <em>J</em>(Θ) (denoted by ∇<em>J</em>(Θ)) is a vector of <a href="https://en.wikipedia.org/wiki/Partial_derivative"><em>partial derivatives</em></a> with respect to each dimension or parameter Θᵢ. Notational details are given in the equation below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*7c0cMSJuWIR5dF5Yjl8HAg.png" /></figure><h4>A little example</h4><p>To make this definition of gradient clearer, let’s calculate the gradient of the following function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/436/1*CFdMNnBclMdb6b45V0M6Qw.png" /></figure><p>As we can see, this function contains three parameters or dimensions. Thus the appropriate way to proceed is by calculating the partial derivative with respect to each param:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/185/1*zgYOw6HzRpWolp07MQClew.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/118/1*nJuMaBDI5tqrbdNNIRth_w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/139/1*pLhSBUbmVuFolXs-KS2xdg.png" /></figure><p>Now we can group those values and that will give us the function’s gradient:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/458/1*PQfFqwUakL6fPji_Ojywgw.png" /></figure><p>And that’s it! With this vector, we can get the steepest direction at any given point simply by replacing each parameter with its corresponding value:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/366/1*9ZumvJktG7SdEIDTIsqFEQ.png" /></figure><h3>Hacking Time</h3><p>And now, for the grand finale, we will go through a full example and we will code our own algorithm for gradient descent.</p><h4>Defining the example</h4><p>In this section, we will apply <a href="https://en.wikipedia.org/wiki/Linear_regression"><em>linear regression</em></a> in order to find the correct function approximation for a given set of points in a plane. The set of points we are trying to predict looks as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*iiR9sSTJOhmlAE66M3dtvQ.png" /></figure><p>As it’s common, the choice for <em>J</em>(Θ) will be the <a href="https://en.wikipedia.org/wiki/Least_squares"><em>least-squares cost function</em></a> for measuring the error of an approximation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/374/1*MFp1f1UdkvO1lSHhnTsK0Q.png" /></figure><p>In the equation above:</p><ul><li><em>m</em> is the amount of points in the set.</li><li>½ is a convenient constant that will cancel out when we take the gradient of <em>J</em>(Θ). This makes maths nicer and doesn’t affect the result.</li><li><em>y</em> is the real value of the y-coordinate for the ith point.</li><li><em>h</em> is our function approximation. It will give us the predicted y-coordinate for the ith-point using parameters Θ and input <em>x</em>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/259/1*iZe7mozC3yasxuuFaVnP7A.png" /></figure><p>Finally, before beginning to code let’s calculate the gradient vector of our function. You can see that as we’ve got two parameters for Θ, we will need to calculate two partial derivatives.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/267/1*scOKHjLVFgzqZHksl_Ou1w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/338/1*gcwz2ije9XOJlv3DiEc3-w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/377/1*CVXuy5xLmTMrLYuFYlbsRg.png" /></figure><p>Okay, time to proceed. It’s important to mention that our implementation will be in a vectorized form. This means that we will transform all the formulas mentioned above into matrices operations. The advantages of this implementation are that code will be more concise, and with this our computer can take advantage of advanced underlying matrix algorithms.</p><p>To work with the vectorized form, we need to add a dummy variable <em>x</em>0 to each point with a value equal to 1. The reason for this is that when we perform matrix multiplication, the intercept parameter Θ0 will be multiplied with that 1 and it will maintain its value as the defined equations establishes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*9sKFS8HNp_V9P5TGaHkzUQ.png" /></figure><p>Below you can see the vectorized form of the error function <em>J</em>(Θ) and its gradient ∇<em>J</em>(Θ):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/409/1*QjFvBrbg_hCGXHTh1F5q5A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/316/1*Pfcs1DaqUNobMMu117UW-Q.png" /></figure><h4>Coding time</h4><p>With every function defined, we can proceed to code our algorithm. The first thing we should do is to declare the points dataset and the Learning Rate α.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7b76e549ff9ea82e518878f950711e0c/href">https://medium.com/media/7b76e549ff9ea82e518878f950711e0c/href</a></iframe><p>Now we can proceed by defining the error function <em>J</em>(Θ) and its gradient ∇<em>J</em>(Θ). Remember everything will be defined in a vectorized way.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8279417c1c1efbbce632ceae8b2f2fdf/href">https://medium.com/media/8279417c1c1efbbce632ceae8b2f2fdf/href</a></iframe><p>This is the heart of our code. Here we will perform steps that update Θ until we reach the (local) minimum. That is, when all the values of the gradient vector are less than or equal to some specified threshold (1/e⁵ in this case).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b350db4231e90b77e74edf8ff8fc7cd5/href">https://medium.com/media/b350db4231e90b77e74edf8ff8fc7cd5/href</a></iframe><p>And we’re done! You can see the complete code in the snippet below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2ac5730d00831004b5750c865432582/href">https://medium.com/media/b2ac5730d00831004b5750c865432582/href</a></iframe><p>Now we can run our algorithm and it will give us the optimal values for Θ that minimize the error. Below you can see the answers I obtained after running it on my computer:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/340/1*tWI5XrbzIAa6Us-itH8XfQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/259/1*RlZDkQua8T34J3MSzHTtAQ.png" /></figure><p>This is the scatter plot we showed before with the line corresponding to the optimal Θ:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*VWpe23HxOqup7sVMMj6LbA.png" /></figure><p>Well, we’ve finished our code and our article. I hope that you’d learned one thing or two about Gradient Descent, and more importantly, that you are now really excited about learning by taking a look at the further reading list.</p><h3>Further reading</h3><ul><li><a href="https://storage.googleapis.com/supplemental_media/udacityu/315142919/Gradient%20Descent.pdf">Gradient Descent lecture notes</a> from <a href="https://www.udacity.com/course/machine-learning--ud262">UD262 Udacity Georgia Tech ML Course</a>. I was inspired a lot by this article, and based mine on it.</li></ul><iframe src="https://drive.google.com/viewerng/viewer?url=https%3A//storage.googleapis.com/supplemental_media/udacityu/315142919/Gradient%2520Descent.pdf&amp;embedded=true" width="600" height="780" frameborder="0" scrolling="no"><a href="https://medium.com/media/8eec4dcaaa1e4e5d09cf53dcc67bfbbd/href">https://medium.com/media/8eec4dcaaa1e4e5d09cf53dcc67bfbbd/href</a></iframe><ul><li><a href="http://cs229.stanford.edu/notes/cs229-notes1.pdf">Supervised Learning lecture notes</a> from <a href="http://cs229.stanford.edu/">CS229 Stanford University ML Course</a>. This article helped me a lot to understand Linear Regression.</li></ul><iframe src="https://drive.google.com/viewerng/viewer?url=http%3A//cs229.stanford.edu/notes/cs229-notes1.pdf&amp;embedded=true" width="600" height="780" frameborder="0" scrolling="no"><a href="https://medium.com/media/750a0ffe68d915bb06a712a9207a4918/href">https://medium.com/media/750a0ffe68d915bb06a712a9207a4918/href</a></iframe><ul><li><a href="https://arxiv.org/pdf/1609.04747.pdf">An overview of gradient descent optimization algorithms</a>. This paper provides you with a lot of information about implementing production-ready Gradient Descent algorithms.</li></ul><iframe src="https://drive.google.com/viewerng/viewer?url=https%3A//arxiv.org/pdf/1609.04747.pdf&amp;embedded=true" width="600" height="780" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c681443f59cfbd2aa51a6830a64e3f5/href">https://medium.com/media/3c681443f59cfbd2aa51a6830a64e3f5/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ef74434bdfa5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/hello-gradient-descent-ef74434bdfa5">Hello, Gradient Descent</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[An Introductory Recommender Systems Tutorial]]></title>
            <link>https://medium.com/ai-society/a-concise-recommender-systems-tutorial-fa40d5a9c0fa?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/fa40d5a9c0fa</guid>
            <category><![CDATA[recommender-systems]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Sebastian Valencia]]></dc:creator>
            <pubDate>Fri, 10 Feb 2017 02:53:40 GMT</pubDate>
            <atom:updated>2017-02-13T15:35:09.723Z</atom:updated>
            <content:encoded><![CDATA[<p>A Recommender System predicts the likelihood that a user would prefer an item. Based on previous user interaction with the data source that the system takes the information from (besides the data from other users, or historical trends), the system is capable of recommending an item to a user. Think about the fact that Amazon recommends you books that they think you could like; Amazon might be making effective use of a Recommender System behind the curtains. This simple definition, allows us to think in a diverse set of applications where Recommender Systems might be useful. Applications such as documents, movies, music, romantic partners, or who to follow on Twitter, are pervasive and widely known in the world of Information Retrieval.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UEIb9b7VT0u5NMBeZajxjg.png" /><figcaption>SICP is a book about Scheme, PLT, Computer Science, etc. Customers that bought it, also bought (an statistical sample) books about Scheme and Functional Programming. Apparently, Amazon makes use of “similar” users to recommend me items.</figcaption></figure><p>Such amazing applications, carry a huge amount of theory behind them. While theory can be a little bit intimidating and dry, basic understanding of data structures, a programming language, and a little bit of abstraction is all you need to understand the basics of recommender systems.</p><p>In this tutorial, We will help you gain a basic understanding on collaborative based Recommender Systems, by building the most basic Recommender System out there. We hope that this tutorial motivates you to find out more about Recommender Systems, both in theory and practice. The prerequisites to reading this tutorial are knowledge of a programming language (we’ll use Python, but if you know how do Hash Maps and List works, you’re in good shape), and a little bit of high-school algebra. You do not need to have prior exposure to Recommender Systems.</p><p>This tutorial makes use of a class of RS (Recommender System) algorithm called <strong>collaborative filtering</strong>. A collaborative filtering algorithm works by finding a set of people (assuming persons are the only client or user of a RS) with preferences or tastes similar to the target user. Using this smaller set of “similar” people, it constructs a ranked list of suggestions. There are several ways to measure the similarity of two people. It’s important to highlight that we’re not going to use attributes or descriptors of an item to recommend it, we’re just using the tastes or preferences over that item.</p><p>Assuming that our users are people, and our items are simply that: items, we need to organize our data to ease the processing step. We’re assuming that the data fits in memory, and that you can organize the data as follows.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fTiGcm3TJ5exvoiKo9rWdg.png" /></figure><p>The data structure that we are going to use, consists of people pointing to a dictionary whose keys are the items, and values are the numeric preference of each person on this item. If a person has never ranked the item, <em>C[i, j]</em>, is null. In this notation <em>C[i, j]</em> represents the numeric rating of <em>Person j</em>, over the <em>Item i</em>. No matter how the rating is expressed, we need to convert them to numeric values. A sample data structure for our working example is the following definition of a Python dictionary, it includes some ratings of people (<strong><em>if you wonder who these folks are, please click over them. We computer scientists owe much to them</em></strong>) to computer science related books. The whole code for this toy Recommender System is on <a href="https://github.com/ai-society/ai-society.github.io/blob/master/src/2016-12-19-Collaborative-Filtering/main.py"><em>Github</em></a>.</p><pre>data = {<br> ‘<a href="https://en.wikipedia.org/wiki/Alan_Perlis"><strong><em>Alan Perlis</em></strong></a>’: { <br> ‘Artificial intelligence’: 1.46, <br> ‘Systems programming’: 5.0, <br> ‘Software engineering’: 3.34, <br> ‘Databases’: 2.32<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Marvin_Minsky"><strong><em>Marvin Minsky</em></strong></a>’: { <br> ‘Artificial intelligence’: 5.0, <br> ‘Systems programming’: 2.54,<br> ‘Computation’: 4.32, <br> ‘Algorithms’: 2.76<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)"><strong><em>John McCarthy</em></strong></a>’: { <br> ‘Artificial intelligence’: 5.0, <br> ‘Programming language theory’: 4.72, <br> ‘Systems programming’: 3.25, <br> ‘Concurrency’: 3.61, <br> ‘Formal methods’: 3.58,<br> ‘Computation’: 3.23, <br> ‘Algorithms’: 3.03 <br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Edsger_W._Dijkstra"><strong><em>Edsger Dijkstra</em></strong></a>’: { <br> ‘Programming language theory’: 4.34, <br> ‘Systems programming’: 4.52,<br> ‘Software engineering’: 4.04, <br> ‘Concurrency’: 3.97,<br> ‘Formal methods’: 5.0, <br> ‘Algorithms’: 4.92 <br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Donald_Knuth"><strong><em>Donald Knuth</em></strong></a>’: { <br> ‘Programming language theory’: 4.33, <br> ‘Systems programming’: 3.57,<br> ‘Computation’: 4.39, <br> ‘Algorithms’: 5.0 <br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/John_Backus"><strong><em>John Backus</em></strong></a>’: { <br> ‘Programming language theory’: 4.58, <br> ‘Systems programming’: 4.43,<br> ‘Software engineering’: 4.38, <br> ‘Formal methods’: 2.42, <br> ‘Databases’: 2.80 <br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Robert_W._Floyd"><strong><em>Robert Floyd</em></strong></a>’: { <br> ‘Programming language theory’: 4.24, <br> ‘Systems programming’: 2.17,<br> ‘Concurrency’: 2.92, <br> ‘Formal methods’: 5.0, <br> ‘Computation’: 3.18, <br> ‘Algorithms’: 5.0 <br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Tony_Hoare"><strong><em>Tony Hoare</em></strong></a>’: { <br> ‘Programming language theory’: 4.64, <br> ‘Systems programming’: 4.38,<br> ‘Software engineering’: 3.62, <br> ‘Concurrency’: 4.88,<br> ‘Formal methods’: 4.72, <br> ‘Algorithms’: 4.38<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Edgar_F._Codd"><strong><em>Edgar Codd</em></strong></a>’: { <br> ‘Systems programming’: 4.60, <br> ‘Software engineering’: 3.54,<br> ‘Concurrency’: 4.28, <br> ‘Formal methods’: 1.53, <br> ‘Databases’: 5.0<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Dennis_Ritchie"><strong><em>Dennis Ritchie</em></strong></a>’: { <br> ‘Programming language theory’: 3.45, <br> ‘Systems programming’: 5.0,<br> ‘Software engineering’: 4.83,<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Niklaus_Wirth"><strong><em>Niklaus Wirth</em></strong></a>’: { <br> ‘Programming language theory’: 4.23, <br> ‘Systems programming’: 4.22,<br> ‘Software engineering’: 4.74, <br> ‘Formal methods’: 3.83, <br> ‘Algorithms’: 3.95<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Robin_Milner"><strong><em>Robin Milner</em></strong></a>’: { <br> ‘Programming language theory’: 5.0, <br> ‘Systems programming’: 1.66,<br> ‘Concurrency’: 4.62, <br> ‘Formal methods’: 3.94,<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Leslie_Lamport"><strong><em>Leslie Lamport</em></strong></a>’: { <br> ‘Programming language theory’: 1.5, <br> ‘Systems programming’: 2.76,<br> ‘Software engineering’: 3.76, <br> ‘Concurrency’: 5.0,<br> ‘Formal methods’: 4.93, <br> ‘Algorithms’: 4.63<br> },</pre><pre>‘<a href="https://en.wikipedia.org/wiki/Michael_Stonebraker"><strong><em>Michael Stonebraker</em></strong></a>’: { <br> ‘Systems programming’: 4.67, <br> ‘Software engineering’: 3.86,<br> ‘Concurrency’: 4.14, <br> ‘Databases’: 5.0,<br> },<br>}</pre><p>In this example, <em>Leslie Lampor</em>t, rates the book <em>Software engineering</em> with <em>3.76</em>, while <em>Robin Milner</em>, rates the <em>Programming language theory</em> book with <em>5.0</em>. A simple problem that we might want to solve using this dataset and a recommender system, is how likely <em>Marvin Minsky</em> is to like the title <em>Programming language theory</em>. In order to solve this kind of problems, we do need a way to measure how similar people are based on their rankings. A naive but popular approach is to compare every pair and find a similarity score; now the problem is to find an adequate similarity score. The most common approaches to the similarity problem, are score by <strong>Euclidean Distance</strong>, and using the <strong>Pearson Correlation Coefficient</strong>; both terms are deeply related to statistics and linear algebra.</p><h3>Euclidean distance score</h3><p>The Euclidean distance between two points is the length of the line segments connecting them. Our Euclidean space in this particular case is the positive portion of the plane where the axes are the ranked items and the points represent the scores that a particular person gives to both items. Two people belong to a certain preference space if and only if, they have ranked the two items that defines the preference space. So we define a preference space for each pair of distinct items, and the points in this preference space, are given by the people that ranked the two items. To visualize this idea, we consider the preference space, defined by the items <em>Systems programming</em>, and <em>Programming language theory</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_Qr1aDmv15YOYEM6Lp8ljQ.png" /><figcaption>This plot shows the users regarding to their tastes on both <strong>Systems Programming</strong> and <strong>Programming Language Theory. </strong>We can recognize similar users by looking to the cluster that they belongs. For example, Robert Floyd is not similar to Leslie Lamport taking into account those two items.</figcaption></figure><p>The figure shows the people that have ranked both items in a preference space defined by those items, and the scores given by the people to each item independently. In the chart, <em>Leslie Lamport</em> appears that low since he has ranked <em>Systems programming</em> with <em>2.76</em> and <em>Programming language theory</em> with <em>1.5</em>. We can clearly see that regarding this items, <em>John McCarthy</em>, and <em>Tony Hoare</em> are pretty similar, while <em>Robin Milner</em> and <em>Bob Floyd</em> are slightly different; <em>Dennis Ritchie</em> and <em>Leslie Lamport</em> have little in common (regarding those items). We can now proceed to define the distance between two people in the preference space as we define the distance between a pair of points in the plane:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/766/1*aY5nL4wQyEoGni9urD4ihg.png" /></figure><p>If <em>d(Person[i], Person[j])</em> is small, then <em>Person[i]</em> is similar to <em>Person[j]</em>. Since we do want a metric that tells us how similar two people are; we do need a number (this number is proportional to the similarity of <em>Person[i]</em> and <em>Person[j]</em>). To achieve that, we are required to take a normalized value based on <em>d(Person[i], Person[j])</em>. Our final similarity metric based on <strong>Euclidean distance</strong> is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/538/1*8givRoS1qpaKVzzbHtr7lw.png" /></figure><p>This formula is designed thinking in division by zero and the proportionality that we need.</p><p>The closest to one this metric is, the closest <em>Person[i]</em> is to <em>Person[j]</em> by similarity. If we extend this idea to the set of ranked items in common for two people, we can design an algorithm that tells us the similarity of a pair based on their tastes. We just need the common items between two people and get this metric for every common distinct pair. The following algorithm, computes the <strong>Euclidean Similarity</strong> between two people based on their common tastes. Those tastes are retrieved from our main data structure stored in our <em>data</em> variable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*46yGybYlCiQAKxPr_c7PYg.png" /><figcaption>The implementation in Python of the <strong>Euclidean Distance</strong> similarity measure, it’s directly inspired by the formula we just found. The whole code for this toy Recommender System is on <a href="https://github.com/ai-society/ai-society.github.io/blob/master/src/2016-12-19-Collaborative-Filtering/main.py"><em>Github</em></a><em>.</em></figcaption></figure><p>Once we have the data and the algorithm, we can analyze it. The major flaw of this algorithm, and in general of Euclidean distance based comparisons, is that if the whole distribution of rankings from a person tends to be higher than those from other person (a person is inclined to give higher scores than the other), this metric would classify them as dissimilar without regard the correlation between two people. There can still be a perfect correlation if the differences between their rankings are consistent. While a clever algorithm would classify them as similar, our <em>Euclidean</em> based algorithm, will say that two people are very different because one is consistently harsher than the other one. That behavior depends on the application of the recommender system (thus far, we have not created a recommender system; we’re just computing similarity).</p><h3>Pearson correlation coefficient</h3><p>In statistics, the Pearson correlation coefficient is a measure of the linear dependence or correlation between two variables X and Y. It has a value between <em>+1</em> and <em>−1</em> inclusive, where <em>1</em> is total positive linear correlation, 0 is no linear correlation, and <em>−1</em> is total negative linear correlation. In the case of recommender systems, we’re supposed to figure out how related two people are based on the items they both have ranked. The <strong>Pearson Correlation Coefficient</strong> (PCC) is better understood in this case as a measure of the slope of two datasets related by a single line (we’re not taking into account dimensions). The derivation and the formula itself are harder to find and understand, but by using this method, we’re eliminating the weight of <em>harshness</em> while measuring the relation between two people.</p><p>The PCC algorithm, requires two datasets as inputs, those datasets don’t come from how people ranked the items, but they come from the common ranked items between two people. PCC helps us to find the similarity of a pair of users. Rather than considering the distance between the rankings on two products, we can consider the correlation between the users ratings.</p><p>To clarify the concept of correlation, we include a new dataset and some charts. The dataset, includes few ratings of some remarkable computer scientists to some CS books.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dgcj_5iRfdXAVWZJsfCRiA.png" /><figcaption>A sample dataset to instruct you on this similarity measure. How some famous computer scientists have rated those famous CS books.</figcaption></figure><p>In order to understand how related are two people, we proceed by plotting their preferences (treating each book as a point, whose coordinates are determined by the rating on this item by both users). Once we have that specific plot, we do need to find the best fit straight line over those points. Finding such a line, requires knowledge of linear regression, a topic that’s out of the scope of this tutorial. While finding the best fit straight line, is not as trivial as it seems, finding the PCC depends just on the data that we already have. This best fit line serves us to explain the concept.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OBNkkEsxw2EvgXqEZKJNGQ.png" /></figure><p>The plot shows the 2-dimensional space defined by the ratings of <em>Ullman</em> and <em>Carmack</em>, as well as the best fit straight line. The positive slope of the line, shows a positive correlation between those points, then, the PCC for <em>Ullman</em> and <em>Carmack</em> is positive.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gS0tis40bntInG0TgAfaqw.png" /></figure><p>The last plot, shows a negative correlation between <em>Navarro</em> and <em>Norvig</em>.</p><p>If we have one dataset <em>{x[1], x[2], …, x[n]}</em> containing <em>n</em> elements, and another dataset <em>{x[1], x[2], …, x[n]}</em> containing <em>n</em> elements, the formula for the sample PCC is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/632/1*a8hIGm_WcZUVAmCl1vymvA.png" /></figure><p>A little algebraic manipulation, yield us to the following formula</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/746/1*cjjU3RQhA3H7Y43NyDh3NA.png" /></figure><p>This formula, let us write a program to compute the PCC between two people.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1Bk06jNX9pbKqwNEzuuvQg.png" /><figcaption>The implementation in Python of the <strong>Pearson Correlation Coefficient</strong> similarity measure, it’s directly inspired by the formula we just found. The whole code for this toy Recommender System is on <a href="https://github.com/ai-society/ai-society.github.io/blob/master/src/2016-12-19-Collaborative-Filtering/main.py"><em>Github</em></a><em>.</em></figcaption></figure><p>Both similarity measures allow us to figure out how similar two people are. The logic behind a recommender system, is to measure everyone against a given person and find the closest people to that specific person, we can do that by taking a group of the people for whom the distance is small, or the similarity is high.</p><p>By using this approach, we’re trying to predict what’s going to be the rating if our person rates a group of products he has not rated yet. One of the most used approaches to this problem, is to take the ratings of all the other users and multiply how similar they are to the specific person by the rating that they gave to the product. If the product is very popular, and it has been rated by many people, it would have a greater weight, to normalize this behavior, we do need to divide that weight by the sum of all the similarities for the people that have rated the product. The following function implements this approach.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cq6qwJ18YzkL4PB6bHLOyA.png" /><figcaption>How to recommend items or retrieve similar people given an specific person, and a similarity measure. We’re using a higher order function to test the recommendations done by using any similarity measure function. The whole code for this toy Recommender System is on <a href="https://github.com/ai-society/ai-society.github.io/blob/master/src/2016-12-19-Collaborative-Filtering/main.py"><em>Github</em></a><em>.</em></figcaption></figure><p>Given a person included in the index (<em>data</em>), a bound (that is maximum number of items to recommend), and a function to measure the similarity between people (<em>euclidean_similarity</em>, or <em>pearson_similarity</em>), this function gives an estimate on how the person would rate the item according to how similar people rate the item. As an example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Jl7HsdigsG7dAjC3rZV25w.png" /></figure><p>While <em>Algorithms</em> and <em>Concurrency</em> are perfect topics to recommend to <em>Alan Perlis</em>, or at least that was what our algorithm found, we should keep <em>Marvin Minsky</em> far from the <em>Databases</em> item. There is a strange phenomenon here, depending on the similarity measure,<em> Marvin Minsky</em> seems to like a lot or dislike a little bit the <em>Programming language theory</em> and <em>Formal methods</em> items. By looking for the <em>scores</em> variable while inspecting the code if you call <em>recommend(“Marvin Minsky”, 5)</em>, you can tell that <em>Robin Milner</em> and <em>John McCarthy</em> are the closest to <em>Marvin Minsky</em>, while both <em>Robin Milner</em> and <em>John McCarthy</em> are very different from each other; and also <em>Robin Milner</em> tends to rate a little bit harsher than <em>John McCarthy</em>. That insight clearly taught us that we do need to compare both measures depending on the nature of our data, the election of <em>bound</em> also affects this kind of strange recommendations.</p><p>Data exploration, and wrangling comes as significant factors while implementing a production recommender system. The more data it can process, the better recommendations we can give our users. While recommender systems theory is much broader, recommender systems is a perfect canvas to explore machine learning, and data mining ideas, algorithms, etc. not only by the nature of the data, but because of the relative ease visualizing and comparing the results.</p><h3>Resources on Recommender Systems</h3><ul><li><a href="https://www.amazon.com/Recommender-Systems-Introduction-Dietmar-Jannach/dp/0521493366"><strong><em>Recommender Systems: An Introduction</em></strong></a><em>. </em>An academic reference whose first chapter explain with more detail and rigor the material discussed here. Besides math it includes design hints and practical usage of recommender systems. It’s the standard textbook on the topic.</li></ul><p><a href="https://www.amazon.com/Recommender-Systems-Introduction-Dietmar-Jannach/dp/0521493366">Recommender Systems: An Introduction</a></p><ul><li><a href="https://www.amazon.com/Programming-Collective-Intelligence-Building-Applications/dp/0596529325"><strong><em>Programming Collective Intelligence</em></strong></a>. Written by Toby Segaran. Its first chapter includes a math lightweight approach to this amazing topic. It includes an explanation on the two similarity measures explained here, and an approach to match items instead of users, it also includes “big” datasets to play with. The whole book explores machine learning related ideas using a programming-first approach.</li></ul><p><a href="https://www.amazon.com/Programming-Collective-Intelligence-Building-Applications/dp/0596529325">Programming Collective Intelligence: Building Smart Web 2.0 Applications</a></p><ul><li><a href="https://www.coursera.org/specializations/recommender-systems"><strong><em>Recommender Systems Specialization</em></strong></a>. A whole Coursera Specialization on the topic.</li></ul><p><a href="https://www.coursera.org/specializations/recommender-systems">Recommender Systems</a></p><h4><strong>The following links provide useful information on deployment of real recommender systems.</strong></h4><ul><li><a href="http://edlab.tc.columbia.edu/index.php?q=node/5781"><strong><em>How Recommendation System Works</em></strong></a>. A review of companies using recommender systems.</li></ul><p><a href="http://edlab.tc.columbia.edu/index.php?q=node/5781">How Recommendation System Works | EdLab</a></p><ul><li><a href="https://www.cs.umd.edu/~samir/498/Amazon-Recommendations.pdf"><strong><em>Amazon.com Recommendations</em></strong></a>. Item-to-Item Collaborative Filtering. A popular-science description of Amazon recommender system written by the engineer that was behind it.</li></ul><iframe src="https://drive.google.com/viewerng/viewer?url=https%3A//www.cs.umd.edu/%7Esamir/498/Amazon-Recommendations.pdf&amp;embedded=true" width="600" height="780" frameborder="0" scrolling="no"><a href="https://medium.com/media/f2197dc997f140d989909a4299b1e1b7/href">https://medium.com/media/f2197dc997f140d989909a4299b1e1b7/href</a></iframe><ul><li><a href="http://stackoverflow.com/questions/2323768/how-does-the-amazon-recommendation-feature-work"><strong><em>How does the Amazon Recommendation feature work?</em></strong></a> Some hints on recommender system design and production-ready artifacts (reading the links related here requires a lot of mathematical maturity and a greedy research enthusiasm).</li></ul><p><a href="http://stackoverflow.com/questions/2323768/how-does-the-amazon-recommendation-feature-work">How does the Amazon Recommendation feature work?</a></p><ul><li><a href="https://www.linkedin.com/pulse/how-amazons-recommendation-system-works-what-might-we-vick-sahita"><strong><em>How Amazon’s Recommendation System works and What it might be missing</em></strong></a>.</li></ul><p><a href="https://www.linkedin.com/pulse/how-amazons-recommendation-system-works-what-might-we-vick-sahita">How Amazon&#39;s Recommendation System works and What it might be missing...How we can build better models. #recsys #algorithms #models #cs #math #amazon</a></p><ul><li><a href="https://www.wired.com/2015/04/now-anyone-can-tap-ai-behind-amazons-recommendations/"><strong><em>Now Anyone Can Tap the AI Behind Amazon’s Recommendations</em></strong></a>.</li></ul><p><a href="https://www.wired.com/2015/04/now-anyone-can-tap-ai-behind-amazons-recommendations/">Now Anyone Can Tap the AI Behind Amazon&#39;s Recommendations</a></p><ul><li><a href="https://www.quora.com/How-does-the-Netflix-movie-recommendation-algorithm-work"><strong><em>How does the Netflix movie recommendation algorithm work?</em></strong></a></li></ul><p><a href="https://www.quora.com/How-does-the-Netflix-movie-recommendation-algorithm-work">How does the Netflix movie recommendation algorithm work?</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fa40d5a9c0fa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/a-concise-recommender-systems-tutorial-fa40d5a9c0fa">An Introductory Recommender Systems Tutorial</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Comprehensive Introduction to Word Vector Representations]]></title>
            <link>https://medium.com/ai-society/jkljlj-7d6e699895c4?source=rss----bc8767f5d170---4</link>
            <guid isPermaLink="false">https://medium.com/p/7d6e699895c4</guid>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[nlp]]></category>
            <dc:creator><![CDATA[Esteban Vargas]]></dc:creator>
            <pubDate>Thu, 09 Feb 2017 21:57:36 GMT</pubDate>
            <atom:updated>2017-02-09T21:57:35.658Z</atom:updated>
            <content:encoded><![CDATA[<p>Making a computer mimic the human cognitive function of understanding text is a really hot topic nowadays. Applications range from sentiment analysis to text summary and language translation among others. We call this field of computer science and artificial intelligence Natural Language Processing, or NLP (gosh, please don’t confuse with Neuro-linguistic Programming).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/1*GzQLI3lNHmda2DZ7VGlUUg.png" /></figure><p><strong>Bag of Words</strong></p><p>The ‘Bag of Words’ model was an important insight that made NLP thrive. This model consists on receiving a list of labeled text corpora, making a word count on each corpus and determining with how much frequency each word (or morpheme [1] to be more precise) appears for every given label. After that, the Bayes’ Theorem is applied on an unlabeled corpus to test which label (a sentiment analysis that labels between positive and negative, perhaps) it has a higher probability of belonging to, based on morpheme frequencies.</p><p>Even Though decent (&gt;90%) test scores can be achieved with this method, it has 2 problems:</p><ol><li>Syntactic and semantic accuracy isn’t as high as it should because of the fact that context is king. For instance; ‘Chicago’ means one thing and ‘Bulls’ means another, but ‘Chicago Bulls’ means a completely different thing. Counting word-frequencies doesn’t take this into account.</li><li>For more practical use cases, we need to understand that data in real-life tends to be unlabeled, therefore passing from a supervised to an unsupervised learning method yields a greater utility.</li></ol><p><strong>Simple Co-occurrence Vectors</strong></p><p>Analyzing the context in which a word is used is a transcendental insight to attack this problem. Taking into account a word’s neighboring words is what has made NLP take a quantum leap in the most recent years.</p><p>We will set a parameter ‘m’ which stands for the window size. In this example we’ll use a size of 1 for educational purposes but 5–10 tends to be more common. This means that each word will be defined by its neighboring word to the left as well as the one to the right. This is modeled mathematically by constructing a co-occurrence matrix for each window. Let’s look at the following example:</p><p>I love Programming. I love Math. I tolerate Biology.</p><p>Here the word ‘love’ is defined by the words ‘I’ and ‘Programming’, meaning that we increment the value both for the ‘I love’ and the ‘love Programming’ co-occurrence. We do that for each window and obtain the following co-occurrence matrix:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*1p0geczj9KbJvwYi25B2Jg.png" /></figure><p>Once we have the co-occurrence matrix filled we can plot its results into a multi-dimensional space. Since ‘Programming’ and ‘Math’ share the same co-occurrence values, they would be placed in the same place; meaning that in this context they mean the same thing (or ‘pretty much’ the same thing). ‘Biology’ would be the closest word to these 2 meaning ‘it has the closest possible meaning but it’s not the same thing’, and so on for every word. The semantic and syntactic relationships generated by this technique are really powerful but it’s computationally expensive since we are talking about a very high-dimensional space. Therefore, we need a technique that reduces dimensionality for us with the least data-loss possible.</p><p><strong>Singular Value Decomposition</strong></p><p>The idea here is to store only the most ‘important’ information in order to have a dense vector (eliminating as much 0’s as possible to keep only the relevant values) with a low number of dimensions. The way we do this is by applying a technique borrowed from Linear Algebra called Singular Value Decomposition [2] which in summary is the generalization of the eigendecomposition of a positive semidefinite normal matrix (such as the matrix in the example above, which is a symmetric one with positive eigenvalues).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*jeIdJBvrAMeJ809h." /></figure><p>This approach generates really interesting semantic and syntactic relationships. Semantically we could visualize things such as ‘San Francisco’ and ‘New York’ are at the highest level of similarity possible, at the next level of similarity there’s ‘Toronto’ and at the next one there’s ‘Tokyo’. Syntactically we can find words clustered around their respective morphemes; for example ‘write’, ‘wrote’ and ‘writing’ can be clustered together and then far away there’s another cluster with the words ‘cook’, ‘cooking’ and ‘cooked’. With this approach dimensionality has indeed been reduced, however, the computational cost of this approach scales quadratically (O(mn²) for the nxm matrix) which is something not very desirable. Let us then introduce you to a model that solves this computational complexity runtime issue:</p><p><strong>GloVe</strong></p><p>The way that we are going to finally solve our computational complexity issue is by predicting the surrounding words of every word instead of counting co-occurrences directly. This method is not only more computationally efficient but it also makes it viable to add new words to the model, which in other words means the model scales with corpus size. There are various prediction models but we’re going to talk about one in particular that generates really powerful word relationships, called <em>GloVe: Global Vectors for Word Representation. </em>[3]</p><p>The way these models predict surrounding words is by maximizing the probability of a context word occurring given a center word by performing a dynamic logistic regression. This just means we are going to find the global optimum of a probability function. Review Convex Optimization [4] if this doesn’t sound familiar. Our cost function is the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/686/0*tGRqUHd0VwwD6kIV." /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*aTmSKgkFhEpBMYzO." /></figure><p>Then something mind-blowing happens. The multi-dimensional plot (represented in 2 dimensions here) understands that what Dollar is to Peso, USA is to Colombia; as well as that what Dollar is to USA, Peso is to Colombia. The most impressive thing about this isn’t that cognitive intelligence assessments test how well can a human build these kind of relations, but that the semantic relation between words turns into a mathematical one. For instance, if you perform the vector operation Peso — Dollar + USA, you will get Colombia as a result. The reason why this happens is because these words tend to appear in the same context. Imagine we are training a corpora of economic news; you’ll often find fragments such as “The {Country} {Currency} appreciated” or “Firms that import from {Country1} to {Country2} are worried because the {Currency2} has depreciated with respect to the {Currency1}.”</p><p>This first tutorial has been a lot about the mathematical background behind modern deep learning for NLP techniques. With this notion we can now crack some code to perform sentiment analysis, which we’ll do on our next tutorial.</p><p>Happy hacking!</p><p>[1] The smallest meaningful unit of a word. For example; reading, read and readable share the morpheme ‘read’. Python libraries such as nltk allow you to run an algorithms that reduce each word in a corpus to its morpheme in only a few lines of code.</p><p>[2] Here’s a comprehensive tutorial from MIT OCW: <a href="https://www.youtube.com/watch?v=cOUTpqlX-Xs">https://www.youtube.com/watch?v=cOUTpqlX-Xs</a> If you need a Linear Algebra refresher, please take it.</p><p>[3] <a href="https://pdfs.semanticscholar.org/b397/ed9a08ca46566aa8c35be51e6b466643e5fb.pdf">https://pdfs.semanticscholar.org/b397/ed9a08ca46566aa8c35be51e6b466643e5fb.pdf</a></p><p>[4] <a href="http://cs229.stanford.edu/section/cs229-cvxopt.pdf">http://cs229.stanford.edu/section/cs229-cvxopt.pdf</a></p><p><strong>Thanks</strong> to Juan C. Saldarriaga, Ana M. Gómez and Melissa M. Argote for revising the drafts of this text.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7d6e699895c4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ai-society/jkljlj-7d6e699895c4">A Comprehensive Introduction to Word Vector Representations</a> was originally published in <a href="https://medium.com/ai-society">AI Society</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>