{"id":31235,"date":"2017-06-22T19:51:18","date_gmt":"2017-06-22T16:51:18","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=31235"},"modified":"2018-12-04T23:23:45","modified_gmt":"2018-12-04T20:23:45","slug":"logical-graphs-native-control-flow-operations-in-tensorflow","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/","title":{"rendered":"Logical Graphs: Native Control Flow Operations in TensorFlow"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#An_example_of_control_flow\" >An example of control flow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#Native_control_flow\" >Native control flow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#Control_dependencies\" >Control dependencies<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#Want_details_Watch_the_video\" >Want details? Watch the video!<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#Further_reading\" >Further reading<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#About_the_expert\" >About the expert<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"An_example_of_control_flow\"><\/span>An example of control flow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Sometimes, your models need to perform different computations depending on intermediate results or random chance. However, placing this sort of logic in the Python layer adds extra complexity and overhead to your code. TensorFlow provides a number of native operations to help create graphs with built-in logical branching structure. At <a href=\"https:\/\/www.altoros.com\/blog\/tag\/tensorbeat\/\">TensorBeat 2017<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/samjabrahams\/\" target=\"_blank\">Sam Abrahams<\/a>, a machine learning engineer at Metis, demonstrated how to make use of them.<\/p>\n<p>In computer science, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Control_flow\" target=\"_blank\">control flow<\/a> defines the order in which individual statements, instructions, or function calls are executed or evaluated. Sam started his talk with highlighting the challenges of executing control flow operations on a sample graph (see the icon above).<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-v11.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-v11-1024x678.jpg\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31242\" \/><\/a><\/p>\n<p>For instance, we need to run one of the functions (B or C) based on the other function\u2019s (A) value. Natively, this can be done simply with <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">if\/else<\/code> and multiple session runs. However, there is little sense in doing so, as we simply fetch a value to feed it right back in.<\/p>\n<p>Furthermore, the Python logic isn\u2019t represented in the graph.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-in-TensorFlow-v11.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-in-TensorFlow-v11-1024x638.jpg\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31238\" \/><\/a><\/p>\n<blockquote><p><em>\u201cIf we export the graph, you are not going to actually see those &#8216;if\/else&#8217; statements, we will lose the structure.\u201d \u2014Sam Abrahams, Metis<\/em><\/p><\/blockquote>\n<p>So, what one needs is a native logic gate.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Native_control_flow\"><\/span>Native control flow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>TensorFlow offers several operations for enabling native control flow:<\/p>\n<ul>\n<li>Dependencies: <a href=\"https:\/\/www.tensorflow.org\/api_docs\/python\/tf\/control_dependencies\" target=\"_blank\">tf.control_dependencies<\/a>, <a href=\"https:\/\/www.tensorflow.org\/api_docs\/python\/tf\/group\" target=\"_blank\">tf.group<\/a>, and <a href=\"https:\/\/www.tensorflow.org\/api_docs\/python\/tf\/tuple\" target=\"_blank\">tf.tuple<\/a><\/li>\n<li>Conditional statements: tf.cond and tf.case<\/li>\n<li>Loops: <a href=\"https:\/\/www.tensorflow.org\/api_docs\/python\/tf\/while_loop\" target=\"_blank\">tf.while_loop<\/a><\/li>\n<\/ul>\n<p>Why would anyone even bother with enabling native control flow?<\/p>\n<p><b>Efficiency.<\/b> While passing data to\/from the Python layer is somewhat slow, one would naturally want to run graph end-to-end as fast as possible, as well as take advantage of pipelining (e.g., queues). With native control flow, data transfer overhead is minimized.<\/p>\n<p><b>Flexibility.<\/b> Static graphs can be empowered with dynamic components. Better decoupling comes through storing the model logic in a single place. Changes can be introduced to the graph without any impact on a training loop. So, with native control flow, graph logic is self-contained.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Logical-Graphs-v11.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Logical-Graphs-v11-1024x679.jpg\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31239\" \/><\/a><\/p>\n<blockquote><p><em>\u201cOne of the things why people like using Torch over TensorFlow is that it uses dynamic graphs, so you can change the graph at a run time. TensorFlow\u2014for its capacity, but it doesn\u2019t mean we can\u2019t have a dynamic graph, though it\u2019s statically defined.\u201d \u2014Sam Abrahams, Metis<\/em><\/p><\/blockquote>\n<p><b>Compatibility.<\/b> One can debug and inspect via <a href=\"https:\/\/www.altoros.com\/blog\/visualizing-tensorflow-graphs-with-tensorboard\/\">TensorBoard<\/a>. Seamless deployment is ensured with TensorFlow Serving. One can make use of auto-differentiation, queues, and pipelining.<\/p>\n<p>&nbsp; <\/p>\n<h3><span class=\"ez-toc-section\" id=\"Control_dependencies\"><\/span>Control dependencies<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>TensorFlow keeps track of each operation\u2019s dependencies and uses them to schedule computation. What it means is that an operation can only be executed once its dependencies have completed. So, any two eligible operations with their dependencies complete can run in any order.<\/p>\n<p>For instance, we have the initial nodes with no dependencies that may run in random order. It may lead to a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Race_condition\" target=\"_blank\">race condition<\/a> and turn into an issue as operations are executed not in the way you expected them to.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Operations-v11.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Operations-v11-1024x678.jpg\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31241\" \/><\/a><\/p>\n<p>What one gets is a variable changed in the course of one operation, while the other operation reads from this very variable. The code then may look like this.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">var = tf.Variable(\u2026)\r\ntop = var * 2\r\nbot = var.assign_add(2)\r\nout = top + bot<\/pre>\n<p>Being non-deterministic, the execution order may lead to unexpected behavior. How to tackle the problem?<\/p>\n<p>On the one hand, TensorFlow automatically determines dependencies. On the other, a user can also define additional dependencies through forcing the specified operations to complete first. A developer can control the order depending on needs.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorBeat-TensorFlow-Control-Flow-Graph-Variable-v11.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorBeat-TensorFlow-Control-Flow-Graph-Variable-v11-1024x576.png\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31237\" \/><\/a><\/p>\n<p>For example, if one wants to change a variable and then read from it, one has to make the top operation depend on the bottom one. In case one needs to read a variable before it is altered, one has to establish a vice versa dependency. This is done by employing <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">tf.control_dependencies<\/code>.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\"># Force bot to wait for top\r\nvar = tf.Variable(\u2026)\r\ntop = var * 2\r\nwith tf.control_dependencies (&#x5B;top]):\r\n     bot = var.assign_add(2)\r\nout = top + bot<\/pre>\n<p>You need to define a list of the necessary dependencies as <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">control_inputs<\/code>, while operations are defined as <em>gain those dependencies<\/em> in the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">with<\/code> block.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Operations-in-TensorFlow-v11.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/Sam-Abrahams-TensorFlow-TensorBeat-Control-Flow-Operations-in-TensorFlow-v11-1024x678.jpg\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31240\" \/><\/a><\/p>\n<p>Where can this be applied? In addition to enforcing the <strong>execution order<\/strong>, one may <strong>group<\/strong> operations (run a bunch of them in a single handle) and add <strong>assertion<\/strong> statement (build exceptions into a graph).<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/tensorbeat-sam-abrahams-graph-tensorflow-native-control-flow-v11.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/02\/tensorbeat-sam-abrahams-graph-tensorflow-native-control-flow-v11-1024x576.png\" alt=\"\" width=\"640\" class=\"aligncenter size-large wp-image-31243\" \/><\/a><\/p>\n<p>Why grouping? As many variable are updated with separate operations, &#8220;running each update operation separately is a pain,&#8221; according to Sam. One may find a operation that depends on all the updates and use <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">_ = sess.run(update_all)<\/code> to get simpler and more semantic code.<\/p>\n<p><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">tf.group<\/code> automates the process. It uses <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">tf.control_dependencies<\/code> under the hood and features a possibility to group operations by device (e.g., CPU, GPU1, GPU2, etc.).<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nupdates = &#x5B;update1, update2\u2026]\r\nupdate_all = tf.group(*updates)\r\n<\/pre>\n<p>Sam then moved on to demonstrating assertions, conditional logic, and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">while<\/code> loops\u2014providing a view on various graphs and more code samples.<\/p>\n<p>Here are the <a href=\"https:\/\/github.com\/samjabrahams\/talks\/blob\/master\/tensorflow\/control_flow\/control_flow_slides.pdf\" target=\"_blank\">presentation slides<\/a> and the <a href=\"https:\/\/github.com\/samjabrahams\/talks\/blob\/master\/tensorflow\/control_flow\/Control%20Flow.ipynb\" target=\"_blank\">source code<\/a> used during the session.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Want_details_Watch_the_video\"><\/span>Want details? Watch the video!<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><center><script src=\"https:\/\/fast.wistia.com\/embed\/medias\/mokvzv31we.jsonp\" async><\/script><script src=\"https:\/\/fast.wistia.com\/assets\/external\/E-v1.js\" async><\/script><\/p>\n<div class=\"wistia_embed wistia_async_mokvzv31we\" style=\"height:358px;width:640px\">&nbsp;<\/div>\n<p><\/center><\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/visualizing-tensorflow-graphs-with-tensorboard\/\">Visualizing TensorFlow Graphs with TensorBoard<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/monitoring-and-visualizing-tensorflow-operations-in-real-time-with-guild-ai\/\">Monitoring and Visualizing TensorFlow Operations in Real Time with Guild AI<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/basic-concepts-and-manipulations-with-tensorflow\/\">Basic Concepts and Manipulations with TensorFlow<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"About_the_expert\"><\/span>About the expert<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><small><a href=\"https:\/\/www.linkedin.com\/in\/samjabrahams\/\" target=\"_blank\">Sam Abrahams<\/a> is a machine-learning engineer and educator, specializing in deep learning implementations and deployments. He is also a long-time TensorFlow contributor and a co-author of &#8220;TensorFlow for Machine Intelligence.&#8221; As a TensorFlow expert, Sam is experienced in teaching technical concepts and communicating effectively to people of varied technical skill and knowledge. You can also check out Sam&#8217;s <a href=\"https:\/\/github.com\/samjabrahams\" target=\"_blank\">GitHub profile <\/a>.<\/small><\/p>\n<hr\/>\n<p><center><small>This post was written by <a href=\"https:\/\/www.altoros.com\/blog\/author\/sophie.turol\/\">Sophie Turol<\/a> and edited by <a href=\"https:\/\/www.altoros.com\/blog\/author\/alex\/\">Alex Khizhniak<\/a>.<\/small><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>An example of control flow<\/p>\n<p>Sometimes, your models need to perform different computations depending on intermediate results or random chance. However, placing this sort of logic in the Python layer adds extra complexity and overhead to your code. TensorFlow provides a number of native operations to help create graphs with built-in [&#8230;]<\/p>\n","protected":false},"author":3,"featured_media":31248,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[748,916,749],"class_list":["post-31235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-machine-learning","tag-tensorbeat","tag-tensorflow"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros<\/title>\n<meta name=\"description\" content=\"This blog post explains how to create graphs with built-in logical branching structure so as to avoid extra complexity of the Python code.\" \/>\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.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros\" \/>\n<meta property=\"og:description\" content=\"An example of control flow Sometimes, your models need to perform different computations depending on intermediate results or random chance. However, placing this sort of logic in the Python layer adds extra complexity and overhead to your code. TensorFlow provides a number of native operations to help create graphs with built-in [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-22T16:51:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-12-04T20:23:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"424\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Sophia Turol\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sophia Turol\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/\"},\"author\":{\"name\":\"Sophia Turol\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/#\\\/schema\\\/person\\\/58194952af19fe7b2b830846e077a58e\"},\"headline\":\"Logical Graphs: Native Control Flow Operations in TensorFlow\",\"datePublished\":\"2017-06-22T16:51:18+00:00\",\"dateModified\":\"2018-12-04T20:23:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/\"},\"wordCount\":955,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/06\\\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif\",\"keywords\":[\"Machine Learning\",\"TensorBeat\",\"TensorFlow\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/\",\"url\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/\",\"name\":\"Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/06\\\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif\",\"datePublished\":\"2017-06-22T16:51:18+00:00\",\"dateModified\":\"2018-12-04T20:23:45+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/#\\\/schema\\\/person\\\/58194952af19fe7b2b830846e077a58e\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/06\\\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif\",\"contentUrl\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/06\\\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif\",\"width\":640,\"height\":424},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/logical-graphs-native-control-flow-operations-in-tensorflow\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Logical Graphs: Native Control Flow Operations in TensorFlow\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/#\\\/schema\\\/person\\\/58194952af19fe7b2b830846e077a58e\",\"name\":\"Sophia Turol\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/trello_card-96x96.jpg\",\"url\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/trello_card-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/trello_card-96x96.jpg\",\"caption\":\"Sophia Turol\"},\"description\":\"Sophia Turol is passionate about delivering well-structured articles that cater for picky technical audience. With 3+ years in technical writing and 5+ years in editorship, she enjoys collaboration with developers to create insightful, yet intelligible technical tutorials, overviews, and case studies. Sophie is enthusiastic about deep learning solutions\u2014TensorFlow in particular\u2014and PaaS systems, such as Cloud Foundry.\",\"url\":\"https:\\\/\\\/www.altoros.com\\\/blog\\\/author\\\/sophie-turol\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros","description":"This blog post explains how to create graphs with built-in logical branching structure so as to avoid extra complexity of the Python code.","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.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/","og_locale":"en_US","og_type":"article","og_title":"Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros","og_description":"An example of control flow Sometimes, your models need to perform different computations depending on intermediate results or random chance. However, placing this sort of logic in the Python layer adds extra complexity and overhead to your code. TensorFlow provides a number of native operations to help create graphs with built-in [...]","og_url":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/","og_site_name":"Altoros","article_published_time":"2017-06-22T16:51:18+00:00","article_modified_time":"2018-12-04T20:23:45+00:00","og_image":[{"width":640,"height":424,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif","type":"image\/gif"}],"author":"Sophia Turol","twitter_misc":{"Written by":"Sophia Turol","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#article","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/"},"author":{"name":"Sophia Turol","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/58194952af19fe7b2b830846e077a58e"},"headline":"Logical Graphs: Native Control Flow Operations in TensorFlow","datePublished":"2017-06-22T16:51:18+00:00","dateModified":"2018-12-04T20:23:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/"},"wordCount":955,"commentCount":0,"image":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif","keywords":["Machine Learning","TensorBeat","TensorFlow"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/","url":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/","name":"Logical Graphs: Native Control Flow Operations in TensorFlow | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif","datePublished":"2017-06-22T16:51:18+00:00","dateModified":"2018-12-04T20:23:45+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/58194952af19fe7b2b830846e077a58e"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/logical-graphs-native-control-flow-operations-in-tensorflow-tensorbeat-sam-abrahams-v2.gif","width":640,"height":424},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/logical-graphs-native-control-flow-operations-in-tensorflow\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Logical Graphs: Native Control Flow Operations in TensorFlow"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/58194952af19fe7b2b830846e077a58e","name":"Sophia Turol","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/05\/trello_card-96x96.jpg","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/05\/trello_card-96x96.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/05\/trello_card-96x96.jpg","caption":"Sophia Turol"},"description":"Sophia Turol is passionate about delivering well-structured articles that cater for picky technical audience. With 3+ years in technical writing and 5+ years in editorship, she enjoys collaboration with developers to create insightful, yet intelligible technical tutorials, overviews, and case studies. Sophie is enthusiastic about deep learning solutions\u2014TensorFlow in particular\u2014and PaaS systems, such as Cloud Foundry.","url":"https:\/\/www.altoros.com\/blog\/author\/sophie-turol\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/31235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=31235"}],"version-history":[{"count":14,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/31235\/revisions"}],"predecessor-version":[{"id":39646,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/31235\/revisions\/39646"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/31248"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=31235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=31235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=31235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}