{"id":485,"date":"2016-01-25T00:37:34","date_gmt":"2016-01-25T00:37:34","guid":{"rendered":"http:\/\/www.marekrei.com\/blog\/?p=485"},"modified":"2019-09-27T23:32:56","modified_gmt":"2019-09-27T23:32:56","slug":"theano-tutorial","status":"publish","type":"post","link":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/","title":{"rendered":"Theano Tutorial"},"content":{"rendered":"<p>This is an introductory tutorial on\u00a0using Theano, the Python library. I&#8217;m going to\u00a0start from scratch and assume no previous knowledge of Theano. However, understanding how neural networks work will be useful when getting to the code examples towards the end.<\/p>\n<p>The plan for the tutorial is as follows:<\/p>\n<ol>\n<li>Give a basic introduction to Theano and explain the important concepts.<\/li>\n<li>Go over the main operations that we have available in Theano.<\/li>\n<li>Look at working code examples.<\/li>\n<\/ol>\n<p>I recently gave this tutorial as a talk\u00a0in University of Cambridge and it turned out to be way more popular than expected. In order to give more people access to the material, I&#8217;m now writing it up as a blog post.<\/p>\n<p>I do not claim to know everything about Theano, and I constantly learn new things myself. If you find any errors or have suggestions on how to improve this tutorial, do let me know.<\/p>\n<p>The code examples can be found in the Github repository:\u00a0<a href=\"https:\/\/github.com\/marekrei\/theano-tutorial\">https:\/\/github.com\/marekrei\/theano-tutorial<\/a><\/p>\n<h2>1. What is Theano?<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-583 size-full\" src=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg\" alt=\"CYh2GMnWkAELDTL\" width=\"599\" height=\"420\" srcset=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg 599w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL-150x105.jpg 150w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL-300x210.jpg 300w\" sizes=\"auto, (max-width: 599px) 100vw, 599px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Theano is a Python library for efficiently handling mathematical expressions involving multi-dimensional arrays (also known as tensors). It is a common choice\u00a0for implementing neural network models. Theano has been developed in University of Montreal, in a group led by Yoshua Bengio, since 2008.<\/span><\/p>\n<p>Some of the features include:<\/p>\n<ul>\n<li><span style=\"font-weight: 400;\">automatic\u00a0differentiation &#8211; you only have to implement the forward (prediction) part of the model, and Theano will automatically figure out how to calculate the gradients at various points, allowing you\u00a0to perform gradient descent for model training.<\/span><\/li>\n<li><span style=\"font-weight: 400;\">transparent use of a GPU &#8211; you can write the same code and run it either on CPU or GPU. More specifically, Theano will figure out which parts of the computation should\u00a0be moved to the GPU.<\/span><\/li>\n<li>speed and stability optimisations &#8211; Theano will internally reorganise and optimise your computations, in order to make them run faster and be more numerically stable. It will also try to compile some operations\u00a0into C code, in order to speed up the computation.<\/li>\n<\/ul>\n<p><!--more--><br \/>\nTechnically, Theano isn&#8217;t actually a machine learning library, as it doesn&#8217;t provide you with pre-built models that you can train on your dataset. Instead, it is a mathematical library that provides you with tools to build your own machine learning models. But if you are looking for machine learning toolkits, there are several good ones implemented on top of Theano:<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Blocks \u00a0\u00a0<\/span><a href=\"http:\/\/blocks.readthedocs.org\/en\/latest\/\"><span style=\"font-weight: 400;\">http:\/\/blocks.readthedocs.org\/en\/latest\/<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Keras \u00a0\u00a0<\/span><a href=\"http:\/\/keras.io\/\"><span style=\"font-weight: 400;\">http:\/\/keras.io\/<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Lasagne \u00a0\u00a0<\/span><a href=\"http:\/\/lasagne.readthedocs.org\/en\/latest\/\"><span style=\"font-weight: 400;\">http:\/\/lasagne.readthedocs.org\/en\/latest\/<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">PyLearn2 \u00a0\u00a0<\/span><a href=\"http:\/\/deeplearning.net\/software\/pylearn2\/\"><span style=\"font-weight: 400;\">http:\/\/deeplearning.net\/software\/pylearn2\/<\/span><\/a><\/li>\n<\/ul>\n<h2>2. Python refresher<\/h2>\n<p>Theano is a Python library, so let&#8217;s go over some important points in Python.<\/p>\n<ul>\n<li>Python is an interpreted language, which makes\u00a0it\u00a0more platform independent but generally slower than C, for example.<\/li>\n<li>Python uses dynamic typing. While each variable does have a specific type during execution, these are not explicitly stated in the code.<\/li>\n<li>Python uses indentation for block delimiting.\u00a0So where C or Java would use curly brackets to separate a block, Python uses whitespace. Here we define a function f to take parameter\u00a0x and return 2*x:\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">def f(x):\r\n    return 2*x<\/pre>\n<\/li>\n<li>We define a list in Python with square brackets:\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">a = &#x5B;1,2,3,4,5]\r\na&#x5B;1] == 2<\/pre>\n<\/li>\n<li>We define a dictionary (key-value mapping) with curly brackets:\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">b = {'key1': 1, 'key2':2}\r\nb&#x5B;'key2'] == 2<\/pre>\n<\/li>\n<li>List comprehension is a neat shorthand\u00a0in Python for constructing lists. Here we loop for 5 steps (values 0-4), and each time add i+1 to the list:\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = &#x5B;i+1 for i in range(5)]\r\nc&#x5B;1] == 2<\/pre>\n<\/li>\n<\/ul>\n<h2>3. Using Theano<\/h2>\n<p>In order to use Theano, you will need to install the dependencies and install Theano itself. If you&#8217;re using Ubuntu (tested for 14.04), you might get away with just running these two commands:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ libopenblas-dev git\r\nsudo pip install Theano\r\n<\/pre>\n<p>If that doesn&#8217;t work for you, take a look at the original Theano homepage, which contains instructions for various platforms:<br \/>\n<a href=\"http:\/\/deeplearning.net\/software\/theano\/install.html\">http:\/\/deeplearning.net\/software\/theano\/install.html<\/a><\/p>\n<p>To use Theano in your Python script, include it using:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport theano\r\n<\/pre>\n<h2>4. Minimal Working Example<\/h2>\n<p>Here is the smallest example I could come up with, which uses Theano and actually does something:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">import theano\r\nimport numpy\r\n\r\nx = theano.tensor.fvector('x')\r\nW = theano.shared(numpy.asarray(&#x5B;0.2, 0.7]), 'W')\r\ny = (x * W).sum()\r\n\r\nf = theano.function(&#x5B;x], y)\r\n\r\noutput = f(&#x5B;1.0, 1.0])\r\nprint output<\/pre>\n<p>So what&#8217;s happening here?<\/p>\n<p>We first define\u00a0a Theano variable x to be a vector of 32-bit floats, and give it name &#8216;x&#8217;:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">x = theano.tensor.fvector('x')<\/pre>\n<p>Next, we create a Theano variable W, assign its value to be vector [0.2, 0.7], and name it &#8216;W&#8217;:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">W = theano.shared(numpy.asarray(&#x5B;0.2, 0.7]), 'W')<\/pre>\n<p>We define y to be the sum of all elements in the element-wise multiplication of x and W:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">y = (x * W).sum()<\/pre>\n<p>We define a Theano function f, which takes as input x and outputs y:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">f = theano.function(&#x5B;x], y)<\/pre>\n<p>Then\u00a0call this function, giving as the argument vector\u00a0[1.0, 1.0], essentially setting the value of variable x:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">output = f(&#x5B;1.0, 1.0])<\/pre>\n<p>The script prints out the summed product of [0.2, 0.7] and\u00a0[1.0, 1.0], which is:<\/p>\n<pre>0.2*1.0 + 0.7*1.0 = 0.9<\/pre>\n<p>Don&#8217;t worry if the code\u00a0doesn&#8217;t fully make sense. We&#8217;ll go over the important parts in more detail.<\/p>\n<h2>5. Symbolic graphs in Theano (!)<\/h2>\n<p>I&#8217;d say this section contains\u00a0the most crucial part to\u00a0understanding Theano.<\/p>\n<p>When we are creating a model\u00a0with Theano, we first define a symbolic graph of all variables and operations that need to be performed. And then we can apply this graph on specific inputs to get outputs.<\/p>\n<p>For example, what do you think happens when this line of Theano code is executed in our script?<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">y = (x * W).sum()<\/pre>\n<p>The system takes x and W, multiplies them together and sums the values. Right?<\/p>\n<p style=\"text-align: center;\"><strong>NOPE<\/strong><\/p>\n<p style=\"text-align: left;\">Instead, we create a Theano object y that knows its values can be calculated as the dot-product of x and W. But the required mathematical operations are not performed here. In fact, when this line was executed in our example code above, x didn&#8217;t even have a value yet.<\/p>\n<p style=\"text-align: left;\">By chaining up various operations, we are creating a graph of all the variables and functions that need to be used to reach the output values. This symbolic graph is also the reason why we can only use Theano-specific operations when defining our models. If we tried to integrate functions from some random Python library into our network,\u00a0they would attempt to perform the calculations immediately, instead of returning a Theano variable as needed. Exceptions do exist\u00a0&#8211; Theano overrides some basic Python operators to act as expected, and <a href=\"http:\/\/www.numpy.org\/\">NumPy<\/a> is quite well integrated with Theano.<\/p>\n<h2 style=\"text-align: left;\">6. Variables<\/h2>\n<p style=\"text-align: left;\">We can define variables which don\u2019t have any values yet. Normally, these would be used for inputs to our network.<\/p>\n<p style=\"text-align: left;\">The variables have to be of a specific type though. For example, here we define variable x to be a vector of 32-bit floats, and give it name &#8216;x&#8217;:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">x = theano.tensor.fvector('x')<\/pre>\n<p>The names are generally useful for debugging and informative error messages. Theano won&#8217;t have access to your Python variable names, so you have to assign explicit Theano names for each variable if you want them to be referred to as something more useful\u00a0than just\u00a0&#8220;a tensor&#8221;.<\/p>\n<p>There are a number of different variable types available, just have a look at the list <a href=\"http:\/\/deeplearning.net\/software\/theano\/library\/tensor\/basic.html\">here<\/a>. Some of the more popular ones include:<\/p>\n<p>[table width=&#8221;500&#8243; colwidth=&#8221;100|50|50&#8243; colalign=&#8221;left|center|center&#8221;]<br \/>\nConstructor,\u00a0dtype,\u00a0ndim<br \/>\nfvector,float32,1<br \/>\nivector,int32,1<br \/>\nfscalar,float32,0<br \/>\nfmatrix,float32,2<br \/>\nftensor3,float32,3<br \/>\ndtensor3,float64,3<br \/>\n[\/table]<\/p>\n<p>You can also define a generic vector (or tensor) and set the type with an argument:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">x = theano.tensor.vector('x', dtype=float32)<\/pre>\n<p>If you don&#8217;t set the <em>dtype<\/em>, you will create vectors of type config.floatX. This will become relevant in\u00a0the section about GPUs.<\/p>\n<h2>7. Shared variables<\/h2>\n<p>We can also define shared variables, which are shared between different functions and different function calls. Normally, these would be used for weights in our neural network. Theano will automatically try to move shared variables to the GPU, provided one is available, in order to speed up computation.<\/p>\n<p>Here we define a shared variable and set its value to [0.2, 0.7].<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">W = theano.shared(numpy.asarray(&#x5B;0.2, 0.7]), 'W')<\/pre>\n<p>The values in shared variables can be accessed and modified outside of our Theano functions using these commands:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">W.get_value()\r\nW.set_value(&#x5B;0.1, 0.9])<\/pre>\n<h2>8. Functions<\/h2>\n<p>Theano functions are basically hooks for interacting with the symbolic graph. Commonly, we use them for passing input into our network and collecting the resulting output.<\/p>\n<p>Here we define a Theano function f that takes x as input and returns y as output:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">f = theano.function(&#x5B;x], y)<\/pre>\n<p>The first parameter is the list of input variables, and the second parameter is the list of output variables. Although if there&#8217;s only one output variable (like now) we don&#8217;t need to make it into a list.<\/p>\n<p>When we construct a function, Theano takes over and performs some of its own magic. It builds the computational graph and optimises it as much as possible. It restructures\u00a0mathematical operations to make them faster and more stable, compiles some parts to C, moves some tensors to the GPU, etc.<\/p>\n<p>Theano compilation can be controlled by setting the value of <em>mode<\/em> in the environement variable THEANO_FLAGS:<\/p>\n<ul>\n<li>FAST_COMPILE &#8211; Fast to compile, slow to run. Python implementations only, minimal graph optimisation.<\/li>\n<li>FAST_RUN &#8211; Slow to compile, fast to run. C implementations where available, full range of optimisations<\/li>\n<\/ul>\n<h2>9. Minimal Training Example<\/h2>\n<p>Here&#8217;s a minimal script for actually training something in Theano. We will be training the weights in W using gradient descent, so that the result from the model would be <em>20<\/em> instead of the original <em>0.9<\/em>.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport theano\r\nimport numpy\r\n\r\nx = theano.tensor.fvector('x')\r\ntarget = theano.tensor.fscalar('target')\r\n\r\nW = theano.shared(numpy.asarray(&#x5B;0.2, 0.7]), 'W')\r\ny = (x * W).sum()\r\n\r\ncost = theano.tensor.sqr(target - y)\r\ngradients = theano.tensor.grad(cost, &#x5B;W])\r\nW_updated = W - (0.1 * gradients&#x5B;0])\r\nupdates = &#x5B;(W, W_updated)]\r\n\r\nf = theano.function(&#x5B;x, target], y, updates=updates)\r\n\r\nfor i in xrange(10):\r\n    output = f(&#x5B;1.0, 1.0], 20.0)\r\n    print output\r\n<\/pre>\n<p>We create a second input variable called <em>target<\/em>, which will act as the target value we use for training:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">target = theano.tensor.fscalar('target')<\/pre>\n<p>In order to train the model, we need a cost function. Here we use a simple squared distance from the target:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">cost = theano.tensor.sqr(target - y)<\/pre>\n<p>Next, we want to calculate the partial gradients for the parameters that will be updated, with respect to the cost function. Luckily, Theano will do that for us. We simply call the <em>grad<\/em> function, pass in the real-valued cost and a list of all the variables we want gradients for, and it will return a list of those gradients:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">gradients = theano.tensor.grad(cost, &#x5B;W])<\/pre>\n<p>Now let&#8217;s define a symbolic variable for what the updated version of the parameters will look like. Using gradient descent, the update rule is to subtract the gradient, multiplied by the learning rate:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">W_updated = W - (0.1 * gradients&#x5B;0])<\/pre>\n<p>And next\u00a0we create a list of updates. More specifically, a list of tuples where the first element is the variable we want to update, and the second element is a variable containing the values that we want the first variable to contain after the update. This is just a syntax that Theano requires.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">updates = &#x5B;(W, W_updated)]<\/pre>\n<p>Have to define a Theano function again, with a couple of changes:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">f = theano.function(&#x5B;x, target], y, updates=updates)<\/pre>\n<p>It now takes two input arguments &#8211; one for the input vector, and another for the target value used for training. And the list of updates also gets attached to the function as well. Every time this function is called, we pass in values for <em>x<\/em> and <em>target<\/em>, get back the value for <em>y<\/em> as output, and Theano performs all the updates in the update list.<\/p>\n<p>In order to train the parameters, we repeatedly call this function (10 times in this case). Normally, we&#8217;d pass in different examples from our training data, but for this example we use the same x=[1.0, 1.0] and target=20 each time:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfor i in xrange(10):\r\n    output = f(&#x5B;1.0, 1.0], 20.0)\r\n    print output\r\n<\/pre>\n<p>When the script is executed, the output looks like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n0.9\r\n8.54\r\n13.124\r\n15.8744\r\n17.52464\r\n18.514784\r\n19.1088704\r\n19.46532224\r\n19.679193344\r\n19.8075160064\r\n<\/pre>\n<p>The first time the function is called, the output value is still 0.9 (like in the previous example), because the updates have not been applied yet. But with each consecutive step, the output value becomes closer and closer to the desired target 20.<\/p>\n<h2>10. Useful operations<\/h2>\n<p>This covers the basic logic behind building models with Theano. The example was very simple, but we are free to define increasingly complicated networks, as long as we use Theano-specific functions. Now let&#8217;s look at some of these building blocks that we have available.<\/p>\n<p><strong>Evaluate the value of a Theano variable<\/strong><\/p>\n<p>The eval() function forces the Theano variable to calculate and return its actual (numerical) value. If we try to just print the variable <em>a<\/em>, we only print its name. But if we use eval(), we get the actual square matrix that it is initialised to.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&gt; a = theano.shared(numpy.asarray(&#x5B;&#x5B;1.0,2.0],&#x5B;3.0,4.0]]), 'a')\r\n&gt; a\r\na\r\n&gt; a.eval()\r\narray(&#x5B;&#x5B;1., 2.],\r\n       &#x5B;3., 4.]])\r\n<\/pre>\n<p>This eval() function isn&#8217;t really used for building models, but it can be useful for debugging and learning how Theano works. In the examples below, I will be using the matrix <em>a<\/em> and the eval() function to print the value of each variable and demonstrate how different operations work.<\/p>\n<p><strong>Basic element-wise operations: + &#8211; * \/<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">c = ((a + a) \/ 4.0)\r\n\r\narray(&#x5B;&#x5B; 0.5, 1. ],\r\n       &#x5B; 1.5, 2. ]])\r\n<\/pre>\n<p><strong>Dot product<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.dot(a, a)\r\n\r\narray(&#x5B;&#x5B; 7., 10.],\r\n       &#x5B;15., 22.]])\r\n<\/pre>\n<p><strong>Activation functions<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.nnet.sigmoid(a)\r\nc = theano.tensor.tanh(a)\r\n\r\narray(&#x5B;&#x5B; 0.76159416,  0.96402758],\r\n       &#x5B; 0.99505475,  0.9993293 ]])\r\n<\/pre>\n<p><strong>Softmax (row-wise)<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.nnet.softmax(a)\r\n\r\narray(&#x5B;&#x5B; 0.26894142,  0.73105858],\r\n       &#x5B; 0.26894142,  0.73105858]])\r\n<\/pre>\n<p><strong>Sum<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = a.sum()\r\nc = a.sum(axis=1)\r\n\r\narray(&#x5B; 3.,  7.])\r\n<\/pre>\n<p><strong>Max<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = a.max()\r\nc = a.max(axis=1)\r\n\r\narray(&#x5B; 2.,  4.])\r\n<\/pre>\n<p><strong>Argmax<\/strong><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.argmax(a)\r\nc = theano.tensor.argmax(a, axis=1)\r\n\r\narray(&#x5B;1, 1])\r\n<\/pre>\n<p><strong>Reshape<\/strong><\/p>\n<p>We sometimes need to change the dimensions of a tensor and reshape() allows us to do that. It takes as input a tuple containing the new shape and returns a new tensor with that shape. In the first example below, we shape a square matrix into a 1&#215;4 matrix. In the second example, we use -1 which means &#8220;as big as the dimension needs to be&#8221;.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\na = theano.shared(numpy.asarray(&#x5B;&#x5B;1,2],&#x5B;3,4]]), 'a')\r\nc = a.reshape((1,4))\r\narray(&#x5B;&#x5B;1, 2, 3, 4]])\r\n\r\nc = a.reshape((-1,))\r\narray(&#x5B;1, 2, 3, 4])\r\n<\/pre>\n<p><strong>Zeros-like, ones-like<\/strong><\/p>\n<p>These functions create new tensors with the same shape but all values set to zero or one.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.zeros_like(a)\r\narray(&#x5B;&#x5B;0, 0],\r\n       &#x5B;0, 0]])\r\n<\/pre>\n<p><strong>Reorder the tensor dimensions<\/strong><\/p>\n<p>Sometimes we need to reorder the dimensions in a tensor. In the examples below, the dimensions in a two-dimensional matrix are first swapped. Then, &#8216;x&#8217; is used to create a brand new dimension.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\na.eval()\r\narray(&#x5B;&#x5B;1, 2],\r\n       &#x5B;3, 4]])\r\n\r\nc = a.dimshuffle((1,0))\r\narray(&#x5B;&#x5B;1, 3],\r\n       &#x5B;2, 4]])\r\n\r\nc = a.dimshuffle(('x',0,1))\r\narray(&#x5B;&#x5B;&#x5B;1, 2],\r\n        &#x5B;3, 4]]])\r\n<\/pre>\n<p><strong>Indexing<\/strong><\/p>\n<p>Using Python indexing tricks can make life so much easier. In the example below, we make a separate list <em>b<\/em>\u00a0containing line numbers, and use it to construct a new matrix which contains exactly the lines we want from the original matrix. This can be useful when dealing with word embeddings &#8211; we can put word ids into a list and use this to retrieve exactly the correct sequence of embeddings from the whole embedding matrix.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\na = theano.shared(numpy.asarray(&#x5B;&#x5B;1.0,2.0],&#x5B;3.0,4.0]]), 'a')\r\narray(&#x5B;&#x5B;1., 2.],\r\n       &#x5B;3., 4.]])\r\n\r\nb = &#x5B;1,1,0]\r\nc = a&#x5B;b]\r\narray(&#x5B;&#x5B; 3.,  4.],\r\n       &#x5B; 3.,  4.],\r\n       &#x5B; 1.,  2.]])\r\n<\/pre>\n<p>For assignment, we can&#8217;t do this:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">a&#x5B;0] = &#x5B;0.0, 0.0]<\/pre>\n<p>But instead, we can use set_subtensor(), which takes as arguments the selection of the original matrix that we want to reassign, and the value we want to assign it to. It returns a new tensor that has the corresponding values modified.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nc = theano.tensor.set_subtensor(a&#x5B;0],&#x5B;0.0, 0.0])\r\narray(&#x5B;&#x5B; 0.,  0.],\r\n       &#x5B; 3.,  4.]])\r\n<\/pre>\n<h2>11. Classifier Code Example<\/h2>\n<p>At this point, it&#8217;s time to move on to some more realistic examples.<\/p>\n<p>Take a look at the <a href=\"https:\/\/github.com\/marekrei\/theano-tutorial\/blob\/master\/classifier.py\">code for a very basic classifier<\/a>, which\u00a0tries to train a small network on a tiny (but real) dataset. I won&#8217;t walk you through it line-by-line any more; you&#8217;ve learned all the necessary parts by now and there are comments in the code as well.<\/p>\n<p>The task is to predict whether the GDP per capita for a country is more than the average GDP, based on the following features:<\/p>\n<ul>\n<li>Population density (per suqare km)<\/li>\n<li>Population growth rate (%)<\/li>\n<li>Urban population (%)<\/li>\n<li>Life expectancy at birth (years)<\/li>\n<li>Fertility rate (births per woman)<\/li>\n<li>Infant mortality (deaths per 1000 births)<\/li>\n<li>Enrolment in tertiary education (%)<\/li>\n<li>Unemployment (%)<\/li>\n<li>Estimated control of corruption (score)<\/li>\n<li>Estimated government effectiveness (score)<\/li>\n<li>Internet users (per 100 people)<\/li>\n<\/ul>\n<p>The <em>data\/<\/em> directory contains the files for training (121 countries) and testing (40 countries). Each row represents one country, the first column is the label, followed by the features. The feature values have been normalised, by subtracting the mean and dividing by the standard deviation. The label is 1 if the GDP is more than average, and 0 otherwise.<\/p>\n<p>Once you clone the github repository (or just download the data files), you can run the script with:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npython classifier.py data\/countries-classify-gdp-normalised.train.txt data\/countries-classify-gdp-normalised.test.txt\r\n<\/pre>\n<p>The script will print information about 10 training epochs and the result on the test set:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nEpoch: 0, Training_cost: 28.4304042768, Training_accuracy: 0.578512396694\r\nEpoch: 1, Training_cost: 24.5186290354, Training_accuracy: 0.619834710744\r\nEpoch: 2, Training_cost: 22.1283727037, Training_accuracy: 0.619834710744\r\nEpoch: 3, Training_cost: 20.7941253329, Training_accuracy: 0.619834710744\r\nEpoch: 4, Training_cost: 19.9641569475, Training_accuracy: 0.619834710744\r\nEpoch: 5, Training_cost: 19.3749411377, Training_accuracy: 0.619834710744\r\nEpoch: 6, Training_cost: 18.8899216914, Training_accuracy: 0.619834710744\r\nEpoch: 7, Training_cost: 18.4006371608, Training_accuracy: 0.677685950413\r\nEpoch: 8, Training_cost: 17.7210185975, Training_accuracy: 0.793388429752\r\nEpoch: 9, Training_cost: 16.315597037, Training_accuracy: 0.876033057851\r\nTest_cost: 5.01800578051, Test_accuracy: 0.925\r\n<\/pre>\n<h2>12. Recurrent functions with scan<\/h2>\n<p>One more important operation\u00a0to cover is scan, which can be used to create various recurrent functions: RNN, GRU, LSTM, etc.<\/p>\n<p>Here is sample code for using scan to define a simple RNN over word vectors in the\u00a0input_vectors matrix:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\ndef rnn_step(x, previous_hidden_vector, W_input, W_recurrent):\r\n    hidden_vector = theano.tensor.dot(x, W_input) + \r\n                    theano.tensor.dot(previous_hidden_vector, W_recurrent)\r\n    hidden_vector = theano.tensor.nnet.sigmoid(hidden_vector)\r\n\r\nW_input = self.create_parameter_matrix('W_input', (word_embedding_size, recurrent_size))\r\nW_recurrent = self.create_parameter_matrix('W_recurrent', (recurrent_size, recurrent_size))\r\ninitial_hidden_vector = theano.tensor.alloc(numpy.array(0, dtype=floatX), recurrent_size)\r\n\r\nhidden_vector, _ = theano.scan(\r\n    rnn_step,\r\n    sequences = input_vectors,\r\n    outputs_info = initial_hidden_vector,\r\n    non_sequences = &#x5B;W_input, W_recurrent]\r\n)\r\n\r\nhidden_vector = hidden_vector&#x5B;-1]\r\n<\/pre>\n<p>The scan function is called on line 10\u00a0and it takes 4 important arguments:<\/p>\n<ul>\n<li>fn: The function that is called at every step of the iteration.<\/li>\n<li>sequences: The variables that we want to iterate over. If this is a matrix, we\u00a0will be iterating over each row of that matrix.<\/li>\n<li>outputs_info: The values that we use as the previous recurrent values for the very first step. Usually these are just set to 0.<\/li>\n<li>non_sequences: Any additional variables that we want to pass into the function (fn) but don&#8217;t want to iterate over.<\/li>\n<\/ul>\n<p>We&#8217;ve defined the helper function rnn_step on line 1, which gets called on each row of\u00a0our input matrix. The scan function will be calling this rnn_step function internally, so we need to accept any arguments in the same order as Theano passes them. This is just something you need to know when dealing with scan. The order is as follows:<\/p>\n<ol>\n<li>First,\u00a0the current items from the variables that we are iterating over. If we are iterating over a matrix, the current row is passed to the function.<\/li>\n<li>Next, anything that was\u00a0output from the function at the previous time step. This is what we use to build recursive and recurrent representations. At the very first time step, the values will be those from\u00a0outputs_info instead.<\/li>\n<li>Finally, anything we specified in\u00a0non_sequences.<\/li>\n<\/ol>\n<p>What comes out from the scan function contains the hidden states (eg the rnn_step outputs) at each step. Not just the last step, but all of them. So if you only want the last step, you need to explicitly retrieve it by indexing from -1 (the last element). Theano is actually smart enough to figure out that you&#8217;re only using the last result, and will optimise to discard all the intermediate ones.<\/p>\n<p>In order to construct the weight matrices, I&#8217;m using a helper function (<code class=\"python color1\">self<\/code><code class=\"python plain\">.create_parameter_matrix<\/code>, definition not shown here) which takes as input the variable name and the shape. This means I don&#8217;t need to define the weight initialisation part again each time.<\/p>\n<h2>13. RNN Classifier Code Example<\/h2>\n<p>Time to look at some more code, this time using recurrent functions and scan. The <a href=\"https:\/\/github.com\/marekrei\/theano-tutorial\/blob\/master\/rnnclassifier.py\">script is available at the Github repository<\/a>. In this example, I&#8217;m using Gated Recurrent Units (GRU) from \u201cLearning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation\u201d (<a href=\"http:\/\/arxiv.org\/abs\/1406.1078\">Cho et al, 2014<\/a>), which are essentially a simpler versions of LSTMs.<\/p>\n<p>The task is to classify sentences into 5 classes, based on their fine-grained sentiment (very negative, slightly negative, neutral, slightly positive, very positive). We use the dataset published in &#8220;Recursive Deep Models for Semantic Compositionality Over a Sentiment Treebank&#8221; (<a href=\"http:\/\/www.aclweb.org\/anthology\/D13-1170\">Socher et al., 2013<\/a>).<\/p>\n<p>Start by downloading the dataset from <a href=\"http:\/\/nlp.stanford.edu\/sentiment\/\">http:\/\/nlp.stanford.edu\/sentiment\/<\/a> (the main zip file) and unpack it somewhere. Then, create training and test splits in the format that is more suitable for us, using the provided script in <a href=\"https:\/\/github.com\/marekrei\/theano-tutorial\">the repository<\/a>:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npython stanford_sentiment_extractor.py 1 full \/path\/to\/sentiment\/dataset\/ &gt; data\/sentiment.train.txt\r\npython stanford_sentiment_extractor.py 2 full \/path\/to\/sentiment\/dataset\/ &gt; data\/sentiment.test.txt\r\n<\/pre>\n<p>Now we can run the classifier with:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npython rnnclassifier.py data\/sentiment.train.txt data\/sentiment.test.txt\r\n<\/pre>\n<p>The script will train for 3 passes over the training data, and will then print performance on the test data.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nEpoch: 0 Cost: 25937.7372292 Accuracy: 0.285814606742\r\nEpoch: 1 Cost: 21656.820174 Accuracy: 0.350655430712\r\nEpoch: 2 Cost: 18020.619533 Accuracy: 0.429073033708\r\nTest_cost: 4784.25137484 Test_accuracy: 0.388235294118\r\n<\/pre>\n<p>The accuracy on the test set is about 38%, which isn&#8217;t a great result. But it is quite a difficult task &#8211; the current state-of-the-art system (<a href=\"https:\/\/aclweb.org\/anthology\/P\/P15\/P15-1150.pdf\">Tai ei al., 2015<\/a>) achieves 50.9% accuracy, using a large amount of additional phrase-level annotations, and a much bigger network based on LSTMs and parse trees. As there are 5 classes to choose from, a random system would get 20% accuracy.<\/p>\n<h2>14. Running on a GPU<\/h2>\n<p>Theano is smart enough to move some parts of the processing to the GPU, as long as CUDA is installed and a graphics card is made available. To install CUDA, follow instructions on one of these links:<\/p>\n<p><a href=\"https:\/\/developer.nvidia.com\/cuda-downloads\">https:\/\/developer.nvidia.com\/cuda-downloads<\/a><br \/>\n<a href=\"http:\/\/www.r-tutor.com\/gpu-computing\/cuda-installation\/cuda7.5-ubuntu\">http:\/\/www.r-tutor.com\/gpu-computing\/cuda-installation\/cuda7.5-ubuntu<\/a><\/p>\n<p>Then, when running your Python script, you need to point Theano to the CUDA installation. I do this by setting the environment variables in the command line:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nLD_LIBRARY_PATH=\/usr\/lib:\/usr\/local\/cuda-7.5\/lib64 THEANO_FLAGS='cuda.root=\/usr\/local\/cuda-7.5,device=gpu,floatX=float32' python mycode.py\r\n<\/pre>\n<p>This command is for CUDA-7.5 in my system. You&#8217;ll need to make sure that the paths match the CUDA installation paths in your machine.\u00a0If it works and Theano is using a GPU, the first line that gets printed will explicitly say so. Something like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">Using gpu device 0: GeForce GTX 780<\/pre>\n<p>If you don&#8217;t get something similar, it probably means Theano is not\u00a0properly hooked up to use the GPU.<\/p>\n<p>At the time of writing, Theano only supports 32-bit variables on the GPU, and this is where the\u00a0floatX=float32 setting comes it. It\u00a0just allows you to set the data type during the execution of the script, without writing it into your code. For example, you can define your vectors like this:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">x = theano.tensor.vector('x', dtype=config.floatX)<\/pre>\n<p>And now\u00a0you can set floatX to be float32 when running the script on a GPU and float64 when running on your CPU.<\/p>\n<p>Finally, if your machine has multiple GPUs, you can control which one is used for the script by setting\u00a0device=gpu0,\u00a0device=gpu1, etc. Based on personal experience, running multiple Theano jobs on the same GPU does not give any advantage, so it&#8217;s best to send them to different ones when possible.<\/p>\n<h2>15. Drawing the computation graph<\/h2>\n<p>Theano provides a command for printing a variable or a function, along with all the required computation, as an image:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nf = theano.function(&#x5B;x], y)\r\ntheano.printing.pydotprint(f, outfile=&quot;f.png&quot;, var_with_name_simple=True)\r\n<\/pre>\n<p>When dealing with very simple models, this can give a nice graphical representation. For example, here is a model from our minimal working example:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-528 size-medium\" src=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/f-300x246.png\" alt=\"Printed Theano function. Figure for the Theano tutorial.\" width=\"300\" height=\"246\" srcset=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/f-300x246.png 300w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/f-150x123.png 150w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/f.png 501w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>However, when the models get more and more complicated, the images also tend to get less informative:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-529 size-full\" src=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2.png\" alt=\"Printed graph of a much larger function. Figure for the Theano tutorial.\" width=\"3899\" height=\"1168\" srcset=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2.png 3899w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2-150x45.png 150w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2-300x90.png 300w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2-768x230.png 768w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/logreg_pydotprint_train2-1024x307.png 1024w\" sizes=\"auto, (max-width: 3899px) 100vw, 3899px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>16. Profiling<\/h2>\n<p>Finally, Theano also provides a useful tool for analysing bottlenecks in your code. Just set profile=True in THEANO_FLAGS, and it will print information about how much time is spent on different operations in your code.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">THEANO_FLAGS='profile=True' python minimal_working_example.py<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-530 size-full\" src=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling.png\" alt=\"Example of profiling output from Theano. Figure for the Theano tutorial.\" width=\"1475\" height=\"958\" srcset=\"https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling.png 1475w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling-150x97.png 150w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling-300x195.png 300w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling-768x499.png 768w, https:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/profiling-1024x665.png 1024w\" sizes=\"auto, (max-width: 1475px) 100vw, 1475px\" \/><\/p>\n<h2>17. References<\/h2>\n<p>This concludes the Theano tutorial. If you haven&#8217;t yet had enough, take a look at the following links that I used for inspiration:<br \/>\n<a href=\"http:\/\/deeplearning.net\/software\/theano\/\">Official Theano homepage and documentation<\/a><br \/>\n<a href=\"http:\/\/deeplearning.net\/software\/theano\/tutorial\/\">Official Theano tutorial<\/a><br \/>\n<a href=\"http:\/\/ir.hit.edu.cn\/~jguo\/docs\/notes\/a_simple_tutorial_on_theano.pdf\">A Simple Tutorial on Theano\u00a0by\u00a0Jiang Guo<\/a><br \/>\n<a href=\"https:\/\/github.com\/Newmu\/Theano-Tutorials\/\">Code samples for learning Theano\u00a0by\u00a0Alec Radford<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is an introductory tutorial on\u00a0using Theano, the Python library. I&#8217;m going to\u00a0start from scratch and assume no previous knowledge of Theano. However, understanding how&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-485","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Theano Tutorial - Marek Rei<\/title>\n<meta name=\"description\" content=\"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Theano Tutorial - Marek Rei\" \/>\n<meta property=\"og:description\" content=\"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Marek Rei\" \/>\n<meta property=\"article:published_time\" content=\"2016-01-25T00:37:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-27T23:32:56+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg\" \/>\n<meta name=\"author\" content=\"Marek\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marek\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/\",\"url\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/\",\"name\":\"Theano Tutorial - Marek Rei\",\"isPartOf\":{\"@id\":\"https:\/\/www.marekrei.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg\",\"datePublished\":\"2016-01-25T00:37:34+00:00\",\"dateModified\":\"2019-09-27T23:32:56+00:00\",\"author\":{\"@id\":\"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/a145eb0a06ed4acf5b0f84a24b7a1191\"},\"description\":\"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage\",\"url\":\"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg\",\"contentUrl\":\"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.marekrei.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Theano Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/#website\",\"url\":\"https:\/\/www.marekrei.com\/blog\/\",\"name\":\"Marek Rei\",\"description\":\"Thoughts on Machine Learning and Natural Language Processing\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.marekrei.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/a145eb0a06ed4acf5b0f84a24b7a1191\",\"name\":\"Marek\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/48a65414bfda6485aaa0703e548de0ed25292b5fe0d979ed8c28ad83cf5a82c0?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/48a65414bfda6485aaa0703e548de0ed25292b5fe0d979ed8c28ad83cf5a82c0?s=96&d=mm&r=g\",\"caption\":\"Marek\"},\"url\":\"https:\/\/www.marekrei.com\/blog\/author\/marek\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Theano Tutorial - Marek Rei","description":"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"Theano Tutorial - Marek Rei","og_description":"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.","og_url":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/","og_site_name":"Marek Rei","article_published_time":"2016-01-25T00:37:34+00:00","article_modified_time":"2019-09-27T23:32:56+00:00","og_image":[{"url":"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg"}],"author":"Marek","twitter_misc":{"Written by":"Marek","Est. reading time":"22 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/","url":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/","name":"Theano Tutorial - Marek Rei","isPartOf":{"@id":"https:\/\/www.marekrei.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage"},"thumbnailUrl":"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg","datePublished":"2016-01-25T00:37:34+00:00","dateModified":"2019-09-27T23:32:56+00:00","author":{"@id":"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/a145eb0a06ed4acf5b0f84a24b7a1191"},"description":"This is an introductory Theano tutorial. It covers the basic concepts and will help readers get started on building neural network models.","breadcrumb":{"@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.marekrei.com\/blog\/theano-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#primaryimage","url":"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg","contentUrl":"http:\/\/www.marekrei.com\/blog\/wp-content\/uploads\/2016\/01\/CYh2GMnWkAELDTL.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.marekrei.com\/blog\/theano-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.marekrei.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Theano Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.marekrei.com\/blog\/#website","url":"https:\/\/www.marekrei.com\/blog\/","name":"Marek Rei","description":"Thoughts on Machine Learning and Natural Language Processing","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.marekrei.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/a145eb0a06ed4acf5b0f84a24b7a1191","name":"Marek","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.marekrei.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/48a65414bfda6485aaa0703e548de0ed25292b5fe0d979ed8c28ad83cf5a82c0?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/48a65414bfda6485aaa0703e548de0ed25292b5fe0d979ed8c28ad83cf5a82c0?s=96&d=mm&r=g","caption":"Marek"},"url":"https:\/\/www.marekrei.com\/blog\/author\/marek\/"}]}},"_links":{"self":[{"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/posts\/485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/comments?post=485"}],"version-history":[{"count":85,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/posts\/485\/revisions"}],"predecessor-version":[{"id":1301,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/posts\/485\/revisions\/1301"}],"wp:attachment":[{"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/media?parent=485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/categories?post=485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.marekrei.com\/blog\/wp-json\/wp\/v2\/tags?post=485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}