Eder Santana http://edersantana.github.io Wed, 16 Mar 2016 22:25:00 -0400 Wintersmith - https://github.com/jnordberg/wintersmith en Keras plays catch, a single file Reinforcement Learning example http://edersantana.github.io/articles/keras_rl/ Wed, 16 Mar 2016 22:25:00 -0400 http://edersantana.github.io/articles/keras_rl/ <p>Get started with reinforcement learning in less that 200 lines of code with Keras (Theano or Tensorflow, it’s your choice).</p> <p><span class="more"></span></p> <p><img src="/articles/keras_rl/catch.gif" alt="Keras play catch"></p> <p>So you are a (Supervised) Machine Learning practitioner that was also sold the hype of making your labels weaker and to the possibility of getting neural networks to play your favorite games. You want to do Reinforcement Learning (RL), but you find it hard to read all those full featured libraries just to get a feeling of what is actually going on.</p> <p>Here we’ve got your back: we took the game engine complexities out of the way and show a minimal Reinforcement Learning example with less than 200 lines of code. And yes, the example does use Keras, your favorite deep learning library!</p> <p>Before I give you a link to the code make sure you read Nervana’s blog post <a href="http://www.nervanasys.com/demystifying-deep-reinforcement-learning/">Demystifying Deep Reinforcement Learning</a>. There you will learn about Q-learning, which is one of the many ways of doing RL. Also, at this point you already know that neural nets love mini-batches and there you will see what Experience Replay is and how to use it to get you them batches - even in problems where an agent only sees one sample of the environment state at a time.</p> <p>So here is the <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093">link for our code</a>. In that code Keras plays the catch game, where it should catch a single pixel “fruit” using a three pixel “basket”. The fruit falls one pixel per step and the Keras network gets a reward of +1 if it catches the fruit and -1 otherwise. The networks see the entire <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093#file-qlearn-py-L34-L40">10x10 pixels grid</a> as input and outputs <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093#file-qlearn-py-L122">three values</a>, each value corresponds to an action (move left, stay, move right). Since these values represent the expected accumulated future reward, we just go greedy and pick the <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093#file-qlearn-py-L147-L148">action corresponding to the largest value</a>.</p> <p>One thing to note though, is that this network is not quite like you in exotic restaurants, it doesn’t take the very same action exploiting what it already knows at every time, once in a while we force system to take a <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093#file-qlearn-py-L144-L145">random action</a>. This would be the equivalent of you learning that life is more than just Penang Curry with fried Tempeh by trial and error.</p> <p>In the link you will also find scripts that plays the game with no random actions and generates the pictures for the animation above.</p> <p>Enjoy!</p> <h2 id="faq">FAQ</h2> <p><strong>1) How does this Q-learning thing even work?</strong></p> <p>C’mon read the blog post I just mentioned above… Anyway, think like this: the fruit is almost hitting the ground and your model is just one pixel away from a “catching” position. The model will face similar cases many many times. If it decides to stay or move left, it will be punished (imagine it smelling a bunch of rotten fruits in the ground because it was lazy). Thus, it learns to assign a small Q-value (sounds much better than just “output of neural net”, han?) to those two actions whenever it sees that picture as input. But, since catching the fruit also gives a juicy +1 reward, the model will learn to assign a larger Q-value to the “move right” action in that case. This is what minimizing the <a href="https://gist.github.com/EderSantana/c7222daa328f0e885093#file-qlearn-py-L98-L106">reward - Q-value error</a> does.</p> <p>One step before that, there will be no reward in the next step.</p> <p>I liked how the previous phrase sounded, so I decided to give it its own paragraph. But, although in that case there is no juicy reward right after, the model can be trained using the maximum Q-value of the future state in the next step. Think about it. If you’re in the kitchen you know that you can just open the fridge to get food. But now you’re in your bedroom writing bad jokes and feel hungry. But you have this vague memory that going to the kitchen could help with that. You just go to the kitchen and there you figure how to help yourself. You have to learn all that by living the game. I know, being Markovian is hard! But then the rest is just propagating these reward expectations further and further into the past, assigning high values for good choices and low values for bad choices (don’t forget that sometimes you hit those random choices in college so you learn the parts of life they don’t talk about in school). For everything else, if you believe in Stochastic Gradient Descent then it is easy to see this actually making sense… I hope…</p> <p><strong>2) How different is that from AlphaGo?</strong></p> <p>Not much… But instead of learning Q-values, AlphaGo thought it was smarter to use REINFORCE and learn to output actions probabilities directly. After that, she played several games against herself, so many that it could later learn the probability of winning from each position. Using all that information, during play time she uses a search technique to look for possible actions that would take her to positions with higher probability of winning. But she told me to mention here that she doesn’t search as many possibilities in the future as her older cousin DeepBlue did. She also said that she can play pretty well using just one GPU, the other 99 were running high resolution Netflix series so she can catch up with human culture.</p> <p>That being said, you should be able to modify this script in 2 or 3 days to get a reimplementation or AlphaGo and Skynet should be 4 weeks away?</p> <p>JK</p> <p><strong>3) Your code sucks why don’t you write something better?</strong></p> <p><a href="https://github.com/EderSantana/X/blob/master/examples/catcher.py">I’m trying…</a></p> <p><strong>4) Did you learn that by yourself?</strong></p> <p>The bad parts, yes. The good things were taught to me by my friends Evan Kriminger and Matthew Emigh.</p> March journal club http://edersantana.github.io/articles/mar_papers/ Thu, 24 Dec 2015 13:00:00 -0500 http://edersantana.github.io/articles/mar_papers/ <p>WORK IN PROGRESS…</p> <p><span class="more"></span></p> <h3 id="detecting-temporally-consistent-objects-in-videos-through-object-class-label-propagation">Detecting Temporally Consistent Objects in Videos through Object Class Label Propagation</h3> <p>link: <a href="http://arxiv.org/pdf/1601.05447v1.pdf">http://arxiv.org/pdf/1601.05447v1.pdf</a></p> <h3 id="weakly-supervised-disentangling-with-recurrent-transformations-for-3d-view-synthesis">Weakly-supervised Disentangling with Recurrent Transformations for 3D View Synthesis</h3> <p>link: <a href="http://arxiv.org/pdf/1601.00706v1.pdf">http://arxiv.org/pdf/1601.00706v1.pdf</a></p> <h3 id="autoencoding-beyond-pixels-using-a-learned-similarity-metric">Autoencoding beyond pixels using a learned similarity metric</h3> <p>link: <a href="http://arxiv.org/pdf/1512.09300v1.pdf">http://arxiv.org/pdf/1512.09300v1.pdf</a></p> <h3 id="reading-car-license-plates-using-deep-convolutional-neural-networks-and-lstms">Reading Car License Plates Using Deep Convolutional Neural Networks and LSTMs</h3> <p>link: <a href="http://arxiv.org/pdf/1601.05610v1.pdf">http://arxiv.org/pdf/1601.05610v1.pdf</a></p> <h3 id="prioritized-experience-replay">PRIORITIZED EXPERIENCE REPLAY</h3> <p>link: <a href="http://arxiv.org/pdf/1511.05952v3.pdf">http://arxiv.org/pdf/1511.05952v3.pdf</a></p> <h3 id="policy-distillation">POLICY DISTILLATION</h3> <p>link: <a href="http://arxiv.org/pdf/1511.06295v2.pdf">http://arxiv.org/pdf/1511.06295v2.pdf</a></p> <h3 id="webnav-a-new-large-scale-task-for-natural-language-based-sequential-decision-making">WebNav: A New Large-Scale Task for Natural Language based Sequential Decision Making</h3> <p>link: <a href="http://arxiv.org/abs/1602.02261">http://arxiv.org/abs/1602.02261</a></p> <h3 id="learning-to-communicate-to-solve-riddles-with-deep-distributed-recurrent-q-networks">Learning to Communicate to Solve Riddles with Deep Distributed Recurrent Q-Networks</h3> <p>link: <a href="http://arxiv.org/abs/1602.02672">http://arxiv.org/abs/1602.02672</a></p> Agnez, analytics for deep learning research http://edersantana.github.io/articles/agnez/ Thu, 24 Dec 2015 13:00:00 -0500 http://edersantana.github.io/articles/agnez/ <p>Machine learning is about writing programs with parameters that are learned from data. But writing the base architecture that will be learned requires intuition, inspection, trial, and error, all elements that can be enhanced with high quality visualization and analytics tools.</p> <p><span class="more"></span></p> <p>Building visualization and analytics tools to assist deep learning (and machine learning in general) development was what motivated my brother <a href="http://edersantana.github.io/articles/agnez/tiag0santana.github.io">Tiago Santana</a> and I to start <a href="http://github.com/AgnezIO">Agnez</a>, a collection of visualization tools for deep learning. Models used for deep learning can be seen a business where the architecture and hyperparameters are the business choices and the accuracy or error in the test set a measure of business success. Keeping that metaphor in mind we looked for companies such as Keen IO and projects such as the <a href="http://edersantana.github.io/articles/agnez/www.automaticstatistician.com">Automatic Statistician</a> for inspiration to build research analytics and visualization tools. </p> <p>Here we will describe our approach to serve the visualizations as a web app using <a href="http://edersantana.github.io/articles/agnez/feathersjs.com">Feathers.js</a> in the backend and <a href="http://edersantana.github.io/articles/agnez/github.com/keenlabs/dashboards">Keen Dashboards</a> in the frontend. For generating the graphs we are using a temporary solution based on <a href="http://edersantana.github.io/articles/agnez/mpld3.github.io">mpld3</a> that converts Matplotlib graphs to D3. The full code is on <a href="http://edersantana.github.io/articles/agnez/github.com/AgnezIO/minimal-app">minimal-app</a> repository. A schematic diagram of our architecture is shown in the figure below.</p> <p><img src="/articles/agnez/drawing2.png" alt="Figure 1"></p> <p>We wanted to generate beautifully organized dashboards and we noticed that Keen Dashboards already lifted most of the design weight. But as an originally Python developer, I suggested to keep Matplotlib’s subplot arrangement and flexibility without needing to rewrite html ourselves. An elegant solution to this problem would be to generate the dashboards dynamically using a REST API. We chose to develop the API with Feathers.js, a thin wrapper around Express.js for building real time REST APIs with Node.js. This is what we needed to start a simple to use and general API for handling, storing and plotting model analytics. In coffeescript and using NeDB as the database, our Feathers app is simply:</p> <pre><code class="lang-coffeescript">feathers = <span class="built_in">require</span> <span class="string">'feathers'</span> mongodb = <span class="built_in">require</span>(<span class="string">'feathers-mongodb'</span>) memory = mongodb { <span class="attribute">db</span>: <span class="string">'edermempy'</span> <span class="attribute">collection</span>: <span class="string">'values'</span> } bodyParser = <span class="built_in">require</span> <span class="string">'body-parser'</span> app = feathers() app.configure feathers.rest() .configure feathers.socketio() .use bodyParser.json() .use <span class="string">'/values'</span>, memory .use <span class="string">'/'</span>, feathers.static(__dirname) .listen <span class="number">3000</span> <span class="built_in">console</span>.log <span class="string">'App listening on port 3000 console.log '</span>Index at<span class="string">', __dirname+'</span><span class="regexp">/static/</span><span class="string">'</span> </code></pre> <p>All the hard work is handled by <a href="http://edersantana.github.io/articles/agnez/">feathers-nedb</a> CRUD and <a href="http://edersantana.github.io/articles/agnez/">feathers-client</a> that uses socket.io to update the browser client in real time. The machine learning client training our model with Python sends POST requests to the server. These requests trigger events in the server that updates the browser page. For this simple demo, our Python client will send html strings generated with mpld3 and a gif. When training a deep learning model the html string would be graphs of cost functions, accuracy, weight norms and other useful analytics. As we mentioned this is a simple temporary solution for illustration purposes, it would be more general to use a native D3 chart, patch the graphs in the browser side and only send numbers from the machine learning side. Nevertheless, deep learning epochs, or passes through the training datasets, usually take a few seconds (or even minutes and hours depending on how large the training dataset is) and sending html strings does not add a considerable overhead.</p> <p>The index.html is pretty minimal since everything will be generated dynamically when we send data using the API. We start with a simple <code>&lt;div id=dashboard&gt;</code> and add new Bootstrap rows later. <code>script.coffee</code> in the server has a basic Keen Dashboard cell as follows:</p> <pre><code class="lang-coffeescript">String.prototype.format = <span class="function">-&gt;</span> args = arguments <span class="keyword">return</span> <span class="keyword">this</span>.replace <span class="regexp">/{(\d+)}/g</span>, <span class="function"><span class="params">(match, number)</span> -&gt;</span> <span class="keyword">return</span> <span class="keyword">if</span> <span class="keyword">typeof</span> args[number] <span class="keyword">isnt</span> <span class="string">'undefined'</span> <span class="keyword">then</span> args[number] <span class="keyword">else</span> match cellstr = <span class="string">""" &lt;div class="col-sm-6"&gt; &lt;div class="chart-wrapper"&gt; &lt;div class="chart-title" id=title{1}&gt; {0} &lt;/div&gt; &lt;div class="chart-stage" id="grid{1}"&gt; {2} &lt;/div&gt; &lt;div class="chart-notes" id="description{1}"&gt; {3} &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; """</span> </code></pre> <p>With this code we can fill the placeholders using a Python inspired syntax: <code>&quot;dat {0} is {1}&quot;.format &quot;string&quot;, &quot;cool&quot;</code> which returns <code>&quot;dat string is cool&quot;</code>. When creating a new cell, we simply append the filled string to <code>#dashboard</code>‘s html. When the html string or an image URL is patched, we update that dashboard cell using the snippet below:</p> <pre><code class="lang-coffeescript">values.<span class="literal">on</span> <span class="string">'patched'</span>, <span class="function"><span class="params">(val)</span> -&gt;</span> <span class="built_in">console</span>.log <span class="string">'patching'</span>, val.name $grid = $ <span class="string">"#grid<span class="subst">#{val.pos}</span>"</span> $title = $ <span class="string">"#title<span class="subst">#{val.pos}</span>"</span> $description = $ <span class="string">"#description<span class="subst">#{val.pos}</span>"</span> $title.html val.name $description.html val.description <span class="keyword">if</span> val.type <span class="keyword">is</span> <span class="string">"html"</span> $grid.html val.value <span class="keyword">if</span> val.type <span class="keyword">is</span> <span class="string">"img"</span> $grid.html <span class="string">"&lt;img src='<span class="subst">#{val.value}</span>'&gt;"</span> </code></pre> <p>To test the app, we use the Python script ahead.</p> <pre><code class="lang-python"><span class="comment"># Remember that we are using feathers database CRUD</span> <span class="comment"># Allocate cell space in the dashboard by calling the CREATE method </span> url = <span class="string">"./images/main_img.gif"</span> r = requests.post(<span class="string">"http://localhost:3000/values"</span>, json={<span class="string">'name'</span>: <span class="string">''</span>, <span class="string">'type'</span>: <span class="string">'html'</span>, <span class="string">'value'</span>: [], <span class="string">'pos'</span>: <span class="number">0</span>, <span class="string">'description'</span>: <span class="string">''</span>}) id0 = json.loads(r.text)[<span class="string">"_id"</span>] r = requests.post(<span class="string">"http://localhost:3000/values"</span>, json={<span class="string">'name'</span>: <span class="string">''</span>, <span class="string">'type'</span>: <span class="string">'img'</span>, <span class="string">'value'</span>: [], <span class="string">'pos'</span>: <span class="number">1</span>, <span class="string">'description'</span>: <span class="string">''</span>}) id1 = json.loads(r.text)[<span class="string">"_id"</span>] fig = plt.figure() numbers = [] <span class="comment"># Update the cell html calling the PATCH method</span> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">100</span>): time.sleep(<span class="number">2</span>) <span class="comment"># simulate wait time of an epoch</span> plt.clf() numbers.append(random.random()) <span class="comment"># new value</span> plt.plot(numbers) <span class="keyword">if</span> len(numbers) &gt; <span class="number">20</span>: <span class="keyword">del</span> numbers[<span class="number">0</span>] <span class="comment"># delete old values</span> html = mpld3.fig_to_html(fig) <span class="comment"># convert matplotlib to d3</span> <span class="comment"># PATCH requests</span> r = requests.patch(<span class="string">"http://localhost:3000/values/"</span> + str(id0), json={<span class="string">'name'</span>: <span class="string">'test1'</span>, <span class="string">'type'</span>: <span class="string">'html'</span>, <span class="string">'value'</span>: html, <span class="string">'pos'</span>: <span class="number">0</span>, <span class="string">'description'</span>: <span class="string">'simple test'</span>}) r = requests.patch(<span class="string">"http://localhost:3000/values/"</span> + str(id1), json={<span class="string">'name'</span>: <span class="string">'test2'</span>, <span class="string">'type'</span>: <span class="string">'img'</span>, <span class="string">'value'</span>: url, <span class="string">'pos'</span>: <span class="number">1</span>, <span class="string">'description'</span>: <span class="string">'simple image'</span>}) <span class="keyword">print</span> r </code></pre> <p>Note that since REST APIs are universal, we could send pictures and graphs with any other language. In the next iteration of this app, using native D3 charts generated in the browser side we will make even easier to serve visualizations in a way that is language agnostic to the machine learning side (Lua and C++ are also popular for deep learning). </p> <p>For those interested in playing with this code, from the source root directory run</p> <pre><code class="lang-shell">coffee app.coffee </code></pre> <p>to start up the app and run</p> <pre><code class="lang-shell">python test.py </code></pre> <p>to send data using the API. We can see the results at <a href="http://localhost:3000">http://localhost:3000</a> and <a href="http://localhost:3000/values">https://localhost:3000/values</a></p> <p>If you are training a deep learning model with Keras you can run the app and use the Keras callbacks we provide, as in this <a href="https://github.com/AgnezIO/agnez/blob/master/examples/MNIST.ipynb">example</a>.</p> <p>Since Agnez is an young project, we are expecting it evolve quickly. Help, suggestions and feedback are welcome.</p> Does AI stand for Alchemical Intelligence? http://edersantana.github.io/articles/ai_alchemy/ Mon, 14 Dec 2015 16:00:00 -0500 http://edersantana.github.io/articles/ai_alchemy/ <p>AI stands for artificial intelligence, but it currently has a lot in common with chemistry in the ages when it was named Alchemy. </p> <p><span class="more"></span></p> <p><img src="/articles/ai_alchemy/alchemy.png" alt="alchemy symbols"></p> <p>Alex net recipe: </p> <ol> <li>5 five convolutional layers </li> <li>2 fully-connected layers </li> <li>Softmax layer with 1000 outputs on top </li> <li>Use Imagenet dataset for training </li> <li>Train it carefully with SGD for 2 weeks if you don’t have proper equipment, or for 16 hours if you do. </li> </ol> <p>In high school we learn that knowledge evolves from myths. The demystification is carried by careful investigation, experimentation, reproducibility and analysis, all guided by the scientific method. </p> <p>The scientific method is a fantastic tool, but I have always been equally fascinated by what was accomplished with other knowledge tools such as art and mythical approaches. My main question was “What did the human mind feel like in pre-scientific method ages?”. For PhD candidate in deep learning, it was humbling to observe that we somewhat live in such an age with respect to artificial intelligence.</p> <p>Deep learning is one of the computational approaches to unlocking the mysteries of intelligence. The understanding intelligence today, resembles the understanding chemistry in the times of the alchemists. Those chemical experimentalists of the old ages developed practical recipes for manipulating the dowries of Nature, all without the guide of today’s chemistry and physics. Similarly, we can achieve arguably intelligent-like behavior with deep learning. There is no broadly accepted definition in chemistry, physics, mathematics, nor in philosophy or poetry about what is Intelligence. Yet over and over again we have been able to write programs to tackle tasks that years ago would require a human to solve. These solutions are developed with intuition and arduous repetition, just like the alchemist’s workings.</p> <p>I’ve noticed a few other parallels between the fields of artificial and alchemical intelligence that I list next.</p> <h3 id="philosopher-s-stone">Philosopher’s stone</h3> <pre><code>Our mission SOLVE INTELLIGENCE - Google DeepMind </code></pre><p>Alchemists’ ultimate goal was to turn any base metal into gold and find the Elixir of Life. Artificial Intelligence seeks general purpose intelligence, universal program solvers, and building machines with human-like intelligence. These ambitious goals are successfully motivating investigators and patrons alike. </p> <p>On the other hand, although those involved in the research know how far they are from their Philosopher’s Stone, possible consequences of their declared ultimate goals can be fearsome for outsiders.</p> <h3 id="fear">Fear</h3> <pre><code>Our greatest existential threat - Elon Musk on AI </code></pre><p>Control over gold and life would be nothing but disruptive. It would break economies, health, politics, religion, and any other power systems. Equally world changing would be a machine with human intelligence and without human weaknesses, built as a single owner homunculus. Couldn’t that owner use his homunculus as the ultimate worker and accumulate unequal wealth or use it as the perfect soldier to conquer less technologically gifted societies?</p> <p>The unknown is scary and not everybody understands how AI or Alchemy works especially when practitioners are so fond of their mystic terminologies.</p> <h3 id="mysticism">Mysticism</h3> <pre><code>This state has a 2-dimensional structure: it consists of w × h vectors of m numbers, i.e., it is a 3-dimensional tensor of shape [w, h, m]. This &quot;mental image&quot; evolves in time in a way defined by a convolutional gated recurrent unit. - Łukasz Kaiser and Ilya Sutskever on Neural GPUs Learn Algorithms. (Quotation marks are ours) </code></pre><p>Arthur C. Clarke noticed that, “Any sufficiently advanced technology is indistinguishable from magic”. This resonates deeply with our minds so much that we sometimes avoid attributing mundane descriptions to what we recently discovered possible with our magic. For example, alchemists used to name their elements after Roman gods to represent their powers. Deep learners like to attribute cognitive properties to their algorithms such as attention and dreaming, even if they are just calculating first order moments or sampling from a parametric probability distribution. Esoteric terminology has also been widely accepted in names such as Hidden Layers, Dark Knowledge, Skip-Thought Vectors and algorithms that Learn to Think.</p> <p>After all, we have always calculated first order moments, but only now we use it to filter context relevant values. Also, random number generators have never consistently generated realistic or scary images. </p> <p>It takes a few generations for a technology to feel common enough for practitioners to retract their mystic terminologies.</p> <h3 id="enlightenment">Enlightenment</h3> <pre><code>&quot;in recognition of the extraordinary services he has rendered by the discovery of the laws of chemical dynamics and osmotic pressure in solutions&quot; - First Nobel of Chemistry, awarded to Jacobus H. van&#39;t Hoff </code></pre><p>No one can deny the importance of chemistry to our daily life. Although we can’t easily transform metals into gold, we know the Quantum laws that would explain how that might work. On average we now live about twice as long as those seeking the Elixir of Life. For that, we should thank understandings of the human body and medicines and all that started by claiming god’s workings in alchemists labs. </p> <p>One day, AI might lose its mystic veil and we will no longer say that Neural Networks can dream or pay attention. But when that time comes we will also be practicing much more than smoke, self-driving cars, image recognition and mirrors.</p> <p>Obviously, we will also rationally regulate AI the same way we regulate chemical weapons, by focusing on the people, companies and governments that might exploit it with bad will, and by teaching the technology alongside ethics classes.</p> <h3 id="predicting-the-future">Predicting the future</h3> <p>I feel happy with better understanding of how the mind of our predecessors might have worked. Looking back also helps me to understand the nature of the fear and wonder surrounding today’s advanced technologies. But these same technologies don’t evolve in unexplainable jumps. By the time we were able to fly, blow up a mountain, transform metal or extend our life spans we no longer felt it was appropriate to call it magic or threatening to human existence.</p> <p>Right now we are still waiting for an AI theory that may enlighten the field in the same way that Quantum Theory unveiled the real magic of Chemistry. A theory that will not only explain what we did but also make even more possible. At that point robots will be able to talk, draw, dance, work, navigate using information in the spectrum of visible light and hearing sound, and behave indistinguishably from humans. When AI becomes less alchemical, I doubt that the majority of us will be scared, expecting the protection of an AI Inquisition or worrying about what a machine is thinking.</p>