{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Theano \n", "===\n", "An optimizing compiler for symbolic math expressions" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import theano\n", "import theano.tensor as T" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Symbolic variables\n", "==========" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "x = T.scalar()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Variables can be used in expressions" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "y = 3*(x**2) + 1" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Result is symbolic as well" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "theano.tensor.var.TensorVariable" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(y)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Investigating expressions" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Elemwise{add,no_inplace}.0\n" ] } ], "source": [ "print(y)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'((TensorConstant{3} * ( ** TensorConstant{2})) + TensorConstant{1})'" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "theano.pprint(y)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Elemwise{add,no_inplace} [@A] '' \n", " |Elemwise{mul,no_inplace} [@B] '' \n", " | |TensorConstant{3} [@C]\n", " | |Elemwise{pow,no_inplace} [@D] '' \n", " | | [@E]\n", " | |TensorConstant{2} [@F]\n", " |TensorConstant{1} [@G]\n" ] } ], "source": [ "theano.printing.debugprint(y)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "G\n", "\n", "\n", "139670232979664\n", "\n", "Elemwise{pow,no_inplace}\n", "\n", "\n", "139670232268304\n", "\n", "Elemwise{mul,no_inplace}\n", "\n", "\n", "139670232979664->139670232268304\n", "\n", "\n", "1 TensorType(float32, scalar)\n", "\n", "\n", "139670232978704\n", "\n", "TensorType(float32, scalar)\n", "\n", "\n", "139670232978704->139670232979664\n", "\n", "\n", "0\n", "\n", "\n", "139670232978832\n", "\n", "val=2 TensorType(int8, scalar)\n", "\n", "\n", "139670232978832->139670232979664\n", "\n", "\n", "1\n", "\n", "\n", "139670232268368\n", "\n", "Elemwise{add,no_inplace}\n", "\n", "\n", "139670232268304->139670232268368\n", "\n", "\n", "0 TensorType(float32, scalar)\n", "\n", "\n", "139670232978640\n", "\n", "val=3 TensorType(int8, scalar)\n", "\n", "\n", "139670232978640->139670232268304\n", "\n", "\n", "0\n", "\n", "\n", "139670231482960\n", "\n", "TensorType(float32, scalar)\n", "\n", "\n", "139670232268368->139670231482960\n", "\n", "\n", "\n", "\n", "139670232978896\n", "\n", "val=1 TensorType(int8, scalar)\n", "\n", "\n", "139670232978896->139670232268368\n", "\n", "\n", "1\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import SVG\n", "SVG(theano.printing.pydotprint(y, return_image=True, format='svg'))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Evaluating expressions\n", "============\n", "\n", "Supply a `dict` mapping variables to values" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array(13.0, dtype=float32)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y.eval({x: 2})" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Or compile a function" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f = theano.function([x], y)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array(13.0, dtype=float32)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Compiled function has been transformed" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "G\n", "\n", "\n", "139670211310224\n", "\n", "GpuFromHost\n", "\n", "\n", "139670211421072\n", "\n", "GpuElemwise{Composite{(i0 + (i1 * sqr(i2)))}}[(0, 2)]\n", "\n", "\n", "139670211310224->139670211421072\n", "\n", "\n", "2 CudaNdarrayType(float32, scalar)\n", "\n", "\n", "139670210791760\n", "\n", "TensorType(float32, scalar)\n", "\n", "\n", "139670210791760->139670211310224\n", "\n", "\n", "\n", "\n", "139670203407696\n", "\n", "HostFromGpu\n", "\n", "\n", "139670211421072->139670203407696\n", "\n", "\n", "CudaNdarrayType(float32, scalar)\n", "\n", "\n", "139670210995600\n", "\n", "val=1.0 CudaNdarrayType(float32, scalar)\n", "\n", "\n", "139670210995600->139670211421072\n", "\n", "\n", "0\n", "\n", "\n", "139670211312528\n", "\n", "val=3.0 CudaNdarrayType(float32, scalar)\n", "\n", "\n", "139670211312528->139670211421072\n", "\n", "\n", "1\n", "\n", "\n", "139670203405776\n", "\n", "TensorType(float32, scalar)\n", "\n", "\n", "139670203407696->139670203405776\n", "\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "SVG(theano.printing.pydotprint(f, return_image=True, format='svg'))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Other tensor types\n", "==========" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "X = T.vector()\n", "X = T.matrix()\n", "X = T.tensor3()\n", "X = T.tensor4()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Numpy style indexing\n", "===========" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "X = T.vector()" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Subtensor{int64:int64:int64}.0" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X[1:-1:2]" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "AdvancedSubtensor1.0" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X[[1,2,3]]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Many functions/operations are available through `theano.tensor` or variable methods" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [], "source": [ "y = X.argmax()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": true }, "outputs": [], "source": [ "y = T.cosh(X)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [], "source": [ "y = T.outer(X, X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But don't try to use numpy functions on Theano variables. Results may vary!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Automatic differention\n", "============\n", "- Gradients are free!" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x = T.scalar()\n", "y = T.log(x)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array(0.5, dtype=float32)" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gradient = T.grad(y, x)\n", "gradient.eval({x: 2})" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Shared Variables\n", "\n", "- Symbolic + Storage" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "x = theano.shared(np.zeros((2, 3), dtype=theano.config.floatX))" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We can get and set the variable's value" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 3)\n", "[[ 0. 0. 0.]\n", " [ 0. 0. 0.]]\n" ] } ], "source": [ "values = x.get_value()\n", "print(values.shape)\n", "print(values)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x.set_value(values)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Shared variables can be used in expressions as well" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "Elemwise{pow,no_inplace}.0" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(x + 2) ** 2" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Their value is used as input when evaluating" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 4., 4., 4.],\n", " [ 4., 4., 4.]], dtype=float32)" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "((x + 2) ** 2).eval()" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 4., 4., 4.],\n", " [ 4., 4., 4.]], dtype=float32)" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "theano.function([], (x + 2) ** 2)()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Updates\n", "\n", "- Store results of function evalution\n", "- `dict` mapping shared variables to new values" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "count = theano.shared(0)\n", "new_count = count + 1\n", "updates = {count: new_count}\n", "\n", "f = theano.function([], count, updates=updates)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array(0)" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array(1)" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array(2)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }