"[View in Colaboratory](https://colab.research.google.com/github/MarkDaoust/models/blob/autopgraph-guide/samples/core/guide/autograph_control_flow.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "kGXS3UWBBNoc"
"id": "Jxv6goXm7oGF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 1. AutoGraph writes graph code for you\n",
"##### Copyright 2018 The TensorFlow Authors.\n",
"\n",
"[AutoGraph](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/autograph/README.md) helps you write complicated graph code using just plain Python -- behind the scenes, AutoGraph automatically transforms your code into the equivalent TF graph code. We support a large chunk of the Python language, which is growing. [Please see this document for what we currently support, and what we're working on](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/autograph/LIMITATIONS.md).\n",
"\n",
"Here's a quick example of how it works:\n",
"\n"
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "llMNufAK7nfK",
"colab_type": "code",
"id": "aA3gOodCBkOw"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"# Autograph can convert functions like this...\n",
"def g(x):\n",
" if x \u003e 0:\n",
" x = x * x\n",
" else:\n",
" x = 0.0\n",
" return x\n",
"\n",
"# ...into graph-building functions like this:\n",
"def tf_g(x):\n",
" with tf.name_scope('g'):\n",
" \n",
" def if_true():\n",
" with tf.name_scope('if_true'):\n",
" x_1, = x,\n",
" x_1 = x_1 * x_1\n",
" return x_1,\n",
"\n",
" def if_false():\n",
" with tf.name_scope('if_false'):\n",
" x_1, = x,\n",
" x_1 = 0.0\n",
" return x_1,\n",
"\n",
" x = autograph_utils.run_cond(tf.greater(x, 0), if_true, if_false)\n",
" return x\n"
]
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" /><span>Run in Google Colab</span></a> \n",
"</td><td>\n",
"<a target=\"_blank\" href=\"https://github.com/tensorflow/models/blob/master/samples/core/guide/autograph_control_flow.ipynb\"><img width=32px src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" /><span>View source on GitHub</span></a></td></table>"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "m-jWmsCmByyw"
"id": "CydFK2CL7ZHA",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"#### Automatically converting complex control flow\n",
"\n",
"AutoGraph can convert a large chunk of the Python language into equivalent graph-construction code, and we're adding new supported language features all the time. In this section, we'll give you a taste of some of the functionality in AutoGraph.\n",
"AutoGraph will automatically convert most Python control flow statements into their correct graph equivalent. \n",
" \n",
"We support common statements like `while`, `for`, `if`, `break`, `return` and more. You can even nest them as much as you like. Imagine trying to write the graph version of this code by hand:\n"
"[AutoGraph](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/autograph/README.md) helps you write complicated graph code using just plain Python -- behind the scenes, AutoGraph automatically transforms your code into the equivalent TF graph code. We support a large chunk of the Python language, which is growing. [Please see this document for what we currently support, and what we're working on](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/autograph/LIMITATIONS.md)."
"Try replacing the `continue` in the above code with `break` -- AutoGraph supports that as well! \n",
" \n",
"Let's try some other useful Python constructs, like `print` and `assert`. We automatically convert Python `assert` statements into the equivalent `tf.Assert` code. "
"Here's a quick example of how it works. Autograph can convert functions like this:"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "aA3gOodCBkOw",
"colab_type": "code",
"id": "IAOgh62zCPZ4"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"def f(x):\n",
" assert x != 0, 'Do not pass zero!'\n",
" return x * x\n",
"\n",
"tf_f = autograph.to_graph(f)\n",
"with tf.Graph().as_default(): \n",
" with tf.Session():\n",
" try:\n",
" print(tf_f(tf.constant(0)).eval())\n",
" except tf.errors.InvalidArgumentError as e:\n",
" print('Got error message:\\n%s' % e.message)"
]
"def g(x):\n",
" if x > 0:\n",
" x = x * x\n",
" else:\n",
" x = 0.0\n",
" return x"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "KRu8iIPBCQr5"
"id": "LICw4XQFZrhH",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"You can also use plain Python `print` functions in in-graph"
"Into graph-compatible functions like this:"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "_EMhGUjRZoKQ",
"colab_type": "code",
"id": "ySTsuxnqCTQi"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"def f(n):\n",
" if n \u003e= 0:\n",
" while n \u003c 5:\n",
" n += 1\n",
" print(n)\n",
" return n\n",
" \n",
"tf_f = autograph.to_graph(f)\n",
"with tf.Graph().as_default():\n",
" with tf.Session():\n",
" tf_f(tf.constant(0)).eval()"
]
"print(autograph.to_code(g))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "NqF0GT-VCVFh"
"id": "xpK0m4TCvkJq",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Appending to lists in loops also works (we create a `TensorArray` for you behind the scenes)"
"You can take code written for eager execution and run it in graph mode. You get the same results, but with all the benfits of graphs:"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "I1RtBvoKBxq5",
"colab_type": "code",
"id": "ABX070KwCczR"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"def f(n):\n",
" z = []\n",
" # We ask you to tell us the element dtype of the list\n",
" z = autograph.utils.set_element_type(z, tf.int32)\n",
" for i in range(n):\n",
" z.append(i)\n",
" # when you're done with the list, stack it\n",
" # (this is just like np.stack)\n",
" return autograph.stack(z) \n",
"\n",
"tf_f = autograph.to_graph(f)\n",
"with tf.Graph().as_default(): \n",
" with tf.Session():\n",
" print(tf_f(tf.constant(3)).eval())\n",
"\n",
"print('\\n\\n'+autograph.to_code(f))"
]
"print('Original value: %2.2f' % g(9.0)) "
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
"id": "Fpk3MxVVv5gn",
"colab_type": "text"
},
"colab_type": "code",
"id": "iu5IF7n2Df7C"
},
"outputs": [],
"cell_type": "markdown",
"source": [
"def fizzbuzz(num):\n",
" if num % 3 == 0 and num % 5 == 0:\n",
" print('FizzBuzz')\n",
" elif num % 3 == 0:\n",
" print('Fizz')\n",
" elif num % 5 == 0:\n",
" print('Buzz')\n",
" else:\n",
" print(num)\n",
" return num"
"Generate a graph-version and call it:"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "SGjSq0WQvwGs",
"colab_type": "code",
"id": "EExAjWuwDPpR"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"tf_g = autograph.to_graph(fizzbuzz)\n",
"tf_g = autograph.to_graph(g)\n",
"\n",
"with tf.Graph().as_default(): \n",
" # The result works like a regular op: takes tensors in, returns tensors.\n",
" # You can inspect the graph using tf.get_default_graph().as_graph_def()\n",
" g_ops = tf_g(tf.constant(15))\n",
" g_ops = tf_g(tf.constant(9.0))\n",
" with tf.Session() as sess:\n",
" sess.run(g_ops) \n",
" \n",
"# You can view, debug and tweak the generated code:\n",
"AutoGraph can convert a large chunk of the Python language into equivalent graph-construction code, and we're adding new supported language features all the time. In this section, we'll give you a taste of some of the functionality in AutoGraph.\n",
"AutoGraph will automatically convert most Python control flow statements into their correct graph equivalent. \n",
" \n",
"\n",
"We support common statements like `while`, `for`, `if`, `break`, `return` and more. You can even nest them as much as you like. Imagine trying to write the graph version of this code by hand:\n"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"id": "toxKBOXbB1ro",
"colab_type": "code",
"id": "dE1Vsmp-mlpK"
"colab": {}
},
"outputs": [],
"cell_type": "code",
"source": [
"# See what happens when you turn AutoGraph off.\n",
"# Do you see the type or the value of x when you print it?\n",
" # The result works like a regular op: takes tensors in, returns tensors.\n",
" # You can inspect the graph using tf.get_default_graph().as_graph_def()\n",
" input = tf.placeholder(tf.int32)\n",
" result = fizzbuzz(input)\n",
" with tf.Session() as sess:\n",
" sess.run(result, feed_dict={input:10}) \n",
" sess.run(result, feed_dict={input:11}) \n",
" sess.run(result, feed_dict={input:12}) \n",
" sess.run(result, feed_dict={input:13}) \n",
" sess.run(result, feed_dict={input:14}) \n",
" sess.run(result, feed_dict={input:15}) \n",
" "
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "b9AXIkNLxp6J"
"id": "-pkEH6OecW7h",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"#### Uncollapse to reveal answer"
"### Assert\n",
"\n",
"Let's try some other useful Python constructs, like `print` and `assert`. We automatically convert Python `assert` statements into the equivalent `tf.Assert` code. "