[
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es6: true,\n    node: true,\n    jest: true,\n  },\n  extends: [\n    'eslint:recommended',\n    'airbnb',\n    'airbnb/hooks',\n    'plugin:import/typescript',\n  ],\n  parser: '@typescript-eslint/parser',\n  plugins: [\n    '@typescript-eslint',\n  ],\n  parserOptions: {\n    ecmaVersion: 2017,\n    sourceType: 'module',\n  },\n  rules: {\n    indent: ['error', 2],\n    'linebreak-style': ['error', 'unix'],\n    quotes: ['error', 'single'],\n    'no-console': 'warn',\n    'no-unused-vars': 'off',\n    '@typescript-eslint/no-unused-vars': [\n      'error',\n      { vars: 'all', args: 'after-used', ignoreRestSiblings: false },\n    ],\n    // Consider using explicit annotations for object literals and function return types even when they can be inferred.\n    '@typescript-eslint/explicit-function-return-type': 'warn',\n    'no-empty': 'warn',\n    'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.tsx'] }],\n    'import/extensions': [1, { extensions: ['.js', '.jsx', '.tsx'] }],\n    'no-use-before-define': 'off',\n    '@typescript-eslint/no-use-before-define': 'error',\n    'no-shadow': 'off',\n    '@typescript-eslint/no-shadow': 'error',\n    'react/require-default-props': 'off',\n    'no-useless-return': 'off',\n    'import/prefer-default-export': 'off',\n    'arrow-body-style': 'off',\n    'react/jsx-one-expression-per-line': 'off',\n  },\n};\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n.idea\n.vscode\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Tailwind generated styles\nsrc/styles/tailwind.css\n"
  },
  {
    "path": "LICENCE",
    "content": "MIT License\n\nCopyright (c) 2020 Oleksii Trekhleb\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.DEV.md",
    "content": "# Links Detector: Engineering Notes\n\n## Working with the repository\n\n#### Installation\n\n`yarn install`\n\n#### Running locally over `http`\n\n`yarn start`\n\nThe app will be available at [http://localhost:3000/links-detector/](http://localhost:3000/links-detector/)\n\n#### Running locally over `https`\n\nIt might be needed to get a camera access while testing the app on mobile devices through a local network.\n\n`yarn start-https`\n\nThe app will be available at [https://localhost:3000/links-detector/](http://localhost:3000/links-detector/). You may also access it through the mobile device at `https://<your.local.ip.here>/links/detector` if it is on the same network.\n\n#### Running the production build\n\nService workers and [PWA](https://web.dev/progressive-web-apps/) (Progressive Web App) features might be tested against production builds only. To build production version of the app and serve it, run:\n\n`yarn start-prod`\n\nThe app will be available at [http://localhost:4000/links-detector/](http://localhost:4000/links-detector/)\n\n## Version locks\n\n`react-router-dom v5.X.X` isn't compatible with `history v5.X.X`.\nTherefore `package.json` locked `history` package version to `v4.X.X`. See [StackOverflow question](https://stackoverflow.com/questions/62449663/react-router-with-custom-history-not-working) for more details.\n"
  },
  {
    "path": "README.md",
    "content": "# 📖 👆🏻 Links Detector\n\n> Links Detector makes printed links clickable _via your smartphone camera_. No need to type a link in, just scan and click on it.\n\n🚀 [**Launch Links Detector**](https://trekhleb.github.io/links-detector/) _(preferably from your smartphone)_\n\n[![Links Detector](./public/images/links-detector-banner-bg-black-2.png)](https://trekhleb.github.io/links-detector)\n\n[📖 Long-read about how the detector works](https://trekhleb.dev/blog/2020/printed-links-detection/)\n\n## 🤷🏻‍ The Problem\n\nSo you read a book or a magazine and see the link like `https://some-url.com/which/may/be/long?and_with_params=true`, but you can't click on it since it is printed. To visit this link you need to start typing it character by character in the browser's address bar, which may be pretty annoying and error-prone.\n\n## 💡 The Solution\n\nSimilarly to QR-code detection, we may try to \"teach\" the smartphone to _detect_ and _recognize_ printed links for us and to make them _clickable_. This way you'll do just _one_ click instead of _multiple_ keystrokes. Your operational complexity goes from `O(N)` to `O(1)`. \n\nThis is exactly what _Links Detector_ tries to achieve. It makes you do just one click on the link instead of typing the whole link manually character by character.\n\n![Links Detector Demo](./public/videos/demo-white.gif)\n\n## ⚠️ Limitations\n\nCurrently, the application is in _experimental_ _Alpha_ stage and has [many issues and limitations](https://github.com/trekhleb/links-detector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). So don't raise your expectations level too high until these issues are resolved 🤷🏻‍.\n\n## 🏋🏻‍ Model Training\n\nThe detection model was trained using [TensorFlow 2 Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection).\n\nYou may found the details of the training in [**📖 👆🏻 Making the Printed Links Clickable Using TensorFlow 2 Object Detection API**](https://trekhleb.dev/blog/2020/printed-links-detection/) long read article.\n\n## ⚙️ Technologies\n\n_Links Detector_ is a pure frontend [React](https://create-react-app.dev/) application written on [TypeScript](https://www.typescriptlang.org/). Links detection is happening right in your browser without the need of sending images to the server.\n\n_Links Detector_ is [PWA](https://web.dev/progressive-web-apps/) (Progressive Web App) friendly application made on top of a [Workbox](https://developers.google.com/web/tools/workbox) library. While you navigate through the app it tries to cache all resources to make them available offline and to make consequent visits much faster for you. You may also [install](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Developer_guide/Installing) Links Detector as a standalone app on your smartphone.\n\nLinks detection and recognition happens by means of [TensorFlow](https://www.tensorflow.org) and [Tesseract.js](https://github.com/naptha/tesseract.js) libraries which in turn rely on [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) and [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) browser support.\n\n## Author\n\n- [@trekhleb](https://trekhleb.dev)\n"
  },
  {
    "path": "articles/printed_links_detection/printed_links_detection.md",
    "content": "# 📖 👆🏻 Making the Printed Links Clickable Using TensorFlow 2 Object Detection API\n\n![Links Detector Cover](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/01-banner.png)\n\n## 📃 TL;DR\n\n_In this article we will start solving the issue of making the printed links (i.e. in a book or in a magazine) clickable via your smartphone camera._\n\nWe will use [TensorFlow 2 Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection) to train a custom object detector model to find positions and bounding boxes of the sub-strings like `https://` in the text image (i.e. in smartphone camera stream).\n\nThe text of each link (right continuation of `https://` bounding box) will be recognized by using [Tesseract](https://tesseract.projectnaptha.com/) library. The recognition part will not be covered in this article, but you may find the complete code example of the application in [links-detector repository](https://github.com/trekhleb/links-detector).   \n\n> 🚀 [**Launch Links Detector demo**](https://trekhleb.github.io/links-detector/) from your smartphone to see the final result.\n\n> 📝 [**Open links-detector repository**](https://github.com/trekhleb/links-detector) on GitHub to see the complete source code of the application.\n\nHere is how the final solution will look like:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\n> ⚠️ Currently the application is in _experimental_ _Alpha_ stage and has [many issues and limitations](https://github.com/trekhleb/links-detector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). So don't raise your expectations level too high until these issues are resolved 🤷🏻‍. Also, the purpose of this article is more about learning how to work with TensorFlow 2 Object Detection API rather than coming up with a production-ready model.\n\n> In case if Python code blocks in this article will lack proper formatting on this platform feel free to [to read the article on GitHub](https://github.com/trekhleb/links-detector/blob/master/articles/printed_links_detection/printed_links_detection.md)\n\n## 🤷🏻‍️ The Problem\n\nI work as a software engineer and in my own time, I learn Machine Learning as a hobby. But this is not the problem yet.\n\nI bought a printed book about Machine Learning recently and while I was reading through the first several chapters I've encountered many printed links in the text that looked like `https://tensorflow.org/` or `https://some-url.com/which/may/be/even/longer?and_with_params=true`.\n\n![Printed Links](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/02-printed-links.jpg)\n\nI saw all these links, but I couldn't click on them since they were printed (thanks, cap!). To visit these links I needed to start typing them character by character in the browser's address bar, which was pretty annoying and error-prone.\n\n## 💡 Possible Solution\n\nSo, I was thinking, what if, similarly to QR-code detection, we will try to \"teach\" the smartphone to _(1)_ _detect_ and _(2)_ _recognize_ printed links for us and to make them _clickable_? This way you would do just one click instead of multiple keystrokes. The operational complexity of \"clicking\" the printed links goes from `O(N)` to `O(1)`.\n\nThis is how the final workflow will look like:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\n## 📝 Solution Requirements\n\nAs I've mentioned earlier I'm just studying Machine Learning as a hobby. Thus, the purpose of this article is more about _learning_ how to work with TensorFlow 2 Object Detection API rather than coming up with a production-ready application.\n\nWith that being said, I simplified the solution requirements to the following:\n\n1. The detection and recognition processes should have a **close-to-real-time** performance (i.e. `0.5-1` frames per second) on a device like iPhone X. It means that the whole _detection + recognition_ process should take up to `2` seconds (pretty bearable as for the amateur project).\n2. Only **English** links should be supported.\n3. Only **dark text** (i.e. black or dark-grey) on **light background** (i.e. white or light-grey) should be supported.\n4. Only `https://` links should be supported for now (it is ok if our model will not recognize the `http://`, `ftp://`, `tcp://` or other types of links).\n\n## 🧩 Solution Breakdown\n\n### High-level breakdown\n\nLet's see how we could approach the problem on a high level.\n\n#### Option 1: Detection model on the back-end\n\n**The flow:**\n\n1. Get camera stream (frame by frame) on the client-side.\n2. Send each frame one by one over the network to the back-end.\n3. Do link detection and recognition on the back-end and send the response back to the client.\n4. Client draws the detection boxes with the clickable links.\n\n![Model on the back-end](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/04-frontend-backend.jpg)\n\n**Pros:**\n\n- 💚 The detection performance is not limited by the client's device. We may speed the detection up by scaling the service horizontally (adding more instances) and vertically (adding more cores/GPUs).\n- 💚 The model might be bigger since there is no need to upload it to the client-side. Downloading the `~10Mb` model on the client-side may be ok, but loading the `~100Mb` model might be a big issue for the client's network and application UX (user experience) otherwise.\n- 💚 It is possible to control who is using the model. Model is guarded behind the API, so we would have complete control over its callers/clients.\n\n**Cons:**\n\n- 💔 System complexity growth. The application tech stack grew from just `JavaScript` to, let's say, `JavaScript + Python`. We need to take care of the autoscaling.\n- 💔 Offline mode for the app is not possible since it needs an internet connection to work.\n- 💔 Too many HTTP requests between the client and the server may become a bottleneck at some point. Imagine if we would want to improve the performance of the detection, let's say, from `1` to `10+` frames per second. This means that each client will send `10+` requests per second. For `10` simultaneous clients it is already `100+` requests per second. The `HTTP/2` bidirectional streaming and `gRPC` might be useful in this case, but we're going back to the increased system complexity here.  \n- 💔 System becomes more expensive. Almost all points from the Pros section need to be paid for.\n\n#### Option 2: Detection model on the front-end\n\n**The flow:**\n\n1. Get camera stream (frame by frame) on the client-side.\n2. Do link detection and recognition on the client-side (without sending anything to the back-end).\n3. Client draws the detection boxes with the clickable links.\n\n![Model on the front-end](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/05-frontend-only.jpg)\n\n**Pros:**\n\n- 💚 System is less complex. We don't need to set up the servers, build the API, and introduce an additional Python stack to the system. \n- 💚 Offline mode is possible. The app doesn't need an internet connection to work since the model is fully loaded to the device. So the Progressive Web Application ([PWA](https://web.dev/progressive-web-apps/)) might be built to support that.\n- 💚 System is \"kind of\" scaling automatically. The more clients you have, the more cores and GPUs they bring. This is not a proper scaling solution though (more about that in a Cons section below). \n- 💚 System is cheaper. We only need a server for static assets (`HTML`, `JS`, `CSS`, model files, etc.). This may be done for free, let's say, on GitHub.\n- 💚 No issue with the growing number of HTTP requests per second to the server-side.\n\n**Cons:**\n\n- 💔 Only horizontal scaling is possible (each client will have its own CPU/GPU). Vertical scaling is not possible since we can't influence the client's device performance. As a result, we can't guarantee fast detection for low performant devices.\n- 💔 It is not possible to guard the model usage and control the callers/clients of the model. Everyone could download the model and re-use it. \n- 💔 Battery consumption of the client's device might become an issue. For the model to work it needs computational resources. So clients might not be happy with their iPhone getting warmer and warmer while the app is working.\n\n#### High-level conclusion\n\nSince the purpose of the project was more about learning and not coming up with a production-ready solution _I decided to go with the second option of serving the model from the client side_. This made the whole project much cheaper (actually with GitHub it was free to host it), and I could focus more on Machine Learning than on the autoscaling back-end infrastructure.\n\n### Lower level breakdown\n\nOk, so we've decided to go with the serverless solution. Now we have an image from the camera stream as an input that looks something like this:\n\n![Printed Links Input](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/06-printed-links-clean.jpg)\n\nWe need to solve two sub-tasks for this image:\n\n1. Links **detection** (finding the position and bounding boxes of the links)\n2. Links **recognition** (recognizing the text of the links)\n\n#### Option 1: Tesseract based solution\n\nThe first and the most obvious approach would be to solve the _Optical Character Recognition_ ([OCR](https://en.wikipedia.org/wiki/Optical_character_recognition)) task by recognizing the whole text of the image by using, let's say, [Tesseract.js](https://github.com/naptha/tesseract.js) library. It returns the bounding boxes of the paragraphs, text lines, and text blocks along with the recognized text.\n\n![Recognized text with bounding boxes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/07-printed-links-boxes.jpg)\n\nWe may try then to extract the links from the recognized text lines or text blocks with a regular expression like [this one](https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url) (example is on TypeScript):\n\n```typescript\nconst URL_REG_EXP = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi;\n\nconst extractLinkFromText = (text: string): string | null => {\n  const urls: string[] | null = text.match(URL_REG_EXP);\n  if (!urls || !urls.length) {\n    return null;\n  }\n  return urls[0];\n};\n```\n\n💚 Seems like the issue is solved in a pretty straightforward and simple way:\n\n- We know the bounding boxes of the links\n- We also know the text of the links to make them clickable\n\n💔 The thing is that the _recognition + detection_ time may vary from `2` to `20+` seconds depending on the size of the text, on the amount of \"something that looks like a text\" on the image, on the image quality and on other factors. So it will be really hard to achieve those `0.5-1` frames per second to make the user experience at least _close_ to real-time.\n\n💔 Also if we would think about it, we're asking the library to recognize the **whole** text from the image for us even though it might contain only one or two links in it (i.e. only ~10% of the text might be useful for us), or it may even not contain the links at all. In this case, it sounds like a waste of computational resources. \n\n#### Option 2: Tesseract + TensorFlow based solution\n\nWe could make Tesseract work faster if we used some _additional \"adviser\" algorithm_ prior to the links text recognition. This \"adviser\" algorithm should detect, but not recognize, _the leftmost position_ of each link on the image if there are any. This will allow us to speed up the recognition part by following these rules:\n\n1. If the image does not contain any link we should not call Tesseract detection/recognition at all.\n2. If the image does have the links then we need to ask Tesseract to recognize only those parts of the image that contains the links. We're not interested in spending the time for recognition of the irrelevant text that does not contain the links.\n\nThe \"adviser\" algorithm that will take place before the Tesseract should work with a constant time regardless of the image quality, or the presence/absence of the text on the image. It also should be pretty fast and detect the leftmost positions of the links for less than `1s` so that we could satisfy the \"close-to-real-time\" requirement (i.e. on iPhone X).\n\n> 💡 So what if we will use another object detection model to help us find all occurrences of the `https://` substrings (every secure link has this prefix, doesn't it) in the image? Then, having these `https://` bounding boxes in the text we may extract the right-side continuation of them and send them to the Tesseract for text recognition.\n\nTake a look at the picture below:\n\n![Tesseract and TensorFlow based solution](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/08-tesseract-vs-tensorflow.jpg)\n\nYou may notice that Tesseract needs to do **much less** work in case if it would have some hints about where are the links might be located (see the number of blue boxes on both pictures).\n\nSo the question now is which object detection model we should choose and how to re-train it to support the detection of the custom `https://` objects.  \n\n> Finally! We've got closer to the TensorFlow part of the article 😀\n\n## 🤖 Selecting the Object Detection Model\n\nTraining a new object detection model is not a reasonable option in our context because of the following reasons:\n\n- 💔 The training process might take days/weeks and bucks.\n- 💔 We most probably won't be able to collect hundreds of thousands of _labeled_ images of the books that have links in them (we might try to generate them though, but more about that later). \n\nSo instead of creating a new model, we should better teach an existing object detection model to do the custom object detection for us (to do the [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning)). In our case, the \"custom objects\" would be the images with `https://` text drawn in them. This approach has the following benefits:\n\n- 💚 The dataset might be much smaller. We don't need to collect hundreds of thousands of the labeled images. Instead, we may do `~100` pictures and label them manually. This is because the model is already pre-trained on the general dataset like [COCO dataset](https://cocodataset.org/#home) and already learned how to extract general image features.\n- 💚 The training process will be much faster (minutes/hours on GPU instead of days/weeks). Again, this is because of a smaller dataset (smaller batches) and because of fewer trainable parameters.\n\nWe may choose the existing model from [TensorFlow 2 Detection Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md) which provides a collection of detection models pre-trained on the [COCO 2017 dataset](https://cocodataset.org/#home). Now it contains `~40` model variations to choose from.\n\nTo re-train and fine-tune the model on the custom dataset we will use a [TensorFlow 2 Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection). The TensorFlow Object Detection API is an open-source framework built on top of [TensorFlow](https://www.tensorflow.org/) that makes it easy to construct, train, and deploy object detection models.\n\nIf you follow the [Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md) link you will find the _detection speed_ and _accuracy_ for each model.\n\n![Model Zoo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/09-model-zoo.jpg)\n\n_Image source: [TensorFlow Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md) repository_\n\nOf course, we would want to find the right balance between the detection **speed** and **accuracy** while picking the model. But what might be even more important in our case is the **size** of the model since it will be loaded to the client-side.\n\nThe size of the archived model might vary drastically from `~20Mb` to `~1Gb`. Here are several examples:\n\n- `1386 (Mb)` `centernet_hg104_1024x1024_kpts_coco17_tpu-32`\n- ` 330 (Mb)` `centernet_resnet101_v1_fpn_512x512_coco17_tpu-8`\n- ` 195 (Mb)` `centernet_resnet50_v1_fpn_512x512_coco17_tpu-8`\n- ` 198 (Mb)` `centernet_resnet50_v1_fpn_512x512_kpts_coco17_tpu-8`\n- ` 227 (Mb)` `centernet_resnet50_v2_512x512_coco17_tpu-8`\n- ` 230 (Mb)` `centernet_resnet50_v2_512x512_kpts_coco17_tpu-8`\n- `  29 (Mb)` `efficientdet_d0_coco17_tpu-32`\n- `  49 (Mb)` `efficientdet_d1_coco17_tpu-32`\n- `  60 (Mb)` `efficientdet_d2_coco17_tpu-32`\n- `  89 (Mb)` `efficientdet_d3_coco17_tpu-32`\n- ` 151 (Mb)` `efficientdet_d4_coco17_tpu-32`\n- ` 244 (Mb)` `efficientdet_d5_coco17_tpu-32`\n- ` 376 (Mb)` `efficientdet_d6_coco17_tpu-32`\n- ` 376 (Mb)` `efficientdet_d7_coco17_tpu-32`\n- ` 665 (Mb)` `extremenet`\n- ` 427 (Mb)` `faster_rcnn_inception_resnet_v2_1024x1024_coco17_tpu-8`\n- ` 424 (Mb)` `faster_rcnn_inception_resnet_v2_640x640_coco17_tpu-8`\n- ` 337 (Mb)` `faster_rcnn_resnet101_v1_1024x1024_coco17_tpu-8`\n- ` 337 (Mb)` `faster_rcnn_resnet101_v1_640x640_coco17_tpu-8`\n- ` 343 (Mb)` `faster_rcnn_resnet101_v1_800x1333_coco17_gpu-8`\n- ` 449 (Mb)` `faster_rcnn_resnet152_v1_1024x1024_coco17_tpu-8`\n- ` 449 (Mb)` `faster_rcnn_resnet152_v1_640x640_coco17_tpu-8`\n- ` 454 (Mb)` `faster_rcnn_resnet152_v1_800x1333_coco17_gpu-8`\n- ` 202 (Mb)` `faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8`\n- ` 202 (Mb)` `faster_rcnn_resnet50_v1_640x640_coco17_tpu-8`\n- ` 207 (Mb)` `faster_rcnn_resnet50_v1_800x1333_coco17_gpu-8`\n- ` 462 (Mb)` `mask_rcnn_inception_resnet_v2_1024x1024_coco17_gpu-8`\n- `  86 (Mb)` `ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8`\n- `  44 (Mb)` `ssd_mobilenet_v2_320x320_coco17_tpu-8`\n- `  20 (Mb)` `ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8`\n- `  20 (Mb)` `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`\n- ` 369 (Mb)` `ssd_resnet101_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 369 (Mb)` `ssd_resnet101_v1_fpn_640x640_coco17_tpu-8`\n- ` 481 (Mb)` `ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 480 (Mb)` `ssd_resnet152_v1_fpn_640x640_coco17_tpu-8`\n- ` 233 (Mb)` `ssd_resnet50_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 233 (Mb)` `ssd_resnet50_v1_fpn_640x640_coco17_tpu-8`\n\nThe **`ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`** model might be a good fit in our case:\n\n- 💚 It is relatively lightweight: `20Mb` archived.\n- 💚 It is pretty fast: `39ms` for the detection.\n- 💚 It uses the MobileNet v2 network as a feature extractor which is optimized for usage on mobile devices to reduce energy consumption.\n- 💚 It does the object detection for the whole image and for all objects in it **in one go** regardless of the image content (no [regions proposal](https://en.wikipedia.org/wiki/Region_Based_Convolutional_Neural_Networks) step is involved which makes the detection faster). \n- 💔 It is not the most accurate model though (everything is a tradeoff ⚖️).\n\nThe model name encodes some several important characteristics that you may read more about if you want:\n\n- The expected image input size is `640x640px`.\n- The model implements [Single Shot MultiBox Detector](https://arxiv.org/abs/1512.02325) (SSD) and [Feature Pyramid Network](https://arxiv.org/abs/1612.03144) (FPN).\n- [MobileNet v2](https://ai.googleblog.com/2018/04/mobilenetv2-next-generation-of-on.html) convolutional neural network ([CNN](https://en.wikipedia.org/wiki/Convolutional_neural_network)) is used as a feature extractor.\n- The model was trained on [COCO dataset](https://cocodataset.org/#home)\n\n## 🛠 Installing Object Detection API \n\nIn this article, we're going to install the Tensorflow 2 Object Detection API _as a Python package_. It is convenient in case if you're experimenting in [Google Colab](https://colab.research.google.com/) (recommended) or in [Jupyter](https://jupyter.org/try). For both cases no local installation is needed, you may experiment right in your browser.\n\nYou may also follow the [official documentation](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2.md) if you would prefer to install Object Detection API via Docker.\n\n> If you stuck with something during the API installation or during the dataset preparation try to read through the [TensorFlow 2 Object Detection API tutorial](https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/index.html) which adds a lot of useful details to this process.\n\nFirst, let's clone the [API repository](https://github.com/tensorflow/models):\n\n```bash\ngit clone --depth 1 https://github.com/tensorflow/models\n```\n\n_output →_\n\n```\nCloning into 'models'...\nremote: Enumerating objects: 2301, done.\nremote: Counting objects: 100% (2301/2301), done.\nremote: Compressing objects: 100% (2000/2000), done.\nremote: Total 2301 (delta 561), reused 922 (delta 278), pack-reused 0\nReceiving objects: 100% (2301/2301), 30.60 MiB | 13.90 MiB/s, done.\nResolving deltas: 100% (561/561), done.\n```\n\nNow, let's compile the [API proto files](https://github.com/tensorflow/models/tree/master/research/object_detection/protos) into Python files by using [protoc](https://grpc.io/docs/protoc-installation/) tool:\n\n```bash\ncd ./models/research\nprotoc object_detection/protos/*.proto --python_out=.\n```\n\nFinally, let's install the TF2 version of [setup.py](https://github.com/tensorflow/models/blob/master/research/object_detection/packages/tf2/setup.py) via `pip`:\n\n```bash\ncp ./object_detection/packages/tf2/setup.py .\npip install . --quiet\n```\n\n> It is possible that the last step will fail because of some dependency errors. In this case, you might want to run `pip install . --quiet` one more time.\n\nWe may test that installation went successfully by running the following tests:\n\n```bash\npython object_detection/builders/model_builder_tf2_test.py\n```\n\nYou should see the logs that end with something similar to this:\n\n```\n[       OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor\n----------------------------------------------------------------------\nRan 20 tests in 45.072s\n\nOK (skipped=1)\n```\n\nThe TensorFlow Object Detection API is installed! You may now use the scripts that API provides for doing the model [inference](https://github.com/tensorflow/models/blob/master/research/object_detection/colab_tutorials/inference_tf2_colab.ipynb), [training](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_training_and_evaluation.md) or [fine-tuning](https://github.com/tensorflow/models/blob/master/research/object_detection/colab_tutorials/eager_few_shot_od_training_tf2_colab.ipynb).\n\n## ⬇️ Downloading the Pre-Trained Model\n\nLet's download our selected `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` model from the TensorFlow Model Zoo and check how it does the general object detection (detection of the objects of classes from COCO dataset like \"cat\", \"dog\", \"car\", etc.).\n\nWe will use the [get_file()](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file) TensorFlow helper to download the archived model from the URL and unpack it.\n\n```python\nimport tensorflow as tf\nimport pathlib\n\nMODEL_NAME = 'ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8'\nTF_MODELS_BASE_PATH = 'http://download.tensorflow.org/models/object_detection/tf2/20200711/'\nCACHE_FOLDER = './cache'\n\ndef download_tf_model(model_name, cache_folder):\n    model_url = TF_MODELS_BASE_PATH + model_name + '.tar.gz'\n    model_dir = tf.keras.utils.get_file(\n        fname=model_name, \n        origin=model_url,\n        untar=True,\n        cache_dir=pathlib.Path(cache_folder).absolute()\n    )\n    return model_dir\n\n# Start the model download.\nmodel_dir = download_tf_model(MODEL_NAME, CACHE_FOLDER)\nprint(model_dir)\n```\n\n_output →_\n\n```\n/content/cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nHere is how the folder structure looks so far:\n\n![Cache Folder](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/10-cache-folder.jpg)\n\nThe `checkpoint` folder contains the snapshot of the pre-trained model.\n\nThe `pipeline.config` file contains the detection settings of the model. We'll come back to this file later when we will need to fine-tune the model.\n\n## 🏄🏻‍️ Trying the Model (Doing the Inference)\n\nFor now, the model can detect the object of [90 COCO dataset classes](https://cocodataset.org/#explore) like a `car`, `bird`, `hot dog` etc.\n\n![COCO classes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/11-coco-classes.jpg)\n\n_Image source: [COCO dataset](https://cocodataset.org/#explore) website_\n\nLet's see how the model performs on some general images that contain the objects of these classes.\n\n### Loading COCO labels\n\nObject Detection API already has a complete set of COCO labels (classes) defined for us.\n\n```python\nimport os\n\n# Import Object Detection API helpers.\nfrom object_detection.utils import label_map_util\n\n# Loads the COCO labels data (class names and indices relations).\ndef load_coco_labels():\n    # Object Detection API already has a complete set of COCO classes defined for us.\n    label_map_path = os.path.join(\n        'models/research/object_detection/data',\n        'mscoco_complete_label_map.pbtxt'\n    )\n    label_map = label_map_util.load_labelmap(label_map_path)\n\n    # Class ID to Class Name mapping.\n    categories = label_map_util.convert_label_map_to_categories(\n        label_map,\n        max_num_classes=label_map_util.get_max_label_map_index(label_map),\n        use_display_name=True\n    )\n    category_index = label_map_util.create_category_index(categories)\n    \n    # Class Name to Class ID mapping.\n    label_map_dict = label_map_util.get_label_map_dict(label_map, use_display_name=True)\n\n    return category_index, label_map_dict\n\n# Load COCO labels.\ncoco_category_index, coco_label_map_dict = load_coco_labels()\n\nprint('coco_category_index:', coco_category_index)\nprint('coco_label_map_dict:', coco_label_map_dict)\n```\n\n_output →_\n\n```\ncoco_category_index:\n{\n    1: {'id': 1, 'name': 'person'},\n    2: {'id': 2, 'name': 'bicycle'},\n    ...\n    90: {'id': 90, 'name': 'toothbrush'},\n}\n\ncoco_label_map_dict:\n{\n    'background': 0,\n    'person': 1,\n    'bicycle': 2,\n    'car': 3,\n    ...\n    'toothbrush': 90,\n}\n```\n\n### Build a detection function\n\nWe need to create a detection function that will use the pre-trained model we've downloaded to do the object detection.\n\n```python\nimport tensorflow as tf\n\n# Import Object Detection API helpers.\nfrom object_detection.utils import config_util\nfrom object_detection.builders import model_builder\n\n# Generates the detection function for specific model and specific model's checkpoint\ndef detection_fn_from_checkpoint(config_path, checkpoint_path):\n    # Build the model.\n    pipeline_config = config_util.get_configs_from_pipeline_file(config_path)\n    model_config = pipeline_config['model']\n    model = model_builder.build(\n        model_config=model_config,\n        is_training=False,\n    )\n\n    # Restore checkpoints.\n    ckpt = tf.compat.v2.train.Checkpoint(model=model)\n    ckpt.restore(checkpoint_path).expect_partial()\n\n    # This is a function that will do the detection.\n    @tf.function\n    def detect_fn(image):\n        image, shapes = model.preprocess(image)\n        prediction_dict = model.predict(image, shapes)\n        detections = model.postprocess(prediction_dict, shapes)\n\n        return detections, prediction_dict, tf.reshape(shapes, [-1])\n    \n    return detect_fn\n\ninference_detect_fn = detection_fn_from_checkpoint(\n    config_path=os.path.join('cache', 'datasets', MODEL_NAME, 'pipeline.config'),\n    checkpoint_path=os.path.join('cache', 'datasets', MODEL_NAME, 'checkpoint', 'ckpt-0'),\n)\n```\n\nThis `inference_detect_fn` function will accept an image and will return the detected objects' info.\n\n### Loading the images for inference\n\nLet's try to detect the object on this image:\n\n![General Object Inference](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/12-inference-01.jpg)\n\n_Image source: [oleksii_trekhleb](https://www.instagram.com/oleksii_trekhleb/?hl=en) Instagram_\n\nTo do that let's save the image to the `inference/test/` folder of our project. If you're using Google Colab you may create this folder and upload the image manually.\n\nHere is how the folder structure looks so far:\n\n![Folder structure](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/14-inference-folders.jpg)\n\n```python\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\n# Creating a TensorFlow dataset of just one image.\ninference_ds = tf.keras.preprocessing.image_dataset_from_directory(\n  directory='inference',\n  image_size=(640, 640),\n  batch_size=1,\n  shuffle=False,\n  label_mode=None\n)\n# Numpy version of the dataset.\ninference_ds_numpy = list(inference_ds.as_numpy_iterator())\n\n# You may preview the images in dataset like this.\nplt.figure(figsize=(14, 14))\nfor i, image in enumerate(inference_ds_numpy):\n    plt.subplot(2, 2, i + 1)\n    plt.imshow(image[0].astype(\"uint8\"))\n    plt.axis(\"off\")\nplt.show()\n```\n\n### Running the detection on test data\n\nNow we're ready to run the detection. The `inference_ds_numpy[0]` array stores the pixel data for the first image in `Numpy` format.\n\n```python\ndetections, predictions_dict, shapes = inference_detect_fn(\n    inference_ds_numpy[0]\n)\n```\n\nLet's see the shapes of the output:\n\n```python\nboxes = detections['detection_boxes'].numpy()\nscores = detections['detection_scores'].numpy()\nclasses = detections['detection_classes'].numpy()\nnum_detections = detections['num_detections'].numpy()[0]\n\nprint('boxes.shape: ', boxes.shape)\nprint('scores.shape: ', scores.shape)\nprint('classes.shape: ', classes.shape)\nprint('num_detections:', num_detections)\n```\n\n_output →_\n\n```\nboxes.shape:  (1, 100, 4)\nscores.shape:  (1, 100)\nclasses.shape:  (1, 100)\nnum_detections: 100.0\n```\n\nThe model has made a `100` detections for us. It doesn't mean that it found `100` objects on the image though. It means that the model has `100` slots, and it can detect `100` objects at max on a single image. Each detection has a score that represents the confidence of the model about it. The bounding boxes for each detection are stored in the `boxes` array. The scores or confidences of the model about each detection are stored in the `scores` array. Finally, the `classes` array stores the labels (classes) for each detection.\n\nLet's check the first 5 detections:\n\n```python\nprint('First 5 boxes:')\nprint(boxes[0,:5])\n\nprint('First 5 scores:')\nprint(scores[0,:5])\n\nprint('First 5 classes:')\nprint(classes[0,:5])\n\nclass_names = [coco_category_index[idx + 1]['name'] for idx in classes[0]]\nprint('First 5 class names:')\nprint(class_names[:5])\n```\n\n_output →_\n\n```\nFirst 5 boxes:\n[[0.17576033 0.84654826 0.25642633 0.88327974]\n [0.5187813  0.12410264 0.6344235  0.34545377]\n [0.5220358  0.5181462  0.6329132  0.7669856 ]\n [0.50933677 0.7045719  0.5619138  0.7446198 ]\n [0.44761637 0.51942706 0.61237675 0.75963426]]\n\nFirst 5 scores:\n[0.6950246 0.6343004 0.591157  0.5827219 0.5415643]\n\nFirst 5 classes:\n[9. 8. 8. 0. 8.]\n\nFirst 5 class names:\n['traffic light', 'boat', 'boat', 'person', 'boat']\n```\n\nThe model sees the `traffic light`, three `boats`, and a `person` on the image. We may confirm that indeed these objects are seen on the image.\n\nFrom the `scores` array may see that the model is most confident (close to 70% of probability) in the `traffic light` object.\n\nEach entry of `boxes` array is `[y1, x1, y2, x2]`, where `(x1, y1)` and `(x2, y2)` are the top-left and bottom-right corners of the bounding box.\n\nLet's visualize the detection boxes:\n\n```python\n# Importing Object Detection API helpers.\nfrom object_detection.utils import visualization_utils\n\n# Visualizes the bounding boxes on top of the image.\ndef visualize_detections(image_np, detections, category_index):\n    label_id_offset = 1\n    image_np_with_detections = image_np.copy()\n\n    visualization_utils.visualize_boxes_and_labels_on_image_array(\n        image_np_with_detections,\n        detections['detection_boxes'][0].numpy(),\n        (detections['detection_classes'][0].numpy() + label_id_offset).astype(int),\n        detections['detection_scores'][0].numpy(),\n        category_index,\n        use_normalized_coordinates=True,\n        max_boxes_to_draw=200,\n        min_score_thresh=.4,\n        agnostic_mode=False,\n    )\n\n    plt.figure(figsize=(12, 16))\n    plt.imshow(image_np_with_detections)\n    plt.show()\n\n# Visualizing the detections.\nvisualize_detections(\n    image_np=tf.cast(inference_ds_numpy[0][0], dtype=tf.uint32).numpy(),\n    detections=detections,\n    category_index=coco_category_index,\n)\n```\n\nHere is the output:\n\n![Inference result](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/14-inference-results-01.jpg)\n\nIf we will do the detection for the text image here is what we will see:\n\n![Inference result for text image](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/15-inference-results-02.jpg)\n\nThe model couldn't detect anything on this image. This is what we're going to change, we want to teach the model to \"see\" the `https://` prefixes on this image.\n\n## 📝 Preparing the Custom Dataset\n\nTo \"teach\" the `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` model to detect the custom objects which are _not_ a part of a COCO dataset we need to do the fine-tune training on a new custom dataset.\n\nThe datasets for object detection consist of two parts:\n\n1. The image itself (i.e. the image of the book page)\n2. The boundary boxes that show where exactly on the image the custom objects are located.\n\n![Bounding Boxes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/16-detection-boxes.jpg)\n\nIn the example above each box has `left-top` and `right-bottom` coordinates in _absolute_ values (in pixels). However, there are also different formats of writing the location of the bounding boxes exists. For example, we may locate the bounding box by setting the coordinate of its `center point` and its `width` and `height`. We might also use _relative_ values (percentage of the width and height of the image) for setting up the coordinates. But you've got the idea, the network needs to know what the image is and where on the image the objects are located.\n\nNow, how can we get the custom dataset for training? We have three options here:\n\n1. _Re-use_ the existing dataset.\n2. _Generate_ a new dataset of fake book images.\n3. _Create_ the dataset manually by taking or downloading the pictures of real book pages which contain `https://` links and labeling all bounding boxes.\n\n### Option 1: Re-using the existing dataset\n\nThere are plenty of the datasets that are shared to be re-used by researches. We could start from the following resources to find a proper dataset:\n\n- [Google Dataset Search](https://datasetsearch.research.google.com/)\n- [Kaggle Datasets](https://www.kaggle.com/datasets)\n- [awesome-public-datasets](https://github.com/awesomedata/awesome-public-datasets) repository\n- etc.\n\n💚 If you could find the needed dataset and its license allows you to re-use it, it is probably the fastest way to get straight to the model training.\n\n💔 I couldn't find the dataset with labeled `https://` prefixes though.\n\nSo we need to skip this option.\n\n### Option 2: Generating the synthetic dataset\n\nThere are tools that exist (i.e. [keras_ocr](https://keras-ocr.readthedocs.io/en/latest/examples/end_to_end_training.html#generating-synthetic-data)) that might help us to generate random text, include the link in it, and draw it on images with some background and distortions.\n\n💚 The cool part about this approach is that we have the freedom to generate training examples for different _fonts_, _ligatures_, _text colors_, _background colors_. This is very useful if we want to avoid the [model overfitting](https://en.wikipedia.org/wiki/Overfitting) during the training (so that the model could generalize well to unseen real-world examples instead of failing once the background shade is changed for a bit).\n\n💚 It is also possible to generate a variety of link types like `http://`, `http://`, `ftp://`, `tcp://` etc. Otherwise, it might be hard to find enough real-world examples of this kind of links for training.\n\n💚 Another benefit of this approach is that we could generate as many training examples as we want. We're not limited to the number of pages of the printed book we've found for the dataset. Increasing the number of training examples may also increase the accuracy of the model.\n\n💔 It is possible though to misuse the generator and to generate the training images that will be quite different from real-world examples. Let's say we may use the wrong and unrealistic distortions for the page (i.e. using waves bend instead of the arc one). In this case, the model will not generalize well to real-world examples.\n\n> I see this approach as a really promising one. It may help to overcome many model issues (more on that below). I didn't try it yet though. But it might be a good candidate for another article.\n\n### Option 3: Creating the dataset manually\n\nThe most straightforward way though is to get the book (or books) and to make the pictures of the pages with the links and to label all of them manually.\n\nThe good news is that the dataset might be pretty small (hundreds of images might be enough) because we're not going to train the model _from scratch_ but instead, we're going to do a [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning) (also see the [few-shot learning](https://paperswithcode.com/task/few-shot-learning).)\n\n💚 In this case, the training dataset will be really close to real-world data. You will literally take the printed book, take a picture of it with realistic fonts, bends, shades, perspectives, and colors.\n\n💔 Even though it doesn't require a lot of images it may still be time-consuming.\n\n💔 It is hard to come up with a diverse database where training examples would have different fonts, background colors, and different types of links (we need to find many diverse books and magazines to accomplish that).\n\nSince the article has a learning purpose and since we're not trying to win an object detection competition let's go with this option for now and try to create a dataset by ourselves.\n\n### Preprocessing the data\n\nSo, I've ended up shooting `125` images of the book pages that contain one or more `https://` links on them.\n\n![Raw Dataset](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/17-dataset-raw.jpg)\n\nI put all these images in the `dataset/printed_links/raw` folder.\n\nNext, I'm going to preprocess the images by doing the following:\n\n- **Resize** each image to the width of `1024px` (they are too big originally and have a width of `3024px`)\n- **Crop** each image to make them squared (this is optional, and we could just resize the image by simply squeezing it, but I want the model to be trained on realistic proportions of `https:` boxes).\n- **Rotate** image if needed by applying the [exif](https://en.wikipedia.org/wiki/Exif) metadata.\n- **Greyscale** the image (we don't need the model to take the colors into consideration).\n- **Increase brightness**\n- **Increase contrast**\n- **Increase sharpness**\n\nRemember, that once we've decided to apply these transformations and adjustments to the dataset we need to do the same in the future for each image that we will send to the model for detection.\n\nHere is how we could apply these adjustments to the image using Python:\n\n```python\nimport os\nimport math\nimport shutil\n\nfrom pathlib import Path\nfrom PIL import Image, ImageOps, ImageEnhance\n\n# Resize an image.\ndef preprocess_resize(target_width):\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        (width, height) = image.size\n        ratio = width / height\n\n        if width > target_width:\n            target_height = math.floor(target_width / ratio)\n            log(f'Resizing: To size {target_width}x{target_height}')\n            image = image.resize((target_width, target_height))\n        else:\n            log('Resizing: Image already resized, skipping...')\n\n        return image\n    return preprocess\n\n# Crop an image.\ndef preprocess_crop_square():\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        (width, height) = image.size\n        \n        left = 0\n        top = 0\n        right = width\n        bottom = height\n        \n        crop_size = min(width, height)\n        \n        if width >= height:\n            # Horizontal image.\n            log(f'Squre cropping: Horizontal {crop_size}x{crop_size}')\n            left = width // 2 - crop_size // 2\n            right = left + crop_size\n        else:\n            # Vetyical image.\n            log(f'Squre cropping: Vertical {crop_size}x{crop_size}')\n            top = height // 2 - crop_size // 2\n            bottom = top + crop_size\n\n        image = image.crop((left, top, right, bottom))\n        return image\n    return preprocess\n\n# Apply exif transpose to an image.\ndef preprocess_exif_transpose():\n    # @see: https://pillow.readthedocs.io/en/stable/reference/ImageOps.html\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        log('EXif transpose')\n        image = ImageOps.exif_transpose(image)\n        return image\n    return preprocess\n\n# Apply color transformations to the image.\ndef preprocess_color(brightness, contrast, color, sharpness):\n    # @see: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        log('Coloring')\n        \n        enhancer = ImageEnhance.Color(image)\n        image = enhancer.enhance(color)\n\n        enhancer = ImageEnhance.Brightness(image)\n        image = enhancer.enhance(brightness)\n        \n        enhancer = ImageEnhance.Contrast(image)\n        image = enhancer.enhance(contrast)\n        \n        enhancer = ImageEnhance.Sharpness(image)\n        image = enhancer.enhance(sharpness)\n        \n        return image\n    return preprocess\n\n# Image pre-processing pipeline.\ndef preprocess_pipeline(src_dir, dest_dir, preprocessors=[], files_num_limit=0, override=False):\n    # Create destination folder if not exists.\n    Path(dest_dir).mkdir(parents=False, exist_ok=True)\n    \n    # Get the list of files to be copied.\n    src_file_names = os.listdir(src_dir)\n    files_total = files_num_limit if files_num_limit > 0 else len(src_file_names)\n    files_processed = 0\n    \n    # Logger function.\n    def preprocessor_log(message):\n        print('  ' + message)\n    \n    # Iterate through files.\n    for src_file_index, src_file_name in enumerate(src_file_names):\n        if files_num_limit > 0 and src_file_index >= files_num_limit:\n            break\n            \n        # Copy file.        \n        src_file_path = os.path.join(src_dir, src_file_name)\n        dest_file_path = os.path.join(dest_dir, src_file_name)\n        \n        progress = math.floor(100 * (src_file_index + 1) / files_total)\n        print(f'Image {src_file_index + 1}/{files_total} | {progress}% |  {src_file_path}')\n        \n        if not os.path.isfile(src_file_path):\n            preprocessor_log('Source is not a file, skipping...\\n')\n            continue\n        \n        if not override and os.path.exists(dest_file_path):\n            preprocessor_log('File already exists, skipping...\\n')\n            continue\n            \n        shutil.copy(src_file_path, dest_file_path)\n        files_processed += 1\n        \n        # Preprocess file.\n        image = Image.open(dest_file_path)\n        \n        for preprocessor in preprocessors:\n            image = preprocessor(image, preprocessor_log)\n        \n        image.save(dest_file_path, quality=95)\n        print('')\n        \n    print(f'{files_processed} out of {files_total} files have been processed')\n\n# Launching the image preprocessing pipeline.\npreprocess_pipeline(\n    src_dir='dataset/printed_links/raw',\n    dest_dir='dataset/printed_links/processed',\n    override=True,\n    # files_num_limit=1,\n    preprocessors=[\n        preprocess_exif_transpose(),\n        preprocess_resize(target_width=1024),\n        preprocess_crop_square(),\n        preprocess_color(brightness=2, contrast=1.3, color=0, sharpness=1),\n    ]\n)\n```\n\nAs a result, all processed images were saved to the `dataset/printed_links/processed` folder.\n\n![Dataset Processed](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/18-dataset-processed.jpg)\n\nYou may preview the images like this:\n\n```python\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef preview_images(images_dir, images_num=1, figsize=(15, 15)):\n    image_names = os.listdir(images_dir)\n    image_names = image_names[:images_num]\n    \n    num_cells = math.ceil(math.sqrt(images_num))\n    figure = plt.figure(figsize=figsize)\n    \n    for image_index, image_name in enumerate(image_names):\n        image_path = os.path.join(images_dir, image_name)\n        image = Image.open(image_path)\n        \n        figure.add_subplot(num_cells, num_cells, image_index + 1)\n        plt.imshow(np.asarray(image))\n    \n    plt.show()\n\npreview_images('dataset/printed_links/processed', images_num=4, figsize=(16, 16))\n```\n\n### Labeling the dataset\n\nTo do the labeling (to mark the locations of the objects that we're interested in, namely the `https://` prefixes) we may use the [LabelImg](https://github.com/tzutalin/labelImg) graphical image annotation tool.\n\n> For this step you might want to install the LabelImg tool on your local machine (not in Colab). You may find the detailed installation instructions in [LabelImg README](https://github.com/tzutalin/labelImg).\n\nOnce you have LabelImg tool installed you may launch it for the `dataset/printed_links/processed` folder from the root of your project like this:\n\n```bash\nlabelImg dataset/printed_links/processed\n```\n\nThen you'll need to label all the images from the `dataset/printed_links/processed` folder and save annotations as XML files to `dataset/printed_links/labels/xml/` folder.\n\n![Labeling](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/18-labeling.jpg)\n\n![Labeling Process](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/19-labeling-process.gif)\n\nAfter the labeling we should have an XML file with bounding boxes data for each image:\n\n![Labels folder structure](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/20-labels-folder.jpg)\n\n### Splitting the dataset into train, test, and validation subsets\n\nTo identify the model's [overfitting or underfitting](https://en.wikipedia.org/wiki/Overfitting) issue we need to split the dataset into `train` and `test` dataset. Let's say `80%` of our images will be used to train the model and `20%` of the images will be used to check how well the model generalizes to the images that it didn't see before.\n\n> In this section we'll do the files splitting by copying them into different folders (`test` and `train` folders). However, this might not be the most optimal way. Instead, the splitting of the dataset may be done on [tf.data.Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset) level.\n\n```python\nimport re\nimport random\n\ndef partition_dataset(\n    images_dir,\n    xml_labels_dir,\n    train_dir,\n    test_dir,\n    val_dir,\n    train_ratio,\n    test_ratio,\n    val_ratio,\n    copy_xml\n):    \n    if not os.path.exists(train_dir):\n        os.makedirs(train_dir)\n        \n    if not os.path.exists(test_dir):\n        os.makedirs(test_dir)\n        \n    if not os.path.exists(val_dir):\n        os.makedirs(val_dir)\n\n    images = [f for f in os.listdir(images_dir)\n              if re.search(r'([a-zA-Z0-9\\s_\\\\.\\-\\(\\):])+(.jpg|.jpeg|.png)$', f, re.IGNORECASE)]\n\n    num_images = len(images)\n    \n    num_train_images = math.ceil(train_ratio * num_images)\n    num_test_images = math.ceil(test_ratio * num_images)\n    num_val_images = math.ceil(val_ratio * num_images)\n    \n    print('Intended split')\n    print(f'  train: {num_train_images}/{num_images} images')\n    print(f'  test: {num_test_images}/{num_images} images')\n    print(f'  val: {num_val_images}/{num_images} images')\n    \n    actual_num_train_images = 0\n    actual_num_test_images = 0\n    actual_num_val_images = 0\n    \n    def copy_random_images(num_images, dest_dir):\n        copied_num = 0\n        \n        if not num_images:\n            return copied_num\n        \n        for i in range(num_images):\n            if not len(images):\n                break\n                \n            idx = random.randint(0, len(images)-1)\n            filename = images[idx]\n            shutil.copyfile(os.path.join(images_dir, filename), os.path.join(dest_dir, filename))\n            \n            if copy_xml:\n                xml_filename = os.path.splitext(filename)[0]+'.xml'\n                shutil.copyfile(os.path.join(xml_labels_dir, xml_filename), os.path.join(dest_dir, xml_filename))\n            \n            images.remove(images[idx])\n            copied_num += 1\n        \n        return copied_num\n    \n    actual_num_train_images = copy_random_images(num_train_images, train_dir)\n    actual_num_test_images = copy_random_images(num_test_images, test_dir)\n    actual_num_val_images = copy_random_images(num_val_images, val_dir)\n    \n    print('\\n', 'Actual split')\n    print(f'  train: {actual_num_train_images}/{num_images} images')\n    print(f'  test: {actual_num_test_images}/{num_images} images')\n    print(f'  val: {actual_num_val_images}/{num_images} images')\n\npartition_dataset(\n    images_dir='dataset/printed_links/processed',\n    train_dir='dataset/printed_links/partitioned/train',\n    test_dir='dataset/printed_links/partitioned/test',\n    val_dir='dataset/printed_links/partitioned/val',\n    xml_labels_dir='dataset/printed_links/labels/xml',\n    train_ratio=0.8,\n    test_ratio=0.2,\n    val_ratio=0,\n    copy_xml=True\n)\n```\n\nAfter splitting your dataset folder structure should look similar to this:\n\n```\ndataset/\n└── printed_links\n    ├── labels\n    │   └── xml\n    ├── partitioned\n    │   ├── test\n    │   └── train\n    │       ├── IMG_9140.JPG\n    │       ├── IMG_9140.xml\n    │       ├── IMG_9141.JPG\n    │       ├── IMG_9141.xml\n    │       ...\n    ├── processed\n    └── raw\n```\n\n### Exporting the dataset\n\nThe last manipulation we should do with the data is to convert our datasets into [TFRecord](https://www.tensorflow.org/tutorials/load_data/tfrecord) format. The `TFRecord` format is a format that TensorFlow is using for storing a sequence of binary records.\n\nFirst, let's create two folders: one is for the labels in `CSV` format, and the other one is for the final dataset in `TFRecord` format.\n\n```bash\nmkdir -p dataset/printed_links/labels/csv\nmkdir -p dataset/printed_links/tfrecords\n```\n\nNow we need to create a `dataset/printed_links/labels/label_map.pbtxt` proto file that will describe the classes of the objects in our dataset. In our case, we only have _one class_ which we may call `http`. Here is the content of this file:\n\n```\nitem {\n  id: 1\n  name: 'http'\n}\n```\n\nNow we're ready to generate the TFRecord datasets out of images in `jpg` format and labels in `xml` format:\n\n```python\nimport os\nimport io\nimport math\nimport glob\nimport tensorflow as tf\nimport pandas as pd\nimport xml.etree.ElementTree as ET\nfrom PIL import Image\nfrom collections import namedtuple\nfrom object_detection.utils import dataset_util, label_map_util\n\ntf1 = tf.compat.v1\n\n# Convers labels from XML format to CSV.\ndef xml_to_csv(path):\n    xml_list = []\n    for xml_file in glob.glob(path + '/*.xml'):\n        tree = ET.parse(xml_file)\n        root = tree.getroot()\n        for member in root.findall('object'):\n            value = (root.find('filename').text,\n                int(root.find('size')[0].text),\n                int(root.find('size')[1].text),\n                member[0].text,\n                int(member[4][0].text),\n                int(member[4][1].text),\n                int(member[4][2].text),\n                int(member[4][3].text)\n            )\n            xml_list.append(value)\n    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']\n    xml_df = pd.DataFrame(xml_list, columns=column_name)\n    return xml_df\n\n\ndef class_text_to_int(row_label, label_map_dict):\n    return label_map_dict[row_label]\n\n\ndef split(df, group):\n    data = namedtuple('data', ['filename', 'object'])\n    gb = df.groupby(group)\n    return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]\n\n\n# Creates a TFRecord.\ndef create_tf_example(group, path, label_map_dict):\n    with tf1.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:\n        encoded_jpg = fid.read()\n        \n    encoded_jpg_io = io.BytesIO(encoded_jpg)\n    image = Image.open(encoded_jpg_io)\n    width, height = image.size\n\n    filename = group.filename.encode('utf8')\n    image_format = b'jpg'\n    xmins = []\n    xmaxs = []\n    ymins = []\n    ymaxs = []\n    classes_text = []\n    classes = []\n\n    for index, row in group.object.iterrows():\n        xmins.append(row['xmin'] / width)\n        xmaxs.append(row['xmax'] / width)\n        ymins.append(row['ymin'] / height)\n        ymaxs.append(row['ymax'] / height)\n        classes_text.append(row['class'].encode('utf8'))\n        classes.append(class_text_to_int(row['class'], label_map_dict))\n\n    tf_example = tf1.train.Example(features=tf1.train.Features(feature={\n        'image/height': dataset_util.int64_feature(height),\n        'image/width': dataset_util.int64_feature(width),\n        'image/filename': dataset_util.bytes_feature(filename),\n        'image/source_id': dataset_util.bytes_feature(filename),\n        'image/encoded': dataset_util.bytes_feature(encoded_jpg),\n        'image/format': dataset_util.bytes_feature(image_format),\n        'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),\n        'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),\n        'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),\n        'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),\n        'image/object/class/text': dataset_util.bytes_list_feature(classes_text),\n        'image/object/class/label': dataset_util.int64_list_feature(classes),\n    }))\n    \n    return tf_example\n\n\ndef dataset_to_tfrecord(\n    images_dir,\n    xmls_dir, \n    label_map_path,\n    output_path,\n    csv_path=None\n):\n    label_map = label_map_util.load_labelmap(label_map_path)\n    label_map_dict = label_map_util.get_label_map_dict(label_map)\n    \n    tfrecord_writer = tf1.python_io.TFRecordWriter(output_path)\n    images_path = os.path.join(images_dir)\n    csv_examples = xml_to_csv(xmls_dir)\n    grouped_examples = split(csv_examples, 'filename')\n    \n    for group in grouped_examples:\n        tf_example = create_tf_example(group, images_path, label_map_dict)\n        tfrecord_writer.write(tf_example.SerializeToString())\n        \n    tfrecord_writer.close()\n    \n    print('Successfully created the TFRecord file: {}'.format(output_path))\n    \n    if csv_path is not None:\n        csv_examples.to_csv(csv_path, index=None)\n        print('Successfully created the CSV file: {}'.format(csv_path))\n\n# Generate a TFRecord for train dataset.\ndataset_to_tfrecord(\n    images_dir='dataset/printed_links/partitioned/train',\n    xmls_dir='dataset/printed_links/partitioned/train',\n    label_map_path='dataset/printed_links/labels/label_map.pbtxt',\n    output_path='dataset/printed_links/tfrecords/train.record',\n    csv_path='dataset/printed_links/labels/csv/train.csv'\n)\n\n# Generate a TFRecord for test dataset.\ndataset_to_tfrecord(\n    images_dir='dataset/printed_links/partitioned/test',\n    xmls_dir='dataset/printed_links/partitioned/test',\n    label_map_path='dataset/printed_links/labels/label_map.pbtxt',\n    output_path='dataset/printed_links/tfrecords/test.record',\n    csv_path='dataset/printed_links/labels/csv/test.csv'\n)\n```\n\nAs a result we should now have two files: `test.record` and `train.record` in `dataset/printed_links/tfrecords/` folder:\n\n```\ndataset/\n└── printed_links\n    ├── labels\n    │   ├── csv\n    │   ├── label_map.pbtxt\n    │   └── xml\n    ├── partitioned\n    │   ├── test\n    │   ├── train\n    │   └── val\n    ├── processed\n    ├── raw\n    └── tfrecords\n        ├── test.record\n        └── train.record\n```\n\nThese two files `test.record` and `train.record` are our final datasets that we will use to fine-tune the `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` model.\n\n## 📖 Exploring the TFRecord Datasets\n\nIn this section, we will see how we may use the TensorFlow 2 Object Detection API to explore the datasets in `TFRecord` format.\n\n**Checking the number of items in a dataset**\n\nTo count the number of items in the dataset we may do the following:\n\n```python\nimport tensorflow as tf\n\n# Count the number of examples in the dataset.\ndef count_tfrecords(tfrecords_filename):\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n    # Keep in mind that the list() operation might be\n    # a performance bottleneck for large datasets. \n    return len(list(raw_dataset))\n\nTRAIN_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/train.record')\nTEST_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/test.record')\n\nprint('TRAIN_RECORDS_NUM: ', TRAIN_RECORDS_NUM)\nprint('TEST_RECORDS_NUM:  ', TEST_RECORDS_NUM)\n```\n\n_output →_\n\n```\nTRAIN_RECORDS_NUM:  100\nTEST_RECORDS_NUM:   25\n```\n\nSo we will train the model on `100` examples, and we will check the model accuracy on `25` test images.\n\n**Previewing the dataset images with bounding boxes**\n\nTo preview images with detection boxes we may do the following:\n\n```python\nimport tensorflow as tf\nimport numpy as np\nfrom google.protobuf import text_format\nimport matplotlib.pyplot as plt\n\n# Import Object Detection API.\nfrom object_detection.utils import visualization_utils\nfrom object_detection.protos import string_int_label_map_pb2\nfrom object_detection.data_decoders.tf_example_decoder import TfExampleDecoder\n\n%matplotlib inline\n\n# Visualize the TFRecord dataset.\ndef visualize_tfrecords(tfrecords_filename, label_map=None, print_num=1):\n    decoder = TfExampleDecoder(\n        label_map_proto_file=label_map,\n        use_display_name=False\n    )\n\n    if label_map is not None:\n        label_map_proto = string_int_label_map_pb2.StringIntLabelMap()\n\n        with tf.io.gfile.GFile(label_map,'r') as f:\n            text_format.Merge(f.read(), label_map_proto)\n            class_dict = {}\n            \n            for entry in label_map_proto.item:\n                class_dict[entry.id] = {'name': entry.name}\n\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n\n    for raw_record in raw_dataset.take(print_num):\n        example = decoder.decode(raw_record)\n\n        image = example['image'].numpy()\n        boxes = example['groundtruth_boxes'].numpy()\n        confidences = example['groundtruth_image_confidences']\n        filename = example['filename']\n        area = example['groundtruth_area']\n        classes = example['groundtruth_classes'].numpy()\n        image_classes = example['groundtruth_image_classes']\n        weights = example['groundtruth_weights']\n\n        scores = np.ones(boxes.shape[0])\n\n        visualization_utils.visualize_boxes_and_labels_on_image_array( \n            image,                                               \n            boxes,                                                     \n            classes,\n            scores,\n            class_dict,\n            max_boxes_to_draw=None,\n            use_normalized_coordinates=True\n        )\n\n        plt.figure(figsize=(8, 8))\n        plt.imshow(image)\n\n    plt.show()\n\n# Visualizing the training TFRecord dataset.\nvisualize_tfrecords(\n    tfrecords_filename='dataset/printed_links/tfrecords/train.record',\n    label_map='dataset/printed_links/labels/label_map.pbtxt',\n    print_num=3\n)\n```\n\nAs a result, we should see several images with bounding boxes drawn on top of each image.\n\n![TFRecord Preview](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/23-tfrecords-preview.jpg)\n\n## 📈 Setting Up TensorBoard\n\nBefore starting the training process we need to launch a [TensorBoard](https://www.tensorflow.org/tensorboard).\n\nTensorBoard will allow us to monitor the training process and see if the model is actually learning something or should we better stop the training and adjust training parameters. It will also help us to analyze what objects and at what location the model is detecting.\n\n![TensorBoard](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/24-tensorboard.gif)\n\n_Image source: [TensorBoard homepage](https://www.tensorflow.org/tensorboard)_\n\nThe cool part about TensorBoard is that we may run it directly in Google Colab. However, if you're running the notebook in your local installation of Jupyter you may also [install it as Python package](https://github.com/tensorflow/tensorboard/blob/master/README.md) and launch it from the terminal.\n\nFirst, let's create a `./logs` folder where all training logs will be written:\n\n```bash\nmkdir -p logs\n```\n\nNext, we may load the TensorBoard extension on Google Colab:\n\n```\n%load_ext tensorboard\n```\n\nAnd finally we may launch a TensorBoard to monitor the `./logs` folder:\n\n```\n%tensorboard --logdir ./logs\n```\n\nAs a result, you should see the empty TensorBoard panel:\n\n![Empty TensorBoard Panel](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/25-tensorboard-launch.jpg)\n\nAfter the model training is be started you may get back to this panel and see the training process progress.\n\n## 🏋🏻‍️ Model Training\n\n### Configuring the Detection Pipeline\n\nNow it's time to get back to the `cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config` file that we've mentioned earlier. This file defines the parameters of `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` model training.\n\nWe need to copy the `pipeline.config` file to the root of the project and adjust a couple of things in it:\n\n1. We should change the **number of classes** from `90` (the COCO classes) to just `1` (the `http` class).\n2. We should reduce the **batch size** to `8` to avoid the errors that are connected to the insufficient memory.\n3. We need to point the model to its **checkpoints** since we don't want to train the model from scratch.\n4. We need to change the `fine_tune_checkpoint_type` to `detection`.\n5. We need to point the model to a proper **labels map**.\n6. Lastly, we need to pint the model to the **train and test datasets**.\n\nAll these changes may be done manually directly in `pipeline.config` file. But we may also do them through code:\n\n```python\nimport tensorflow as tf\nfrom shutil import copyfile\nfrom google.protobuf import text_format\nfrom object_detection.protos import pipeline_pb2\n\n# Adjust pipeline config modification here if needed.\ndef modify_config(pipeline):\n    # Model config.\n    pipeline.model.ssd.num_classes = 1    \n\n    # Train config.\n    pipeline.train_config.batch_size = 8\n\n    pipeline.train_config.fine_tune_checkpoint = 'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0'\n    pipeline.train_config.fine_tune_checkpoint_type = 'detection'\n\n    # Train input reader config.\n    pipeline.train_input_reader.label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'\n    pipeline.train_input_reader.tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/train.record'\n\n    # Eval input reader config.\n    pipeline.eval_input_reader[0].label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'\n    pipeline.eval_input_reader[0].tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/test.record'\n\n    return pipeline\n\ndef clone_pipeline_config():\n    copyfile(\n        'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config',\n        'pipeline.config'\n    )\n\ndef setup_pipeline(pipeline_config_path):\n    clone_pipeline_config()\n    pipeline = read_pipeline_config(pipeline_config_path)\n    pipeline = modify_config(pipeline)\n    write_pipeline_config(pipeline_config_path, pipeline)\n    return pipeline\n\ndef read_pipeline_config(pipeline_config_path):\n    pipeline = pipeline_pb2.TrainEvalPipelineConfig()                                                                                                                                                                                                          \n    with tf.io.gfile.GFile(pipeline_config_path, \"r\") as f:                                                                                                                                                                                                                     \n        proto_str = f.read()                                                                                                                                                                                                                                          \n        text_format.Merge(proto_str, pipeline)\n    return pipeline\n\ndef write_pipeline_config(pipeline_config_path, pipeline):\n    config_text = text_format.MessageToString(pipeline)                                                                                                                                                                                                        \n    with tf.io.gfile.GFile(pipeline_config_path, \"wb\") as f:                                                                                                                                                                                                                       \n        f.write(config_text)\n\n# Adjusting the pipeline configuration.\npipeline = setup_pipeline('pipeline.config')\n\nprint(pipeline)\n```\n\nHere is the content of the `pipeline.config` file:\n\n```\nmodel {\n  ssd {\n    num_classes: 1\n    image_resizer {\n      fixed_shape_resizer {\n        height: 640\n        width: 640\n      }\n    }\n    feature_extractor {\n      type: \"ssd_mobilenet_v2_fpn_keras\"\n      depth_multiplier: 1.0\n      min_depth: 16\n      conv_hyperparams {\n        regularizer {\n          l2_regularizer {\n            weight: 3.9999998989515007e-05\n          }\n        }\n        initializer {\n          random_normal_initializer {\n            mean: 0.0\n            stddev: 0.009999999776482582\n          }\n        }\n        activation: RELU_6\n        batch_norm {\n          decay: 0.996999979019165\n          scale: true\n          epsilon: 0.0010000000474974513\n        }\n      }\n      use_depthwise: true\n      override_base_feature_extractor_hyperparams: true\n      fpn {\n        min_level: 3\n        max_level: 7\n        additional_layer_depth: 128\n      }\n    }\n    box_coder {\n      faster_rcnn_box_coder {\n        y_scale: 10.0\n        x_scale: 10.0\n        height_scale: 5.0\n        width_scale: 5.0\n      }\n    }\n    matcher {\n      argmax_matcher {\n        matched_threshold: 0.5\n        unmatched_threshold: 0.5\n        ignore_thresholds: false\n        negatives_lower_than_unmatched: true\n        force_match_for_each_row: true\n        use_matmul_gather: true\n      }\n    }\n    similarity_calculator {\n      iou_similarity {\n      }\n    }\n    box_predictor {\n      weight_shared_convolutional_box_predictor {\n        conv_hyperparams {\n          regularizer {\n            l2_regularizer {\n              weight: 3.9999998989515007e-05\n            }\n          }\n          initializer {\n            random_normal_initializer {\n              mean: 0.0\n              stddev: 0.009999999776482582\n            }\n          }\n          activation: RELU_6\n          batch_norm {\n            decay: 0.996999979019165\n            scale: true\n            epsilon: 0.0010000000474974513\n          }\n        }\n        depth: 128\n        num_layers_before_predictor: 4\n        kernel_size: 3\n        class_prediction_bias_init: -4.599999904632568\n        share_prediction_tower: true\n        use_depthwise: true\n      }\n    }\n    anchor_generator {\n      multiscale_anchor_generator {\n        min_level: 3\n        max_level: 7\n        anchor_scale: 4.0\n        aspect_ratios: 1.0\n        aspect_ratios: 2.0\n        aspect_ratios: 0.5\n        scales_per_octave: 2\n      }\n    }\n    post_processing {\n      batch_non_max_suppression {\n        score_threshold: 9.99999993922529e-09\n        iou_threshold: 0.6000000238418579\n        max_detections_per_class: 100\n        max_total_detections: 100\n        use_static_shapes: false\n      }\n      score_converter: SIGMOID\n    }\n    normalize_loss_by_num_matches: true\n    loss {\n      localization_loss {\n        weighted_smooth_l1 {\n        }\n      }\n      classification_loss {\n        weighted_sigmoid_focal {\n          gamma: 2.0\n          alpha: 0.25\n        }\n      }\n      classification_weight: 1.0\n      localization_weight: 1.0\n    }\n    encode_background_as_zeros: true\n    normalize_loc_loss_by_codesize: true\n    inplace_batchnorm_update: true\n    freeze_batchnorm: false\n  }\n}\ntrain_config {\n  batch_size: 8\n  data_augmentation_options {\n    random_horizontal_flip {\n    }\n  }\n  data_augmentation_options {\n    random_crop_image {\n      min_object_covered: 0.0\n      min_aspect_ratio: 0.75\n      max_aspect_ratio: 3.0\n      min_area: 0.75\n      max_area: 1.0\n      overlap_thresh: 0.0\n    }\n  }\n  sync_replicas: true\n  optimizer {\n    momentum_optimizer {\n      learning_rate {\n        cosine_decay_learning_rate {\n          learning_rate_base: 0.07999999821186066\n          total_steps: 50000\n          warmup_learning_rate: 0.026666000485420227\n          warmup_steps: 1000\n        }\n      }\n      momentum_optimizer_value: 0.8999999761581421\n    }\n    use_moving_average: false\n  }\n  fine_tune_checkpoint: \"cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0\"\n  num_steps: 50000\n  startup_delay_steps: 0.0\n  replicas_to_aggregate: 8\n  max_number_of_boxes: 100\n  unpad_groundtruth_tensors: false\n  fine_tune_checkpoint_type: \"detection\"\n  fine_tune_checkpoint_version: V2\n}\ntrain_input_reader {\n  label_map_path: \"dataset/printed_links/labels/label_map.pbtxt\"\n  tf_record_input_reader {\n    input_path: \"dataset/printed_links/tfrecords/train.record\"\n  }\n}\neval_config {\n  metrics_set: \"coco_detection_metrics\"\n  use_moving_averages: false\n}\neval_input_reader {\n  label_map_path: \"dataset/printed_links/labels/label_map.pbtxt\"\n  shuffle: false\n  num_epochs: 1\n  tf_record_input_reader {\n    input_path: \"dataset/printed_links/tfrecords/test.record\"\n  }\n}\n```\n\n### Launching the training process\n\nWe're ready now to launch a training process using the TensorFlow 2 Object Detection API. The API contains a [model_main_tf2.py](https://github.com/tensorflow/models/blob/master/research/object_detection/model_main_tf2.py) script that will run training for us. Feel free to explore the flags that this Python script supports in the source-code (i.e. `num_train_steps`, `model_dir` and others) to see their meanings.\n\nWe will be training the model for `1000` iterations (epochs). Feel free to train it for a smaller or larger number of iterations depending on the learning progress (see the TensorBoard charts).\n\n```bash\n%%bash\n\nNUM_TRAIN_STEPS=1000\nCHECKPOINT_EVERY_N=1000\n\nPIPELINE_CONFIG_PATH=pipeline.config\nMODEL_DIR=./logs\nSAMPLE_1_OF_N_EVAL_EXAMPLES=1\n\npython ./models/research/object_detection/model_main_tf2.py \\\n  --model_dir=$MODEL_DIR \\\n  --num_train_steps=$NUM_TRAIN_STEPS \\\n  --sample_1_of_n_eval_examples=$SAMPLE_1_OF_N_EVAL_EXAMPLES \\\n  --pipeline_config_path=$PIPELINE_CONFIG_PATH \\\n  --checkpoint_every_n=$CHECKPOINT_EVERY_N \\\n  --alsologtostderr\n```\n\nWhile the model is training (it may take around`~10 minutes` for `1000` iterations in [GoogleColab GPU](https://colab.research.google.com/notebooks/gpu.ipynb) runtime) you should be able to observe the training progress in TensorBoard. The `localization` and `classification` losses should decrease which means that the model is doing a good job in localizing and classifying new custom objects.  \n\n![Training Process](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/26-tensorboard-training.jpg)\n\nAlso during the training, the new model checkpoints (parameters that the model has learned during the training) will be saved to the `logs` folder.\n\nThe `logs` folder structure now looks like this:\n\n```\nlogs\n├── checkpoint\n├── ckpt-1.data-00000-of-00001\n├── ckpt-1.index\n└── train\n    └── events.out.tfevents.1606560330.b314c371fa10.1747.1628.v2\n```\n\n### Evaluating the Model (Optional)\n\nThe evaluation process uses the trained model checkpoints and evaluates how well the model performs in detecting objects in the test dataset. The results of this evaluation are summarised in the form of some [metrics](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/evaluation_protocols.md), which can be examined over time. You may read more about how to evaluate these metrics [here](https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/training.html#evaluating-the-model-optional).\n\nWe will skip the metrics evaluation step in this article. But we may still use the evaluation step to see the model's detections in TensorBoard:\n\n```bash\n%%bash\n\nPIPELINE_CONFIG_PATH=pipeline.config\nMODEL_DIR=logs\n\npython ./models/research/object_detection/model_main_tf2.py \\\n  --model_dir=$MODEL_DIR \\\n  --pipeline_config_path=$PIPELINE_CONFIG_PATH \\\n  --checkpoint_dir=$MODEL_DIR \\\n```\n\nAfter launching the script you should be able to see several side-by-side images with detections boxes:\n\n![Model Evaluation](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/27-tensorboard-evaluation.jpg)\n\n## 🗜 Exporting the Model\n\nOnce the training process is complete we should save the trained model for further usage. To export the model we will use the [exporter_main_v2.py](https://github.com/tensorflow/models/blob/master/research/object_detection/exporter_main_v2.py) script from Object Detection API. It prepares an object detection TensorFlow graph for inference using model configuration and a trained checkpoint. The script outputs associated checkpoint files, a SavedModel, and a copy of the model config: \n\n```bash\n%%bash\n\npython ./models/research/object_detection/exporter_main_v2.py \\\n    --input_type=image_tensor \\\n    --pipeline_config_path=pipeline.config \\\n    --trained_checkpoint_dir=logs \\\n    --output_directory=exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nHere is what the `exported` folder contains after the export:\n\n```\nexported\n└── ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n    ├── checkpoint\n    │   ├── checkpoint\n    │   ├── ckpt-0.data-00000-of-00001\n    │   └── ckpt-0.index\n    ├── pipeline.config\n    └── saved_model\n        ├── assets\n        ├── saved_model.pb\n        └── variables\n            ├── variables.data-00000-of-00001\n            └── variables.index\n```\n\nAt this moment we have a `saved_model` that may be used for inference.\n\n## 🚀 Using the Exported Model\n\nLet's see how can we use the saved model from the previous step for object detections.\n\nFirst, we need to create a detection function that will use the saved model. It will accept the image and will output the detected objects:\n\n```python\nimport time\nimport math\n\nPATH_TO_SAVED_MODEL = 'exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model'\n\ndef detection_function_from_saved_model(saved_model_path):\n    print('Loading saved model...', end='')\n    start_time = time.time()\n\n    # Load saved model and build the detection function\n    detect_fn = tf.saved_model.load(saved_model_path)\n\n    end_time = time.time()\n    elapsed_time = end_time - start_time\n\n    print('Done! Took {} seconds'.format(math.ceil(elapsed_time)))\n\n    return detect_fn\n\nexported_detect_fn = detection_function_from_saved_model(\n    PATH_TO_SAVED_MODEL\n)\n```\n\n_output →_\n\n```\nLoading saved model...Done! Took 9 seconds\n```\n\nTo map the IDs of the detected classes back to the class names we need to load the label map as well:\n\n```python\nfrom object_detection.utils import label_map_util\n\ncategory_index = label_map_util.create_category_index_from_labelmap(\n    'dataset/printed_links/labels/label_map.pbtxt',\n    use_display_name=True\n)\n\nprint(category_index)\n```\n\n_output →_\n\n```\n{1: {'id': 1, 'name': 'http'}}\n```\n\nTesting the model on a test dataset.\n\n```python\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport numpy as np\n\nfrom object_detection.utils import visualization_utils\nfrom object_detection.data_decoders.tf_example_decoder import TfExampleDecoder\n\n%matplotlib inline\n\ndef tensors_from_tfrecord(\n    tfrecords_filename,\n    tfrecords_num,\n    dtype=tf.float32\n):\n    decoder = TfExampleDecoder()\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n    images = []\n\n    for raw_record in raw_dataset.take(tfrecords_num):\n        example = decoder.decode(raw_record)\n        image = example['image']\n        image = tf.cast(image, dtype=dtype)\n        images.append(image)\n    \n    return images\n\ndef test_detection(tfrecords_filename, tfrecords_num, detect_fn):\n    image_tensors = tensors_from_tfrecord(\n        tfrecords_filename,\n        tfrecords_num,\n        dtype=tf.uint8\n    )\n\n    for image_tensor in image_tensors:   \n        image_np = image_tensor.numpy()\n    \n        # The model expects a batch of images, so add an axis with `tf.newaxis`.\n        input_tensor = tf.expand_dims(image_tensor, 0)\n\n        detections = detect_fn(input_tensor)\n\n        # All outputs are batches tensors.\n        # Convert to numpy arrays, and take index [0] to remove the batch dimension.\n        # We're only interested in the first num_detections.\n        num_detections = int(detections.pop('num_detections'))\n        \n        detections = {key: value[0, :num_detections].numpy() for key, value in detections.items()}\n        detections['num_detections'] = num_detections\n\n        # detection_classes should be ints.\n        detections['detection_classes'] = detections['detection_classes'].astype(np.int64)\n        \n        image_np_with_detections = image_np.astype(int).copy()\n\n        visualization_utils.visualize_boxes_and_labels_on_image_array(\n            image_np_with_detections,\n            detections['detection_boxes'],\n            detections['detection_classes'],\n            detections['detection_scores'],\n            category_index,\n            use_normalized_coordinates=True,\n            max_boxes_to_draw=100,\n            min_score_thresh=.3,\n            agnostic_mode=False\n        )\n\n        plt.figure(figsize=(8, 8))\n        plt.imshow(image_np_with_detections)\n        \n    plt.show()\n\n\ntest_detection(\n    tfrecords_filename='dataset/printed_links/tfrecords/test.record',\n    tfrecords_num=10,\n    detect_fn=exported_detect_fn\n)\n```\n\nAs a result, you should see `10` images from the test dataset and highlighted `https:` prefixes that were detected by the model:\n\n![Testing the model on a test dataset](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/28-testing-the-model.jpg)\n\nThe fact that the model is able to detect custom objects (in our case the `https://` prefixes) on the images it hasn't seen before is a good sign and something that we wanted to achieve.\n\n## 🗜 Converting the Model for Web\n\nAs you remember from the beginning of this article, our goal was to use the custom object detection model in the browser. Luckily, there is a [TensorFlow.js](https://www.tensorflow.org/js) JavaScript version of the TensorFlow library exists. In JavaScript, we can't work with our saved model directly. Instead, we need to convert it to [tfjs_graph_model](https://www.tensorflow.org/js/tutorials/conversion/import_saved_model) format.  \n\nTo do this we need to install the tensorflowjs Python package:\n\n```bash\npip install tensorflowjs --quiet\n```\n\nThe model may be exported like this:\n\n```bash\n%%bash\n\ntensorflowjs_converter \\\n    --input_format=tf_saved_model \\\n    --output_format=tfjs_graph_model \\\n    exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model \\\n    exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nThe `exported_web` folder contains the `.json` file with the model metadata and a bunch of `.bin` files with trained model parameters:\n\n```\nexported_web\n└── ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n    ├── group1-shard1of4.bin\n    ├── group1-shard2of4.bin\n    ├── group1-shard3of4.bin\n    ├── group1-shard4of4.bin\n    └── model.json\n```\n\nFinally, we have the model that is able to detect `https://` prefixes for us, and it is saved in JavaScript-understandable format.\n\nLet's check the model size to see if it is light enough to be loaded completely to the client-side:\n\n```python\nimport pathlib\n\ndef get_folder_size(folder_path):\n    mB = 1000000\n    root_dir = pathlib.Path(folder_path)\n    sizeBytes = sum(f.stat().st_size for f in root_dir.glob('**/*') if f.is_file())\n    return f'{sizeBytes//mB} MB'\n\n\nprint(f'Original model size:      {get_folder_size(\"cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\nprint(f'Exported model size:      {get_folder_size(\"exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\nprint(f'Exported WEB model size:  {get_folder_size(\"exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\n```\n\n_output →_\n\n```\nOriginal model size:      31 MB\nExported model size:      28 MB\nExported WEB model size:  13 MB\n```\n\nAs you may see the model that we're going to use for the Web has `13MB` which is quite acceptable in our case.\n\nLater in JavaScript we may start using the model like this:\n\n```javascript\nimport * as tf from '@tensorflow/tfjs';\nconst model = await tf.loadGraphModel(modelURL);\n```\n\n> 🧭 The next step is to implement the Links Detector UI which will use this model, but this is another story for another article. The final source code of the application may be found in [links-detector repository](https://github.com/trekhleb/links-detector) on GitHub.\n\n## 🤔 Conclusions\n\nIn this article, we started to solve the issue with printed links detection. We ended up creating the custom object detector to recognize the `https://` prefixes on text images (i.e. on smartphone camera stream images). We have also converted the model to a `tfjs_graph_model` to be able to re-use it on the client-side.\n\nYou may 🚀 [**launch Links Detector demo**](https://trekhleb.github.io/links-detector/) from your smartphone to see the final result and to try how the model performs on your books or magazines.\n\nHere is how the final solution looks like:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\nYou may also 📝 [**browse the links-detector repository**](https://github.com/trekhleb/links-detector) on GitHub to see the complete source code of the UI part of the application.\n\n> ⚠️ Currently the application is in _experimental_ _Alpha_ stage and has [many issues and limitations](https://github.com/trekhleb/links-detector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). So don't raise your expectations level too high until these issues are resolved 🤷🏻‍.\n\nAs the next steps which might improve the model performance we might do the following:\n\n- Extend the dataset with more link types (`http://`, `tcp://`, `ftp://` etc)\n- Extended the dataset with images that have dark backgrounds\n- Extend the dataset with underlined links\n- Extend the dataset with examples of different fonts and ligatures\n- etc.\n\nEven though the model has a lot to be improved to make it closer to the production-ready state, I still hope that this article was useful for you and gave you some guidelines and inspiration to play around with your custom object detectors.\n \nHappy training, folks!\n\n"
  },
  {
    "path": "articles/printed_links_detection/printed_links_detection.ru.md",
    "content": "# 📖 👆🏻 Делаем печатные ссылки кликабельными с помощью TensorFlow 2 Object Detection API\n\n![Links Detector Cover](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/01-banner.png)\n\n## 📃 TL;DR\n\n_В этой статье мы начнем решать проблему того, как сделать печатные ссылки в книгах или журналах кликабельными используя камеру смартфона._\n\nС помощью [TensorFlow 2 Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection) мы научим TensorFlow модель находить позиции и габариты строк `https://` в изображениях (например в каждом кадре видео из камеры смартфона).\n\nТекст каждой ссылки, расположенный по правую сторону от `https://`, будет распознан с помощью библиотеки [Tesseract](https://tesseract.projectnaptha.com/). Работа с библиотекой Tesseract не является предметом этой статьи, но вы можете найти полный исходный код приложения в репозитории [links-detector repository](https://github.com/trekhleb/links-detector) на GitHub.\n\n> 🚀 [**Запустить Links Detector**](https://trekhleb.github.io/links-detector/) со смартфона, чтобы увидеть конечный результат.\n\n> 📝 [**Открыть репозиторий links-detector**](https://github.com/trekhleb/links-detector) на GitHub с полным исходным кодом приложения.\n\nВот так в итоге будет выглядеть процесс распознавания печатных ссылок:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\n> ⚠️ На данный момент приложение находится в _экспериментальной_ стадии и имеет [множество недоработок и ограничений](https://github.com/trekhleb/links-detector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). Поэтому, до тех пор, пока вышеуказанные недоработки не будут ликвидированы, не ожидайте от приложения слишком многого 🤷🏻‍. Также стоит отметить, что целью данной статьи является экспериментирование с TensorFlow 2 Object Detection API, а не создание production-ready приложения.\n\n> В случае, если блоки с исходным кодом в этой статье будут отображаться без подсветки кода вы можете [перейти на GitHub версию этой статьи](https://github.com/trekhleb/links-detector/blob/master/articles/printed_links_detection/printed_links_detection.ru.md)\n\n## 🤷🏻‍️ Проблема\n\nЯ работаю программистом, и в свободное от работы время учу Machine Learning в качестве хобби. Но проблема не в этом.\n\nЯ купил книгу по машинному обучению и, читая первые главы, столкнулся с множеством печатных ссылок на подобии `https://tensorflow.org/` или `https://some-url.com/which/may/be/even/longer?and_with_params=true`.\n\n![Printed Links](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/02-printed-links.jpg)\n\nК сожалению, кликать по печатным ссылкам не представлялось возможным (спасибо, Кэп!). Чтобы открыть ссылки в браузере мне приходилось набирать их посимвольно в адресной строке, что было довольно медленно. К тому же опечатки никто не отменял.\n\n## 💡 Возможное решение\n\nЯ подумал, а что если, по аналогии с распознавателем QR кодов, мы \"научим\" смартфон _(1)_ _определять местоположение_ и _(2)_ _распознавать_ печатные гипер-ссылки и делать их кликабельными? В таком случае читатель делал бы всего один клик вместо посимвольного ввода с множеством нажатий на клавиши. Операционная сложность всей этой операции уменьшилась бы с `O(N)` до `O(1)`.\n\nВот так бы этот процесс выглядел:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\n## 📝 Требования к решению\n\nКак я уже упомянул выше, я не эксперт в машинном обучении. Для меня это больше как хобби. Поэтому и цель этой статьи заключается больше в _экспериментировании_ и _обучении_ работе с TensorFlow 2 Object Detection API, чем в попытке создания production-ready приложения.\n\nС учетом вышесказанного, я упростил требования к финальному решению и свел их к следующим пунктам:\n\n1. Производительность процесса обнаружения и распознавания должна быть **близка** к реальному времени (например, `0.5-1` кадров в секунду на устройстве схожем по производительности с iPhone X). Это будет означать, что весь процесс _обнаружения + распознавания_ должен происходить не более чем за `2` секунды.\n2. Должны поддерживаться только ссылки на **английском** языке.\n3. Должны поддерживаться только ссылки **черного (темно-серого) цвета на белом (светло-сером) фоне**.\n4. Должны поддерживаться только `https://` ссылки (допускается, что `http://`, `ftp://`, `tcp://` и прочие ссылки не будут распознаны).\n\n## 🧩 Находим решение\n\n### Общий подход\n\n#### Вариант №1: Модель на стороне сервера\n\n**Алгоритм действий:**\n\n1. Получаем видео-поток (кадр за кадром) на стороне клиента.\n2. Отправляем каждый кадр на сервер.\n3. Осуществляем обнаружение и распознавание ссылок на сервере и отправляем результат клиенту.\n4. Отображаем распознанные ссылки ни стороне клиента и делаем их кликабельными.\n\n![Model on the back-end](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/04-frontend-backend.jpg)\n\n**Преимущества:**\n\n- 💚 Скорость обнаружения и распознавания ссылок не ограничена производительностью клиентского устройства. При желании мы можем ускорить скорость обнаружения ссылок масштабируя наши сервера горизонтально (больше серверов) или вертикально (больше ядер и GPUs).\n- 💚 Модель может иметь больший размер (и, возможно, большую точность), поскольку отсутствует необходимость ее загрузки на сторону клиента. Загрузить модель размером `~10Mb` на сторону клиента выглядит реалистичным, но все-же загрузить модель размером `~100Mb` может быть довольно проблематичным с точки зрения пользовательского UX (user experience).\n- 💚 У нас появляется возможность контролировать доступ к модели. Поскольку модель \"спрятана\" за публичным API, мы можем контролировать каким клиентам она будет доступна.\n\n**Недостатки:**\n\n- 💔 Сложность системы растет. Вместо использования одного лишь `JavaScript` на стороне клиента нам необходимо будет так же создать, например, `Python` инфраструктуру на стороне сервера. Нам так же будет необходимо позаботиться об автоматическом масштабировании сервиса.\n- 💔 Работа приложения в режиме оффлайн невозможна поскольку для работы приложения требуется доступ к интернету.\n- 💔 Множество HTTP запросов к сервису со стороны клиента может стать слабым местом системы с точки зрения производительности. Предположим, мы хотим улучшить производительность обнаружения и распознавания ссылок с `1` до `10+` кадров в секунду. В таком случае каждый клиент будет слать `10+` запросов в секунду на сервер. Для `10` клиентов, работающих одновременно, это уже будет означать `100+` запросов в секунду. На помощь могут прийти двусторонний стриминг `HTTP/2` и `gRPC`, но мы снова возвращаемся к первому пункту, связанному с растущей сложностью системы.\n- 💔 Стоимость системы растет. В основном это связано с оплатой за аренду серверов.\n\n#### Вариант №2: Модель на стороне клиента\n\n**Алгоритм действий:**\n\n1. Получаем видео-поток (кадр за кадром) на стороне клиента.\n2. Осуществляем обнаружение и распознавание ссылок на стороне клиента (без отправки на сервер).\n3. Отображаем распознанные ссылки ни стороне клиента и делаем их кликабельными.\n\n![Model on the front-end](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/05-frontend-only.jpg)\n\n**Преимущества:**\n\n- 💚 Менее сложная система. Нет необходимости в разработке серверной части приложения и создания API.\n- 💚 Приложение может работать в режиме оффлайн. Модель загружена на сторону клиента и нет необходимости в доступе к интернету (см. [Progressive Web Application](https://web.dev/progressive-web-apps/))\n- 💚 Система \"почти\" автоматически масштабируема. Каждый новый клиент приложения \"приходит\" со своим процессором и видеокартой. Это конечно же неполноценное масштабирование (мы затронем причины ниже).\n- 💚 Система гораздо дешевле. Нам необходимо заплатить только за сервер со статическими данными (`HTML`, `JS`, `CSS`, файлы модели и пр.). В случае с GitHub, такой сервер может быть предоставлен бесплатно.\n- 💚 Отсутствует (так же как и серверы) проблема большого количества HTTP запросов в секунду к серверам.\n\n**Недостатки:**\n\n- 💔 Возможно только горизонтальное масштабирование, когда каждый клиент автоматически имеет свои собственные процессоры и графическую карту. Вертикальное масштабирование невозможно поскольку мы не можем повлиять на производительность клиентского устройства. В результате мы не можем гарантировать быстрого обнаружения и распознавания ссылок для медленных устройств.\n- 💔 Невозможно контролировать использование модели клиентами. Каждый может загрузить к себе модель и использовать ее где и как угодно.\n- 💔 Скорость расхода батареи клиентского устройства может стать проблемой. Модель при работе потребляет вычислительные ресурсы. Пользователи приложения могут быть недовольны тем, что их iPhone становится все теплее и теплее во время работы.\n\n#### Выбираем общий подход\n\nПоскольку целю этой статьи и проекта в целом является обучение, а не создание приложения коммерческого уровня _мы можем выбрать второй вариант и хранить модель на стороне клиента_. Это сделает весь проект менее затратным и у нас будет возможность больше сфокусироваться на машинном обучении, а не на создании автоматически масштабируемой серверной инфраструктуры.\n\n### Углубляемся в детали\n\nИтак, мы выбрали вариант приложения без серверной части. Предположим теперь, что у нас на входе есть изображение (кадр) из видео-потока камеры, который выглядит так:\n\n![Printed Links Input](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/06-printed-links-clean.jpg)\n\nНам необходимо решить две подзадачи:\n\n1. **Обнаружение** ссылок (найти позицию и габариты ссылок на странице)\n2. **Распознавание** ссылок (распознать текст ссылок)\n\n#### Вариант №1: Решение на основе библиотеки Tesseract\n\nПервым и наиболее очевидным вариантом решением задачи _оптического распознавания символов_ ([OCR](https://en.wikipedia.org/wiki/Optical_character_recognition)) может быть распознавания текста всего изображения с помощью, например, библиотеки [Tesseract.js](https://github.com/naptha/tesseract.js). Она принимает изображение на вход и выдает распознанные параграфы, текстовые строки, блоки текста и слова и вместе с габаритами и координатами.\n\n![Recognized text with bounding boxes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/07-printed-links-boxes.jpg)\n\nДалее мы можем попытаться найти ссылки в распознанном тексте с помощью регулярного выражения [похожего на это](https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url) (пример на TypeScript):\n\n```typescript\nconst URL_REG_EXP = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi;\n\nconst extractLinkFromText = (text: string): string | null => {\n  const urls: string[] | null = text.match(URL_REG_EXP);\n  if (!urls || !urls.length) {\n    return null;\n  }\n  return urls[0];\n};\n```\n\n💚 Похоже, что задача решена довольно прямолинейным и простым способом:\n\n- Мы знаем габариты и координаты ссылок.\n- Мы так же знаем текст ссылок и можем сделать их кликабельными.\n\n💔 Проблема в том, что время _обнаружения + распознавания_ может варьироваться от `2` до `20+` секунд в зависимости от размера изображения, его качества и \"похожих на текст\" объектов в изображении. В итоге будет очень сложно достичь той _близкой_ к реальному времени производительности в `0.5-1` кадров в секунду.\n\n💔 Также, если подумать, то мы просим библиотеку распознать **весь** текст на картинке, даже если в тексте совсем нет ссылок или если в тексте есть одна-две ссылки, которые составляют, пускай, ~10% от всего объема текста. Это звучит как неэффективная трата вычислительных ресурсов.\n\n#### Вариант №2: Решение на основе библиотек Tesseract и TensorFlow (+1 модель)\n\nМы могли бы заставить Tesseract работать быстрее используя еще один _дополнительный \"алгоритм-советчик\"_ перед тем, как приступить к распознаванию ссылок. Этот \"алгоритм-советчик\" должен обнаруживать (но не распознавать) _начало ссылок (координаты самой левой границы ссылки)_ для каждой ссылки в изображении. Это позволит нам ускорить задачу распознавания текста ссылок, если мы будем следовать следующим правилам:\n\n1. Если изображение не содержит ни одной ссылки мы должны полностью избежать распознавания текста библиотекой Tesseract.\n2. Если изображение содержит ссылки, то мы должны \"попросить\" Tesseract распознать только те части изображения, которые содержат текст ссылок. Мы хотим тратить время на распознавание \"полезного\" для нашей задачи текста.\n\nЭтот \"алгоритм-советчик\", который будет срабатывать перед вызовом Tesseract должен выполняться каждый раз за одно и то же время, независимо от качества и содержимого изображения. Он также должен быть достаточно быстрым и должен определять наличие и позиции ссылок быстрее чем за `1` секунду (например, на iPhone X). В таком случае мы сможем попытаться заставить наше приложение работать в режиме близком к реальному времени (определения \"близости\" мы дали выше). \n\n> 💡 Итак, что если мы воспользуемся еще одним алгоритмом (еще одной моделью) обнаружения объектов, который поможет нам найти строки `https://` в изображении (каждая защищенная ссылка начинается с `https://`, не так ли?). Тогда, зная расположение и габариты префиксов `https://` в изображении, мы сможем отправить на распознавание текста с помощью библиотеки Tesseract только те части изображения, которые находятся по правую сторону от префиксов `https://` и являются их продолжением.\n\nОбратите внимание на изображение ниже:\n\n![Tesseract and TensorFlow based solution](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/08-tesseract-vs-tensorflow.jpg)\n\nНа этом изображении можно заметить, что Tesseract будет выполнять **гораздо меньше** работы по распознаванию текста, если мы подскажем ему, где в тексте могут находиться ссылки (обратите внимание на количество голубых прямоугольников, чем не доказательство 🤓).  \n\nИтак, вопрос, на который нам необходимо ответить теперь, какую же модель обнаружения объектов нам выбрать и как \"научить\" ее находить на изображении префиксы `https://`.\n\n> Наконец-то мы подобрались ближе к TensorFlow 😀\n\n## 🤖 Выбираем подходящую модель обнаружения объектов\n\nТренировка новой модели обнаружения объектов с нуля не является хорошим вариантом в нашем случае по следующим причинам:\n\n- 💔 Тренировка может занять дни/недели и стоить много денег (за аренду тех-же серверов с GPU).\n- 💔 У нас скорее всего не получится собрать набор данных, состоящий из сотен тысяч фотографий книг и журналов со ссылками. Тем-более, что нам нужны не только изображения, но еще и координаты префиксов `https://` для каждого из них. С другой стороны мы можем попытаться сгенерировать такой набор данных, но об этом ниже.\n\nИтак, вместо создания новой модели обнаружения объектов, мы будем обучать уже существующую и натренированную модель обнаруживать новый для нее класс объектов (см. [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning)). В нашем случае под \"новым классом\" объектов мы имеем в виду изображения префикса `https://`. Такой подход имеет следующие преимущества:\n\n- 💚 Набор данных может быть гораздо меньшим. Нет необходимости собирать сотни тысяч изображений с локализациями (координатами объектов в изображении). Вместо этого мы можем обойтись сотней изображений и сделать локализацию объектов вручную. Это возможно по той причине, что модель уже натренированна на общем наборе данных типа [COCO](https://cocodataset.org/#home) и уже умеет извлекать основные характеристики изображения (научить \"первокурсника\" линейной алгебре, _как правило_, легче, чем \"первоклассника\").\n- 💚 Время тренировки так же будет гораздо меньшим (на GPU получим минуты/часы вместо дней/недель). Время сокращается за счет меньшего объема данных (меньших партий данных во время тренировки) и меньшего количества тренируемых параметров модели.\n\nМы можем выбрать существующую модель из [\"зоопарка\" моделей TensorFlow 2](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md), который представляет собой коллекцию моделей натренированных на наборе данных [COCO 2017](https://cocodataset.org/#home). На данный момент эта коллекция включает в себя `~40` разных вариаций моделей.\n\nДля того, чтобы \"научить\" модель обнаруживать новые, ранее неизвестные ей объекты, мы можем воспользоваться [TensorFlow 2 Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection). TensorFlow Object Detection API - это фреймворк на основе [TensorFlow](https://www.tensorflow.org/), который позволяет конструировать и тренировать модели обнаружения объектов.\n\nЕсли вы перейдете по ссылке на [\"зоопарк\" моделей](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md) вы увидите, что для каждой модели там указана _скорость_ и _точность_ обнаружения объектов. \n\n![Model Zoo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/09-model-zoo.jpg)\n\n_Изображение взято с репозитория [TensorFlow Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md)_\n\nКонечно же, для того, чтобы выбрать подходящую модель, нам важно найти правильный баланс между **скоростью** и **точностью** обнаружения. Но что еще важнее в нашем случае, это **размер** модели, поскольку мы планируем загружать ее на сторону клиента.\n\nРазмер архива с моделью может варьироваться от `~20Mb` до `~1Gb`. Вот несколько примеров:\n\n- `1386 (Mb)` `centernet_hg104_1024x1024_kpts_coco17_tpu-32`\n- ` 330 (Mb)` `centernet_resnet101_v1_fpn_512x512_coco17_tpu-8`\n- ` 195 (Mb)` `centernet_resnet50_v1_fpn_512x512_coco17_tpu-8`\n- ` 198 (Mb)` `centernet_resnet50_v1_fpn_512x512_kpts_coco17_tpu-8`\n- ` 227 (Mb)` `centernet_resnet50_v2_512x512_coco17_tpu-8`\n- ` 230 (Mb)` `centernet_resnet50_v2_512x512_kpts_coco17_tpu-8`\n- `  29 (Mb)` `efficientdet_d0_coco17_tpu-32`\n- `  49 (Mb)` `efficientdet_d1_coco17_tpu-32`\n- `  60 (Mb)` `efficientdet_d2_coco17_tpu-32`\n- `  89 (Mb)` `efficientdet_d3_coco17_tpu-32`\n- ` 151 (Mb)` `efficientdet_d4_coco17_tpu-32`\n- ` 244 (Mb)` `efficientdet_d5_coco17_tpu-32`\n- ` 376 (Mb)` `efficientdet_d6_coco17_tpu-32`\n- ` 376 (Mb)` `efficientdet_d7_coco17_tpu-32`\n- ` 665 (Mb)` `extremenet`\n- ` 427 (Mb)` `faster_rcnn_inception_resnet_v2_1024x1024_coco17_tpu-8`\n- ` 424 (Mb)` `faster_rcnn_inception_resnet_v2_640x640_coco17_tpu-8`\n- ` 337 (Mb)` `faster_rcnn_resnet101_v1_1024x1024_coco17_tpu-8`\n- ` 337 (Mb)` `faster_rcnn_resnet101_v1_640x640_coco17_tpu-8`\n- ` 343 (Mb)` `faster_rcnn_resnet101_v1_800x1333_coco17_gpu-8`\n- ` 449 (Mb)` `faster_rcnn_resnet152_v1_1024x1024_coco17_tpu-8`\n- ` 449 (Mb)` `faster_rcnn_resnet152_v1_640x640_coco17_tpu-8`\n- ` 454 (Mb)` `faster_rcnn_resnet152_v1_800x1333_coco17_gpu-8`\n- ` 202 (Mb)` `faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8`\n- ` 202 (Mb)` `faster_rcnn_resnet50_v1_640x640_coco17_tpu-8`\n- ` 207 (Mb)` `faster_rcnn_resnet50_v1_800x1333_coco17_gpu-8`\n- ` 462 (Mb)` `mask_rcnn_inception_resnet_v2_1024x1024_coco17_gpu-8`\n- `  86 (Mb)` `ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8`\n- `  44 (Mb)` `ssd_mobilenet_v2_320x320_coco17_tpu-8`\n- `  20 (Mb)` `ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8`\n- `  20 (Mb)` `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`\n- ` 369 (Mb)` `ssd_resnet101_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 369 (Mb)` `ssd_resnet101_v1_fpn_640x640_coco17_tpu-8`\n- ` 481 (Mb)` `ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 480 (Mb)` `ssd_resnet152_v1_fpn_640x640_coco17_tpu-8`\n- ` 233 (Mb)` `ssd_resnet50_v1_fpn_1024x1024_coco17_tpu-8`\n- ` 233 (Mb)` `ssd_resnet50_v1_fpn_640x640_coco17_tpu-8`\n\nМодель **`ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`** выглядит наиболее подходящей в нашем случае:\n\n- 💚 Она относительно небольшая - `20Mb` в архиве.\n- 💚 Она достаточно быстрая - `39ms` на одно обнаружение.\n- 💚 Она использует сеть MobileNet v2 в качестве экстрактора свойств изображения (feature extractor), которая в свою очередь оптимизирована под работу на мобильных устройствах и обеспечивает меньший расход батареи.\n- 💚 Она производит обнаружение всех известных ей объектов в изображении **за один проход** независимо от содержимого изображения (отсутствует шаг [regions proposal](https://en.wikipedia.org/wiki/Region_Based_Convolutional_Neural_Networks), что делает работу сети быстрее).\n- 💔 В то же время это не самая точная модель (все является компромиссом ⚖️)\n\nНазвание модели включает в себя ее несколько важных характеристик, с которыми вы при желании можете ознакомиться детальнее:\n\n- Ожидаемый размер изображения на входе - `640x640px`.\n- Модель построена на основе [Single Shot MultiBox Detector](https://arxiv.org/abs/1512.02325) (SSD) и [Feature Pyramid Network](https://arxiv.org/abs/1612.03144) (FPN).\n- Сверточная нейронная сеть ([CNN](https://en.wikipedia.org/wiki/Convolutional_neural_network)) [MobileNet v2](https://ai.googleblog.com/2018/04/mobilenetv2-next-generation-of-on.html) используется в качестве экстрактора свойств изображения   (feature extractor).\n- Модель была обучена на наборе данных [COCO](https://cocodataset.org/#home)\n\n## 🛠 Устанавливаем Object Detection API \n\nВ этой статье мы будем устанавливать Tensorflow 2 Object Detection API _в виде пакета Python_. Это достаточно удобно, в случае если вы экспериментируете в [Google Colab](https://colab.research.google.com/) (предпочтительно) или в [Jupyter](https://jupyter.org/try). В обоих случаях вы можете избежать локальной инсталляции пакетов и проводить эксперименты непосредственно в браузере.\n\nТакже есть возможность установки Object Detection API используя Docker, о котором вы можете прочитать в [документации](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2.md).\n\n> Если у вас возникнут трудности во время установки API или во время создания набора данных (следующие разделы), вы можете обратиться к статье [TensorFlow 2 Object Detection API tutorial](https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/index.html), в которой есть много полезных деталей и советов.\n\nДля начала давайте клонируем [репозиторий с API](https://github.com/tensorflow/models):\n\n```bash\ngit clone --depth 1 https://github.com/tensorflow/models\n```\n\n_output →_\n\n```\nCloning into 'models'...\nremote: Enumerating objects: 2301, done.\nremote: Counting objects: 100% (2301/2301), done.\nremote: Compressing objects: 100% (2000/2000), done.\nremote: Total 2301 (delta 561), reused 922 (delta 278), pack-reused 0\nReceiving objects: 100% (2301/2301), 30.60 MiB | 13.90 MiB/s, done.\nResolving deltas: 100% (561/561), done.\n```\n\nТеперь можем скомпилировать [файлы-прототипы API](https://github.com/tensorflow/models/tree/master/research/object_detection/protos) в Python формат, используя [protoc](https://grpc.io/docs/protoc-installation/):\n\n```bash\ncd ./models/research\nprotoc object_detection/protos/*.proto --python_out=.\n```\n\nСледующим шагом будет установка API для версии TensorFlow 2 используя `pip` и файл [setup.py](https://github.com/tensorflow/models/blob/master/research/object_detection/packages/tf2/setup.py)`:\n\n```bash\ncp ./object_detection/packages/tf2/setup.py .\npip install . --quiet\n```\n\n> Если на этом шаге вы обнаружите ошибки, связанные установкой зависимых пакетов, попробуйте запустить `pip install . --quiet` во второй раз.\n\nПроверить успешность установки вы можете запустив тест:\n\n```bash\npython object_detection/builders/model_builder_tf2_test.py\n```\n\nВ итоге вы должны будете увидеть в консоли, что-то вроде этого:\n\n```\n[       OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor\n----------------------------------------------------------------------\nRan 20 tests in 45.072s\n\nOK (skipped=1)\n```\n\nTensorFlow Object Detection API установлена! Теперь мы можем использовать скрипты, предоставляемы этой API, для [обнаружения объектов в изображениях](https://github.com/tensorflow/models/blob/master/research/object_detection/colab_tutorials/inference_tf2_colab.ipynb), [тренировки](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_training_and_evaluation.md) или [доработки](https://github.com/tensorflow/models/blob/master/research/object_detection/colab_tutorials/eager_few_shot_od_training_tf2_colab.ipynb) моделей.\n\n## ⬇️ Загружаем заранее обученную модель\n\nДавайте загрузим ранее выбранную нами модель `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` из коллекции моделей TensorFlow и посмотрим, как мы можем использовать ее для обнаружения общих объектов, таких как \"кот\", \"собака\", \"машина\" и пр. (объектов с классами, поддерживаемыми набором данных COCO). \n\nМы воспользуемся утилитой TensorFlow [get_file()](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file) для загрузки архивированной модели по URL и для дальнейшей ее распаковки.\n\n```python\nimport tensorflow as tf\nimport pathlib\n\nMODEL_NAME = 'ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8'\nTF_MODELS_BASE_PATH = 'http://download.tensorflow.org/models/object_detection/tf2/20200711/'\nCACHE_FOLDER = './cache'\n\ndef download_tf_model(model_name, cache_folder):\n    model_url = TF_MODELS_BASE_PATH + model_name + '.tar.gz'\n    model_dir = tf.keras.utils.get_file(\n        fname=model_name, \n        origin=model_url,\n        untar=True,\n        cache_dir=pathlib.Path(cache_folder).absolute()\n    )\n    return model_dir\n\n# Start the model download.\nmodel_dir = download_tf_model(MODEL_NAME, CACHE_FOLDER)\nprint(model_dir)\n```\n\n_output →_\n\n```\n/content/cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nВот как на данный момент выглядит структура папок:\n\n![Cache Folder](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/10-cache-folder.jpg)\n\nПапка `checkpoint` содержит \"слепок\" параметров обученной модели.\n\nФайл `pipeline.config` содержит настройки обнаружения. Мы еще вернемся к этому файлу ниже, когда будем обучать нашу модель.\n\n## 🏄🏻‍️ Обнаружение объектов с помощью загруженной модели\n\nНа данный момент модель способна обнаруживать объекты классов, поддерживаемых набором данных COCO ([их всего 90](https://cocodataset.org/#explore)), таких, как `car`, `bird`, `hot dog` и пр. Эти классы еще могут называть ярлыками (labels).\n\n![COCO classes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/11-coco-classes.jpg)\n\n_Источник изображения: [сайт COCO](https://cocodataset.org/#explore)_\n\nПопробуем, обнаружит ли модель объекты этих классов.\n\n### Загружаем ярлыки COCO\n\nObject Detection API уже содержит файл с полным набор классов (ярлыков) COCO для нашего удобства. \n\n```python\nimport os\n\n# Import Object Detection API helpers.\nfrom object_detection.utils import label_map_util\n\n# Loads the COCO labels data (class names and indices relations).\ndef load_coco_labels():\n    # Object Detection API already has a complete set of COCO classes defined for us.\n    label_map_path = os.path.join(\n        'models/research/object_detection/data',\n        'mscoco_complete_label_map.pbtxt'\n    )\n    label_map = label_map_util.load_labelmap(label_map_path)\n\n    # Class ID to Class Name mapping.\n    categories = label_map_util.convert_label_map_to_categories(\n        label_map,\n        max_num_classes=label_map_util.get_max_label_map_index(label_map),\n        use_display_name=True\n    )\n    category_index = label_map_util.create_category_index(categories)\n    \n    # Class Name to Class ID mapping.\n    label_map_dict = label_map_util.get_label_map_dict(label_map, use_display_name=True)\n\n    return category_index, label_map_dict\n\n# Load COCO labels.\ncoco_category_index, coco_label_map_dict = load_coco_labels()\n\nprint('coco_category_index:', coco_category_index)\nprint('coco_label_map_dict:', coco_label_map_dict)\n```\n\n_output →_\n\n```\ncoco_category_index:\n{\n    1: {'id': 1, 'name': 'person'},\n    2: {'id': 2, 'name': 'bicycle'},\n    ...\n    90: {'id': 90, 'name': 'toothbrush'},\n}\n\ncoco_label_map_dict:\n{\n    'background': 0,\n    'person': 1,\n    'bicycle': 2,\n    'car': 3,\n    ...\n    'toothbrush': 90,\n}\n```\n\n### Создаем функцию обнаружения\n\nВ этом разделе мы создадим так называемую функцию обнаружения, которая будет использовать загруженную нами ранее модель, собственно, для обнаружения объектов в изображении. \n\n```python\nimport tensorflow as tf\n\n# Import Object Detection API helpers.\nfrom object_detection.utils import config_util\nfrom object_detection.builders import model_builder\n\n# Generates the detection function for specific model and specific model's checkpoint\ndef detection_fn_from_checkpoint(config_path, checkpoint_path):\n    # Build the model.\n    pipeline_config = config_util.get_configs_from_pipeline_file(config_path)\n    model_config = pipeline_config['model']\n    model = model_builder.build(\n        model_config=model_config,\n        is_training=False,\n    )\n\n    # Restore checkpoints.\n    ckpt = tf.compat.v2.train.Checkpoint(model=model)\n    ckpt.restore(checkpoint_path).expect_partial()\n\n    # This is a function that will do the detection.\n    @tf.function\n    def detect_fn(image):\n        image, shapes = model.preprocess(image)\n        prediction_dict = model.predict(image, shapes)\n        detections = model.postprocess(prediction_dict, shapes)\n\n        return detections, prediction_dict, tf.reshape(shapes, [-1])\n    \n    return detect_fn\n\ninference_detect_fn = detection_fn_from_checkpoint(\n    config_path=os.path.join('cache', 'datasets', MODEL_NAME, 'pipeline.config'),\n    checkpoint_path=os.path.join('cache', 'datasets', MODEL_NAME, 'checkpoint', 'ckpt-0'),\n)\n```\n\nФункция `inference_detect_fn` принимает на входе изображение и возвращает информацию об обнаруженных в нем объектах.\n\n### Загружаем тестовые изображения\n\nДавайте попробуем найти объекты на следующем изображении:\n\n![General Object Inference](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/12-inference-01.jpg)\n\nДля этого сохраним это изображение в папку `inference/test/` нашего проекта. Если вы используете Google Colab, вы можете создать эту папку и произвести загрузку файла вручную.\n\nВот как структура папок должна выглядеть на данный момент:\n\n![Folder structure](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/14-inference-folders.jpg)\n\n```python\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\n# Creating a TensorFlow dataset of just one image.\ninference_ds = tf.keras.preprocessing.image_dataset_from_directory(\n  directory='inference',\n  image_size=(640, 640),\n  batch_size=1,\n  shuffle=False,\n  label_mode=None\n)\n# Numpy version of the dataset.\ninference_ds_numpy = list(inference_ds.as_numpy_iterator())\n\n# You may preview the images in dataset like this.\nplt.figure(figsize=(14, 14))\nfor i, image in enumerate(inference_ds_numpy):\n    plt.subplot(2, 2, i + 1)\n    plt.imshow(image[0].astype(\"uint8\"))\n    plt.axis(\"off\")\nplt.show()\n```\n\n### Запускаем обнаружение для тестового изображения\n\nНа данном этапе мы готовы запустить обнаружение. Первый элемент массива `inference_ds_numpy[0]` содержит наше первое тестовое изображение в формате массива `Numpy`.\n\n```python\ndetections, predictions_dict, shapes = inference_detect_fn(\n    inference_ds_numpy[0]\n)\n```\n\nПроверим размерность массивов, которые нам вернула функция:\n\n```python\nboxes = detections['detection_boxes'].numpy()\nscores = detections['detection_scores'].numpy()\nclasses = detections['detection_classes'].numpy()\nnum_detections = detections['num_detections'].numpy()[0]\n\nprint('boxes.shape: ', boxes.shape)\nprint('scores.shape: ', scores.shape)\nprint('classes.shape: ', classes.shape)\nprint('num_detections:', num_detections)\n```\n\n_output →_\n\n```\nboxes.shape:  (1, 100, 4)\nscores.shape:  (1, 100)\nclasses.shape:  (1, 100)\nnum_detections: 100.0\n```\n\nМодель вернула нам массив со `100` \"обнаружениями\". Это не означает, что модель нашла `100` объектов в изображении. Это скорее говорит нам, что модель имеет `100` ячеек и поддерживает обнаружение максимум `100` объектов одновременно в одном изображении. Каждое \"обнаружение\" имеет соответствующий рейтинг (вероятность, score), который говорит об уверенности модели в том, что обнаружен именно этот объект. Габариты каждого найденного объекта хранятся в массиве `boxes`. Рейтинг каждого обнаружения хранится в массиве `scores`. Массив `classes` хранит ярлыки для каждого \"обнаружения\".\n\nДавайте проверим первые 5 таких \"обнаружений\":\n\n```python\nprint('First 5 boxes:')\nprint(boxes[0,:5])\n\nprint('First 5 scores:')\nprint(scores[0,:5])\n\nprint('First 5 classes:')\nprint(classes[0,:5])\n\nclass_names = [coco_category_index[idx + 1]['name'] for idx in classes[0]]\nprint('First 5 class names:')\nprint(class_names[:5])\n```\n\n_output →_\n\n```\nFirst 5 boxes:\n[[0.17576033 0.84654826 0.25642633 0.88327974]\n [0.5187813  0.12410264 0.6344235  0.34545377]\n [0.5220358  0.5181462  0.6329132  0.7669856 ]\n [0.50933677 0.7045719  0.5619138  0.7446198 ]\n [0.44761637 0.51942706 0.61237675 0.75963426]]\n\nFirst 5 scores:\n[0.6950246 0.6343004 0.591157  0.5827219 0.5415643]\n\nFirst 5 classes:\n[9. 8. 8. 0. 8.]\n\nFirst 5 class names:\n['traffic light', 'boat', 'boat', 'person', 'boat']\n```\n\nМодель видит светофор (`traffic light`), три лодки (`boats`) и человека (`person`). И мы можем подтвердить, что эти объекты действительно существуют в изображении.\n\nВ массиве `scores` мы видим, что модель наиболее уверенна (с 70% вероятностью) в найденном объекте класса `traffic light`.\n\nКаждый элемент массива `boxes` представляет собой координаты `[y1, x1, y2, x2]`, где `(x1, y1)` и `(x2, y2)` соответственно координаты левого верхнего и правого нижнего углов габаритного прямоугольника.\n\nПопробуем визуализировать габаритные прямоугольники:\n\n```python\n# Importing Object Detection API helpers.\nfrom object_detection.utils import visualization_utils\n\n# Visualizes the bounding boxes on top of the image.\ndef visualize_detections(image_np, detections, category_index):\n    label_id_offset = 1\n    image_np_with_detections = image_np.copy()\n\n    visualization_utils.visualize_boxes_and_labels_on_image_array(\n        image_np_with_detections,\n        detections['detection_boxes'][0].numpy(),\n        (detections['detection_classes'][0].numpy() + label_id_offset).astype(int),\n        detections['detection_scores'][0].numpy(),\n        category_index,\n        use_normalized_coordinates=True,\n        max_boxes_to_draw=200,\n        min_score_thresh=.4,\n        agnostic_mode=False,\n    )\n\n    plt.figure(figsize=(12, 16))\n    plt.imshow(image_np_with_detections)\n    plt.show()\n\n# Visualizing the detections.\nvisualize_detections(\n    image_np=tf.cast(inference_ds_numpy[0][0], dtype=tf.uint32).numpy(),\n    detections=detections,\n    category_index=coco_category_index,\n)\n```\n\nВ итоге мы увидим:\n\n![Inference result](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/14-inference-results-01.jpg)\n\nВ то же время, если мы попробуем обнаружить объекты на текстовом изображении мы увидим следующее:\n\n![Inference result for text image](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/15-inference-results-02.jpg)\n\nМодель не смогла найти ничего в этом изображении. Это как-раз то, что мы собираемся исправить и чему хотим научить нашу модель - видеть приставки `https://` в текстовых изображениях.\n\n## 📝 Подготавливаем набор данных для тренировки\n\nДля того, чтобы научить модель `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8` обнаруживать объекты, которые _не были_ описаны в наборе данных COCO нам необходимо подготовить свой набор данных и \"доучить\" модель на нем.\n\nНаборы данных для задачи обнаружения объектов состоят из двух компонентов:\n\n1. Собственно само изображение (например, изображение печатной странички книги или журнала)\n2. Габаритные прямоугольники, которые показывают где именно в изображении расположены объекты.\n\n![Bounding Boxes](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/16-detection-boxes.jpg)\n\nВ примере выше координаты `левого верхнего` и `правого нижнего` углов имеют _абсолютные_ значения (в пикселях). Также существуют альтернативные способы записи параметров таких габаритных прямоугольников. Например, мы можем описать прямоугольник с помощью его `координат центра`, а так же `ширины` и `высоты`. Мы также можем использовать _относительные_ значения координат (процент от ширины или высоты изображения). Но в целом, думаю идея понятна: модель должна знать где именно в изображении находится тот или иной объект.\n\nВопрос в том, где же нам взять такие данные для тренировки. У нас есть три варианта:\n\n1. _Воспользоваться имеющимся_ набором данных.\n2. _Сгенерировать новый_ искусственный набор данных.\n3. _Создать_ набор данных вручную путем фотографирования или загрузки реальных изображений с текстом и `https://` ссылками и дальнейшей аннотацией (указанием позиций объектов) каждого изображения вручную.\n\n### Вариант №1: Использование существующих наборов данных\n\nЕсть множество общедоступных наборов данных. Мы можем воспользоваться следующими ресурсами для поиска подходящего набора:\n\n- [Google Dataset Search](https://datasetsearch.research.google.com/)\n- [Kaggle Datasets](https://www.kaggle.com/datasets)\n- репозиторий [awesome-public-datasets](https://github.com/awesomedata/awesome-public-datasets)\n- и пр.\n\n💚 Если у вас получится найти подходящий набор данных с лицензией, позволяющей его использовать, то это, пожалуй, наиболее быстрый способ начать тренировку модели.\n\n💔 Но проблема в том, что мне не удалось найти набор данных, содержащий изображения книг со ссылками и их координатами.\n\nЭтот вариант нам прийдется пропустить.\n\n### Вариант №2: Генерирование искусственного набора данных\n\nСуществуют библиотеки (например [keras_ocr](https://keras-ocr.readthedocs.io/en/latest/examples/end_to_end_training.html#generating-synthetic-data)), которые могли бы нам помочь сгенерировать случайный текст, поместить в него ссылку и отрисовать текст на различных фонах и с различными искажениями.\n\n💚 Преимущество данного подхода заключается в том, что он дает нам возможность сгенерировать экземпляры данных с разными _шрифтами_, _лигатурами_, _цветами текста_ и _фона_. Это помогло бы нам избежать проблемы [переученности модели](https://en.wikipedia.org/wiki/Overfitting). Модель могла-бы легко обобщать свои \"знания\" в случае с изображениями, которые она не видела ранее.\n\n💚 Этот подход дает нам возможность сгенерировать разные типы ссылок, таких как: `http://`, `http://`, `ftp://`, `tcp://` и пр. Ведь найти множество реальных изображений с разными типами ссылок могло бы стать проблемой. \n\n💚 Еще одним преимуществом этого подхода является то, что мы можем сгенерировать столько изображений сколько хотим. Мы не ограничены количеством страниц со ссылками в книге, которую нам удалось найти. Увеличение набора данных может в итоге улучшить точность модели.\n\n💔 С другой стороны, существует возможность неправильного использования такого генератора, что в итоге может привести к набору \nданных, который будет существенно отличаться от реальных изображений. Например, мы можем ошибочно применить неправдоподобные изгибы страниц (волна вместо дуги) или неправдоподобные фоны. Модель в таком может не обобщить свои \"знания\" на изображения из реального мира.\n\n> Этот подход мне кажется очень многообещающим. Он может помочь нам преодолеть множество недостатков модели (о них мы упомянем ниже в статье). Я пока еще не пробовал применить этот подход, но, возможно, это будет предметом отдельной статьи.\n\n### Вариант №3: Создание набора данных вручную\n\nНаиболее прямолинейный способ - это взять книгу (или книги), сфотографировать странички, содержащие ссылки и обозначить локации префиксов `https://` для каждой странички вручную.\n\nХорошая новость в том, что набор данных, который нам нужен, может быть достаточно небольшим (сотни изображений будет достаточно). Это обусловлено тем, что мы не собираемся тренировать модель _с нуля_. Вместо этого мы будем \"доучивать\" уже обученную модель (см. [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning) и [few-shot learning](https://paperswithcode.com/task/few-shot-learning)).\n\n💚 В данном случае набор данных будет максимально приближен к реальному миру. Мы в буквальном смысле возьмем книгу, сфотографируем странички с реальными шрифтами, изгибами, тенями и цветами.\n\n💔 С другой стороны, даже с учетом того, что нам нужны всего сотни страничек, работа по сбору таких страничек и их дальнейшей аннотации может занять достаточно много времени.\n\n💔 Тяжело найти разные книги и журналы с разными шрифтами, типами ссылок, с разными фонами и лигатурами. В итоге набора данных будет достаточно узконаправленным (у пользователей должны будут быть книги со шрифтами и фонами похожими на ваши).\n\nПоскольку целью этой статьи, как было упомянуто выше, не является создание модели, которая должна выиграть соревнование по обнаружению объектов, мы можем пойти по пути создания модели вручную.\n\n### Обрабатываем фото для набора данных\n\nЯ сфотографировал `125` страничек одной книги, в которых нашел `https://` ссылки.\n\n![Raw Dataset](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/17-dataset-raw.jpg)\n\nВсе изображения были помещены в папку `dataset/printed_links/raw`.\n\nСледующим шаг - обработка изображений. Давайте применим следующие преобразования:\n\n- **Изменим размер** каждого изображения так, чтобы их ширина составила `1024px` (изначально изображения были чересчур большими с шириной в `3024px`)\n- **Обрежем** каждое изображение так, чтобы оно стало квадратным (это делать не обязательно, можно просто сжать изображение до квадратных пропорций, не обрезая его, но я хотел сохранить естественные пропорции префиксов `https:` перед обучением).\n- **Развернем** каждое изображения до правильной ориентации, применив метаданные из тега [exif](https://en.wikipedia.org/wiki/Exif).\n- **Сделаем каждое изображение черно-белым**, поскольку мы не хотим, чтобы модель брала во внимание цвет.\n- **Увеличим яркость**\n- **Увеличим контраст**\n- **Увеличим резкость**\n\nСтоить отметить, что в будущем, мы должны будем применять эти же манипуляции над изображениями перед тем, как отправлять их на вход нашей модели (если тренировочные изображения были черно-белыми и квадратными, то и реальные изображения, которые мы будем отправлять в нашу модель должны быть такими же квадратными и черно-белыми).\n\nМы можем применить все вышеописанные трансформации используя Python:\n\n```python\nimport os\nimport math\nimport shutil\n\nfrom pathlib import Path\nfrom PIL import Image, ImageOps, ImageEnhance\n\n# Resize an image.\ndef preprocess_resize(target_width):\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        (width, height) = image.size\n        ratio = width / height\n\n        if width > target_width:\n            target_height = math.floor(target_width / ratio)\n            log(f'Resizing: To size {target_width}x{target_height}')\n            image = image.resize((target_width, target_height))\n        else:\n            log('Resizing: Image already resized, skipping...')\n\n        return image\n    return preprocess\n\n# Crop an image.\ndef preprocess_crop_square():\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        (width, height) = image.size\n        \n        left = 0\n        top = 0\n        right = width\n        bottom = height\n        \n        crop_size = min(width, height)\n        \n        if width >= height:\n            # Horizontal image.\n            log(f'Squre cropping: Horizontal {crop_size}x{crop_size}')\n            left = width // 2 - crop_size // 2\n            right = left + crop_size\n        else:\n            # Vetyical image.\n            log(f'Squre cropping: Vertical {crop_size}x{crop_size}')\n            top = height // 2 - crop_size // 2\n            bottom = top + crop_size\n\n        image = image.crop((left, top, right, bottom))\n        return image\n    return preprocess\n\n# Apply exif transpose to an image.\ndef preprocess_exif_transpose():\n    # @see: https://pillow.readthedocs.io/en/stable/reference/ImageOps.html\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        log('EXif transpose')\n        image = ImageOps.exif_transpose(image)\n        return image\n    return preprocess\n\n# Apply color transformations to the image.\ndef preprocess_color(brightness, contrast, color, sharpness):\n    # @see: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html\n    def preprocess(image: Image.Image, log) -> Image.Image:\n        log('Coloring')\n        \n        enhancer = ImageEnhance.Color(image)\n        image = enhancer.enhance(color)\n\n        enhancer = ImageEnhance.Brightness(image)\n        image = enhancer.enhance(brightness)\n        \n        enhancer = ImageEnhance.Contrast(image)\n        image = enhancer.enhance(contrast)\n        \n        enhancer = ImageEnhance.Sharpness(image)\n        image = enhancer.enhance(sharpness)\n        \n        return image\n    return preprocess\n\n# Image pre-processing pipeline.\ndef preprocess_pipeline(src_dir, dest_dir, preprocessors=[], files_num_limit=0, override=False):\n    # Create destination folder if not exists.\n    Path(dest_dir).mkdir(parents=False, exist_ok=True)\n    \n    # Get the list of files to be copied.\n    src_file_names = os.listdir(src_dir)\n    files_total = files_num_limit if files_num_limit > 0 else len(src_file_names)\n    files_processed = 0\n    \n    # Logger function.\n    def preprocessor_log(message):\n        print('  ' + message)\n    \n    # Iterate through files.\n    for src_file_index, src_file_name in enumerate(src_file_names):\n        if files_num_limit > 0 and src_file_index >= files_num_limit:\n            break\n            \n        # Copy file.        \n        src_file_path = os.path.join(src_dir, src_file_name)\n        dest_file_path = os.path.join(dest_dir, src_file_name)\n        \n        progress = math.floor(100 * (src_file_index + 1) / files_total)\n        print(f'Image {src_file_index + 1}/{files_total} | {progress}% |  {src_file_path}')\n        \n        if not os.path.isfile(src_file_path):\n            preprocessor_log('Source is not a file, skipping...\\n')\n            continue\n        \n        if not override and os.path.exists(dest_file_path):\n            preprocessor_log('File already exists, skipping...\\n')\n            continue\n            \n        shutil.copy(src_file_path, dest_file_path)\n        files_processed += 1\n        \n        # Preprocess file.\n        image = Image.open(dest_file_path)\n        \n        for preprocessor in preprocessors:\n            image = preprocessor(image, preprocessor_log)\n        \n        image.save(dest_file_path, quality=95)\n        print('')\n        \n    print(f'{files_processed} out of {files_total} files have been processed')\n\n# Launching the image preprocessing pipeline.\npreprocess_pipeline(\n    src_dir='dataset/printed_links/raw',\n    dest_dir='dataset/printed_links/processed',\n    override=True,\n    # files_num_limit=1,\n    preprocessors=[\n        preprocess_exif_transpose(),\n        preprocess_resize(target_width=1024),\n        preprocess_crop_square(),\n        preprocess_color(brightness=2, contrast=1.3, color=0, sharpness=1),\n    ]\n)\n```\n\nВ результате все обработанные изображения будут сохранены в папке `dataset/printed_links/processed`.\n\n![Dataset Processed](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/18-dataset-processed.jpg)\n\nМы можем просмотреть полученные изображения следующим образом:\n\n```python\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef preview_images(images_dir, images_num=1, figsize=(15, 15)):\n    image_names = os.listdir(images_dir)\n    image_names = image_names[:images_num]\n    \n    num_cells = math.ceil(math.sqrt(images_num))\n    figure = plt.figure(figsize=figsize)\n    \n    for image_index, image_name in enumerate(image_names):\n        image_path = os.path.join(images_dir, image_name)\n        image = Image.open(image_path)\n        \n        figure.add_subplot(num_cells, num_cells, image_index + 1)\n        plt.imshow(np.asarray(image))\n    \n    plt.show()\n\npreview_images('dataset/printed_links/processed', images_num=4, figsize=(16, 16))\n```\n\n### Указываем позиции и габариты объектов для нашего набора данных\n\nДля того, чтобы указать позиции и габариты объектов (префиксов `https://`) в нашем наборе данных мы можем воспользоваться программой аннотации изображений [LabelImg](https://github.com/tzutalin/labelImg).\n\n> Вам понадобится установить LabelImg локально на ваш компьютер. Детальную инструкцию по установке вы сможете найти в [документации LabelImg](https://github.com/tzutalin/labelImg)\n\nПосле установки LabelImg, вы можете запустить программу из консоли, указав папку с изображениями (в нашем случае `dataset/printed_links/processed`), которую вы хотите аннотировать:\n\n```bash\nlabelImg dataset/printed_links/processed\n```\n\nВ открывшемся окне вам необходимо аннотировать все изображения из папки `dataset/printed_links/processed` и сохранить все изображения в формате XML в папку `dataset/printed_links/labels/xml/`.\n\n![Labeling](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/18-labeling.jpg)\n\n![Labeling Process](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/19-labeling-process.gif)\n\nПосле завершения процесса аннотирования для каждого изображения мы должны получить XML файл с позицией и габаритами каждого объекта:\n\n![Labels folder structure](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/20-labels-folder.jpg)\n\n### Разбиваем общий набор данных на тренировочный и тестовый наборы\n\nДля того, чтобы идентифицировать проблему [переучивания или недоучивания](https://en.wikipedia.org/wiki/Overfitting) модели, нам необходимо разбить наш общий набор данных на тренировочный и тестовый наборы. Мы можем использовать `80%` всех изображений для тренировки и `20%` изображений для тестирования модели. Задача тестового набора - понять насколько наша модель может обобщить свои \"знания\" на данных, которые она не \"видела\" раньше.\n\n> В этой статье мы будем разбивать файлы путем их перемешивания и копирования в разные папки (в папки `test` и `train`). Стоит отметить, что такой подход, возможно, не является оптимальным. Вместо физического размещения файлов в разных папках мы так же можем разбивать набор данных на подгруппы на лету с помощью [tf.data.Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset).\n\n```python\nimport re\nimport random\n\ndef partition_dataset(\n    images_dir,\n    xml_labels_dir,\n    train_dir,\n    test_dir,\n    val_dir,\n    train_ratio,\n    test_ratio,\n    val_ratio,\n    copy_xml\n):    \n    if not os.path.exists(train_dir):\n        os.makedirs(train_dir)\n        \n    if not os.path.exists(test_dir):\n        os.makedirs(test_dir)\n        \n    if not os.path.exists(val_dir):\n        os.makedirs(val_dir)\n\n    images = [f for f in os.listdir(images_dir)\n              if re.search(r'([a-zA-Z0-9\\s_\\\\.\\-\\(\\):])+(.jpg|.jpeg|.png)$', f, re.IGNORECASE)]\n\n    num_images = len(images)\n    \n    num_train_images = math.ceil(train_ratio * num_images)\n    num_test_images = math.ceil(test_ratio * num_images)\n    num_val_images = math.ceil(val_ratio * num_images)\n    \n    print('Intended split')\n    print(f'  train: {num_train_images}/{num_images} images')\n    print(f'  test: {num_test_images}/{num_images} images')\n    print(f'  val: {num_val_images}/{num_images} images')\n    \n    actual_num_train_images = 0\n    actual_num_test_images = 0\n    actual_num_val_images = 0\n    \n    def copy_random_images(num_images, dest_dir):\n        copied_num = 0\n        \n        if not num_images:\n            return copied_num\n        \n        for i in range(num_images):\n            if not len(images):\n                break\n                \n            idx = random.randint(0, len(images)-1)\n            filename = images[idx]\n            shutil.copyfile(os.path.join(images_dir, filename), os.path.join(dest_dir, filename))\n            \n            if copy_xml:\n                xml_filename = os.path.splitext(filename)[0]+'.xml'\n                shutil.copyfile(os.path.join(xml_labels_dir, xml_filename), os.path.join(dest_dir, xml_filename))\n            \n            images.remove(images[idx])\n            copied_num += 1\n        \n        return copied_num\n    \n    actual_num_train_images = copy_random_images(num_train_images, train_dir)\n    actual_num_test_images = copy_random_images(num_test_images, test_dir)\n    actual_num_val_images = copy_random_images(num_val_images, val_dir)\n    \n    print('\\n', 'Actual split')\n    print(f'  train: {actual_num_train_images}/{num_images} images')\n    print(f'  test: {actual_num_test_images}/{num_images} images')\n    print(f'  val: {actual_num_val_images}/{num_images} images')\n\npartition_dataset(\n    images_dir='dataset/printed_links/processed',\n    train_dir='dataset/printed_links/partitioned/train',\n    test_dir='dataset/printed_links/partitioned/test',\n    val_dir='dataset/printed_links/partitioned/val',\n    xml_labels_dir='dataset/printed_links/labels/xml',\n    train_ratio=0.8,\n    test_ratio=0.2,\n    val_ratio=0,\n    copy_xml=True\n)\n```\n\nПосле разбития нашего набора данных структура папок должна выглядеть так:\n\n```\ndataset/\n└── printed_links\n    ├── labels\n    │   └── xml\n    ├── partitioned\n    │   ├── test\n    │   └── train\n    │       ├── IMG_9140.JPG\n    │       ├── IMG_9140.xml\n    │       ├── IMG_9141.JPG\n    │       ├── IMG_9141.xml\n    │       ...\n    ├── processed\n    └── raw\n```\n\n### Экспортируем набор данных\n\nПоследней манипуляцией над данными, которую нам необходимо произвести, будет конвертация данных в формат [TFRecord](https://www.tensorflow.org/tutorials/load_data/tfrecord). Формат `TFRecord` используется TensorFlow для хранения последовательности записей (в нашем случае для хранения последовательности изображений).\n\nСначала создадим две папки: одну для хранения аннотаций в формате `CSV`, другую для хранения нашей финальной версии набора данных в формате `TFRecord`.\n\n```bash\nmkdir -p dataset/printed_links/labels/csv\nmkdir -p dataset/printed_links/tfrecords\n```\n\nТеперь нам необходимо создать файл-прототип `dataset/printed_links/labels/label_map.pbtxt` с классами объектов, которые наша модель должна научиться распознавать. В нашем случае у нас будет всего _один класс_, который мы назовем `http`. Содержимое файла должно быть следующим:\n\n```\nitem {\n  id: 1\n  name: 'http'\n}\n```\n\nТеперь мы готовы конвертировать набор данных в формат TFRecord из набора `jpg` изображений и аннотаций в `xml` формате:\n\n```python\nimport os\nimport io\nimport math\nimport glob\nimport tensorflow as tf\nimport pandas as pd\nimport xml.etree.ElementTree as ET\nfrom PIL import Image\nfrom collections import namedtuple\nfrom object_detection.utils import dataset_util, label_map_util\n\ntf1 = tf.compat.v1\n\n# Convers labels from XML format to CSV.\ndef xml_to_csv(path):\n    xml_list = []\n    for xml_file in glob.glob(path + '/*.xml'):\n        tree = ET.parse(xml_file)\n        root = tree.getroot()\n        for member in root.findall('object'):\n            value = (root.find('filename').text,\n                int(root.find('size')[0].text),\n                int(root.find('size')[1].text),\n                member[0].text,\n                int(member[4][0].text),\n                int(member[4][1].text),\n                int(member[4][2].text),\n                int(member[4][3].text)\n            )\n            xml_list.append(value)\n    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']\n    xml_df = pd.DataFrame(xml_list, columns=column_name)\n    return xml_df\n\n\ndef class_text_to_int(row_label, label_map_dict):\n    return label_map_dict[row_label]\n\n\ndef split(df, group):\n    data = namedtuple('data', ['filename', 'object'])\n    gb = df.groupby(group)\n    return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]\n\n\n# Creates a TFRecord.\ndef create_tf_example(group, path, label_map_dict):\n    with tf1.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:\n        encoded_jpg = fid.read()\n        \n    encoded_jpg_io = io.BytesIO(encoded_jpg)\n    image = Image.open(encoded_jpg_io)\n    width, height = image.size\n\n    filename = group.filename.encode('utf8')\n    image_format = b'jpg'\n    xmins = []\n    xmaxs = []\n    ymins = []\n    ymaxs = []\n    classes_text = []\n    classes = []\n\n    for index, row in group.object.iterrows():\n        xmins.append(row['xmin'] / width)\n        xmaxs.append(row['xmax'] / width)\n        ymins.append(row['ymin'] / height)\n        ymaxs.append(row['ymax'] / height)\n        classes_text.append(row['class'].encode('utf8'))\n        classes.append(class_text_to_int(row['class'], label_map_dict))\n\n    tf_example = tf1.train.Example(features=tf1.train.Features(feature={\n        'image/height': dataset_util.int64_feature(height),\n        'image/width': dataset_util.int64_feature(width),\n        'image/filename': dataset_util.bytes_feature(filename),\n        'image/source_id': dataset_util.bytes_feature(filename),\n        'image/encoded': dataset_util.bytes_feature(encoded_jpg),\n        'image/format': dataset_util.bytes_feature(image_format),\n        'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),\n        'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),\n        'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),\n        'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),\n        'image/object/class/text': dataset_util.bytes_list_feature(classes_text),\n        'image/object/class/label': dataset_util.int64_list_feature(classes),\n    }))\n    \n    return tf_example\n\n\ndef dataset_to_tfrecord(\n    images_dir,\n    xmls_dir, \n    label_map_path,\n    output_path,\n    csv_path=None\n):\n    label_map = label_map_util.load_labelmap(label_map_path)\n    label_map_dict = label_map_util.get_label_map_dict(label_map)\n    \n    tfrecord_writer = tf1.python_io.TFRecordWriter(output_path)\n    images_path = os.path.join(images_dir)\n    csv_examples = xml_to_csv(xmls_dir)\n    grouped_examples = split(csv_examples, 'filename')\n    \n    for group in grouped_examples:\n        tf_example = create_tf_example(group, images_path, label_map_dict)\n        tfrecord_writer.write(tf_example.SerializeToString())\n        \n    tfrecord_writer.close()\n    \n    print('Successfully created the TFRecord file: {}'.format(output_path))\n    \n    if csv_path is not None:\n        csv_examples.to_csv(csv_path, index=None)\n        print('Successfully created the CSV file: {}'.format(csv_path))\n\n# Generate a TFRecord for train dataset.\ndataset_to_tfrecord(\n    images_dir='dataset/printed_links/partitioned/train',\n    xmls_dir='dataset/printed_links/partitioned/train',\n    label_map_path='dataset/printed_links/labels/label_map.pbtxt',\n    output_path='dataset/printed_links/tfrecords/train.record',\n    csv_path='dataset/printed_links/labels/csv/train.csv'\n)\n\n# Generate a TFRecord for test dataset.\ndataset_to_tfrecord(\n    images_dir='dataset/printed_links/partitioned/test',\n    xmls_dir='dataset/printed_links/partitioned/test',\n    label_map_path='dataset/printed_links/labels/label_map.pbtxt',\n    output_path='dataset/printed_links/tfrecords/test.record',\n    csv_path='dataset/printed_links/labels/csv/test.csv'\n)\n```\n\nВ результате мы должны получить файлы `test.record` и `train.record` в папке `dataset/printed_links/tfrecords/`:\n\n```\ndataset/\n└── printed_links\n    ├── labels\n    │   ├── csv\n    │   ├── label_map.pbtxt\n    │   └── xml\n    ├── partitioned\n    │   ├── test\n    │   ├── train\n    │   └── val\n    ├── processed\n    ├── raw\n    └── tfrecords\n        ├── test.record\n        └── train.record\n```\n\nЭти два файла `test.record` и `train.record` являются конечной версией нашего набора данных, который мы будем использовать для обучения модели `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`.\n\n## 📖 Работаем с набором данных в формате TFRecord\n\nВ этом разделе мы посмотрим, какие инструменты для исследования наборов данных в формате `TFRecord` имеются в TensorFlow 2 Object Detection API.\n\n**Проверяем количество экземпляров в наборе данных**\n\nПосчитать количество экземпляров мы можем следующим образом:\n\n```python\nimport tensorflow as tf\n\n# Count the number of examples in the dataset.\ndef count_tfrecords(tfrecords_filename):\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n    # Keep in mind that the list() operation might be\n    # a performance bottleneck for large datasets. \n    return len(list(raw_dataset))\n\nTRAIN_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/train.record')\nTEST_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/test.record')\n\nprint('TRAIN_RECORDS_NUM: ', TRAIN_RECORDS_NUM)\nprint('TEST_RECORDS_NUM:  ', TEST_RECORDS_NUM)\n```\n\n_output →_\n\n```\nTRAIN_RECORDS_NUM:  100\nTEST_RECORDS_NUM:   25\n```\n\nИтак, мы будем тренировать нашу модель на `100` экземплярах и проверять ее способность к обобщению на `25` изображениях.\n\n**Отображаем габариты и локализацию объектов в изображениях**\n\nОтобразить габариты и позицию объектов в изображении мы можем следующим образом:\n\n```python\nimport tensorflow as tf\nimport numpy as np\nfrom google.protobuf import text_format\nimport matplotlib.pyplot as plt\n\n# Import Object Detection API.\nfrom object_detection.utils import visualization_utils\nfrom object_detection.protos import string_int_label_map_pb2\nfrom object_detection.data_decoders.tf_example_decoder import TfExampleDecoder\n\n%matplotlib inline\n\n# Visualize the TFRecord dataset.\ndef visualize_tfrecords(tfrecords_filename, label_map=None, print_num=1):\n    decoder = TfExampleDecoder(\n        label_map_proto_file=label_map,\n        use_display_name=False\n    )\n\n    if label_map is not None:\n        label_map_proto = string_int_label_map_pb2.StringIntLabelMap()\n\n        with tf.io.gfile.GFile(label_map,'r') as f:\n            text_format.Merge(f.read(), label_map_proto)\n            class_dict = {}\n            \n            for entry in label_map_proto.item:\n                class_dict[entry.id] = {'name': entry.name}\n\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n\n    for raw_record in raw_dataset.take(print_num):\n        example = decoder.decode(raw_record)\n\n        image = example['image'].numpy()\n        boxes = example['groundtruth_boxes'].numpy()\n        confidences = example['groundtruth_image_confidences']\n        filename = example['filename']\n        area = example['groundtruth_area']\n        classes = example['groundtruth_classes'].numpy()\n        image_classes = example['groundtruth_image_classes']\n        weights = example['groundtruth_weights']\n\n        scores = np.ones(boxes.shape[0])\n\n        visualization_utils.visualize_boxes_and_labels_on_image_array( \n            image,                                               \n            boxes,                                                     \n            classes,\n            scores,\n            class_dict,\n            max_boxes_to_draw=None,\n            use_normalized_coordinates=True\n        )\n\n        plt.figure(figsize=(8, 8))\n        plt.imshow(image)\n\n    plt.show()\n\n# Visualizing the training TFRecord dataset.\nvisualize_tfrecords(\n    tfrecords_filename='dataset/printed_links/tfrecords/train.record',\n    label_map='dataset/printed_links/labels/label_map.pbtxt',\n    print_num=3\n)\n```\n\nВ результате мы должны увидеть несколько изображений с прямоугольными габаритами для каждого из объектов,\n\n![TFRecord Preview](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/23-tfrecords-preview.jpg)\n\n## 📈 Устанавливаем TensorBoard\n\nПеред тем, как начать тренировку мы можем запустить [TensorBoard](https://www.tensorflow.org/tensorboard).\n\nTensorBoard поможет нам в мониторинге тренировочного процесса. Он поможет нам увидеть, действительно ли модель обучается или же нам лучше остановить тренировку и подправить параметры тренировки. TensorBoard также поможет нам какие объекты и где именно на изображении наша модель обнаруживает.\n\n![TensorBoard](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/24-tensorboard.gif)\n\n_Источник изображения: [домашняя страница TensorBoard](https://www.tensorflow.org/tensorboard)_\n\nОтличной особенностью TensorBoard является то, что мы можем запустить его прямо в Google Colab. Если же вы экспериментируете с моделью локально в Jupyter ноутбуке, то вы можете [установить TensorBoard как Python пакет](https://github.com/tensorflow/tensorboard/blob/master/README.md) и запустить его локально из консоли.\n\nДля начала создадим папку `./logs`, в которой во время тренировки будут храниться параметры модели.\n\n```bash\nmkdir -p logs\n```\n\nДалее, мы загружаем расширение TensorBoard в Google Colab:\n\n```\n%load_ext tensorboard\n```\n\nИ теперь мы можем запустить TensorBoard и указать папку `./logs` в качестве папки с логами тренировки,\n\n```\n%tensorboard --logdir ./logs\n```\n\nВ результате вы должны увидеть пустую панель TensorBoard:\n\n![Empty TensorBoard Panel](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/25-tensorboard-launch.jpg)\n\nПосле того, как мы начнем тренировку, мы сможем вернуться к этой панели и проверить насколько хорошо она обучается.\n\n## 🏋🏻‍️ Тренировка модели\n\n### Настраиваем параметры тренировки\n\nТеперь мы можем вернуться к ранее упомянутому файлу `cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config`. В этом файле собраны параметры для тренировки модели `ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8`.\n\nНам необходимо скопировать файл `pipeline.config` в корень нашего проекта и изменить следующие параметры:\n\n1. Необходимо **количество классов** с `90` (количество классов набора данных COCO) на `1` (наш единственный класс `http`)\n2. Необходимо уменьшить **размер тренировочного пакета** (batch size) до `8` изображений на один пакет, чтобы избежать проблем  с недостатком памяти.\n3. Необходимо указать нашей модели, где хранятся сохраненные **слепки** ранее натренированных параметров модели, поскольку мы не хотим тренировать ее с нуля.\n4. Необходимо установить параметр `fine_tune_checkpoint_type` в `detection`.\n5. Необходимо указать модели, где находится **карта новых классов** объектов.\n6. Необходимо указать модели, где находятся **тренировочный и тестовый наборы данных**.\n\nВсе эти изменения можно сделать вручную в файле `pipeline.config`, но это так же можно сделать программно:\n\n```python\nimport tensorflow as tf\nfrom shutil import copyfile\nfrom google.protobuf import text_format\nfrom object_detection.protos import pipeline_pb2\n\n# Adjust pipeline config modification here if needed.\ndef modify_config(pipeline):\n    # Model config.\n    pipeline.model.ssd.num_classes = 1    \n\n    # Train config.\n    pipeline.train_config.batch_size = 8\n\n    pipeline.train_config.fine_tune_checkpoint = 'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0'\n    pipeline.train_config.fine_tune_checkpoint_type = 'detection'\n\n    # Train input reader config.\n    pipeline.train_input_reader.label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'\n    pipeline.train_input_reader.tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/train.record'\n\n    # Eval input reader config.\n    pipeline.eval_input_reader[0].label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'\n    pipeline.eval_input_reader[0].tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/test.record'\n\n    return pipeline\n\ndef clone_pipeline_config():\n    copyfile(\n        'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config',\n        'pipeline.config'\n    )\n\ndef setup_pipeline(pipeline_config_path):\n    clone_pipeline_config()\n    pipeline = read_pipeline_config(pipeline_config_path)\n    pipeline = modify_config(pipeline)\n    write_pipeline_config(pipeline_config_path, pipeline)\n    return pipeline\n\ndef read_pipeline_config(pipeline_config_path):\n    pipeline = pipeline_pb2.TrainEvalPipelineConfig()                                                                                                                                                                                                          \n    with tf.io.gfile.GFile(pipeline_config_path, \"r\") as f:                                                                                                                                                                                                                     \n        proto_str = f.read()                                                                                                                                                                                                                                          \n        text_format.Merge(proto_str, pipeline)\n    return pipeline\n\ndef write_pipeline_config(pipeline_config_path, pipeline):\n    config_text = text_format.MessageToString(pipeline)                                                                                                                                                                                                        \n    with tf.io.gfile.GFile(pipeline_config_path, \"wb\") as f:                                                                                                                                                                                                                       \n        f.write(config_text)\n\n# Adjusting the pipeline configuration.\npipeline = setup_pipeline('pipeline.config')\n\nprint(pipeline)\n```\n\nВот окончательная версия файла `pipeline.config` после редактирования:\n\n```\nmodel {\n  ssd {\n    num_classes: 1\n    image_resizer {\n      fixed_shape_resizer {\n        height: 640\n        width: 640\n      }\n    }\n    feature_extractor {\n      type: \"ssd_mobilenet_v2_fpn_keras\"\n      depth_multiplier: 1.0\n      min_depth: 16\n      conv_hyperparams {\n        regularizer {\n          l2_regularizer {\n            weight: 3.9999998989515007e-05\n          }\n        }\n        initializer {\n          random_normal_initializer {\n            mean: 0.0\n            stddev: 0.009999999776482582\n          }\n        }\n        activation: RELU_6\n        batch_norm {\n          decay: 0.996999979019165\n          scale: true\n          epsilon: 0.0010000000474974513\n        }\n      }\n      use_depthwise: true\n      override_base_feature_extractor_hyperparams: true\n      fpn {\n        min_level: 3\n        max_level: 7\n        additional_layer_depth: 128\n      }\n    }\n    box_coder {\n      faster_rcnn_box_coder {\n        y_scale: 10.0\n        x_scale: 10.0\n        height_scale: 5.0\n        width_scale: 5.0\n      }\n    }\n    matcher {\n      argmax_matcher {\n        matched_threshold: 0.5\n        unmatched_threshold: 0.5\n        ignore_thresholds: false\n        negatives_lower_than_unmatched: true\n        force_match_for_each_row: true\n        use_matmul_gather: true\n      }\n    }\n    similarity_calculator {\n      iou_similarity {\n      }\n    }\n    box_predictor {\n      weight_shared_convolutional_box_predictor {\n        conv_hyperparams {\n          regularizer {\n            l2_regularizer {\n              weight: 3.9999998989515007e-05\n            }\n          }\n          initializer {\n            random_normal_initializer {\n              mean: 0.0\n              stddev: 0.009999999776482582\n            }\n          }\n          activation: RELU_6\n          batch_norm {\n            decay: 0.996999979019165\n            scale: true\n            epsilon: 0.0010000000474974513\n          }\n        }\n        depth: 128\n        num_layers_before_predictor: 4\n        kernel_size: 3\n        class_prediction_bias_init: -4.599999904632568\n        share_prediction_tower: true\n        use_depthwise: true\n      }\n    }\n    anchor_generator {\n      multiscale_anchor_generator {\n        min_level: 3\n        max_level: 7\n        anchor_scale: 4.0\n        aspect_ratios: 1.0\n        aspect_ratios: 2.0\n        aspect_ratios: 0.5\n        scales_per_octave: 2\n      }\n    }\n    post_processing {\n      batch_non_max_suppression {\n        score_threshold: 9.99999993922529e-09\n        iou_threshold: 0.6000000238418579\n        max_detections_per_class: 100\n        max_total_detections: 100\n        use_static_shapes: false\n      }\n      score_converter: SIGMOID\n    }\n    normalize_loss_by_num_matches: true\n    loss {\n      localization_loss {\n        weighted_smooth_l1 {\n        }\n      }\n      classification_loss {\n        weighted_sigmoid_focal {\n          gamma: 2.0\n          alpha: 0.25\n        }\n      }\n      classification_weight: 1.0\n      localization_weight: 1.0\n    }\n    encode_background_as_zeros: true\n    normalize_loc_loss_by_codesize: true\n    inplace_batchnorm_update: true\n    freeze_batchnorm: false\n  }\n}\ntrain_config {\n  batch_size: 8\n  data_augmentation_options {\n    random_horizontal_flip {\n    }\n  }\n  data_augmentation_options {\n    random_crop_image {\n      min_object_covered: 0.0\n      min_aspect_ratio: 0.75\n      max_aspect_ratio: 3.0\n      min_area: 0.75\n      max_area: 1.0\n      overlap_thresh: 0.0\n    }\n  }\n  sync_replicas: true\n  optimizer {\n    momentum_optimizer {\n      learning_rate {\n        cosine_decay_learning_rate {\n          learning_rate_base: 0.07999999821186066\n          total_steps: 50000\n          warmup_learning_rate: 0.026666000485420227\n          warmup_steps: 1000\n        }\n      }\n      momentum_optimizer_value: 0.8999999761581421\n    }\n    use_moving_average: false\n  }\n  fine_tune_checkpoint: \"cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0\"\n  num_steps: 50000\n  startup_delay_steps: 0.0\n  replicas_to_aggregate: 8\n  max_number_of_boxes: 100\n  unpad_groundtruth_tensors: false\n  fine_tune_checkpoint_type: \"detection\"\n  fine_tune_checkpoint_version: V2\n}\ntrain_input_reader {\n  label_map_path: \"dataset/printed_links/labels/label_map.pbtxt\"\n  tf_record_input_reader {\n    input_path: \"dataset/printed_links/tfrecords/train.record\"\n  }\n}\neval_config {\n  metrics_set: \"coco_detection_metrics\"\n  use_moving_averages: false\n}\neval_input_reader {\n  label_map_path: \"dataset/printed_links/labels/label_map.pbtxt\"\n  shuffle: false\n  num_epochs: 1\n  tf_record_input_reader {\n    input_path: \"dataset/printed_links/tfrecords/test.record\"\n  }\n}\n```\n\n### Запускаем процесс тренировки\n\nМы готовы запустить процесс тренировки модели используя TensorFlow 2 Object Detection API. API содержит файл [model_main_tf2.py](https://github.com/tensorflow/models/blob/master/research/object_detection/model_main_tf2.py), который содержит всю логику тренировки. Вы можете детальнее ознакомиться с исходным Python кодом файла, в котором описаны входные параметры скрипта (например, `num_train_steps`, `model_dir` и пр.). \n\nМы будем тренировать модель в течение `1000` итераций (эпох).\n\n```bash\n%%bash\n\nNUM_TRAIN_STEPS=1000\nCHECKPOINT_EVERY_N=1000\n\nPIPELINE_CONFIG_PATH=pipeline.config\nMODEL_DIR=./logs\nSAMPLE_1_OF_N_EVAL_EXAMPLES=1\n\npython ./models/research/object_detection/model_main_tf2.py \\\n  --model_dir=$MODEL_DIR \\\n  --num_train_steps=$NUM_TRAIN_STEPS \\\n  --sample_1_of_n_eval_examples=$SAMPLE_1_OF_N_EVAL_EXAMPLES \\\n  --pipeline_config_path=$PIPELINE_CONFIG_PATH \\\n  --checkpoint_every_n=$CHECKPOINT_EVERY_N \\\n  --alsologtostderr\n```\n\nВо время тренировки модели (это может занять `~10` минут для `1000` итераций с использованием [GPU runtime](https://colab.research.google.com/notebooks/gpu.ipynb) в GoogleColab) вы можете увидеть как процесс тренировки в TensorBoard. Ошибки `localization` и `classification` должны уменьшаться, что означает, что модель все лучше и лучше локализует объекты и определяет их класс. \n\n![Training Process](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/26-tensorboard-training.jpg)\n\nТакже по мере обучения модели в папке `logs` будут создаваться новые чекпоинты (слепки) параметров модели.\n\nПапка `logs` может выглядеть следующим образом:\n\n```\nlogs\n├── checkpoint\n├── ckpt-1.data-00000-of-00001\n├── ckpt-1.index\n└── train\n    └── events.out.tfevents.1606560330.b314c371fa10.1747.1628.v2\n```\n\n### Оцениваем модель (опционально)\n\nЧтобы оценить точность работы модели мы пробуем обнаружить объекты на изображения из тестового набора данных. Результат такой оценки обобщается в виде [метрик](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/evaluation_protocols.md), изменение которых мы можем наблюдать с течением времени. Вы можете более детально ознакомиться с тем, какие именно метрики используются [здесь](https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/training.html#evaluating-the-model-optional).\n\nВ этой статье мы пропустим этот шаг с метриками, но мы все-же можем воспользоваться панелью TensorBoard, чтобы увидеть, какие объекты модель обнаруживает на тестовом наборе данных:\n\n```bash\n%%bash\n\nPIPELINE_CONFIG_PATH=pipeline.config\nMODEL_DIR=logs\n\npython ./models/research/object_detection/model_main_tf2.py \\\n  --model_dir=$MODEL_DIR \\\n  --pipeline_config_path=$PIPELINE_CONFIG_PATH \\\n  --checkpoint_dir=$MODEL_DIR \\\n```\n\nПосле запуска скрипта вы сможете увидеть несколько изображений с обнаруженными в них предметами:\n\n![Model Evaluation](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/27-tensorboard-evaluation.jpg)\n\n## 🗜 Экспортируем модель\n\nПосле окончания тренировки необходимо сохранить модель для дальнейшего использования. Для экспортирования модели мы воспользуемся скриптом [exporter_main_v2.py](https://github.com/tensorflow/models/blob/master/research/object_detection/exporter_main_v2.py) из Object Detection API. Этот скрипт подготавливает TensorFlow граф на основании чекпоинтов модели и ее тренировочной конфигурации. После выполнения скрипта мы получим папку с чекпоинтами, моделью в формате SavedModel и копией конфигурационного файла модели.\n\n```bash\n%%bash\n\npython ./models/research/object_detection/exporter_main_v2.py \\\n    --input_type=image_tensor \\\n    --pipeline_config_path=pipeline.config \\\n    --trained_checkpoint_dir=logs \\\n    --output_directory=exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nВот так выглядит содержимое папки `exported`:\n\n```\nexported\n└── ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n    ├── checkpoint\n    │   ├── checkpoint\n    │   ├── ckpt-0.data-00000-of-00001\n    │   └── ckpt-0.index\n    ├── pipeline.config\n    └── saved_model\n        ├── assets\n        ├── saved_model.pb\n        └── variables\n            ├── variables.data-00000-of-00001\n            └── variables.index\n```\n\nНа этом этапе у нас есть модель в папке `saved_model`, которую мы уже можем использовать для обнаружения объектов.\n\n## 🚀 Использование экспортированной модели\n\nДавайте посмотрим, как мы можем использовать модель, экспортированную на предыдущем этапе.\n\nВ начале нам необходимо создать функцию-обнаружитель, которая будет использовать сохраненную модель. Эта функция будет принимать изображение на вход и выдавать информацию об обнаруженных объектах:\n\n```python\nimport time\nimport math\n\nPATH_TO_SAVED_MODEL = 'exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model'\n\ndef detection_function_from_saved_model(saved_model_path):\n    print('Loading saved model...', end='')\n    start_time = time.time()\n\n    # Load saved model and build the detection function\n    detect_fn = tf.saved_model.load(saved_model_path)\n\n    end_time = time.time()\n    elapsed_time = end_time - start_time\n\n    print('Done! Took {} seconds'.format(math.ceil(elapsed_time)))\n\n    return detect_fn\n\nexported_detect_fn = detection_function_from_saved_model(\n    PATH_TO_SAVED_MODEL\n)\n```\n\n_output →_\n\n```\nLoading saved model...Done! Took 9 seconds\n```\n\nДля сопоставления идентификаторов обнаруженных классов с именами классов нам также необходимо загрузить карту классов:\n\n```python\nfrom object_detection.utils import label_map_util\n\ncategory_index = label_map_util.create_category_index_from_labelmap(\n    'dataset/printed_links/labels/label_map.pbtxt',\n    use_display_name=True\n)\n\nprint(category_index)\n```\n\n_output →_\n\n```\n{1: {'id': 1, 'name': 'http'}}\n```\n\nТестируем нашу модель на тестовом наборе данных.\n\n```python\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport numpy as np\n\nfrom object_detection.utils import visualization_utils\nfrom object_detection.data_decoders.tf_example_decoder import TfExampleDecoder\n\n%matplotlib inline\n\ndef tensors_from_tfrecord(\n    tfrecords_filename,\n    tfrecords_num,\n    dtype=tf.float32\n):\n    decoder = TfExampleDecoder()\n    raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)\n    images = []\n\n    for raw_record in raw_dataset.take(tfrecords_num):\n        example = decoder.decode(raw_record)\n        image = example['image']\n        image = tf.cast(image, dtype=dtype)\n        images.append(image)\n    \n    return images\n\ndef test_detection(tfrecords_filename, tfrecords_num, detect_fn):\n    image_tensors = tensors_from_tfrecord(\n        tfrecords_filename,\n        tfrecords_num,\n        dtype=tf.uint8\n    )\n\n    for image_tensor in image_tensors:   \n        image_np = image_tensor.numpy()\n    \n        # The model expects a batch of images, so add an axis with `tf.newaxis`.\n        input_tensor = tf.expand_dims(image_tensor, 0)\n\n        detections = detect_fn(input_tensor)\n\n        # All outputs are batches tensors.\n        # Convert to numpy arrays, and take index [0] to remove the batch dimension.\n        # We're only interested in the first num_detections.\n        num_detections = int(detections.pop('num_detections'))\n        \n        detections = {key: value[0, :num_detections].numpy() for key, value in detections.items()}\n        detections['num_detections'] = num_detections\n\n        # detection_classes should be ints.\n        detections['detection_classes'] = detections['detection_classes'].astype(np.int64)\n        \n        image_np_with_detections = image_np.astype(int).copy()\n\n        visualization_utils.visualize_boxes_and_labels_on_image_array(\n            image_np_with_detections,\n            detections['detection_boxes'],\n            detections['detection_classes'],\n            detections['detection_scores'],\n            category_index,\n            use_normalized_coordinates=True,\n            max_boxes_to_draw=100,\n            min_score_thresh=.3,\n            agnostic_mode=False\n        )\n\n        plt.figure(figsize=(8, 8))\n        plt.imshow(image_np_with_detections)\n        \n    plt.show()\n\n\ntest_detection(\n    tfrecords_filename='dataset/printed_links/tfrecords/test.record',\n    tfrecords_num=10,\n    detect_fn=exported_detect_fn\n)\n```\n\nВ результате вы должны увидеть `10` изображений из тестового набора данных с обнаруженными и подсвеченными `https:` префиксами:\n\n![Testing the model on a test dataset](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/28-testing-the-model.jpg)\n\nТот факт, что модель смогла обнаружить объекты (в нашем случае префиксы `https://`) в изображениях, которые она раньше не \"видела\" является хорошим знаком и, собственно, тем, что мы хотели достигнуть этой тренировкой.\n\n## 🗜 Конвертируем модель в веб-совместимый формат\n\nКак вы помните из начала данной статьи нашей целью была тренировка модели обнаружения объектов, которую мы могли бы использовать в браузере. К счастью, существует JavaScript версия TensorFlow - [TensorFlow.js](https://www.tensorflow.org/js). В JavaScript мы не можем работать с сохраненной ранее моделью напрямую. Нам нужна еще одна последняя конвертация модели в формат [tfjs_graph_model](https://www.tensorflow.org/js/tutorials/conversion/import_saved_model).\n\nДля того, чтобы осуществить эту конвертацию, нам понадобится Python пакет tensorflowjs:\n\n```bash\npip install tensorflowjs --quiet\n```\n\nТеперь мы можем конвертировать модель в нужный нам формат:\n\n```bash\n%%bash\n\ntensorflowjs_converter \\\n    --input_format=tf_saved_model \\\n    --output_format=tfjs_graph_model \\\n    exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model \\\n    exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n```\n\nПапка `exported_web` содержит `.json` файл с информацией об архитектуре модели, а несколько файлов в формате `.bin` содержат ее параметры.\n\n```\nexported_web\n└── ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\n    ├── group1-shard1of4.bin\n    ├── group1-shard2of4.bin\n    ├── group1-shard3of4.bin\n    ├── group1-shard4of4.bin\n    └── model.json\n```\n\nНаконец-то мы получили модель, которая способна обнаруживать `https://` префиксы в изображениях и которая сохранена в формате, понятном JavaScript приложениям.\n\nДавайте проверим размеры моделей, которые мы создали:\n\n```python\nimport pathlib\n\ndef get_folder_size(folder_path):\n    mB = 1000000\n    root_dir = pathlib.Path(folder_path)\n    sizeBytes = sum(f.stat().st_size for f in root_dir.glob('**/*') if f.is_file())\n    return f'{sizeBytes//mB} MB'\n\n\nprint(f'Original model size:      {get_folder_size(\"cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\nprint(f'Exported model size:      {get_folder_size(\"exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\nprint(f'Exported WEB model size:  {get_folder_size(\"exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8\")}')\n```\n\n_output →_\n\n```\nOriginal model size:      31 MB\nExported model size:      28 MB\nExported WEB model size:  13 MB\n```\n\nКак вы можете заметить, модель, которую мы собираемся использовать на стороне клиента весит `13MB`, что вполне допустимо и соответствует требованиям, которые мы определили в начале статьи.\n\nПозже на стороне клиента мы сможем импортировать эту модель следующим образом:\n\n```javascript\nimport * as tf from '@tensorflow/tfjs';\nconst model = await tf.loadGraphModel(modelURL);\n```\n\n> 🧭 Следующим шагом будет реализация пользовательского интерфейса для модели, что является темой для другой статьи. Но уже сейчас, при желании, вы можете ознакомиться с финальным примером кода приложения на TypeScript в [репозитории links-detector](https://github.com/trekhleb/links-detector) на GitHub.\n\n## 🤔 Заключение\n\nВ этой статье мы начали решать проблему распознавания печатных ссылок. В итоге мы обучили модель, способную распознавать префиксы `https://` в текстовых изображениях (например, в кадрах видео-потока с камеры смартфона). Мы также конвертировали обученную модель в формат `tfjs_graph_model` для дальнейшего использования ее на стороне клиента в JavaScript/TypeScript приложении.\n\nВы можете 🚀 [**запустить Links Detector**](https://trekhleb.github.io/links-detector/) со своего смартфона и попробовать, как он обнаруживает ссылки в вашей книге или журнале.\n\nФинальное решение выглядит следующим образом:\n\n![Links Detector Demo](https://raw.githubusercontent.com/trekhleb/links-detector/master/articles/printed_links_detection/assets/03-links-detector-demo.gif)\n\nВы также можете 📝 [**ознакомиться с репозиторием links-detector**](https://github.com/trekhleb/links-detector) на GitHub, в котором сможете найти исходный код клиентской части приложения.\n\n> ⚠️ На данный момент приложение находится в _экспериментальной_ стадии и имеет [множество недоработок и ограничений](https://github.com/trekhleb/links-detector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). Поэтому, до тех пор, пока вышеуказанные недоработки не будут ликвидированы, не ожидайте от приложения слишком многого 🤷🏻‍.\n\nВ качестве следующих шагов по улучшению точности модели мы можем сделать следующее:\n\n- Дополнить тренировочный и тестовый наборы данных ссылками разных форматов (`http://`, `tcp://`, `ftp://` и пр.)\n- Дополнить набор данных примерами изображений с темным фоном и светлым текстом.\n- Дополнить набор данных подчеркнутыми ссылками.\n- Дополнить набор данных текстами и ссылками с другими шрифтами\n- и пр.\n\nНесмотря на то, что точность модели недостаточна для релиза полноценного приложения, я все-же надеюсь, что эта статья была для вас полезной и вдохновила вас на дальнейшие эксперименты с моделями обнаружения объектов.\n\nУспешной тренировки!\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"links-detector\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"author\": {\n    \"name\": \"Oleksii Trekhleb\",\n    \"url\": \"https://www.linkedin.com/in/trekhleb/\"\n  },\n  \"homepage\": \"https://trekhleb.github.io/links-detector/\",\n  \"scripts\": {\n    \"format:index\": \"prettier \\\"public/index.html\\\" --write\",\n    \"cp-wasm\": \"cp node_modules/@tensorflow/tfjs-backend-wasm/dist/tfjs-backend-wasm.wasm ./public/wasm\",\n    \"cp-wasm-simd\": \"cp node_modules/@tensorflow/tfjs-backend-wasm/dist/tfjs-backend-wasm-simd.wasm ./public/wasm\",\n    \"cp-wasm-simd-thread\": \"cp node_modules/@tensorflow/tfjs-backend-wasm/dist/tfjs-backend-wasm-threaded-simd.wasm ./public/wasm\",\n    \"build:wasm\": \"yarn cp-wasm && yarn cp-wasm-simd && yarn cp-wasm-simd-thread\",\n    \"build:style\": \"tailwind build src/styles/index.css -o src/styles/tailwind.css\",\n    \"build:pwa\": \"pwa-asset-generator src/icons/pwa/links-detector-logo-white.svg public/icons --manifest public/manifest.json --index public/index.html --background black --path \\\"%PUBLIC_URL%\\\" --scrape false --icon-only\",\n    \"postbuild:pwa\": \"yarn run format:index\",\n    \"build:assets\": \"yarn build:wasm && yarn build:style && yarn build:pwa\",\n    \"prebuild\": \"yarn build:assets\",\n    \"build\": \"react-scripts build\",\n    \"prestart\": \"yarn build:assets\",\n    \"start\": \"react-scripts start\",\n    \"start-https\": \"HTTPS=true yarn start\",\n    \"prestart-prod\": \"yarn build\",\n    \"start-prod\": \"serve -c serve.json -l 4000\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\",\n    \"lint\": \"eslint 'src/**/*.{js,ts,tsx}'\",\n    \"predeploy\": \"yarn build\",\n    \"deploy\": \"gh-pages -d ./build\"\n  },\n  \"dependencies\": {\n    \"@tensorflow/tfjs\": \"^2.4.0\",\n    \"@tensorflow/tfjs-backend-wasm\": \"^2.7.0\",\n    \"@tensorflow/tfjs-core\": \"^2.4.0\",\n    \"@testing-library/jest-dom\": \"^5.11.5\",\n    \"@testing-library/react\": \"^11.1.0\",\n    \"@testing-library/user-event\": \"^12.1.10\",\n    \"@types/gtag.js\": \"^0.0.3\",\n    \"@types/jest\": \"^26.0.15\",\n    \"@types/lodash\": \"^4.14.161\",\n    \"@types/node\": \"^14.14.5\",\n    \"@types/react\": \"^16.9.0\",\n    \"@types/react-dom\": \"^16.9.0\",\n    \"@types/react-helmet\": \"^6.1.0\",\n    \"@types/react-router-dom\": \"^5.1.5\",\n    \"@types/tesseract.js\": \"^0.0.2\",\n    \"history\": \"^4.10.1\",\n    \"lodash\": \"^4.17.20\",\n    \"react\": \"^17.0.1 \",\n    \"react-dom\": \"^17.0.1\",\n    \"react-helmet\": \"^6.1.0\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"react-scripts\": \"4.0.0\",\n    \"tailwindcss\": \"^1.8.10\",\n    \"tesseract.js\": \"^2.1.3\",\n    \"typescript\": \"~4.0.5\",\n    \"workbox-core\": \"^5.1.3\",\n    \"workbox-expiration\": \"^5.1.3\",\n    \"workbox-precaching\": \"^5.1.3\",\n    \"workbox-routing\": \"^5.1.3\",\n    \"workbox-strategies\": \"^5.1.3\",\n    \"workbox-cacheable-response\": \"^5.1.3\",\n    \"workbox-google-analytics\": \"^5.1.3\"\n  },\n  \"devDependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^4.1.1\",\n    \"@typescript-eslint/parser\": \"^4.1.1\",\n    \"eslint-config-airbnb\": \"^18.2.0\",\n    \"eslint-plugin-import\": \"^2.22.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.3.1\",\n    \"eslint-plugin-react\": \"^7.20.6\",\n    \"eslint-plugin-react-hooks\": \"^4.1.2\",\n    \"gh-pages\": \"^3.1.0\",\n    \"prettier\": \"^2.1.2\",\n    \"pwa-asset-generator\": \"^3.2.3\",\n    \"serve\": \"^11.3.2\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "public/index.css",
    "content": "html, body {\n  background-color: black;\n  color: white;\n  height: 100%;\n  font-family: Roboto, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n}\n\n.full-height {\n  height: 100%;\n  box-sizing: border-box;\n}\n\n.fade-in-1 {\n  animation: fadeIn ease-in-out .1s;\n}\n\n.fade-in-2 {\n  animation: fadeIn ease-in-out .2s;\n}\n\n.fade-in-5 {\n  animation: fadeIn ease-in-out .5s;\n}\n\n.fade-in-10 {\n  animation: fadeIn ease-in-out 1s;\n}\n\n.pulsate-1 {\n  animation: pulsate-1 2s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n\n.pulsate-2 {\n  animation: pulsate-2 2s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n\n@keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n\n@keyframes pulsate-1 {\n  0% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  75%, 100% {\n    transform: scale(1.5);\n    opacity: 0;\n  }\n}\n\n@keyframes pulsate-2 {\n  0%, 10% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  100% {\n    transform: scale(1.5);\n    opacity: 0;\n  }\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <!-- Global site tag (gtag.js) - Google Analytics -->\n    <script\n      async\n      src=\"https://www.googletagmanager.com/gtag/js?id=G-YJ73BX984Z\"\n    ></script>\n    <script>\n      window.dataLayer = window.dataLayer || [];\n      function gtag(){dataLayer.push(arguments);}\n      gtag('js', new Date());\n      gtag('config', 'G-YJ73BX984Z');\n    </script>\n\n    <title>Links Detector</title>\n    <meta\n      name=\"description\"\n      content=\"Links Detector makes printed links clickable via your smartphone camera. No need to type a link in, just scan and click on it.\"\n    />\n\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <meta name=\"theme-color\" content=\"#000000\" />\n\n    <meta property=\"og:type\" content=\"website\" />\n    <meta property=\"og:title\" content=\"Links Detector\" />\n    <meta\n      property=\"og:description\"\n      content=\"Links Detector makes printed links clickable via your smartphone camera. No need to type a link in, just scan and click on it.\"\n    />\n    <meta\n      property=\"og:url\"\n      content=\"https://trekhleb.github.io/links-detector\"\n    />\n    <meta\n      property=\"og:image\"\n      content=\"https://trekhleb.github.io/links-detector/images/links-detector-banner-bg-black-2.png\"\n    />\n\n    <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap\"\n      rel=\"stylesheet\"\n    />\n    <link rel=\"stylesheet\" href=\"%PUBLIC_URL%/index.css\" />\n\n    <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n    <link\n      rel=\"icon\"\n      type=\"image/png\"\n      sizes=\"32x32\"\n      href=\"%PUBLIC_URL%/icons/favicon-32x32.png\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/png\"\n      sizes=\"16x16\"\n      href=\"%PUBLIC_URL%/icons/favicon-16x16.png\"\n    />\n\n    <link\n      rel=\"apple-touch-icon\"\n      sizes=\"180x180\"\n      href=\"%PUBLIC_URL%/icons/apple-icon-180.jpg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      sizes=\"167x167\"\n      href=\"%PUBLIC_URL%/icons/apple-icon-167.jpg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      sizes=\"152x152\"\n      href=\"%PUBLIC_URL%/icons/apple-icon-152.jpg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      sizes=\"120x120\"\n      href=\"%PUBLIC_URL%/icons/apple-icon-120.jpg\"\n    />\n\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n  </head>\n  <body>\n    <noscript>You need to enable JavaScript to run Links Detector.</noscript>\n    <div id=\"root\" class=\"full-height\">\n      <small>Loading links detector app...</small>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "public/manifest.json",
    "content": "{\n  \"name\": \"Links Detector\",\n  \"short_name\": \"Links Detector\",\n  \"description\": \"Links Detector makes printed links clickable via your smartphone camera. No need to type a link in, just scan and click on it.\",\n  \"start_url\": \"/links-detector/?src=pwa\",\n  \"scope\": \"/links-detector/\",\n  \"display\": \"standalone\",\n  \"orientation\": \"portrait\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#000000\",\n  \"icons\": [\n    {\n      \"src\": \"icons/manifest-icon-192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable any\"\n    },\n    {\n      \"src\": \"icons/manifest-icon-512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable any\"\n    },\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"48x48\",\n      \"type\": \"image/x-icon\"\n    }\n  ]\n}"
  },
  {
    "path": "public/models/links_detector/v1/model.json",
    "content": "{\n  \"format\": \"graph-model\",\n  \"generatedBy\": \"2.3.0\",\n  \"convertedBy\": \"TensorFlow.js Converter v2.4.0\",\n  \"userDefinedMetadata\": {\n    \"signature\": {\n      \"inputs\": {\n        \"input_tensor:0\": {\n          \"name\": \"input_tensor:0\",\n          \"dtype\": \"DT_UINT8\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"-1\"\n              },\n              {\n                \"size\": \"-1\"\n              },\n              {\n                \"size\": \"3\"\n              }\n            ]\n          }\n        }\n      },\n      \"outputs\": {\n        \"Identity_1:0\": {\n          \"name\": \"Identity_1:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"100\"\n              },\n              {\n                \"size\": \"4\"\n              }\n            ]\n          }\n        },\n        \"Identity_3:0\": {\n          \"name\": \"Identity_3:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"100\"\n              },\n              {\n                \"size\": \"2\"\n              }\n            ]\n          }\n        },\n        \"Identity_5:0\": {\n          \"name\": \"Identity_5:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              }\n            ]\n          }\n        },\n        \"Identity:0\": {\n          \"name\": \"Identity:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"100\"\n              }\n            ]\n          }\n        },\n        \"Identity_7:0\": {\n          \"name\": \"Identity_7:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"51150\"\n              },\n              {\n                \"size\": \"2\"\n              }\n            ]\n          }\n        },\n        \"Identity_2:0\": {\n          \"name\": \"Identity_2:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"100\"\n              }\n            ]\n          }\n        },\n        \"Identity_4:0\": {\n          \"name\": \"Identity_4:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"100\"\n              }\n            ]\n          }\n        },\n        \"Identity_6:0\": {\n          \"name\": \"Identity_6:0\",\n          \"dtype\": \"DT_FLOAT\",\n          \"tensorShape\": {\n            \"dim\": [\n              {\n                \"size\": \"1\"\n              },\n              {\n                \"size\": \"51150\"\n              },\n              {\n                \"size\": \"4\"\n              }\n            ]\n          }\n        }\n      }\n    }\n  },\n  \"modelTopology\": {\n    \"node\": [\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_7\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_6\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/Reshape_3\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_12/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_6/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_2/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_3/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_6/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_1/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_1/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_11\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_10\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/add_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"100\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_18/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_9/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/add/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_9\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_16/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_17/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_8\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_14/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_7/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_15/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_8/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_3\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/start\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/delta\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/start\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/delta\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_4/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_2/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/t\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/e\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/GreaterEqual/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Const_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split/split_dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_6/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split/split_dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul_1/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split/split_dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split/split_dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"100\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Const\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"100\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_4_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_5_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_2_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_6_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_1/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_2/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_3/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_328\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_329\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_330\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_4/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/concat/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Reshape_1/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose/perm\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_3_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"51150\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_7_recip\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose_1/perm\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/ExpandDims_1/dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"4\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_269\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_270\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_271\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"4\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_261\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_262\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_263\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_1/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_2/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_3/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/mul/x\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/sub/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ExpandDims/dim\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"2\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_259\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1280\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_260\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_277\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_283\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_304\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_310\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_316\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_322\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_331\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_332\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"12\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"unknown_333\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"12\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_4/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/concat_1/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Slice/begin\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Slice/size\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/iou_threshold\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/score_threshold\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/soft_nms_sigma\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Const\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_6/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_3\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Greater/y\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6/axis\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_1\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_2\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Reshape/shape\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Const\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {}\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"input_tensor\",\n        \"op\": \"Placeholder\",\n        \"attr\": {\n          \"shape\": {\n            \"shape\": {\n              \"dim\": [\n                {\n                  \"size\": \"1\"\n                },\n                {\n                  \"size\": \"-1\"\n                },\n                {\n                  \"size\": \"-1\"\n                },\n                {\n                  \"size\": \"3\"\n                }\n              ]\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_UINT8\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"16\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"16\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"16\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"24\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  },\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"24\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"24\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"144\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"144\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"32\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"32\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"192\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"192\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"64\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"64\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"384\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"384\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"96\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"96\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"576\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"576\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"160\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"160\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"3\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"960\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"960\"\n                  },\n                  {\n                    \"size\": \"320\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"320\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"320\"\n                  },\n                  {\n                    \"size\": \"1280\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1280\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_weights\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"1\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  },\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_bn_offset\",\n        \"op\": \"Const\",\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_FLOAT\",\n              \"tensorShape\": {\n                \"dim\": [\n                  {\n                    \"size\": \"128\"\n                  }\n                ]\n              }\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Cast\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"input_tensor\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_UINT8\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/mul\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/mul/x\",\n          \"StatefulPartitionedCall/Cast\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/mul\",\n          \"StatefulPartitionedCall/Preprocessor/sub/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/unstack\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/sub\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"1\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ExpandDims\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/unstack\",\n          \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ExpandDims/dim\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ResizeBilinear\",\n        \"op\": \"ResizeBilinear\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ExpandDims\",\n          \"StatefulPartitionedCall/Preprocessor/ResizeImage/stack\"\n        ],\n        \"attr\": {\n          \"align_corners\": {\n            \"b\": false\n          },\n          \"half_pixel_centers\": {\n            \"b\": false\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/Squeeze\",\n        \"op\": \"Squeeze\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ResizeBilinear\"\n        ],\n        \"attr\": {\n          \"squeeze_dims\": {\n            \"list\": {\n              \"i\": [\n                \"0\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Preprocessor/stack_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Preprocessor/ResizeImage/resize/Squeeze\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Preprocessor/stack\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/Squeeze\",\n          \"ConstantFolding/StatefulPartitionedCall/Preprocessor/stack_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/Preprocessor/stack\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_1/BiasAdd\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_add/add\",\n          \"unknown_269\",\n          \"unknown_270\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_2/BiasAdd\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_add/add\",\n          \"unknown_261\",\n          \"unknown_262\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_add/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project_BN/FusedBatchNormV3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_add/add\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise\",\n        \"op\": \"FusedDepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand_relu/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_bn_offset\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project_BN/FusedBatchNormV3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/out_relu/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project_BN/FusedBatchNormV3\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_3/BiasAdd\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/out_relu/Relu6\",\n          \"unknown_259\",\n          \"unknown_260\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/stack\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_3/BiasAdd\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_3/BiasAdd\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"3\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_3/BiasAdd\",\n          \"unknown_304\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_3/BiasAdd\",\n          \"unknown_277\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/stack_1\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/stack\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/stack\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"2\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_2/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/stack_1\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_2/Relu6\",\n          \"unknown_310\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20/Relu6\",\n          \"unknown_304\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20/Relu6\",\n          \"unknown_283\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"2\",\n                \"2\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/Reshape\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_2/BiasAdd\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_2/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_3/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/add\",\n          \"unknown_263\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_2/Relu6\",\n          \"unknown_316\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_3/Relu6\",\n          \"unknown_310\"\n        ],\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21/Relu6\",\n          \"unknown_304\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_2/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_3/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_4/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/stack\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2/Relu6\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2/Relu6\"\n        ],\n        \"attr\": {\n          \"axis\": {\n            \"i\": \"3\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2/Relu6\",\n          \"unknown_304\"\n        ],\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_2/Relu6\",\n          \"unknown_322\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_3/Relu6\",\n          \"unknown_316\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_4/Relu6\",\n          \"unknown_310\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/stack_1\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/stack\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/stack\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"2\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_1/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_2/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_3/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_4/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/stack_1\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_1/Relu6\",\n          \"unknown_310\"\n        ],\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_2/Relu6\",\n          \"unknown_328\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_2/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_2/Relu6\",\n          \"unknown_331\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_3/Relu6\",\n          \"unknown_322\"\n        ],\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_4/Relu6\",\n          \"unknown_316\"\n        ],\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/add_1\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/Reshape\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/projection_1/BiasAdd\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_1/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_2\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_2/depthwise\",\n          \"unknown_329\",\n          \"unknown_330\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_2\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_2/depthwise\",\n          \"unknown_332\",\n          \"unknown_333\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_3/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_4/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/add_1\",\n          \"unknown_271\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_1/Relu6\",\n          \"unknown_316\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_2\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_2\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_2/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_2\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_2\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_2/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_3/Relu6\",\n          \"unknown_328\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_3/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_3/Relu6\",\n          \"unknown_331\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_4/Relu6\",\n          \"unknown_322\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_1/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_3/depthwise\",\n          \"unknown_329\",\n          \"unknown_330\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_3\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_3/depthwise\",\n          \"unknown_332\",\n          \"unknown_333\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_4/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1/Relu6\",\n          \"unknown_304\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_1/Relu6\",\n          \"unknown_322\"\n        ],\n        \"attr\": {\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_3\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_3\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_3/shape\"\n        ],\n        \"attr\": {\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_3\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_3\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_3/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_4/Relu6\",\n          \"unknown_328\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_4/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_4/Relu6\",\n          \"unknown_331\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_0/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_1/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_4\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_4/depthwise\",\n          \"unknown_329\",\n          \"unknown_330\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_4\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_4/depthwise\",\n          \"unknown_332\",\n          \"unknown_333\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/activation_0/Relu6\",\n          \"unknown_310\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_1/Relu6\",\n          \"unknown_328\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_1/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_1/Relu6\",\n          \"unknown_331\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_4\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_4\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_4/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_4\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_4\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_4/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_0/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_1\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d_1/depthwise\",\n          \"unknown_329\",\n          \"unknown_330\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_1\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d_1/depthwise\",\n          \"unknown_332\",\n          \"unknown_333\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/activation_0/Relu6\",\n          \"unknown_316\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_1\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd_1\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_1/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_1\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd_1\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_1/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_0/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/activation_0/Relu6\",\n          \"unknown_322\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_0/Relu6\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d/depthwise\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_weights\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_bn_offset\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\",\n                \"UmVsdTY=\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_0/Relu6\",\n          \"unknown_328\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d/depthwise\",\n        \"op\": \"DepthwiseConv2dNative\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/activation_0/Relu6\",\n          \"unknown_331\"\n        ],\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"padding\": {\n            \"s\": \"U0FNRQ==\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/separable_conv2d/depthwise\",\n          \"unknown_329\",\n          \"unknown_330\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd\",\n        \"op\": \"_FusedConv2D\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/separable_conv2d/depthwise\",\n          \"unknown_332\",\n          \"unknown_333\"\n        ],\n        \"device\": \"/device:CPU:0\",\n        \"attr\": {\n          \"use_cudnn_on_gpu\": {\n            \"b\": true\n          },\n          \"explicit_paddings\": {\n            \"list\": {}\n          },\n          \"num_args\": {\n            \"i\": \"1\"\n          },\n          \"epsilon\": {\n            \"f\": 0.0\n          },\n          \"padding\": {\n            \"s\": \"VkFMSUQ=\"\n          },\n          \"fused_ops\": {\n            \"list\": {\n              \"s\": [\n                \"Qmlhc0FkZA==\"\n              ]\n            }\n          },\n          \"dilations\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"data_format\": {\n            \"s\": \"TkhXQw==\"\n          },\n          \"strides\": {\n            \"list\": {\n              \"i\": [\n                \"1\",\n                \"1\",\n                \"1\",\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/BoxPredictor/BiasAdd\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/ClassPredictor/BiasAdd\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/concat\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_1\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_2\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_3\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_4\",\n          \"StatefulPartitionedCall/concat/axis\"\n        ],\n        \"attr\": {\n          \"N\": {\n            \"i\": \"5\"\n          },\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/concat_1\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_1\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_2\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_3\",\n          \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_4\",\n          \"StatefulPartitionedCall/concat_1/axis\"\n        ],\n        \"attr\": {\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"N\": {\n            \"i\": \"5\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Reshape_1\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/concat\",\n          \"StatefulPartitionedCall/Postprocessor/Reshape_1/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/convert_scores\",\n        \"op\": \"Sigmoid\",\n        \"input\": [\n          \"StatefulPartitionedCall/concat_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose\",\n        \"op\": \"Transpose\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Reshape_1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/transpose/perm\"\n        ],\n        \"attr\": {\n          \"Tperm\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack_5\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/convert_scores\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"1\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Slice\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/convert_scores\",\n          \"StatefulPartitionedCall/Postprocessor/Slice/begin\",\n          \"StatefulPartitionedCall/Postprocessor/Slice/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/unstack\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/transpose\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"4\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack_1\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Slice\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"1\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/mul_2\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/unstack\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/mul_3\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/unstack:1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_2\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/unstack:2\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_2_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_3\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/unstack:3\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_3_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul_2\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/add_1\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul_3\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/Exp_1\",\n        \"op\": \"Exp\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/Exp\",\n        \"op\": \"Exp\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/mul_1\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/Exp_1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/mul\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/Exp\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_4\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul_1\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_4_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_6\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul_1\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_6_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_5\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_5_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_7\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/mul\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_7_recip\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/add\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/add_2\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/add\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/sub_1\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/add_1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/add_3\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/add_1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/truediv_7\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/stack\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/sub\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/sub_1\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/add_2\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/add_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          },\n          \"N\": {\n            \"i\": \"4\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose_1\",\n        \"op\": \"Transpose\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/stack\",\n          \"StatefulPartitionedCall/Postprocessor/Decode/transpose_1/perm\"\n        ],\n        \"attr\": {\n          \"Tperm\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Reshape_2\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Decode/transpose_1\",\n          \"StatefulPartitionedCall/Postprocessor/stack\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/ExpandDims_1\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Reshape_2\",\n          \"StatefulPartitionedCall/Postprocessor/ExpandDims_1/dim\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Squeeze\",\n        \"op\": \"Squeeze\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/ExpandDims_1\"\n        ],\n        \"attr\": {\n          \"squeeze_dims\": {\n            \"list\": {\n              \"i\": [\n                \"2\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/ExpandDims_1\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"1\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/unstack\",\n        \"op\": \"Unpack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack\"\n        ],\n        \"attr\": {\n          \"num\": {\n            \"i\": \"1\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/NonMaxSuppressionV5\",\n        \"op\": \"NonMaxSuppressionV5\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/unstack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Reshape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/iou_threshold\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/score_threshold\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/soft_nms_sigma\"\n        ],\n        \"attr\": {\n          \"pad_to_max_output_size\": {\n            \"b\": false\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_2\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/NonMaxSuppressionV5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Less\",\n        \"op\": \"Less\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/sub_1\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/sub_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/sub\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1\",\n        \"op\": \"Fill\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Reshape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Const\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"index_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros\",\n        \"op\": \"Fill\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Reshape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Const\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"index_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat_1\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/NonMaxSuppressionV5:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat_1/axis\"\n        ],\n        \"attr\": {\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/NonMaxSuppressionV5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat/axis\"\n        ],\n        \"attr\": {\n          \"N\": {\n            \"i\": \"2\"\n          },\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Less\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/Reshape_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/unstack_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/unstack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Shape\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Shape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2\",\n        \"op\": \"TopKV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice\"\n        ],\n        \"attr\": {\n          \"sorted\": {\n            \"b\": true\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/add_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_6\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_6/axis\"\n        ],\n        \"attr\": {\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_1\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_1/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split\",\n        \"op\": \"Split\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split/split_dim\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"num_split\": {\n            \"i\": \"4\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum\",\n        \"op\": \"Minimum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_2\",\n        \"op\": \"Minimum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_1\",\n        \"op\": \"Minimum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split:2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_3\",\n        \"op\": \"Minimum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split:3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum\",\n        \"op\": \"Maximum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_2\",\n        \"op\": \"Maximum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_1\",\n        \"op\": \"Maximum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_3\",\n        \"op\": \"Maximum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Minimum_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Maximum_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat/axis\"\n        ],\n        \"attr\": {\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"N\": {\n            \"i\": \"4\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split\",\n        \"op\": \"Split\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split/split_dim\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"num_split\": {\n            \"i\": \"4\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split:2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/sub_1\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split:3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split:1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/mul\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/sub\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/sub_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/Squeeze\",\n        \"op\": \"Squeeze\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/mul\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"squeeze_dims\": {\n            \"list\": {\n              \"i\": [\n                \"1\"\n              ]\n            }\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Greater\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/Squeeze\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Greater/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Where\",\n        \"op\": \"Where\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Greater\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_BOOL\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Where\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT64\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Reshape\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_INT64\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_1\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_1/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Shape\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split\",\n        \"op\": \"Split\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split/split_dim\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"num_split\": {\n            \"i\": \"4\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_3\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Shape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split:2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/sub_1\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split:3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split:1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/mul\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/sub\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/sub_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Reshape\",\n        \"op\": \"Reshape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Reshape/shape\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tshape\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/Squeeze\",\n        \"op\": \"Squeeze\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/mul\"\n        ],\n        \"attr\": {\n          \"squeeze_dims\": {\n            \"list\": {\n              \"i\": [\n                \"1\"\n              ]\n            }\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1\",\n        \"op\": \"Fill\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Reshape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Const\"\n        ],\n        \"attr\": {\n          \"index_type\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Cast\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/Squeeze\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_BOOL\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul_1\",\n        \"op\": \"Mul\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul_1/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_1\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Cast\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/GreaterEqual\",\n        \"op\": \"GreaterEqual\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/GreaterEqual/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Equal\",\n        \"op\": \"NoOp\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice\",\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_1\"\n        ]\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Cast_1\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/GreaterEqual\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_BOOL\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_6\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Squeeze\",\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Equal\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2\",\n        \"op\": \"TopKV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice\",\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Equal\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"sorted\": {\n            \"b\": true\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_7\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/convert_scores\",\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Equal\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Sum\",\n        \"op\": \"Sum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Cast_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Const_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"keep_dims\": {\n            \"b\": false\n          },\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_1\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_1/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_6\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/TopKV2:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_6/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split\",\n        \"op\": \"Split\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split/split_dim\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"num_split\": {\n            \"i\": \"4\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat\",\n        \"op\": \"ConcatV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split:1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split:2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split:3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat/axis\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"N\": {\n            \"i\": \"4\"\n          },\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_4\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat\"\n        ],\n        \"attr\": {\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Shape_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1\",\n        \"op\": \"Minimum\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n        \"op\": \"Range\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/start\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/delta\"\n        ],\n        \"attr\": {\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Greater\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Sum\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_1\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_1/axis\"\n        ],\n        \"attr\": {\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_6\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_6/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_2\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Greater\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Sum\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n        \"op\": \"Range\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/start\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/delta\"\n        ],\n        \"attr\": {\n          \"Tidx\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_12_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_2\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5/axis\"\n        ],\n        \"attr\": {\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4/axis\"\n        ],\n        \"attr\": {\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6\",\n        \"op\": \"GatherV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6/axis\"\n        ],\n        \"attr\": {\n          \"Taxis\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"batch_dims\": {\n            \"i\": \"0\"\n          },\n          \"Tindices\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Tparams\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_12\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Select_2\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_12_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_6\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_10\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_8\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_2\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Cast_4\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_12\"\n        ],\n        \"attr\": {\n          \"DstT\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"SrcT\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_10\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_2\"\n        ],\n        \"attr\": {\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_8\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_8\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_2\"\n        ],\n        \"attr\": {\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_2\"\n        ],\n        \"attr\": {\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_2\"\n        ],\n        \"attr\": {\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_5\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Cast_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_12\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_12/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_18\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_18/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_14\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_14/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_15\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_15/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_4\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_4/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_1\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_1/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_6\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_12\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_6/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_9\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_18\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_9/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_7\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_14\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_7/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_8\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_15\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_8/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_2\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_2/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_1\",\n        \"op\": \"Greater\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_1/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_9\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_7\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_8\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1\",\n        \"op\": \"Select\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/t\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/e\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3/size_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5/size_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_4/size\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1/size_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice/size\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3/size\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3/size_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5/size\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5/size_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_4\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_8\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_4/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1/size\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1/size_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_6\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_10\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_9\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1\",\n        \"op\": \"Slice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1/size\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_1\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_7\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_11\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_9\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_9\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_3\",\n        \"op\": \"Shape\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"out_type\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_7\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_11\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_2\"\n        ],\n        \"attr\": {\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_16\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_16/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_17\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_17/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5\",\n        \"op\": \"StridedSlice\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Shape_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_2\"\n        ],\n        \"attr\": {\n          \"shrink_axis_mask\": {\n            \"i\": \"1\"\n          },\n          \"ellipsis_mask\": {\n            \"i\": \"0\"\n          },\n          \"begin_mask\": {\n            \"i\": \"0\"\n          },\n          \"new_axis_mask\": {\n            \"i\": \"0\"\n          },\n          \"end_mask\": {\n            \"i\": \"0\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Index\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_2\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_2/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_3\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_3/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_4/values_1\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_16\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_17\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5\",\n        \"op\": \"Sub\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5/x\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack/values_1\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_2\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"0\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3/values_1_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5/values_1_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_4\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_9\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_4/values_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1/values_1_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack/values_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3/values_1\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3/values_1_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5/values_1\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5/values_1_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_4\",\n        \"op\": \"Pad\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_4\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_4\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tpaddings\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1/values_1\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1/values_1_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad\",\n        \"op\": \"Pad\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack\"\n        ],\n        \"attr\": {\n          \"Tpaddings\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_7\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3/values_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_11\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5/values_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_11_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_4\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1\",\n        \"op\": \"Pack\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1/values_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"axis\": {\n            \"i\": \"1\"\n          },\n          \"N\": {\n            \"i\": \"2\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_6_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_3\",\n        \"op\": \"Pad\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tpaddings\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_5\",\n        \"op\": \"Pad\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tpaddings\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_11\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_4\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_11_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_1\",\n        \"op\": \"Pad\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1\",\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tpaddings\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_6\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_6_const_axis\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_10_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_3\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_8_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_5\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_3\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_11\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_7_const_axis\",\n        \"op\": \"Const\",\n        \"input\": [\n          \"^StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_1\"\n        ],\n        \"attr\": {\n          \"value\": {\n            \"tensor\": {\n              \"dtype\": \"DT_INT32\",\n              \"tensorShape\": {}\n            }\n          },\n          \"dtype\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_1\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_6\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_10\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_3\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_10_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_8\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_5\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_8_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_7\",\n        \"op\": \"ExpandDims\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Pad_1\",\n          \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_7_const_axis\"\n        ],\n        \"attr\": {\n          \"Tdim\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Postprocessor/Cast_5\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_10\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_FLOAT\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_INT32\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/add\",\n        \"op\": \"AddV2\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_8\",\n          \"StatefulPartitionedCall/add/y\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_4\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_7\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"StatefulPartitionedCall/Cast_1\",\n        \"op\": \"Cast\",\n        \"input\": [\n          \"StatefulPartitionedCall/Postprocessor/Cast_5\"\n        ],\n        \"attr\": {\n          \"SrcT\": {\n            \"type\": \"DT_INT32\"\n          },\n          \"Truncate\": {\n            \"b\": false\n          },\n          \"DstT\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity_2\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/add\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      },\n      {\n        \"name\": \"Identity\",\n        \"op\": \"Identity\",\n        \"input\": [\n          \"StatefulPartitionedCall/Cast_1\"\n        ],\n        \"attr\": {\n          \"T\": {\n            \"type\": \"DT_FLOAT\"\n          }\n        }\n      }\n    ],\n    \"library\": {},\n    \"versions\": {\n      \"producer\": 440\n    }\n  },\n  \"weightsManifest\": [\n    {\n      \"paths\": [\n        \"group1-shard1of4.bin\",\n        \"group1-shard2of4.bin\",\n        \"group1-shard3of4.bin\",\n        \"group1-shard4of4.bin\"\n      ],\n      \"weights\": [\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_7\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_13/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_6\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/Reshape_3\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_3/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_12/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_12/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_6/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_6/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_13/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_1\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_2/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_2/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_3/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_6/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_6/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_1/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_1/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_1/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_1/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_3/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_11\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_19/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_10\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/add_1\",\n          \"shape\": [\n            100\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_18/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_18/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_9/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_9/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_19/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/add/y\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_9\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_16/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_16/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_17/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_8\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_14/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_14/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_7/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_7/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_4/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_15/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_15/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_8/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_8/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_17/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_3\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_5/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/zeros_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/start\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_1/delta\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_1/GatherV2_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/start\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range_2/delta\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather_2/GatherV2_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_4/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/sub_4/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Greater_2/y\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/t\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Select_2/e\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/strided_slice_5/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/GreaterEqual/y\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Const_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum_1/x\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/split/split_dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/Gather/GatherV2_6/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_4/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField_1/strided_slice/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Area/split/split_dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul_1/x\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Area/split/split_dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_2\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/split/split_dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/range\",\n          \"shape\": [\n            100\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Reshape/shape\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros_1/Const\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/mul\",\n          \"shape\": [\n            100\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_4_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_5_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_2_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub_1\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_6_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/truediv_1\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/add_1\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_1/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_2/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_3/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"unknown_328\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_329\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_330\",\n          \"shape\": [\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalBoxHead/Reshape_4/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/concat/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Reshape_1/shape\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose/perm\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_3_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/get_center_coordinates_and_sizes/sub\",\n          \"shape\": [\n            51150\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/Decode/truediv_7_recip\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Decode/transpose_1/perm\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/stack\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/ExpandDims_1/dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling_1/Reshape/shape\",\n          \"shape\": [\n            4\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"unknown_269\",\n          \"shape\": [\n            1,\n            1,\n            32,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_270\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_271\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/nearest_neighbor_upsampling/nearest_neighbor_upsampling/Reshape/shape\",\n          \"shape\": [\n            4\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"unknown_261\",\n          \"shape\": [\n            1,\n            1,\n            96,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_262\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_263\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_1/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_2/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_3/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Preprocessor/mul/x\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Preprocessor/sub/y\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/resize/ExpandDims/dim\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Preprocessor/ResizeImage/stack\",\n          \"shape\": [\n            2\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"unknown_259\",\n          \"shape\": [\n            1,\n            1,\n            1280,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_260\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_277\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_283\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_304\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_310\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_316\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_322\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_331\",\n          \"shape\": [\n            3,\n            3,\n            128,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_332\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            12\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"unknown_333\",\n          \"shape\": [\n            12\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/WeightSharedConvolutionalClassHead/Reshape_4/shape\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/concat_1/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Slice/begin\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/Slice/size\",\n          \"shape\": [\n            3\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Reshape/shape\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Minimum\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/iou_threshold\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/score_threshold\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/non_max_suppression_with_scores/soft_nms_sigma\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_2/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Reshape/shape\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/zeros/Const\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/concat/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/Gather/GatherV2_5/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/strided_slice/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/SortByField/Gather/GatherV2_6/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_3\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/strided_slice_1\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/concat/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Greater/y\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Reshape/shape\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ClipToWindow/Gather/GatherV2_6/axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_1\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/strided_slice_3/stack_2\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Reshape/shape\",\n          \"shape\": [\n            1\n          ],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ones_1/Const\",\n          \"shape\": [],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_weights\",\n          \"shape\": [\n            3,\n            3,\n            3,\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv1/Conv2D_bn_offset\",\n          \"shape\": [\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            32,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            32,\n            16\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/expanded_conv_project/Conv2D_bn_offset\",\n          \"shape\": [\n            16\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            16,\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            96,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            96,\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_1_project/Conv2D_bn_offset\",\n          \"shape\": [\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            24,\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            144,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            144,\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_2_project/Conv2D_bn_offset\",\n          \"shape\": [\n            24\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            24,\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            144,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            144\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            144,\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_3_project/Conv2D_bn_offset\",\n          \"shape\": [\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            32,\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            192,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            192,\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_4_project/Conv2D_bn_offset\",\n          \"shape\": [\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            32,\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            192,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            192,\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_5_project/Conv2D_bn_offset\",\n          \"shape\": [\n            32\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            32,\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            192,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            192\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            192,\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_6_project/Conv2D_bn_offset\",\n          \"shape\": [\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            64,\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            384,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            384,\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_7_project/Conv2D_bn_offset\",\n          \"shape\": [\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            64,\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            384,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            384,\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_8_project/Conv2D_bn_offset\",\n          \"shape\": [\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            64,\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            384,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            384,\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_9_project/Conv2D_bn_offset\",\n          \"shape\": [\n            64\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            64,\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            384,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            384\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            384,\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_10_project/Conv2D_bn_offset\",\n          \"shape\": [\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            96,\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            576,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            576,\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_11_project/Conv2D_bn_offset\",\n          \"shape\": [\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            96,\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            576,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            576,\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_12_project/Conv2D_bn_offset\",\n          \"shape\": [\n            96\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            96,\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            576,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            576\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            576,\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_13_project/Conv2D_bn_offset\",\n          \"shape\": [\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            160,\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            960,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            960,\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_14_project/Conv2D_bn_offset\",\n          \"shape\": [\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            160,\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            960,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            960,\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_15_project/Conv2D_bn_offset\",\n          \"shape\": [\n            160\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            160,\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_expand/Conv2D_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_weights\",\n          \"shape\": [\n            3,\n            3,\n            960,\n            1\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_depthwise/depthwise_bn_offset\",\n          \"shape\": [\n            960\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            960,\n            320\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/block_16_project/Conv2D_bn_offset\",\n          \"shape\": [\n            320\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_weights\",\n          \"shape\": [\n            1,\n            1,\n            320,\n            1280\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/functional_1/Conv_1/Conv2D_bn_offset\",\n          \"shape\": [\n            1280\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_2_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_20_depthwise_conv/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_2_depthwise_conv/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_2_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_3_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/bottom_up_Conv2d_21_depthwise_conv/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_1_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_2_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_3_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_4_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/ssd_mobile_net_v2fpn_keras_feature_extractor/FeatureMaps/top_down/smoothing_1_depthwise_conv/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_1_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_2_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_3_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_4_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_0/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_1_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_3_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_4_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_1/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_1_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_4_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_2/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_weights\",\n          \"shape\": [\n            1,\n            1,\n            128,\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"StatefulPartitionedCall/WeightSharedConvolutionalBoxPredictor/PredictionTower/conv2d_3/separable_conv2d_bn_offset\",\n          \"shape\": [\n            128\n          ],\n          \"dtype\": \"float32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Preprocessor/stack_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_12_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_3/size_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_5/size_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/Slice_1/size_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_3/values_1_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_5/values_1_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/PadOrClipBoxList/stack_1/values_1_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_11_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_6_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_10_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_8_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        },\n        {\n          \"name\": \"ConstantFolding/StatefulPartitionedCall/Postprocessor/BatchMultiClassNonMaxSuppression/stack_7_const_axis\",\n          \"shape\": [],\n          \"dtype\": \"int32\"\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "serve.json",
    "content": "{\n  \"public\": \"./build\",\n  \"rewrites\": [\n    {\n      \"source\": \"/links-detector\",\n      \"destination\": \"index.html\"\n    },\n    {\n      \"source\": \"/links-detector/\",\n      \"destination\": \"index.html\"\n    },\n    {\n      \"source\": \"/links-detector/:a/:b?/:c?/:d?/:e?/:f?/:g?\",\n      \"destination\": \"/:a/:b?/:c?/:d?/:e?/:f?/:g?\"\n    }\n  ],\n  \"redirects\": [\n    {\n      \"source\": \"/\",\n      \"destination\": \"/links-detector/\",\n      \"type\": 302\n    }\n  ]\n}\n"
  },
  {
    "path": "src/components/App.tsx",
    "content": "import React from 'react';\nimport { Router } from 'react-router-dom';\nimport { createHashHistory, Location } from 'history';\n\nimport Template from './shared/Template';\nimport Routes from './Routes';\nimport ErrorBoundary from './shared/ErrorBoundary';\nimport { gaPageView } from '../utils/analytics';\n\nconst history = createHashHistory();\n\nhistory.listen((location: Location): void => {\n  gaPageView(location);\n});\n\nfunction App(): React.ReactElement {\n  return (\n    <Router history={history}>\n      <Template>\n        <ErrorBoundary>\n          <Routes />\n        </ErrorBoundary>\n      </Template>\n    </Router>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "src/components/Routes.tsx",
    "content": "import React from 'react';\nimport { Switch, Route } from 'react-router-dom';\n\nimport { ROUTES } from '../constants/routes';\nimport HomeScreen from './screens/HomeScreen';\nimport DetectorScreen from './screens/DetectorScreen';\nimport NoteFoundScreen from './screens/NotFoundScreen';\nimport DebugScreen from './screens/DebugScreen';\nimport DemoScreen from './screens/DemoScreen';\n\nfunction Routes(): React.ReactElement {\n  return (\n    <Switch>\n      <Route path={ROUTES.home.path} exact>\n        <HomeScreen />\n      </Route>\n      <Route path={ROUTES.detector.path} exact>\n        <DetectorScreen />\n      </Route>\n      <Route path={ROUTES.debug.path} exact>\n        <DebugScreen />\n      </Route>\n      <Route path={ROUTES.demo.path} exact>\n        <DemoScreen />\n      </Route>\n      <Route>\n        <NoteFoundScreen />\n      </Route>\n    </Switch>\n  );\n}\n\nexport default Routes;\n"
  },
  {
    "path": "src/components/elements/BoxesCanvas.tsx",
    "content": "import React, { useRef, useEffect, useCallback } from 'react';\nimport { DetectionBox } from '../../utils/graphModel';\nimport useLogger from '../../hooks/useLogger';\n\ntype BoxesCanvasProps = {\n  boxes: DetectionBox[],\n  width: number,\n  height: number,\n  normalized?: boolean,\n  boxColor?: string,\n  boxLabelColor?: string,\n};\n\nconst boxColorDefault = '#2fff00';\nconst boxFrameWidth = 1;\nconst boxLabelFont = '10px helvetica';\nconst boxLabelColorDefault = '#000000';\nconst boxLabelPadding = 4;\n\nconst BoxesCanvas = (props: BoxesCanvasProps): React.ReactElement => {\n  const {\n    boxes,\n    width,\n    height,\n    normalized = true,\n    boxColor = boxColorDefault,\n    boxLabelColor = boxLabelColorDefault,\n  } = props;\n\n  const logger = useLogger({ context: 'DetectionBoxes' });\n\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n\n  const drawDetections = (): void => {\n    if (!canvasRef.current || !boxes) {\n      return;\n    }\n\n    const ctx: CanvasRenderingContext2D | null = canvasRef.current.getContext('2d');\n    if (!ctx) {\n      logger.logError('cannot get canvas 2D context');\n      return;\n    }\n\n    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n    ctx.font = boxLabelFont;\n    ctx.textBaseline = 'top';\n\n    let normalizedBoxes: DetectionBox[] = [...boxes];\n\n    if (normalized) {\n      normalizedBoxes = normalizedBoxes.map((box: DetectionBox) => {\n        const {\n          x1,\n          y1,\n          x2,\n          y2,\n          categoryId,\n          score,\n        } = box;\n\n        const normalizeByWidth = (w: number): number => Math.floor(width * w);\n        const normalizeByHeight = (h: number): number => Math.floor(height * h);\n\n        return {\n          x1: normalizeByWidth(x1),\n          y1: normalizeByHeight(y1),\n          x2: normalizeByWidth(x2),\n          y2: normalizeByHeight(y2),\n          categoryId,\n          score,\n        };\n      });\n    }\n\n    logger.logDebug('drawDetections', {\n      boxes,\n      normalizedBoxes,\n    });\n\n    normalizedBoxes.forEach((box: DetectionBox) => {\n      const {\n        x1,\n        y1,\n        x2,\n        y2,\n        score,\n      } = box;\n\n      // Draw the bounding box.\n      ctx.strokeStyle = boxColor;\n      ctx.lineWidth = boxFrameWidth;\n      ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);\n\n      // Draw the label background.\n      ctx.fillStyle = boxColor;\n      const label = `${Math.floor(score * 100)}%`;\n      const textWidth = ctx.measureText(label).width;\n      const textHeight = parseInt(boxLabelFont, 10);\n\n      // Draw top left rectangle.\n      ctx.fillRect(\n        x1 - boxFrameWidth,\n        y1 - textHeight - boxLabelPadding,\n        textWidth + boxLabelPadding,\n        textHeight + boxLabelPadding,\n      );\n\n      // Draw the text last to ensure it's on top.\n      ctx.fillStyle = boxLabelColor;\n      ctx.fillText(\n        label,\n        x1 + boxLabelPadding / 2 - boxFrameWidth,\n        y1 - boxLabelPadding / 2 - textHeight,\n      );\n    });\n  };\n\n  const drawDetectionsCallback = useCallback(drawDetections, [\n    boxes,\n    boxColor,\n    boxLabelColor,\n    normalized,\n    width,\n    height,\n    logger,\n  ]);\n\n  useEffect(() => {\n    drawDetectionsCallback();\n  }, [drawDetectionsCallback]);\n\n  return (\n    <canvas\n      ref={canvasRef}\n      width={width}\n      height={height}\n    />\n  );\n};\n\nexport default BoxesCanvas;\n"
  },
  {
    "path": "src/components/elements/DebugInfo.tsx",
    "content": "import React, { useEffect, useState } from 'react';\n\nimport {\n  getTFInfo,\n  isCanvasFilterSupported,\n  isWebGLSupported,\n  TFInfo,\n} from '../../utils/debug';\nimport useLogger from '../../hooks/useLogger';\nimport { DETECTION_CONFIG } from '../../configs/detectionConfig';\n\nfunction DebugInfo(): React.ReactElement {\n  const [tfInfo, setTfInfo] = useState<TFInfo | null>(null);\n  const logger = useLogger({ context: 'DebugInfo' });\n\n  useEffect(() => {\n    logger.logDebug('useEffect');\n    getTFInfo({\n      modelURL: DETECTION_CONFIG.modelLoading.linksDetectorModelURL,\n    }).then((info: TFInfo) => {\n      setTfInfo(info);\n      logger.logDebug('useEffect: then', { info });\n    });\n  }, [logger]);\n\n  if (!tfInfo) {\n    return <div>Loading...</div>;\n  }\n\n  const supported = 'YES';\n  const notSupported = 'NO';\n\n  return (\n    <ul>\n      <li>\n        Platform name: <code>{tfInfo.platformName}</code>\n      </li>\n      <li>\n        Backend name: <code>{tfInfo.backendName}</code>\n      </li>\n      <li>\n        WebGL: <code>{isWebGLSupported() ? supported : notSupported}</code>\n      </li>\n      <li>\n        Canvas Filters: <code>{isCanvasFilterSupported() ? supported : notSupported}</code>\n      </li>\n    </ul>\n  );\n}\n\nexport default DebugInfo;\n"
  },
  {
    "path": "src/components/elements/DetectedLinks.tsx",
    "content": "import React, { CSSProperties } from 'react';\nimport { DetectedLink } from '../../hooks/useLinksDetector';\nimport Icon from '../shared/Icon';\nimport { ICON_KEYS } from '../../icons';\nimport {\n  DETECTION_BACKGROUND_COLOR_CLASS,\n  DETECTION_TEXT_COLOR_CLASS,\n} from '../../constants/style';\n\ntype DetectedLinksProps = {\n  links: DetectedLink[],\n  containerSize: number,\n};\n\nfunction DetectedLinks(props: DetectedLinksProps): React.ReactElement | null {\n  const { links, containerSize } = props;\n\n  if (!links || !links.length) {\n    return null;\n  }\n\n  const containerStyle: CSSProperties = {\n    width: `${containerSize}px`,\n    height: `${containerSize}px`,\n  };\n\n  const linkStyle: CSSProperties = {\n    fontSize: '12px',\n  };\n\n  const linksElements = links.map((link: DetectedLink) => {\n    const linkContainerStyle: CSSProperties = {\n      marginTop: `${link.y1}px`,\n      marginLeft: `${link.x1}px`,\n      boxShadow: '0px 5px 10px 0px rgba(0,0,0,0.3)',\n    };\n\n    /* eslint-disable react/jsx-no-target-blank */\n    return (\n      <div\n        key={link.url}\n        style={linkContainerStyle}\n        className={\n          `absolute block overflow-hidden fade-in-2 rounded ${DETECTION_TEXT_COLOR_CLASS}`\n        }\n      >\n        <a\n          href={link.url}\n          style={linkStyle}\n          className={\n            `flex flex-row items-start rounded justify-center pt-2 pb-2 pl-3 pr-3 font-bold ${DETECTION_BACKGROUND_COLOR_CLASS}`\n          }\n          target=\"_blank\"\n        >\n          <Icon iconKey={ICON_KEYS.LINK} className=\"w-4 h-4 mr-2\" />\n          <span>{link.url}</span>\n        </a>\n      </div>\n    );\n  });\n\n  return (\n    <div style={containerStyle} className=\"block overflow-hidden\">\n      { linksElements }\n    </div>\n  );\n}\n\nexport default DetectedLinks;\n"
  },
  {
    "path": "src/components/elements/DetectedLinksPrefixes.tsx",
    "content": "import React, { CSSProperties } from 'react';\nimport { DetectionBox } from '../../utils/graphModel';\nimport { relativeToAbsolute } from '../../utils/image';\nimport Spinner from '../shared/Spinner';\nimport { DETECTION_CONFIG } from '../../configs/detectionConfig';\n\ntype DetectedLinksPrefixesProps = {\n  boxes: DetectionBox[] | null,\n  containerSize: number,\n};\n\nfunction DetectedLinksPrefixes(props: DetectedLinksPrefixesProps): React.ReactElement | null {\n  const { boxes, containerSize } = props;\n\n  if (!boxes || !boxes.length) {\n    return null;\n  }\n\n  const regionProposalPadding: number = Math.ceil(\n    containerSize * DETECTION_CONFIG.ocr.regionProposalPadding,\n  );\n\n  const containerStyle: CSSProperties = {\n    width: `${containerSize}px`,\n    height: `${containerSize}px`,\n    display: 'block',\n    overflow: 'hidden',\n  };\n\n  const boxesElements = boxes.map((box: DetectionBox) => {\n    const left: number = relativeToAbsolute(box.x1, containerSize);\n    const top: number = relativeToAbsolute(box.y1, containerSize);\n    const right: number = relativeToAbsolute(box.x2, containerSize);\n    const bottom: number = relativeToAbsolute(box.y2, containerSize);\n    const width: number = right - left;\n    const height: number = bottom - top;\n\n    const horizontalScaleFactor: number = 10;\n\n    const boxStyle: CSSProperties = {\n      marginLeft: `${left - regionProposalPadding}px`,\n      marginTop: `${top}px`,\n      width: `${horizontalScaleFactor * Math.max(width, height)}px`,\n      height: `${height}px`,\n    };\n\n    return (\n      <div\n        key={`${left}${top}${width}${height}`}\n        style={boxStyle}\n        className=\"flex flex-row justify-start items-start absolute\"\n      >\n        <Spinner />\n      </div>\n    );\n  });\n\n  return (\n    <div style={containerStyle}>\n      { boxesElements }\n    </div>\n  );\n}\n\nexport default DetectedLinksPrefixes;\n"
  },
  {
    "path": "src/components/elements/LinksDetector.tsx",
    "content": "import React, {\n  CSSProperties,\n  useCallback,\n  useEffect,\n  useState,\n} from 'react';\nimport { Rectangle } from 'tesseract.js';\n\nimport CameraStream from '../shared/CameraStream';\nimport useWindowSize from '../../hooks/useWindowSize';\nimport { DETECTION_CONFIG } from '../../configs/detectionConfig';\nimport Notification, { NotificationLevel } from '../shared/Notification';\nimport useLogger from '../../hooks/useLogger';\nimport ProgressBar from '../shared/ProgressBar';\nimport BoxesCanvas from './BoxesCanvas';\nimport { isDebugMode } from '../../constants/debug';\nimport ErrorBoundary from '../shared/ErrorBoundary';\nimport PixelsCanvas from './PixelsCanvas';\nimport useLinksDetector, { DetectionPerformance } from '../../hooks/useLinksDetector';\nimport { normalizeCSSFilterParam } from '../../utils/image';\nimport PerformanceMonitor from './PerformanceMonitor';\nimport { DetectionBox } from '../../utils/graphModel';\nimport DetectedLinks from './DetectedLinks';\nimport DetectedLinksPrefixes from './DetectedLinksPrefixes';\nimport { FRAME_PADDING_CLASS } from '../../constants/style';\n\nconst uiVideoBrightness = normalizeCSSFilterParam(\n  DETECTION_CONFIG.imagePreprocessing.ui.brightness,\n);\n\nconst uiVideoContrast = normalizeCSSFilterParam(\n  DETECTION_CONFIG.imagePreprocessing.ui.contrast,\n);\n\nconst videoStyle: CSSProperties = DETECTION_CONFIG.imagePreprocessing.ui.enabled ? {\n  filter: `brightness(${uiVideoBrightness}) contrast(${uiVideoContrast}) grayscale(1)`,\n} : {};\n\ntype LinksDetectorProps = {\n  onLoaded?: () => void,\n  onError?: () => void,\n};\n\nfunction LinksDetector(props: LinksDetectorProps): React.ReactElement | null {\n  const {\n    onLoaded = (): void => {},\n    onError = (): void => {},\n  } = props;\n\n  const logger = useLogger({ context: 'LiveDetector' });\n  const windowSize = useWindowSize();\n\n  const [\n    detectionPerformance,\n    setDetectionPerformance,\n  ] = useState<DetectionPerformance | null>(null);\n\n  const {\n    detectedLinks,\n    detectLinks,\n    error,\n    loadingProgress,\n    loadingStage,\n    httpsBoxes,\n    regionProposals,\n    pixels,\n  } = useLinksDetector({\n    modelURL: DETECTION_CONFIG.modelLoading.linksDetectorModelURL,\n    maxBoxesNum: DETECTION_CONFIG.httpsDetection.maxBoxesNum,\n    scoreThreshold: DETECTION_CONFIG.httpsDetection.scoreThreshold,\n    iouThreshold: DETECTION_CONFIG.httpsDetection.IOUThreshold,\n    workersNum: DETECTION_CONFIG.ocr.workersNum,\n    language: DETECTION_CONFIG.ocr.language,\n  });\n\n  const onLoadedCallback = useCallback(onLoaded, [onLoaded]);\n  useEffect(() => {\n    if (loadingProgress === null || loadingProgress < 1) {\n      return;\n    }\n    logger.logDebug('useEffect: onLoadedCallback', { loadingProgress });\n    onLoadedCallback();\n  }, [loadingProgress, onLoadedCallback, logger]);\n\n  const onErrorCallback = useCallback(onError, [onError]);\n  useEffect(() => {\n    if (!error) {\n      return;\n    }\n    logger.logDebug('useEffect: onErrorCallback', { error });\n    onErrorCallback();\n  }, [error, onErrorCallback, logger]);\n\n  const isDebug: boolean = isDebugMode();\n\n  if (error) {\n    return (\n      <div className={`flex-grow ${FRAME_PADDING_CLASS}`}>\n        <Notification level={NotificationLevel.DANGER}>\n          {error}\n        </Notification>\n      </div>\n    );\n  }\n\n  if (loadingProgress === null || loadingProgress < 1) {\n    return <ProgressBar progress={loadingProgress} text={loadingStage} />;\n  }\n\n  if (!windowSize || !windowSize.width || !windowSize.height) {\n    return <ProgressBar text=\"Detecting the window size\" />;\n  }\n\n  const onFrame = async (video: HTMLVideoElement): Promise<void> => {\n    const resizeToSize: number = Math.min(\n      video.width,\n      DETECTION_CONFIG.imagePreprocessing.model.size,\n    );\n    logger.logDebug('onFrame start', { resizeToSize });\n    const currentDetectionPerformance: DetectionPerformance | null = await detectLinks({\n      video,\n      applyFilters: DETECTION_CONFIG.imagePreprocessing.model.enabled,\n      videoBrightness: DETECTION_CONFIG.imagePreprocessing.model.brightness,\n      videoContrast: DETECTION_CONFIG.imagePreprocessing.model.contrast,\n      regionProposalsPadding: DETECTION_CONFIG.ocr.regionProposalPadding,\n      useRegionProposals: DETECTION_CONFIG.ocr.useRegionProposals,\n      resizeToSize,\n    });\n    if (isDebug) {\n      setDetectionPerformance(currentDetectionPerformance);\n    }\n    logger.logDebug('onFrame end');\n  };\n\n  const videoSize: number = Math.min(windowSize.width, windowSize.height);\n\n  const canvasContainerStyles: CSSProperties = {\n    marginTop: `-${videoSize}px`,\n  };\n\n  const detectedLinksContainerStyles: CSSProperties = {\n    marginTop: `-${videoSize}px`,\n    width: `${videoSize}px`,\n    height: `${videoSize}px`,\n  };\n\n  const cameraStream = (\n    <ErrorBoundary>\n      <CameraStream\n        onFrame={onFrame}\n        width={videoSize}\n        height={videoSize}\n        videoStyle={videoStyle}\n        idealFrameRate={DETECTION_CONFIG.videoStreaming.idealFPS}\n        withGrid\n      />\n    </ErrorBoundary>\n  );\n\n  const imageCanvas = isDebug ? (\n    <ErrorBoundary>\n      <div style={canvasContainerStyles} className=\"absolute\">\n        <PixelsCanvas\n          pixels={pixels}\n          width={videoSize}\n          height={videoSize}\n        />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  const regionProposalBoxes: DetectionBox[] = regionProposals && regionProposals.length\n    ? regionProposals.map((regionProposal: Rectangle): DetectionBox => {\n      return {\n        x1: regionProposal.left,\n        x2: regionProposal.left + regionProposal.width,\n        y1: regionProposal.top,\n        y2: regionProposal.top + regionProposal.height,\n        score: 0,\n        categoryId: 0,\n      };\n    })\n    : [];\n\n  const regionProposalsCanvas = regionProposalBoxes && regionProposalBoxes.length && isDebug ? (\n    <ErrorBoundary>\n      <div style={canvasContainerStyles} className=\"absolute\">\n        <BoxesCanvas\n          boxes={regionProposalBoxes}\n          width={videoSize}\n          height={videoSize}\n          boxColor=\"#0000ff\"\n          normalized={false}\n        />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  const httpsBoxesCanvas = httpsBoxes && isDebug ? (\n    <ErrorBoundary>\n      <div style={canvasContainerStyles} className=\"absolute\">\n        <BoxesCanvas\n          boxes={httpsBoxes}\n          width={videoSize}\n          height={videoSize}\n          boxColor=\"#00ff00\"\n          normalized\n        />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  const performanceMonitor = isDebug ? (\n    <ErrorBoundary>\n      <div className=\"absolute left-0 bottom-0\">\n        <PerformanceMonitor metrics={detectionPerformance} />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  const detectedLinksPrefixesCanvas = httpsBoxes && httpsBoxes.length ? (\n    <ErrorBoundary>\n      <div style={detectedLinksContainerStyles} className=\"absolute overflow-hidden\">\n        <DetectedLinksPrefixes boxes={httpsBoxes} containerSize={videoSize} />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  const detectedLinksCanvas = detectedLinks && detectedLinks.length ? (\n    <ErrorBoundary>\n      <div style={detectedLinksContainerStyles} className=\"absolute overflow-hidden\">\n        <DetectedLinks links={detectedLinks} containerSize={videoSize} />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  return (\n    <div>\n      {cameraStream}\n      {imageCanvas}\n      {regionProposalsCanvas}\n      {httpsBoxesCanvas}\n      {performanceMonitor}\n      {detectedLinksPrefixesCanvas}\n      {detectedLinksCanvas}\n    </div>\n  );\n}\n\nexport default LinksDetector;\n"
  },
  {
    "path": "src/components/elements/PerformanceMonitor.tsx",
    "content": "import React, { CSSProperties } from 'react';\nimport { DetectionPerformance } from '../../hooks/useLinksDetector';\n\ntype DetectionPerformanceProps = {\n  metrics: DetectionPerformance | null,\n};\n\nfunction PerformanceMonitor(props: DetectionPerformanceProps): React.ReactElement | null {\n  const { metrics } = props;\n\n  const monitorStyles: CSSProperties = {\n    color: 'white',\n    backgroundColor: 'black',\n    padding: '10px',\n    fontSize: '10px',\n  };\n\n  if (!metrics) {\n    return null;\n  }\n\n  return (\n    <div style={monitorStyles}>\n      <div>\n        proc: <b>{metrics.processing}</b>s\n      </div>\n      <div>\n        avgProc: <b>{metrics.avgProcessing}</b>s\n      </div>\n      <div>\n        https: <b>{metrics.inference}</b>s\n      </div>\n      <div>\n        avgHttps: <b>{metrics.avgInference}</b>s\n      </div>\n      <div>\n        ocr: <b>{metrics.ocr}</b>s\n      </div>\n      <div>\n        avgOcr: <b>{metrics.avgOcr}</b>s\n      </div>\n      <div>\n        total: <b>{metrics.total}</b>s\n      </div>\n      <div>\n        fps: <b>{metrics.fps}</b>\n      </div>\n    </div>\n  );\n}\n\nexport default PerformanceMonitor;\n"
  },
  {
    "path": "src/components/elements/PixelsCanvas.tsx",
    "content": "import React, { useEffect, useRef } from 'react';\nimport useLogger from '../../hooks/useLogger';\nimport { Pixels } from '../../utils/image';\n\ntype PixelsCanvasProps = {\n  pixels: Pixels | null,\n  width: number,\n  height: number,\n};\n\nfunction PixelsCanvas(props: PixelsCanvasProps): React.ReactElement {\n  const { width, height, pixels } = props;\n\n  const logger = useLogger({ context: 'ImageCanvas' });\n\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n\n  useEffect(() => {\n    if (!canvasRef.current || !pixels) {\n      return;\n    }\n    const ctx: CanvasRenderingContext2D | null = canvasRef.current.getContext('2d');\n    if (!ctx) {\n      return;\n    }\n    logger.logDebug('useEffect');\n    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n    ctx.drawImage(pixels, 0, 0);\n  }, [pixels, width, height, logger]);\n\n  return (\n    <canvas\n      width={width}\n      height={height}\n      ref={canvasRef}\n    />\n  );\n}\n\nexport default PixelsCanvas;\n"
  },
  {
    "path": "src/components/screens/DebugScreen.tsx",
    "content": "import React from 'react';\n\nimport DebugInfo from '../elements/DebugInfo';\nimport PageTitle from '../shared/PageTitle';\n\nfunction DebugScreen(): React.ReactElement {\n  return (\n    <>\n      <PageTitle />\n      <DebugInfo />\n    </>\n  );\n}\n\nexport default DebugScreen;\n"
  },
  {
    "path": "src/components/screens/DemoScreen.tsx",
    "content": "import React from 'react';\n\nimport PageTitle from '../shared/PageTitle';\nimport Demo from '../shared/Demo';\n\nfunction DemoScreen(): React.ReactElement {\n  return (\n    <>\n      <PageTitle />\n      <div className=\"flex justify-center items-center flex-col flex-grow self-stretch fade-in-5\">\n        <Demo />\n      </div>\n    </>\n  );\n}\n\nexport default DemoScreen;\n"
  },
  {
    "path": "src/components/screens/DetectorScreen.tsx",
    "content": "import React, { useState } from 'react';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { History, Location, LocationDescriptor } from 'history';\n\nimport LinksDetector from '../elements/LinksDetector';\nimport Modal from '../shared/Modal';\nimport { RouteNames, ROUTES } from '../../constants/routes';\nimport PageTitle from '../shared/PageTitle';\nimport useLogger from '../../hooks/useLogger';\n\nfunction DetectorScreen(): React.ReactElement {\n  const logger = useLogger({ context: 'DetectorScreen' });\n  const history: History = useHistory();\n  const location: Location = useLocation();\n  const [loaded, setLoaded] = useState<boolean>(false);\n  const [error, setError] = useState<boolean>(false);\n\n  const onModalClose = (): void => {\n    const path: LocationDescriptor = {\n      pathname: ROUTES[RouteNames.home].path,\n      search: location.search,\n      hash: location.hash,\n    };\n    history.push(path);\n  };\n\n  const onLoaded = (): void => {\n    logger.logDebug('onLoaded', { loaded });\n    if (!loaded) {\n      setLoaded(true);\n    }\n  };\n\n  const onError = (): void => {\n    logger.logDebug('onError', { error });\n    if (!error) {\n      setError(true);\n    }\n  };\n\n  return (\n    <>\n      <PageTitle />\n      <Modal onClose={onModalClose} disableClose={!(loaded || error)}>\n        <LinksDetector onLoaded={onLoaded} onError={onError} />\n      </Modal>\n    </>\n  );\n}\n\nexport default DetectorScreen;\n"
  },
  {
    "path": "src/components/screens/HomeScreen.tsx",
    "content": "import React from 'react';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { History, LocationDescriptor, Location } from 'history';\n\nimport { ROUTES } from '../../constants/routes';\nimport LaunchButton from '../shared/LaunchButton';\nimport Promo from '../shared/Promo';\nimport PageTitle from '../shared/PageTitle';\n\nfunction HomeScreen(): React.ReactElement {\n  const history: History = useHistory();\n  const location: Location = useLocation();\n\n  const onLaunch = (): void => {\n    const path: LocationDescriptor = {\n      pathname: ROUTES.detector.path,\n      search: location.search,\n      hash: location.hash,\n    };\n    history.push(path);\n  };\n\n  return (\n    <>\n      <PageTitle />\n      <div className=\"flex justify-center items-center flex-col flex-grow self-stretch fade-in-5\">\n        <div className=\"text-left self-stretch\">\n          <Promo />\n        </div>\n        <div className=\"flex justify-center items-center flex-col flex-grow self-stretch\">\n          <LaunchButton onClick={onLaunch}>\n            Scan\n          </LaunchButton>\n        </div>\n      </div>\n    </>\n  );\n}\n\nexport default HomeScreen;\n"
  },
  {
    "path": "src/components/screens/NotFoundScreen.tsx",
    "content": "import React, { useEffect } from 'react';\nimport { Link, useLocation } from 'react-router-dom';\nimport { Location } from 'history';\n\nimport { HOME_ROUTE } from '../../constants/routes';\nimport Notification, { NotificationLevel } from '../shared/Notification';\nimport PageTitle from '../shared/PageTitle';\nimport useLogger from '../../hooks/useLogger';\n\nfunction NoteFoundScreen(): React.ReactElement {\n  const logger = useLogger({ context: 'NoteFoundScreen' });\n  const location: Location = useLocation();\n\n  useEffect(() => {\n    const path: string = (location.pathname || '') + (location.search || '') + (location.hash || '');\n    logger.logError(`page no found: ${path}`);\n  }, [logger, location.pathname, location.search, location.hash]);\n\n  return (\n    <>\n      <PageTitle />\n      <div className=\"flex-grow\">\n        <Notification level={NotificationLevel.WARNING}>\n          <div>\n            Page not found\n          </div>\n          <div>\n            Try to start from <Link to={HOME_ROUTE.path} className=\"underline\">Homepage</Link>\n          </div>\n        </Notification>\n      </div>\n    </>\n  );\n}\n\nexport default NoteFoundScreen;\n"
  },
  {
    "path": "src/components/shared/CameraStream.tsx",
    "content": "import React, {\n  CSSProperties,\n  useCallback, useEffect, useRef, useState,\n} from 'react';\nimport throttle from 'lodash/throttle';\n\nimport useLogger from '../../hooks/useLogger';\nimport Notification, { NotificationLevel } from './Notification';\nimport ErrorBoundary from './ErrorBoundary';\nimport Grid from './Grid';\n\ntype FacingMode = 'user' | 'environment';\n\ntype CameraStreamProps = {\n  width: number,\n  height: number,\n  idealFrameRate: number,\n  onFrame: (video: HTMLVideoElement) => Promise<void>,\n  facingMode?: FacingMode,\n  videoStyle?: CSSProperties,\n  withGrid?: boolean,\n};\n\nconst videoFrameRate = 30;\nconst oneSecond = 1000;\nconst gridVerticalCells = 10;\nconst gridHorizontalCells = 4;\n\n/* global MediaStreamConstraints */\nfunction CameraStream(props: CameraStreamProps): React.ReactElement {\n  const {\n    width,\n    height,\n    onFrame,\n    idealFrameRate,\n    facingMode = 'environment',\n    videoStyle: videoStyleOverrides = {},\n    withGrid = false,\n  } = props;\n\n  const frameThrottlingMs = Math.floor(oneSecond / idealFrameRate);\n\n  const logger = useLogger({ context: 'CameraStream' });\n\n  const videoRef = useRef<HTMLVideoElement | null>(null);\n\n  const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n  // On iOS Safari filters add weird 1px left and bottom white borders to the video.\n  // To hide that border the -1px shift is introduced in the styles below.\n  const VIDEO_PADDING = 2;\n\n  const videoWidth = width + 2 * VIDEO_PADDING;\n  const videoHeight = height + 2 * VIDEO_PADDING;\n\n  const onLocalFrame = (): void => {\n    requestAnimationFrame(() => {\n      logger.logDebug('onLocalFrame');\n      if (videoRef.current) {\n        // eslint-disable-next-line @typescript-eslint/no-use-before-define\n        onFrame(videoRef.current).then(throttledOnLocalFrame);\n      }\n    });\n  };\n\n  const throttledOnLocalFrame = throttle(\n    onLocalFrame,\n    frameThrottlingMs,\n    {\n      leading: false,\n      trailing: true,\n    },\n  );\n\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  const throttledOnLocalFrameCallback = useCallback(throttledOnLocalFrame, []);\n\n  useEffect((): () => void => {\n    if (!videoRef.current) {\n      return (): void => {\n      };\n    }\n\n    logger.logDebug('useEffect');\n\n    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n      const msg = 'Your browser does not support camera access';\n      setErrorMessage(msg);\n      logger.logError(msg);\n      return (): void => {\n      };\n    }\n\n    let localStream: MediaStream | null = null;\n\n    const userMediaConstraints: MediaStreamConstraints = {\n      audio: false,\n      video: {\n        width: { ideal: videoWidth },\n        height: { ideal: videoHeight },\n        facingMode: { ideal: facingMode },\n        frameRate: { ideal: videoFrameRate },\n      },\n    };\n\n    // @see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n    navigator.mediaDevices.getUserMedia(userMediaConstraints)\n      .then((stream: MediaStream) => {\n        localStream = stream;\n        if (!videoRef.current) {\n          return;\n        }\n        videoRef.current.srcObject = stream;\n        videoRef.current.onloadedmetadata = (): void => {\n          logger.logDebug('onloadedmetadata');\n          requestAnimationFrame(throttledOnLocalFrameCallback);\n        };\n      })\n      .catch((error: DOMException) => {\n        let message = 'Video cannot be started';\n        if (error && error.message) {\n          message += `: ${error.message}`;\n        }\n        setErrorMessage(message);\n        logger.logError(message, error);\n      });\n\n    return (): void => {\n      logger.logDebug('useEffect return');\n      // Stop animation frames.\n      throttledOnLocalFrameCallback.cancel();\n      // Stop camera access.\n      if (localStream) {\n        logger.logDebug('useEffect return: Stopping the camera access');\n        localStream.getTracks().forEach((track: MediaStreamTrack) => {\n          track.stop();\n        });\n      }\n    };\n  }, [videoWidth, videoHeight, facingMode, logger, throttledOnLocalFrameCallback]);\n\n  if (errorMessage) {\n    return (\n      <Notification level={NotificationLevel.DANGER}>\n        {errorMessage}\n      </Notification>\n    );\n  }\n\n  const videoWrapperStyle: CSSProperties = {\n    width: `${width}px`,\n    height: `${height}px`,\n    overflow: 'hidden',\n  };\n\n  const videoStyle: CSSProperties = {\n    objectFit: 'cover',\n    width: `${videoWidth}px`,\n    minWidth: `${videoWidth}px`,\n    height: `${videoHeight}px`,\n    minHeight: `${videoHeight}px`,\n    marginLeft: `-${VIDEO_PADDING}px`,\n    ...videoStyleOverrides,\n  };\n\n  const gridStyles: CSSProperties = {\n    marginTop: `-${videoHeight}px`,\n  };\n\n  const gridCanvas = withGrid ? (\n    <ErrorBoundary>\n      <div style={gridStyles} className=\"absolute\">\n        <Grid\n          hCells={gridHorizontalCells}\n          vCells={gridVerticalCells}\n          width={videoWidth}\n          height={videoHeight}\n        />\n      </div>\n    </ErrorBoundary>\n  ) : null;\n\n  return (\n    <div style={videoWrapperStyle}>\n      <video\n        ref={videoRef}\n        width={videoWidth}\n        height={videoHeight}\n        style={videoStyle}\n        className=\"fade-in-10\"\n        playsInline\n        autoPlay\n        muted\n      >\n        Your browser does not support embedded videos\n      </video>\n      {gridCanvas}\n    </div>\n  );\n}\n\nexport default CameraStream;\n"
  },
  {
    "path": "src/components/shared/Demo.tsx",
    "content": "import React, {\n  SyntheticEvent,\n  useState,\n} from 'react';\n\nimport { BASE_VIDEO_PATH } from '../../constants/routes';\nimport useLogger from '../../hooks/useLogger';\nimport Notification, { NotificationLevel } from './Notification';\n\nconst mp4DemoPath: string = `${BASE_VIDEO_PATH}/demo-black-720p.mp4`;\nconst webmDemoPath: string = `${BASE_VIDEO_PATH}/demo-black-720p.webm`;\n\nfunction Demo(): React.ReactElement {\n  const logger = useLogger({ context: 'Demo' });\n  const [videoError, setVideoError] = useState<string | null>(null);\n\n  const onVideoError = (event: SyntheticEvent<HTMLVideoElement>): void => {\n    const errorMessage: string = 'Video cannot be loaded';\n    setVideoError(errorMessage);\n    logger.logError(errorMessage, { event });\n  };\n\n  if (videoError) {\n    return (\n      <Notification level={NotificationLevel.DANGER}>\n        {videoError}\n      </Notification>\n    );\n  }\n  /* eslint-disable jsx-a11y/media-has-caption */\n  return (\n    <video\n      width=\"250\"\n      className=\"fade-in-5\"\n      controls={false}\n      autoPlay\n      loop\n      playsInline\n      muted\n      onError={onVideoError}\n    >\n      <source src={mp4DemoPath} type=\"video/mp4\" />\n      <source src={webmDemoPath} type=\"video/webm\" />\n      Your browser does not support the video tag.\n    </video>\n  );\n}\n\nexport default Demo;\n"
  },
  {
    "path": "src/components/shared/EnhancedRow.tsx",
    "content": "import React from 'react';\n\ntype EnhancedRowProps = {\n  content: React.ReactNode,\n  contentClassName?: string,\n  className?: string,\n  startEnhancer?: React.ReactNode,\n};\n\nfunction EnhancedRow(props: EnhancedRowProps): React.ReactElement {\n  const {\n    startEnhancer,\n    content,\n    contentClassName = '',\n    className = '',\n  } = props;\n\n  const startEnhancerElement = startEnhancer ? (\n    <div>\n      {startEnhancer}\n    </div>\n  ) : null;\n\n  const contentElement = (\n    <div className={`flex-grow ${contentClassName}`}>\n      {content}\n    </div>\n  );\n\n  return (\n    <div className={`flex flex-row justify-center items-center ${className}`}>\n      {startEnhancerElement}\n      {contentElement}\n    </div>\n  );\n}\n\nexport default EnhancedRow;\n"
  },
  {
    "path": "src/components/shared/ErrorBoundary.tsx",
    "content": "import React, { ErrorInfo } from 'react';\nimport Notification, { NotificationLevel } from './Notification';\nimport { buildLoggers, Loggers } from '../../utils/logger';\n\ntype ErrorBoundaryProps = {\n  children: React.ReactNode,\n};\n\ntype ErrorBoundaryState = {\n  hasError: boolean,\n};\n\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n  private logger: Loggers;\n\n  constructor(props: any) {\n    super(props);\n    this.state = {\n      hasError: false,\n    };\n    this.logger = buildLoggers({ context: 'ErrorBoundary' });\n  }\n\n  static getDerivedStateFromError(): ErrorBoundaryState {\n    return { hasError: true };\n  }\n\n  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n    this.logger.logError('componentDidCatch', {\n      error,\n      errorInfo,\n    });\n  }\n\n  render(): React.ReactNode {\n    const { hasError } = this.state;\n    const { children } = this.props;\n\n    if (hasError) {\n      return (\n        <Notification level={NotificationLevel.DANGER}>\n          Component has crashed\n        </Notification>\n      );\n    }\n\n    return children;\n  }\n}\n\nexport default ErrorBoundary;\n"
  },
  {
    "path": "src/components/shared/Footer.tsx",
    "content": "import React from 'react';\n\nimport HyperLink from './HyperLink';\nimport { GITHUB_BASE_URL, GITHUB_ISSUES_LINK } from '../../constants/links';\nimport { ICON_KEYS } from '../../icons';\nimport { ROUTES } from '../../constants/routes';\n\nfunction Footer(): React.ReactElement {\n  return (\n    <footer>\n      <div className=\"flex flex-row fade-in-5\">\n        <HyperLink to={GITHUB_BASE_URL} iconKey={ICON_KEYS.GIT_HUB} className=\"mr-4\">\n          About\n        </HyperLink>\n\n        <HyperLink to={ROUTES.demo.path} iconKey={ICON_KEYS.YOUTUBE} routerLink className=\"mr-4\">\n          Demo\n        </HyperLink>\n\n        <HyperLink to={GITHUB_ISSUES_LINK} iconKey={ICON_KEYS.EDIT}>\n          Issues\n        </HyperLink>\n      </div>\n    </footer>\n  );\n}\n\nexport default Footer;\n"
  },
  {
    "path": "src/components/shared/Grid.tsx",
    "content": "import React, { CSSProperties } from 'react';\n\ntype GridProps = {\n  vCells: number,\n  hCells: number,\n  width: number,\n  height: number,\n};\n\nfunction Grid(props: GridProps): React.ReactElement {\n  const {\n    vCells,\n    hCells,\n    width,\n    height,\n  } = props;\n\n  const containerStyle: CSSProperties = {\n    display: 'grid',\n    width: `${width}px`,\n    height: `${height}px`,\n    gridTemplateColumns: `repeat(${hCells}, 1fr)`,\n    gridTemplateRows: `repeat(${vCells}, 1fr)`,\n  };\n\n  const borderStyle: string = '1px dashed rgba(0, 0, 0, 0.4)';\n\n  const cellStyle: CSSProperties = {\n    borderLeft: borderStyle,\n    borderBottom: borderStyle,\n  };\n\n  const leftColumnCellStyle: CSSProperties = {\n    borderLeft: '0px',\n    borderBottom: borderStyle,\n  };\n\n  const lastRowCellStyle: CSSProperties = {\n    borderLeft: borderStyle,\n    borderBottom: '0px',\n  };\n\n  const leftBottomCellStyle: CSSProperties = {\n    borderLeft: '0px',\n    borderBottom: '0px',\n  };\n\n  const gridItems: React.ReactNode[] = [];\n  for (let itemIndex = 0; itemIndex < vCells * hCells; itemIndex += 1) {\n    // Generic row style.\n    let style: CSSProperties = cellStyle;\n\n    if (itemIndex === hCells * (vCells - 1)) {\n      // Left bottom column.\n      style = leftBottomCellStyle;\n    } else if (itemIndex % hCells === 0) {\n      // Left column.\n      style = leftColumnCellStyle;\n    } else if (itemIndex > hCells * (vCells - 1)) {\n      // Bottom row.\n      style = lastRowCellStyle;\n    }\n\n    gridItems.push((\n      <div style={style} key={itemIndex} />\n    ));\n  }\n\n  return (\n    <div className=\"fade-in-10\" style={containerStyle}>\n      {gridItems}\n    </div>\n  );\n}\n\nexport default Grid;\n"
  },
  {
    "path": "src/components/shared/Header.tsx",
    "content": "import React from 'react';\n\nimport Logo from './Logo';\n\nfunction Header(): React.ReactElement {\n  return (\n    <header className=\"fade-in-5\">\n      <Logo />\n    </header>\n  );\n}\n\nexport default Header;\n"
  },
  {
    "path": "src/components/shared/HyperLink.tsx",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { ICON_KEYS } from '../../icons';\nimport Icon from './Icon';\nimport { LINKS_TEXT_HOVER_COLOR_CLASS } from '../../constants/style';\n\ntype HyperLinkProps = {\n  to: string,\n  children: React.ReactNode,\n  iconKey?: ICON_KEYS,\n  className?: string,\n  routerLink?: boolean,\n};\n\nfunction HyperLink(props: HyperLinkProps): React.ReactElement {\n  const {\n    to,\n    children,\n    iconKey,\n    className = '',\n    routerLink = false,\n  } = props;\n\n  const icon = iconKey ? (\n    <Icon iconKey={iconKey} className=\"w-4 h-4\" />\n  ) : null;\n\n  const linkContent = icon ? (\n    <span className=\"flex flex-row justify-center items-center\">\n      <span className=\"block\">\n        {icon}\n      </span>\n      <span className=\"flex-grow ml-1 block\">\n        {children}\n      </span>\n    </span>\n  ) : children;\n\n  const linkClassName: string = `underline text-sm ${className} hover:${LINKS_TEXT_HOVER_COLOR_CLASS}`;\n\n  if (routerLink) {\n    return (\n      <Link to={to} className={linkClassName}>\n        {linkContent}\n      </Link>\n    );\n  }\n\n  return (\n    <a href={to} className={linkClassName}>\n      {linkContent}\n    </a>\n  );\n}\n\nexport default HyperLink;\n"
  },
  {
    "path": "src/components/shared/Icon.tsx",
    "content": "import React from 'react';\nimport { ICON_KEYS, ICONS } from '../../icons';\n\ntype IconProps = {\n  iconKey: ICON_KEYS,\n  className?: string | undefined,\n};\n\nfunction Icon(props: IconProps): React.ReactElement | null {\n  const { iconKey, className } = props;\n\n  if (!Object.prototype.hasOwnProperty.call(ICONS, iconKey)) {\n    return null;\n  }\n\n  const icon = ICONS[iconKey];\n  const IconComponent = icon.component;\n\n  const fillCurrent = Object.prototype.hasOwnProperty.call(icon, 'fillCurrent')\n    ? icon.fillCurrent\n    : true;\n\n  const fillCurrentClass = fillCurrent ? 'fill-current' : '';\n\n  return (\n    <IconComponent className={`${fillCurrentClass} ${className || ''}`} />\n  );\n}\n\nexport default Icon;\n"
  },
  {
    "path": "src/components/shared/LaunchButton.tsx",
    "content": "import React, { CSSProperties } from 'react';\nimport { LAUNCH_BUTTON_BACKGROUND_HOVER_CLASS } from '../../constants/style';\n\n// import detectionImage from '../../images/detection.gif';\n\ntype LaunchButtonProps = {\n  onClick: () => void,\n  children: React.ReactNode,\n};\n\nfunction LaunchButton(props: LaunchButtonProps): React.ReactElement {\n  const { children, onClick } = props;\n\n  const buttonSizePx: number = 180;\n\n  const wrapperStyles: CSSProperties = {\n    width: `${buttonSizePx}px`,\n    height: `${buttonSizePx}px`,\n    overflow: 'visible',\n  };\n\n  const buttonBackgroundStyle: CSSProperties = {\n    width: `${buttonSizePx}px`,\n    height: `${buttonSizePx}px`,\n    background: 'rgba(255, 255, 255, .3)',\n    border: '1px solid rgba(255, 255, 255, .7)',\n    position: 'absolute',\n  };\n\n  const buttonStyles: CSSProperties = {\n    width: `${buttonSizePx}px`,\n    height: `${buttonSizePx}px`,\n    // backgroundImage: `url(${detectionImage})`,\n    backgroundSize: 'cover',\n    overflow: 'hidden',\n    position: 'absolute',\n  };\n\n  const buttonTextStyles: CSSProperties = {\n    width: `${buttonSizePx}px`,\n    height: `${buttonSizePx}px`,\n    // backgroundColor: 'rgba(255, 255, 255, .7)',\n    overflow: 'hidden',\n  };\n\n  return (\n    <div style={wrapperStyles}>\n      <div\n        style={buttonBackgroundStyle}\n        className=\"rounded-full pulsate-1\"\n      />\n      <div\n        style={buttonBackgroundStyle}\n        className=\"rounded-full pulsate-2\"\n      />\n      <button\n        style={buttonStyles}\n        onClick={onClick}\n        type=\"button\"\n        className={\n          `flex flex-row items-center justify-center border-0 rounded-full transition duration-300 ease-in-out bg-white hover:${LAUNCH_BUTTON_BACKGROUND_HOVER_CLASS}`\n        }\n      >\n        <div\n          style={buttonTextStyles}\n          className=\"flex flex-row items-center justify-center font-light text-5xl text-black\"\n        >\n          { children }\n        </div>\n      </button>\n    </div>\n  );\n}\n\nexport default LaunchButton;\n"
  },
  {
    "path": "src/components/shared/Logo.tsx",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\n\nimport Icon from './Icon';\nimport { ICON_KEYS } from '../../icons';\nimport EnhancedRow from './EnhancedRow';\nimport { HOME_ROUTE } from '../../constants/routes';\nimport { LINKS_TEXT_HOVER_COLOR_CLASS, THEME_BG_COLOR_CLASS } from '../../constants/style';\nimport { GITHUB_ISSUES_LINK } from '../../constants/links';\n\nfunction Logo(): React.ReactElement {\n  const logoIcon = (\n    <Icon iconKey={ICON_KEYS.LINKS_DETECTOR_LOGO} className=\"w-8 h-8\" />\n  );\n\n  const content = (\n    <>\n      <span className=\"text-3xl\">\n        <Link to={HOME_ROUTE.path} className={`hover:${LINKS_TEXT_HOVER_COLOR_CLASS}`}>\n          Links Detector\n        </Link>\n      </span>\n      <sup className={`text-xs bg-white hover:${THEME_BG_COLOR_CLASS} text-black rounded-full pl-1 pr-1 ml-2`}>\n        <a href={GITHUB_ISSUES_LINK}>alpha</a>\n      </sup>\n    </>\n  );\n\n  return (\n    <EnhancedRow\n      content={content}\n      contentClassName=\"ml-2\"\n      startEnhancer={logoIcon}\n    />\n  );\n}\n\nexport default Logo;\n"
  },
  {
    "path": "src/components/shared/MainNavigation.tsx",
    "content": "import React from 'react';\nimport { NavLink } from 'react-router-dom';\nimport { ROUTES } from '../../constants/routes';\n\nfunction MainNavigation(): React.ReactElement {\n  return (\n    <ul>\n      <li>\n        <NavLink to={`${ROUTES.detector.path}?debug=true`}>Debug</NavLink>\n      </li>\n      <li>\n        <NavLink to={ROUTES.debug.path}>Debug</NavLink>\n      </li>\n    </ul>\n  );\n}\n\nexport default MainNavigation;\n"
  },
  {
    "path": "src/components/shared/Modal.tsx",
    "content": "import React from 'react';\n\nimport ModalCloseButton from './ModalCloseButton';\n\ntype ModalProps = {\n  children: React.ReactNode,\n  onClose?: () => void,\n  disableClose?: boolean,\n};\n\nfunction Modal(props: ModalProps): React.ReactElement {\n  const {\n    children,\n    onClose = (): void => {},\n    disableClose = false,\n  } = props;\n\n  const bgClass = 'bg-black';\n\n  let modalContainerClasses = 'absolute left-0 top-0 z-10 w-full h-full overflow-hidden flex items-center justify-center flex-col fade-in-5';\n  if (bgClass) {\n    modalContainerClasses += ` ${bgClass}`;\n  }\n\n  const iconContainerClass = 'w-8 h-8 absolute right-0 top-0 m-3 z-20';\n\n  const modalContentClass = 'w-full flex items-center justify-center flex-col';\n\n  const closeButton = !disableClose ? (<ModalCloseButton onClick={onClose} />) : null;\n\n  return (\n    <div className={modalContainerClasses}>\n      <div className={iconContainerClass}>\n        {closeButton}\n      </div>\n      <div className={modalContentClass}>\n        {children}\n      </div>\n    </div>\n  );\n}\n\nexport default Modal;\n"
  },
  {
    "path": "src/components/shared/ModalCloseButton.tsx",
    "content": "import React from 'react';\n\nimport Icon from './Icon';\nimport { ICON_KEYS } from '../../icons';\n\ntype ModalCloseButtonProps = {\n  onClick: () => void,\n};\n\nfunction ModalCloseButton(props: ModalCloseButtonProps): React.ReactElement {\n  const { onClick } = props;\n\n  const commonClasses = 'transition duration-300 ease-in-out w-full h-full fade-in-10';\n  const iconButtonClass = `${commonClasses} cursor-pointer border-0 p-0 m-0 rounded-full focus:outline-none bg-black hover:bg-white`;\n  const iconClass = `${commonClasses} text-white hover:text-black`;\n\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      className={iconButtonClass}\n    >\n      <Icon\n        iconKey={ICON_KEYS.X}\n        className={iconClass}\n      />\n    </button>\n  );\n}\n\nexport default ModalCloseButton;\n"
  },
  {
    "path": "src/components/shared/Notification.tsx",
    "content": "import React from 'react';\nimport { ICON_KEYS } from '../../icons';\nimport Icon from './Icon';\n\nexport enum NotificationLevel {\n  INFO,\n  WARNING,\n  DANGER,\n}\n\ntype NotificationProps = {\n  children: React.ReactNode,\n  level?: NotificationLevel,\n};\n\nfunction Notification(props: NotificationProps): React.ReactElement {\n  const {\n    children,\n    level = NotificationLevel.INFO,\n  } = props;\n\n  let bgColor;\n  let textColor;\n  let borderColor;\n\n  switch (level) {\n  case NotificationLevel.DANGER:\n    bgColor = 'bg-red-600';\n    textColor = 'text-white';\n    borderColor = bgColor;\n    break;\n\n  case NotificationLevel.WARNING:\n    bgColor = 'bg-yellow-600';\n    textColor = 'text-white';\n    borderColor = bgColor;\n    break;\n\n  case NotificationLevel.INFO:\n    bgColor = 'bg-blue-600';\n    textColor = 'text-white';\n    borderColor = bgColor;\n    break;\n\n  default:\n    bgColor = 'bg-white';\n    textColor = 'text-black';\n    borderColor = 'border-black';\n  }\n\n  return (\n    <div className={`${bgColor} ${textColor} ${borderColor} border-solid p-3 rounded text-xs flex flex-row justify-center items-center`}>\n      <div className=\"mr-3\">\n        <Icon iconKey={ICON_KEYS.ALERT_CIRCLE} className=\"w-6 h-6\" />\n      </div>\n      <div className=\"flex-grow\">\n        {children}\n      </div>\n    </div>\n  );\n}\n\nexport default Notification;\n"
  },
  {
    "path": "src/components/shared/PageTitle.tsx",
    "content": "import React from 'react';\nimport { Helmet } from 'react-helmet';\n\nimport usePageTitle from '../../hooks/usePageTitle';\nimport { APP_TITLE } from '../../constants/page';\n\nfunction PageTitle(): React.ReactElement | null {\n  const { pageTitle } = usePageTitle();\n\n  return (\n    <Helmet>\n      <title>{pageTitle || APP_TITLE}</title>\n    </Helmet>\n  );\n}\n\nexport default PageTitle;\n"
  },
  {
    "path": "src/components/shared/ProgressBar.tsx",
    "content": "import React from 'react';\nimport { ZeroOneRange } from '../../utils/types';\n\ntype ProgressBarProps = {\n  progress?: ZeroOneRange | null,\n  text?: string | null,\n};\n\nconst progressAnimationTimeS = 0.5;\n\nfunction ProgressBar(props: ProgressBarProps): React.ReactElement {\n  const { progress, text } = props;\n\n  const progressPercentage = progress !== undefined && progress !== null\n    ? Math.max(Math.min(Math.floor(progress * 100), 100), 0)\n    : 0;\n\n  const progressLine = progressPercentage !== undefined && progressPercentage !== null ? (\n    <div className=\"w-full h-1 bg-gray-800 mb-4\">\n      <div\n        className=\"h-full bg-white transition duration-500 ease-in-out rounded\"\n        style={{ width: `${progressPercentage}%`, transition: `width ${progressAnimationTimeS}s` }}\n      />\n    </div>\n  ) : null;\n\n  const progressText = text ? (\n    <div className=\"text-white animate-pulse text-xs rounded\">\n      {text}\n    </div>\n  ) : null;\n\n  return (\n    <div className=\"flex flex-col justify-center items-center w-full\">\n      {progressLine}\n      {progressText}\n    </div>\n  );\n}\n\nexport default ProgressBar;\n"
  },
  {
    "path": "src/components/shared/Promo.tsx",
    "content": "import React from 'react';\n\nfunction Promo(): React.ReactElement {\n  return (\n    <div className=\"flex flex-col\">\n      <span className=\"mb mb-2\">\n        Links Detector makes printed links clickable via your smartphone camera\n      </span>\n      <span className=\"text-xs font-light\">\n        No need to type a link in, just scan and click on it\n      </span>\n    </div>\n  );\n}\n\nexport default Promo;\n"
  },
  {
    "path": "src/components/shared/Spinner.css",
    "content": "@keyframes sk-scaleout {\n  0% {\n    -webkit-transform: scaleX(0);\n    transform: scaleX(0);\n  }\n  100% {\n    -webkit-transform: scaleX(1.0);\n    transform: scaleX(1.0);\n    opacity: 0;\n  }\n}\n"
  },
  {
    "path": "src/components/shared/Spinner.tsx",
    "content": "import React, { CSSProperties } from 'react';\nimport './Spinner.css';\nimport { DETECTION_BACKGROUND_COLOR_CLASS } from '../../constants/style';\n\nfunction Spinner(): React.ReactElement {\n  const spinnerStyles: CSSProperties = {\n    width: '100%',\n    height: '100%',\n    transformOrigin: 'top left',\n    animation: 'sk-scaleout 1.2s ease-in-out infinite',\n  };\n\n  return (\n    <div\n      style={spinnerStyles}\n      className={`${DETECTION_BACKGROUND_COLOR_CLASS} fade-in-5 rounded`}\n    />\n  );\n}\n\nexport default Spinner;\n"
  },
  {
    "path": "src/components/shared/Template.tsx",
    "content": "import React, { CSSProperties } from 'react';\n\nimport Header from './Header';\nimport Footer from './Footer';\nimport { FRAME_PADDING_CLASS } from '../../constants/style';\n\ntype TemplateProps = {\n  children?: React.ReactNode,\n}\n\nfunction Template(props: TemplateProps): React.ReactElement {\n  const { children } = props;\n\n  const headerStyles: CSSProperties = {\n    zIndex: 1,\n  };\n\n  const footerStyles: CSSProperties = {\n    zIndex: 1,\n  };\n\n  return (\n    <main className={`full-height flex flex-col ${FRAME_PADDING_CLASS}`}>\n      <header style={headerStyles} className=\"mb-5\">\n        <Header />\n      </header>\n      <section className=\"flex flex-row flex-grow mb-5 justify-center items-center\">\n        {children}\n      </section>\n      <footer style={footerStyles}>\n        <Footer />\n      </footer>\n    </main>\n  );\n}\n\nexport default Template;\n"
  },
  {
    "path": "src/configs/analytics.ts",
    "content": "export const GOOGLE_ANALYTICS_ID = 'G-NEPEGVZ6TM';\n"
  },
  {
    "path": "src/configs/detectionConfig.ts",
    "content": "import { ZeroOneRange } from '../utils/types';\nimport { BASE_APP_PATH } from '../constants/routes';\n\nexport const MODELS_BASE_URL = `${BASE_APP_PATH}`;\n\nexport type DetectionConfig = {\n  modelLoading: {\n    linksDetectorModelURL: string,\n  },\n  imagePreprocessing: {\n    ui: {\n      enabled: boolean,\n      brightness: ZeroOneRange,\n      contrast: ZeroOneRange,\n    },\n    model: {\n      enabled: boolean,\n      brightness: ZeroOneRange,\n      contrast: ZeroOneRange,\n      size: number, // Size in pixels (0 means do not resize).\n    },\n  },\n  videoStreaming: {\n    idealFPS: number,\n  },\n  httpsDetection: {\n    maxBoxesNum: number,\n    IOUThreshold: ZeroOneRange,\n    scoreThreshold: ZeroOneRange,\n  },\n  ocr: {\n    useRegionProposals: boolean,\n    workersNum: number,\n    language: string,\n    regionProposalPadding: ZeroOneRange,\n  },\n};\n\nexport const DETECTION_CONFIG: DetectionConfig = {\n  modelLoading: {\n    linksDetectorModelURL: `${MODELS_BASE_URL}/models/links_detector/v1/model.json`,\n  },\n  imagePreprocessing: {\n    ui: {\n      enabled: true,\n      brightness: 0.2,\n      contrast: 0.2,\n    },\n    model: {\n      enabled: true,\n      brightness: 0.6,\n      contrast: 0.7,\n      size: 640,\n    },\n  },\n  videoStreaming: {\n    idealFPS: 10,\n  },\n  httpsDetection: {\n    // @see: https://js.tensorflow.org/api/latest/#image.nonMaxSuppressionAsync\n    maxBoxesNum: 2,\n    IOUThreshold: 0.5,\n    scoreThreshold: 0.5,\n  },\n  ocr: {\n    // @see: https://github.com/naptha/tesseract.js/blob/master/docs/examples.md\n    useRegionProposals: true,\n    workersNum: 2,\n    language: 'eng',\n    regionProposalPadding: 0.02,\n  },\n};\n"
  },
  {
    "path": "src/configs/pwa.ts",
    "content": "export const PWA_ENABLED: boolean = true;\nexport const CACHE_PREFIX: string = 'links-detector';\nexport const CACHE_VERSION: string = 'v1';\n"
  },
  {
    "path": "src/constants/debug.ts",
    "content": "import { DEBUG_GET_PARAM } from './routes';\n\nexport const isDebugMode = (): boolean => {\n  const url = new URL(window.location.href);\n  return !!url.searchParams.get(DEBUG_GET_PARAM);\n};\n"
  },
  {
    "path": "src/constants/links.ts",
    "content": "export const GITHUB_BASE_URL: string = 'https://github.com/trekhleb/links-detector';\nexport const GITHUB_ISSUES_LINK: string = `${GITHUB_BASE_URL}/issues`;\n"
  },
  {
    "path": "src/constants/page.ts",
    "content": "export const APP_TITLE: string = 'Links Detector';\nexport const APP_TITLE_SEPARATOR: string = ' | ';\n"
  },
  {
    "path": "src/constants/routes.ts",
    "content": "import { APP_TITLE, APP_TITLE_SEPARATOR } from './page';\n\nexport const BASE_APP_PATH: string = '/links-detector';\nexport const BASE_VIDEO_PATH: string = `${BASE_APP_PATH}/videos`;\n\n// The BASE_ROUTE_PATH may be different from BASE_APP_PATH path in case of a hash router.\n// Compare /links-detector/#/home (hash router) vs /links-detector/home (history router)\nexport const BASE_ROUTE_PATH: string = '/';\n\nexport const DEBUG_GET_PARAM = 'debug';\n\nexport enum RouteNames {\n  home = 'home',\n  detector = 'detector',\n  debug = 'debug',\n  demo = 'demo',\n}\n\nexport type RouteType = {\n  path: string,\n  title: string,\n};\n\nexport type RoutesType = {\n  [routeName in RouteNames]: RouteType;\n};\n\nconst generateAppTitle = (pageTitle: string): string => {\n  return `${APP_TITLE}${APP_TITLE_SEPARATOR}${pageTitle}`;\n};\n\nconst generatePath = (path: string): string => {\n  if (path === '/') {\n    return BASE_ROUTE_PATH;\n  }\n  if (BASE_ROUTE_PATH === '/') {\n    return path;\n  }\n  return `${BASE_ROUTE_PATH}${path}`;\n};\n\nexport const ROUTES: RoutesType = {\n  [RouteNames.home]: {\n    path: generatePath('/'),\n    title: generateAppTitle('Start'),\n  },\n  [RouteNames.detector]: {\n    path: generatePath('/detector'),\n    title: generateAppTitle('Scanning'),\n  },\n  [RouteNames.debug]: {\n    path: generatePath('/debug'),\n    title: generateAppTitle('Debug'),\n  },\n  [RouteNames.demo]: {\n    path: generatePath('/demo'),\n    title: generateAppTitle('Demo'),\n  },\n};\n\nexport const HOME_ROUTE: RouteType = ROUTES.home;\n"
  },
  {
    "path": "src/constants/style.ts",
    "content": "// @see: https://tailwindcss.com/docs/background-color#class-reference\nconst THEME_COLOR: string = 'yellow';\nconst THEME_COLOR_INTENSITY: number = 400;\n\nexport const DETECTION_TEXT_COLOR_CLASS: string = 'text-black';\nexport const DETECTION_BACKGROUND_COLOR_CLASS: string = `bg-${THEME_COLOR}-${THEME_COLOR_INTENSITY}`;\nexport const LINKS_TEXT_HOVER_COLOR_CLASS: string = `text-${THEME_COLOR}-${THEME_COLOR_INTENSITY}`;\nexport const THEME_BG_COLOR_CLASS: string = `bg-${THEME_COLOR}-${THEME_COLOR_INTENSITY}`;\nexport const LAUNCH_BUTTON_BACKGROUND_HOVER_CLASS: string = `bg-${THEME_COLOR}-${THEME_COLOR_INTENSITY}`;\n\n// @see: https://tailwindcss.com/docs/padding#app\nexport const FRAME_PADDING_CLASS: string = 'p-5';\n"
  },
  {
    "path": "src/hooks/useGraphModel.ts",
    "content": "import { useState, useEffect, useCallback } from 'react';\nimport * as tf from '@tensorflow/tfjs';\n\nimport useLogger from './useLogger';\nimport { graphModelLoad, graphModelWarmup } from '../utils/graphModel';\nimport { ZeroOneRange } from '../utils/types';\nimport { toFloatFixed } from '../utils/numbers';\n\ntype UseGraphModelProps = {\n  modelURL: string,\n  warmup?: boolean,\n};\n\ntype UseGraphModelOutput = {\n  model: tf.GraphModel | null,\n  error: string | null,\n  loadingProgress: ZeroOneRange,\n};\n\nconst useGraphModel = (props: UseGraphModelProps): UseGraphModelOutput => {\n  const { modelURL, warmup = false } = props;\n\n  const logger = useLogger({ context: 'useGraphModel' });\n\n  const [model, setModel] = useState<tf.GraphModel | null>(null);\n  const [isWarm, setIsWarm] = useState<boolean | null>(null);\n  const [error, setError] = useState<string | null>(null);\n  const [loadingProgress, setLoadingProgress] = useState<ZeroOneRange>(0);\n\n  const warmupGraphModel = async (): Promise<void> => {\n    if (!warmup || !model || isWarm) {\n      return;\n    }\n    await graphModelWarmup(model);\n  };\n\n  const warmupCallback = useCallback(\n    warmupGraphModel,\n    [warmup, model, isWarm],\n  );\n\n  const calculateLoadingProgress = (progress: ZeroOneRange): ZeroOneRange => {\n    if (!warmup) {\n      return toFloatFixed(progress, 2);\n    }\n    // In case of model warm up we need to reserve some percentage of loader for warming up.\n    const warmupLoadingRatio = 0.05;\n    return toFloatFixed((1 - warmupLoadingRatio) * progress, 2);\n  };\n\n  const calculateLoadingProgressCallback = useCallback(calculateLoadingProgress, [warmup]);\n\n  const onLoadingProgress = (progress: ZeroOneRange): void => {\n    logger.logDebug('onLoadingProgress', { progress });\n    setLoadingProgress(calculateLoadingProgressCallback(progress));\n  };\n\n  const onLoadingProgressCallback = useCallback(\n    onLoadingProgress,\n    [calculateLoadingProgressCallback, logger],\n  );\n\n  // Effect for loading a model.\n  useEffect(() => {\n    logger.logDebug('useEffect');\n    if (!model) {\n      logger.logDebug('useEffect: loading the model');\n      graphModelLoad(modelURL, onLoadingProgressCallback)\n        .then((graphModel: tf.GraphModel) => {\n          setModel(graphModel);\n        })\n        .catch((e: Error) => {\n          setError(e.message);\n          logger.logError(`cannot load the model: ${e.message}`);\n        });\n    }\n    return (): void => {\n      logger.logDebug('useEffect: shutdown', { model });\n      if (model) {\n        try {\n          logger.logDebug('useEffect: shutdown: disposing the model');\n          model.dispose();\n        } catch (e) {\n          logger.logDebug('useEffect: shutdown: disposing the model: CAUGHT ERROR');\n        }\n      }\n    };\n  }, [modelURL, setError, setModel, logger, onLoadingProgressCallback, model]);\n\n  // Effect for warming up a model.\n  useEffect(() => {\n    if (!warmup || !model || isWarm) {\n      return;\n    }\n    logger.logDebug('useEffect: warming up the model');\n    warmupCallback().then(() => {\n      setIsWarm(true);\n      setLoadingProgress(1);\n    });\n  }, [\n    model,\n    warmup,\n    isWarm,\n    setIsWarm,\n    warmupCallback,\n    logger,\n  ]);\n\n  let finalModel: tf.GraphModel | null = model;\n  if (warmup) {\n    finalModel = isWarm ? model : null;\n  }\n\n  return {\n    model: finalModel,\n    loadingProgress,\n    error,\n  };\n};\n\nexport default useGraphModel;\n"
  },
  {
    "path": "src/hooks/useLinksDetector.ts",
    "content": "import { GraphModel } from '@tensorflow/tfjs';\nimport {\n  ConfigResult,\n  DetectResult,\n  Line,\n  RecognizeOptions,\n  RecognizeResult,\n  Rectangle,\n  Scheduler,\n} from 'tesseract.js';\nimport {\n  useCallback,\n  useEffect,\n  useRef,\n  useState,\n} from 'react';\n\nimport useGraphModel from './useGraphModel';\nimport useLogger from './useLogger';\nimport useTesseract from './useTesseract';\nimport { ZeroOneRange } from '../utils/types';\nimport { newProfiler, Profiler } from '../utils/profiler';\nimport { DetectionBox, graphModelExecute } from '../utils/graphModel';\nimport {\n  brightnessFilter,\n  contrastFilter,\n  FilterFunc,\n  greyscaleFilter,\n  Pixels,\n  preprocessPixels,\n  relativeToAbsolute,\n} from '../utils/image';\nimport { JobTypes } from '../utils/tesseract';\nimport { toFloatFixed } from '../utils/numbers';\nimport { Loggers } from '../utils/logger';\n\nexport type DetectionPerformance = {\n  processing: number,\n  avgProcessing: number,\n  inference: number,\n  avgInference: number,\n  ocr: number,\n  avgOcr: number,\n  total: number,\n  avgFps: number,\n  fps: number,\n};\n\nexport type DetectedLink = {\n  url: string,\n  x1: number,\n  y1: number,\n  x2: number,\n  y2: number,\n};\n\nexport type UseLinkDetectorProps = {\n  modelURL: string,\n  maxBoxesNum: number,\n  scoreThreshold: number,\n  iouThreshold: number,\n  workersNum: number,\n  language: string,\n};\n\nexport type DetectProps = {\n  video: HTMLVideoElement,\n  videoBrightness: number,\n  videoContrast: number,\n  resizeToSize: number,\n  applyFilters: boolean,\n  regionProposalsPadding: ZeroOneRange,\n  useRegionProposals: boolean,\n};\n\nexport type UseLinkDetectorOutput = {\n  detectLinks: (props: DetectProps) => Promise<DetectionPerformance | null>,\n  detectedLinks: DetectedLink[],\n  error: string | null,\n  loadingProgress: ZeroOneRange | null,\n  loadingStage: string | null,\n  httpsBoxes: DetectionBox[] | null,\n  regionProposals: Rectangle[],\n  pixels: Pixels | null,\n};\n\nexport type TesseractDetection = ConfigResult | RecognizeResult | DetectResult;\n\n// @see: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url\nconst URL_REG_EXP = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi;\n\nconst extractLinkFromText = (text: string): string | null => {\n  const urls: string[] | null = text.match(URL_REG_EXP);\n  if (!urls || !urls.length) {\n    return null;\n  }\n  return urls[0];\n};\n\nconst extractLinkFromDetection = (\n  detection: TesseractDetection | null,\n  logger: Loggers,\n): DetectedLink | null => {\n  if (!detection || !detection.data || !detection.data.lines || !detection.data.lines.length) {\n    logger.logDebug('extractLinkFromDetection: empty');\n    return null;\n  }\n  for (let lineIndex = 0; lineIndex < detection.data.lines.length; lineIndex += 1) {\n    const line: Line = detection.data.lines[lineIndex];\n    const url: string | null = extractLinkFromText(line.text);\n    logger.logDebug('extractLinkFromDetection: line link', { url, text: line.text });\n    if (url) {\n      const detectedLink: DetectedLink = {\n        url,\n        x1: line.bbox.x0,\n        y1: line.bbox.y0,\n        x2: line.bbox.x1,\n        y2: line.bbox.y1,\n      };\n      logger.logDebug('extractLinkFromDetection: detected', { detectedLink });\n      return detectedLink;\n    }\n  }\n  return null;\n};\n\nconst useLinksDetector = (props: UseLinkDetectorProps): UseLinkDetectorOutput => {\n  const {\n    modelURL,\n    iouThreshold,\n    maxBoxesNum,\n    scoreThreshold,\n    workersNum,\n    language,\n  } = props;\n\n  const preprocessingProfiler = useRef<Profiler>(newProfiler());\n  const inferenceProfiler = useRef<Profiler>(newProfiler());\n  const ocrProfiler = useRef<Profiler>(newProfiler());\n  const onFrameProfiler = useRef<Profiler>(newProfiler());\n\n  const modelRef = useRef<GraphModel | null>(null);\n  const tesseractSchedulerRef = useRef<Scheduler | null>(null);\n\n  const logger: Loggers = useLogger({ context: 'useLinksDetector' });\n\n  const [detectedLinks, setDetectedLinks] = useState<DetectedLink[]>([]);\n  const [pixels, setPixels] = useState<Pixels | null>(null);\n  const [detectionError, setDetectionError] = useState<string | null>(null);\n  const [httpsBoxes, setHttpsBoxes] = useState<DetectionBox[] | null>(null);\n  const [regionProposals, setRegionProposals] = useState<Rectangle[]>([]);\n  const [loadingProgress, setLoadingProgress] = useState<ZeroOneRange | null>(null);\n  const [loadingStage, setLoadingStage] = useState<string | null>(null);\n\n  const {\n    model,\n    error: modelError,\n    loadingProgress: modelLoadingProgress,\n  } = useGraphModel({\n    modelURL,\n    warmup: true,\n  });\n\n  const {\n    scheduler: tesseractScheduler,\n    loaded: tesseractSchedulerLoaded,\n    error: tesseractSchedulerError,\n    loadingProgress: tesseractLoadingProgress,\n  } = useTesseract({\n    workersNum,\n    language,\n  });\n\n  const detectLinks = async (detectProps: DetectProps): Promise<DetectionPerformance | null> => {\n    const {\n      video,\n      videoBrightness,\n      videoContrast,\n      resizeToSize,\n      applyFilters,\n      regionProposalsPadding,\n      useRegionProposals,\n    } = detectProps;\n\n    logger.logDebug('detectLinks', detectProps);\n\n    if (!modelRef.current) {\n      const errMsg = 'Model is not ready for detection yet';\n      logger.logError(errMsg);\n      setDetectionError(errMsg);\n      return null;\n    }\n\n    /* eslint-disable no-else-return */\n    if (!tesseractSchedulerRef.current) {\n      const errMsg = 'Tesseract is not loaded yet';\n      logger.logError(errMsg);\n      setDetectionError(errMsg);\n      return null;\n    } else if (tesseractSchedulerRef.current.getNumWorkers() !== workersNum) {\n      const errMsg = 'Tesseract workers are not loaded yet';\n      logger.logError(errMsg);\n      setDetectionError(errMsg);\n      return null;\n    }\n\n    onFrameProfiler.current.start();\n\n    // Image preprocessing.\n    const filters: FilterFunc[] = applyFilters ? [\n      brightnessFilter(videoBrightness),\n      contrastFilter(videoContrast),\n      greyscaleFilter(),\n    ] : [];\n\n    preprocessingProfiler.current.start();\n    let processedPixels: Pixels | null = null;\n    try {\n      processedPixels = preprocessPixels({\n        pixels: video,\n        resizeToSize,\n        filters,\n      });\n    } catch (error) {\n      const errMessage: string = (error && error.message) || 'Image preprocessing failed';\n      logger.logError(errMessage);\n      setDetectionError(errMessage);\n    }\n    if (!processedPixels) {\n      return null;\n    }\n    setPixels(processedPixels);\n    const imageProcessingTime = preprocessingProfiler.current.stop();\n\n    // HTTPS prefixes detection model execution.\n    inferenceProfiler.current.start();\n    const httpsPredictions: DetectionBox[] | null = await graphModelExecute({\n      model: modelRef.current,\n      pixels: processedPixels,\n      maxBoxesNum,\n      scoreThreshold,\n      iouThreshold,\n    });\n    const modelExecutionTime = inferenceProfiler.current.stop();\n    setHttpsBoxes(httpsPredictions);\n\n    // OCR execution.\n    ocrProfiler.current.start();\n\n    const rectanglesImage: Rectangle[] = [\n      {\n        left: 0,\n        top: 0,\n        width: processedPixels.width,\n        height: processedPixels.height,\n      },\n    ];\n\n    /* eslint-disable-next-line max-len */\n    const rectanglesRegions: Rectangle[] = !useRegionProposals || !httpsPredictions || !httpsPredictions.length\n      ? []\n      : httpsPredictions.map((httpsPrediction: DetectionBox): Rectangle => {\n        const { x1, y1, y2 } = httpsPrediction;\n\n        const imageW: number = (processedPixels && processedPixels.width) || 0;\n        const imageH: number = (processedPixels && processedPixels.height) || 0;\n\n        const left: number = relativeToAbsolute(x1 - regionProposalsPadding, imageW);\n        const top: number = relativeToAbsolute(y1 - regionProposalsPadding, imageH);\n        const bottom: number = relativeToAbsolute(y2 + regionProposalsPadding, imageH);\n        const width: number = imageW - left;\n        const height: number = bottom - top;\n\n        return {\n          left,\n          top,\n          width,\n          height,\n        };\n      });\n\n    const rectangles: Rectangle[] = useRegionProposals ? rectanglesRegions : rectanglesImage;\n\n    setRegionProposals(rectangles);\n\n    logger.logDebug('detectLinks: tesseract is ready', {\n      numWorkers: tesseractSchedulerRef.current.getNumWorkers(),\n      rectangles: { ...rectangles },\n    });\n\n    if (rectangles.length) {\n      const texts: Array<TesseractDetection | null> = await Promise.all(\n        rectangles.map((rectangle: Rectangle): Promise<TesseractDetection | null> => {\n          const recognizeOptions: Partial<RecognizeOptions> = { rectangle };\n          if (!tesseractSchedulerRef.current) {\n            return Promise.resolve(null);\n          }\n          return tesseractSchedulerRef.current.addJob(\n            JobTypes.Recognize,\n            processedPixels,\n            recognizeOptions,\n          );\n        }),\n      );\n      if (texts && texts.length) {\n        const currentDetectedLinks: Array<DetectedLink | null> = texts\n          .map((text: TesseractDetection | null): DetectedLink | null => {\n            return extractLinkFromDetection(text, logger);\n          })\n          .filter(\n            (detection: DetectedLink | null): boolean => detection !== null,\n          );\n        // @ts-ignore\n        setDetectedLinks(currentDetectedLinks);\n      } else {\n        // If no links are recognized we should clear the previously recognized links.\n        // However to give users more time to click on them even if the next recognition\n        // round was not successful we may avoid clearing the array of links.\n        // setDetectedLinks([]);\n      }\n      logger.logDebug('recognized texts', { texts });\n    } else {\n      logger.logDebug('skipping the text recognition');\n    }\n\n    const ocrExecutionTime = ocrProfiler.current.stop();\n\n    const onFrameTime = onFrameProfiler.current.stop();\n\n    // Performance summary.\n    const detectionPerformance: DetectionPerformance = {\n      processing: imageProcessingTime,\n      avgProcessing: preprocessingProfiler.current.avg(),\n      inference: modelExecutionTime,\n      avgInference: inferenceProfiler.current.avg(),\n      ocr: ocrExecutionTime,\n      avgOcr: ocrProfiler.current.avg(),\n      total: onFrameTime,\n      avgFps: onFrameProfiler.current.avgFps(),\n      fps: onFrameProfiler.current.fps(),\n    };\n    logger.logDebugTable('onFrame', detectionPerformance);\n\n    return detectionPerformance;\n  };\n\n  const detectLinksCallback = useCallback(detectLinks, [\n    modelRef, iouThreshold, logger, maxBoxesNum, scoreThreshold, workersNum, tesseractSchedulerRef,\n  ]);\n\n  // Calculate the loading progress.\n  useEffect(() => {\n    const normalizedProgress: ZeroOneRange = toFloatFixed(\n      (modelLoadingProgress + tesseractLoadingProgress) / 2,\n      2,\n    );\n    logger.logDebug('useEffect: loading progress', {\n      modelLoadingProgress,\n      tesseractLoadingProgress,\n      normalizedProgress,\n      loadingProgress,\n    });\n    setLoadingProgress(normalizedProgress);\n    setLoadingStage('Loading links detector');\n  }, [loadingProgress, modelLoadingProgress, logger, tesseractLoadingProgress]);\n\n  // Update model references.\n  useEffect(() => {\n    logger.logDebug('useEffect: Model');\n    modelRef.current = model;\n  }, [model, logger]);\n\n  // Update tesseract scheduler references.\n  useEffect(() => {\n    logger.logDebug('useEffect: Tesseract Scheduler');\n    if (!tesseractScheduler || !tesseractSchedulerLoaded) {\n      return;\n    }\n    tesseractSchedulerRef.current = tesseractScheduler;\n  }, [tesseractScheduler, logger, tesseractSchedulerLoaded]);\n\n  return {\n    detectedLinks,\n    detectLinks: detectLinksCallback,\n    loadingProgress,\n    loadingStage,\n    pixels,\n    httpsBoxes,\n    regionProposals,\n    error: modelError || detectionError || tesseractSchedulerError,\n  };\n};\n\nexport default useLinksDetector;\n"
  },
  {
    "path": "src/hooks/useLogger.ts",
    "content": "import { useRef } from 'react';\nimport { buildLoggers, LoggerContext, Loggers } from '../utils/logger';\n\ntype UseLoggerParams = {\n  context?: LoggerContext,\n};\n\nfunction useLogger(params: UseLoggerParams = {}): Loggers {\n  const { context } = params;\n  const loggers = useRef<Loggers>(buildLoggers({ context }));\n  return loggers.current;\n}\n\nexport default useLogger;\n"
  },
  {
    "path": "src/hooks/usePageTitle.ts",
    "content": "import { useEffect, useState } from 'react';\nimport { useRouteMatch } from 'react-router-dom';\n\nimport { routeTitleFromPath } from '../utils/routes';\n\ntype UsePageTitleOutput = {\n  pageTitle: string | null,\n};\n\nfunction usePageTitle(): UsePageTitleOutput {\n  const [pageTitle, setPageTitle] = useState<string | null>(null);\n  const routeMatch = useRouteMatch();\n\n  useEffect(() => {\n    const detectedPageTitle: string | null = routeTitleFromPath(routeMatch.path);\n    setPageTitle(detectedPageTitle);\n  }, [routeMatch.path]);\n\n  return {\n    pageTitle,\n  };\n}\n\nexport default usePageTitle;\n"
  },
  {
    "path": "src/hooks/useTesseract.ts",
    "content": "import { Scheduler } from 'tesseract.js';\nimport {\n  useCallback,\n  useEffect,\n  useRef,\n  useState,\n} from 'react';\n\nimport { initScheduler, InitSchedulerProps } from '../utils/tesseract';\nimport useLogger from './useLogger';\nimport { ZeroOneRange } from '../utils/types';\n\ntype UseSchedulerProps = InitSchedulerProps;\n\ntype UseSchedulerOutput = {\n  scheduler: Scheduler | null,\n  loaded: boolean,\n  loadingProgress: ZeroOneRange,\n  error: string | null,\n};\n\nconst useTesseract = (props: UseSchedulerProps): UseSchedulerOutput => {\n  const { workersNum, language } = props;\n  const [loaded, setLoaded] = useState<boolean>(false);\n  const [loadingProgress, serLoadingProgress] = useState<ZeroOneRange>(0);\n  const [error, setError] = useState<string | null>(null);\n\n  const scheduler = useRef<Scheduler | null>(null);\n\n  const logger = useLogger({ context: 'useTesseract' });\n\n  const onSchedulerLoading = (progress: ZeroOneRange): void => {\n    logger.logDebug('onSchedulerLoading', {\n      progress,\n      workersNum: scheduler.current ? scheduler.current.getNumWorkers() : 0,\n    });\n    serLoadingProgress(progress);\n  };\n\n  const onSchedulerLoadingCallback = useCallback(onSchedulerLoading, [logger]);\n\n  const onSchedulerError = (schedulerError: any): void => {\n    let errMessage = 'Scheduler error';\n    if (typeof schedulerError === 'string') {\n      errMessage = schedulerError;\n    } else if (schedulerError && schedulerError.message && typeof schedulerError.message === 'string') {\n      errMessage = schedulerError.message;\n    }\n    setError(errMessage);\n  };\n\n  const onSchedulerErrorCallback = useCallback(onSchedulerError, []);\n\n  useEffect((): () => void => {\n    logger.logDebug('useEffect');\n    if (scheduler && scheduler.current) {\n      logger.logDebug('useEffect: skip');\n      return (): void => {};\n    }\n    initScheduler({\n      workersNum,\n      language,\n      onLoading: onSchedulerLoadingCallback,\n      onError: onSchedulerErrorCallback,\n    })\n      .then((ocrScheduler: Scheduler) => {\n        logger.logDebug('useEffect: init finished', {\n          ocrScheduler,\n          workersNum: ocrScheduler.getNumWorkers(),\n          queueLen: ocrScheduler.getQueueLen(),\n        });\n        scheduler.current = ocrScheduler;\n        setLoaded(true);\n      });\n\n    return (): void => {\n      logger.logDebug('useEffect: shutdown', { scheduler: scheduler.current });\n      if (scheduler.current) {\n        logger.logDebug('useEffect: shutdown: terminating the scheduler');\n        scheduler.current.terminate().then(() => {\n          logger.logDebug('useEffect: shutdown: scheduler is terminated');\n        });\n      }\n    };\n  }, [workersNum, language, logger, onSchedulerErrorCallback, onSchedulerLoadingCallback]);\n\n  return {\n    scheduler: scheduler.current,\n    loadingProgress,\n    loaded,\n    error,\n  };\n};\n\nexport default useTesseract;\n"
  },
  {
    "path": "src/hooks/useWindowSize.ts",
    "content": "import { useEffect, useState } from 'react';\nimport throttle from 'lodash/throttle';\n\nimport useLogger from './useLogger';\n\ntype WindowSize = {\n  width: number | undefined,\n  height: number | undefined,\n};\n\nconst resizeThrottleMs = 200;\n\nfunction useWindowSize(): WindowSize {\n  const logger = useLogger({ context: 'useWindowSize' });\n\n  const [windowSize, setWindowSize] = useState<WindowSize>({\n    width: undefined,\n    height: undefined,\n  });\n\n  useEffect((): () => void => {\n    logger.logDebug('useEffect');\n\n    const handleResize = (): void => {\n      setWindowSize({\n        width: window.innerWidth,\n        height: window.innerHeight,\n      });\n    };\n\n    const handleResizeThrottled = throttle(\n      handleResize,\n      resizeThrottleMs,\n      {\n        leading: false,\n        trailing: true,\n      },\n    );\n\n    window.addEventListener('resize', handleResizeThrottled);\n\n    handleResizeThrottled();\n\n    return (): void => {\n      logger.logDebug('useEffect return');\n      window.removeEventListener('resize', handleResizeThrottled);\n    };\n  }, [logger]);\n\n  return windowSize;\n}\n\nexport default useWindowSize;\n"
  },
  {
    "path": "src/icons/README.md",
    "content": "# Icons\n\n- [Tutorial](https://tailwindcss.com/course/working-with-svg-icons/#app) of how to style icons with Tailwind\n- [SVG OMG](https://jakearchibald.github.io/svgomg/) - for icons optimization\n- [SVG Icons Packs](https://tailwindcss.com/resources/) - list by Tailwind\n- [Icomoon](https://icomoon.io/) - SVG icons set\n- [FeatherIcons](https://feathericons.com/) - SVG icons set\n- [Vectr](https://vectr.com/) - creating vector icons online\n- [FaviconGenerator](https://realfavicongenerator.net/) - to generate favicon and app icons\n"
  },
  {
    "path": "src/icons/index.ts",
    "content": "import React, { SVGProps } from 'react';\n\nimport { ReactComponent as XIcon } from './feathericons/x.svg';\nimport { ReactComponent as AlertCircleIcon } from './feathericons/alert-circle.svg';\nimport { ReactComponent as Link2Icon } from './feathericons/link-2.svg';\nimport { ReactComponent as LinkIcon } from './feathericons/link.svg';\nimport { ReactComponent as ExternalLinkIcon } from './feathericons/external-link.svg';\nimport { ReactComponent as GitHubIcon } from './feathericons/github.svg';\nimport { ReactComponent as EditIcon } from './feathericons/edit-3.svg';\nimport { ReactComponent as BookOpenIcon } from './feathericons/book-open.svg';\nimport { ReactComponent as SearchIcon } from './feathericons/search.svg';\nimport { ReactComponent as SmartphoneIcon } from './feathericons/smartphone.svg';\nimport { ReactComponent as EyeIcon } from './feathericons/eye.svg';\nimport { ReactComponent as YoutubeIcon } from './feathericons/youtube.svg';\nimport { ReactComponent as LinksDetectorLogoIcon } from './vectr/links-detector-logo.svg';\n\nexport enum ICON_KEYS {\n  X = 'x',\n  ALERT_CIRCLE = 'alert-circle',\n  LINK = 'link',\n  LINK_2 = 'link-2',\n  EXTERNAL_LINK = 'external-link',\n  GIT_HUB = 'github',\n  EDIT = 'edit',\n  LINKS_DETECTOR_LOGO = 'links-detector-logo',\n  BOOK_OPEN = 'book-open',\n  SEARCH = 'search',\n  SMARTPHONE = 'smartphone',\n  EYE = 'eye',\n  YOUTUBE = 'youtube',\n}\n\ntype IconType = {\n  component: React.FunctionComponent<SVGProps<SVGSVGElement> & { title?: string | undefined; }>,\n  fillCurrent?: boolean,\n}\n\ntype IconsType = {\n  [iconKey in ICON_KEYS]: IconType;\n}\n\nexport const ICONS: IconsType = {\n  [ICON_KEYS.X]: {\n    component: XIcon,\n  },\n  [ICON_KEYS.ALERT_CIRCLE]: {\n    component: AlertCircleIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.LINK]: {\n    component: LinkIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.LINK_2]: {\n    component: Link2Icon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.EXTERNAL_LINK]: {\n    component: ExternalLinkIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.GIT_HUB]: {\n    component: GitHubIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.EDIT]: {\n    component: EditIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.LINKS_DETECTOR_LOGO]: {\n    component: LinksDetectorLogoIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.BOOK_OPEN]: {\n    component: BookOpenIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.SEARCH]: {\n    component: SearchIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.SMARTPHONE]: {\n    component: SmartphoneIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.EYE]: {\n    component: EyeIcon,\n    fillCurrent: false,\n  },\n  [ICON_KEYS.YOUTUBE]: {\n    component: YoutubeIcon,\n    fillCurrent: false,\n  },\n};\n"
  },
  {
    "path": "src/index.tsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport './styles/tailwind.css';\nimport App from './components/App';\nimport * as serviceWorker from './serviceWorkerRegistration';\nimport { PWA_ENABLED } from './configs/pwa';\n\nReactDOM.render(\n  <React.StrictMode>\n    <App />\n  </React.StrictMode>,\n  document.getElementById('root'),\n);\n\nif (PWA_ENABLED) {\n  serviceWorker.register();\n} else {\n  serviceWorker.unregister();\n}\n"
  },
  {
    "path": "src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n\n/*\ndeclare module 'glfx';\n\nor\n\ndeclare namespace bananaJs {\n    function getBanana(): string;\n    function addBanana(n: number) void;\n    function removeBanana(n: number) void;\n}\n*/\n"
  },
  {
    "path": "src/service-worker.ts",
    "content": "/// <reference lib=\"webworker\" />\n\n// This service worker can be customized!\n// See https://developers.google.com/web/tools/workbox/modules\n// for the list of available Workbox modules, or add any other code you'd like.\n// You can also remove this file if you'd prefer not to use a\n// service worker, and the Workbox build step will be skipped.\n\nimport { clientsClaim, skipWaiting, setCacheNameDetails } from 'workbox-core';\nimport { ExpirationPlugin } from 'workbox-expiration';\nimport { registerRoute } from 'workbox-routing';\nimport { StaleWhileRevalidate } from 'workbox-strategies';\nimport { CacheableResponsePlugin } from 'workbox-cacheable-response';\nimport { precacheAndRoute } from 'workbox-precaching';\n// import * as googleAnalytics from 'workbox-google-analytics';\n\nimport { CACHE_PREFIX, CACHE_VERSION } from './configs/pwa';\nimport { daysToSeconds } from './utils/numbers';\n\n// @see: https://developers.google.com/web/tools/workbox/modules/workbox-core\nsetCacheNameDetails({\n  prefix: CACHE_PREFIX,\n  suffix: CACHE_VERSION,\n  precache: 'precache',\n  runtime: 'runtime',\n  googleAnalytics: 'ga',\n});\n\n// Precache all of the assets generated by your build process.\n// Their URLs are injected into the manifest variable below.\n// This variable must be present somewhere in your service worker file,\n// even if you decide not to use precaching. See https://cra.link/PWA\n// eslint-disable-next-line no-undef\ndeclare const self: ServiceWorkerGlobalScope;\n\n// googleAnalytics.initialize();\n\n// Precache logic needs to go before registerRoute. Otherwise the caching strategy\n// from registerRoute will be applied instead of a CacheFirst strategy of precacheAndRoute.\n// @see: https://developers.google.com/web/tools/workbox/modules/workbox-precaching#serving_precached_responses\n// eslint-disable-next-line no-restricted-globals, no-underscore-dangle\nprecacheAndRoute(self.__WB_MANIFEST, {\n  ignoreURLParametersMatching: [/.*/],\n});\n\nconst getCacheName = (name: string): string => {\n  return `${CACHE_PREFIX}-${name}-${CACHE_VERSION}`;\n};\n\nskipWaiting();\nclientsClaim();\n\n// @see: https://developer.mozilla.org/en-US/docs/Web/API/Request\n// @see: https://developer.mozilla.org/en-US/docs/Web/API/RequestDestination\n\nregisterRoute(\n  ({ request, url }: { request: Request; url: URL }) => {\n    // Assets by type.\n    // eslint-disable-next-line no-undef\n    const assetTypes: RequestDestination[] = [\n      'image',\n      'style',\n      'script',\n      'worker',\n      'font',\n    ];\n    if (assetTypes.includes(request.destination)) {\n      return true;\n    }\n\n    // Assets by extension.\n    const assetExtensions: string[] = [\n      '.json', // i.e. TensorFlow model summary.\n      '.bin', // i.e. TensorFlow model data.\n      '.gz', // i.e. Tesseract training data.\n    ];\n    for (let extIndex = 0; extIndex < assetExtensions.length; extIndex += 1) {\n      const extension: string = assetExtensions[extIndex];\n      if (url.href.endsWith(extension)) {\n        return true;\n      }\n    }\n\n    // Assets by origin.\n    // @see: https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts\n    const assetOrigins: string[] = [\n      'https://fonts.googleapis.com', // i.e. Google Fonts stylesheets.\n      'https://fonts.gstatic.com', // i.e. Google Font font files.\n    ];\n    for (let originIndex = 0; originIndex < assetOrigins.length; originIndex += 1) {\n      const origin: string = assetOrigins[originIndex];\n      if (url.origin === origin) {\n        return true;\n      }\n    }\n\n    return false;\n  },\n  new StaleWhileRevalidate({\n    cacheName: getCacheName('assets'),\n    plugins: [\n      new ExpirationPlugin({\n        maxAgeSeconds: daysToSeconds(30),\n      }),\n      // @see: https://developers.google.com/web/tools/workbox/modules/workbox-cacheable-response#caching_based_on_status_codes\n      new CacheableResponsePlugin({ statuses: [0, 200] }),\n    ],\n  }),\n);\n"
  },
  {
    "path": "src/serviceWorkerRegistration.ts",
    "content": "// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nimport { buildLoggers } from './utils/logger';\n\nconst logger = buildLoggers({ context: 'swRegistration' });\n\nconst isServiceWorkerSupported = (): boolean => {\n  return 'serviceWorker' in navigator;\n};\n\ntype Config = {\n  onSuccess?: (registration: ServiceWorkerRegistration) => void;\n  onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nfunction registerValidSW(swUrl: string, config?: Config): void {\n  logger.logDebug('registerValidSW');\n  navigator.serviceWorker\n    .register(swUrl)\n    .then((registration: ServiceWorkerRegistration) => {\n      logger.logDebug('registerValidSW: registered', { registration });\n      // eslint-disable-next-line no-param-reassign\n      registration.onupdatefound = (): void => {\n        const installingWorker = registration.installing;\n        logger.logDebug('registerValidSW: onupdatefound', { installingWorker });\n        if (installingWorker == null) {\n          return;\n        }\n        installingWorker.onstatechange = (): void => {\n          if (installingWorker.state === 'installed') {\n            if (navigator.serviceWorker.controller) {\n              // At this point, the updated precached content has been fetched,\n              // but the previous service worker will still serve the older\n              // content until all client tabs are closed.\n              // @see: https://bit.ly/CRA-PWA\n              logger.logDebug(\n                'registerValidSW: New content is available and will be used when all tabs for this page are closed',\n                {\n                  state: installingWorker.state,\n                  controller: navigator.serviceWorker.controller,\n                },\n              );\n\n              // Execute callback\n              if (config && config.onUpdate) {\n                config.onUpdate(registration);\n              }\n            } else {\n              // At this point, everything has been precached. It's the perfect time to display a\n              // \"Content is cached for offline use.\" message.\n              logger.logDebug(\n                'registerValidSW: Content is cached for offline use',\n                {\n                  state: installingWorker.state,\n                  controller: navigator.serviceWorker.controller,\n                },\n              );\n\n              // Execute callback\n              if (config && config.onSuccess) {\n                config.onSuccess(registration);\n              }\n            }\n          }\n        };\n      };\n    })\n    .catch((error: Error) => {\n      logger.logError('Error during service worker registration:', error);\n    });\n}\n\nexport function register(config?: Config): void {\n  if (!isServiceWorkerSupported()) {\n    logger.logDebug('register: no supported');\n    return;\n  }\n\n  if (process.env.NODE_ENV !== 'production') {\n    logger.logDebug('register: not a production environment');\n    return;\n  }\n\n  // The URL constructor is available in all browsers that support SW.\n  const publicUrl = new URL(\n    process.env.PUBLIC_URL,\n    window.location.href,\n  );\n  logger.logDebug('register', {\n    publicUrlString: publicUrl.toString(),\n  });\n\n  if (publicUrl.origin !== window.location.origin) {\n    // Our service worker won't work if PUBLIC_URL is on a different origin\n    // from what our page is served on. This might happen if a CDN is used to\n    // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n    logger.logError('register: PUBLIC_URL is on a different origin', {\n      publicURLOrigin: publicUrl.origin,\n      locationOrigin: window.location.origin,\n    });\n    return;\n  }\n\n  window.addEventListener('load', () => {\n    const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n    logger.logDebug('register: window loaded', { swUrl });\n    registerValidSW(swUrl, config);\n  });\n}\n\nexport function unregister(): void {\n  if (!isServiceWorkerSupported()) {\n    logger.logDebug('unregister: not supported');\n    return;\n  }\n  logger.logDebug('unregister', { sw: navigator.serviceWorker });\n  navigator.serviceWorker.ready\n    .then((registration: ServiceWorkerRegistration) => {\n      logger.logDebug('unregister: starting');\n      registration.unregister()\n        .then((result) => {\n          logger.logDebug('unregister: finished', { result });\n        })\n        .catch((error) => {\n          logger.logError('unregister: failed', { error });\n        });\n    })\n    .catch((error: Error) => {\n      logger.logError(`unregister: failed: ${error.message}`, { error });\n    });\n}\n"
  },
  {
    "path": "src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom/extend-expect';\n"
  },
  {
    "path": "src/styles/index.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
  },
  {
    "path": "src/utils/analytics.ts",
    "content": "import { Location } from 'history';\nimport { GOOGLE_ANALYTICS_ID } from '../configs/analytics';\n\nconst getPathFromLocation = (routerLocation: Location): string => {\n  // @ts-ignore\n  const documentLocation: Location | null = document && document.location;\n  const location: Location = documentLocation || routerLocation;\n  let path = location.pathname;\n  if (location.search) {\n    path += location.search;\n  }\n  if (location.hash) {\n    path += location.hash;\n  }\n  return path;\n};\n\nconst gTagSupported = (): boolean => {\n  return window && window.gtag && true;\n};\n\nexport const gaPageView = (location: Location): void => {\n  if (!gTagSupported()) {\n    return;\n  }\n  // @see: https://developers.google.com/gtagjs/reference/api#config\n  window.gtag('config', GOOGLE_ANALYTICS_ID, {\n    page_path: getPathFromLocation(location),\n  });\n};\n\nexport const gaErrorLog = (errorType: string, errorMessage: string): void => {\n  if (!gTagSupported()) {\n    return;\n  }\n  // @see: https://developers.google.com/gtagjs/reference/api#config\n  window.gtag('config', GOOGLE_ANALYTICS_ID);\n  // @see: https://developers.google.com/gtagjs/reference/event#exception\n  window.gtag('event', 'exception', {\n    type: errorType,\n    description: errorMessage,\n  });\n};\n"
  },
  {
    "path": "src/utils/debug.ts",
    "content": "import * as tf from '@tensorflow/tfjs';\nimport { setTFBackend } from './graphModel';\n\ntype TFInfoProps = {\n  modelURL: string,\n};\n\nexport type TFInfo = {\n  platformName: string,\n  backendName: string,\n};\n\nexport const getTFInfo = async (props: TFInfoProps): Promise<TFInfo> => {\n  const { modelURL } = props;\n\n  await setTFBackend();\n\n  await tf.loadGraphModel(modelURL);\n\n  return {\n    platformName: tf.env().platformName,\n    backendName: tf.engine().backendName,\n  };\n};\n\nexport const isWebGLSupported = (): boolean => {\n  try {\n    const canvas: HTMLCanvasElement = document.createElement('canvas');\n    return !!window.WebGLRenderingContext\n      && (\n        !!canvas.getContext('webgl')\n        || !!canvas.getContext('experimental-webgl')\n      );\n  } catch (e) {\n    return false;\n  }\n};\n\nexport const isCanvasFilterSupported = (): boolean => {\n  try {\n    const canvas: HTMLCanvasElement = document.createElement('canvas');\n    const context: CanvasRenderingContext2D | null = canvas.getContext('2d');\n    if (!context) {\n      return false;\n    }\n    if (!context.filter) {\n      return false;\n    }\n    return true;\n  } catch (e) {\n    return false;\n  }\n};\n"
  },
  {
    "path": "src/utils/graphModel.ts",
    "content": "import * as tf from '@tensorflow/tfjs';\nimport { setWasmPaths } from '@tensorflow/tfjs-backend-wasm';\nimport { DataType } from '@tensorflow/tfjs-core/src/types';\n\nimport { buildLoggers } from './logger';\nimport { Pixels } from './image';\nimport { newProfiler, Profiler } from './profiler';\n\nexport enum TFBackends {\n  cpu = 'cpu',\n  webgl = 'webgl',\n  wasm = 'wasm',\n}\n\nexport const setTFBackend = async (\n  backendName: string = TFBackends.webgl,\n): Promise<void> => {\n  if (backendName === TFBackends.wasm) {\n    // @see: package.json\n    setWasmPaths({\n      'tfjs-backend-wasm.wasm': '/wasm/tfjs-backend-wasm.wasm',\n      'tfjs-backend-wasm-simd.wasm': '/wasm/tfjs-backend-wasm-simd.wasm',\n      'tfjs-backend-wasm-threaded-simd.wasm': '/wasm/tfjs-backend-wasm-threaded-simd.wasm',\n    });\n  }\n  await tf.setBackend(backendName);\n  await tf.ready();\n};\n\nexport const graphModelLoad = async (\n  modelURL: string,\n  onProgress: (progress: number) => void,\n): Promise<tf.GraphModel> => {\n  const logger = buildLoggers({ context: 'graphModelLoad' });\n\n  await setTFBackend();\n\n  const model: tf.GraphModel = await tf.loadGraphModel(modelURL, { onProgress });\n\n  logger.logDebug('Model is loaded', {\n    backendName: tf.engine().backendName,\n    platformName: tf.env().platformName,\n    model,\n    backend: tf.engine().backend,\n    features: tf.env().features,\n  });\n\n  return model;\n};\n\nexport const graphModelWarmup = async (\n  model: tf.GraphModel,\n): Promise<void> => {\n  if (!model) {\n    return;\n  }\n\n  const logger = buildLoggers({ context: 'graphModelWarmup' });\n\n  const inputShapeWithNulls = model.inputs[0].shape;\n\n  if (!inputShapeWithNulls) {\n    logger.logWarn('Cannot warmup the model: unknown input shape');\n    return;\n  }\n\n  const inputShape = inputShapeWithNulls.map((dimension: number) => {\n    if (dimension === null || dimension === -1) {\n      return 1;\n    }\n    return dimension;\n  });\n\n  const dataType: DataType = 'int32';\n  const fakeInput = tf.zeros(inputShape, dataType);\n\n  logger.logDebug('warmupModel', { inputShape, fakeInput });\n\n  try {\n    await model.executeAsync(fakeInput);\n    logger.logDebug('Model is wormed up');\n  } catch (error) {\n    logger.logError(`Cannot warmup the model: ${error.message}`, { error });\n  }\n};\n\ntype ModelPredictions = {\n  detectionsNum: number,\n  detectionScores: number[],\n  detectionClasses: number[],\n  detectionBoxes: number[][],\n};\n\nexport type DetectionBox = {\n  x1: number,\n  y1: number,\n  x2: number,\n  y2: number,\n  score: number,\n  categoryId: number,\n};\n\ntype GraphModelExecuteProps = {\n  model: tf.GraphModel,\n  pixels: Pixels,\n  maxBoxesNum: number,\n  iouThreshold: number,\n  scoreThreshold: number,\n};\n\nexport const graphModelExecute = async (\n  props: GraphModelExecuteProps,\n): Promise<DetectionBox[] | null> => {\n  const {\n    model,\n    pixels,\n    maxBoxesNum,\n    iouThreshold,\n    scoreThreshold,\n  } = props;\n\n  const profiler: Profiler = newProfiler();\n\n  const logger = buildLoggers({ context: 'graphModelExecute' });\n\n  if (!model || !pixels) {\n    logger.logError('executeModel: model or video is undefined');\n    return null;\n  }\n\n  const inputTensor: tf.Tensor3D = tf.browser.fromPixels(pixels).expandDims(0);\n\n  let results: tf.Tensor | tf.Tensor[] | null = null;\n\n  try {\n    profiler.start();\n    results = await model.executeAsync(inputTensor);\n    const inferenceTime = profiler.stop();\n    logger.logDebug('executeModel: executing', {\n      inputTensorShape: inputTensor.shape,\n      inferenceTime,\n      results,\n    });\n  } catch (e) {\n    const errorMessage = (e && e.message) || 'Cannot execute the model';\n    logger.logError(errorMessage);\n  }\n\n  if (!results) {\n    logger.logError('executeModel: model results are empty');\n    return null;\n  }\n\n  if (!Array.isArray(results)) {\n    logger.logError('executeModel: expected an array of Tensors, got one Tensor', {\n      results,\n    });\n    return null;\n  }\n\n  const DETECTIONS_NUM_INDEX = 2;\n  const DETECTIONS_CLASSES_INDEX = 5;\n  const DETECTIONS_BOXES_INDEX = 0;\n  const DETECTIONS_SCORES_INDEX = 6;\n\n  const detectionsNum: number = tf.util.flatten(\n    results[DETECTIONS_NUM_INDEX].arraySync(),\n  )[0];\n\n  const detectionClasses: number[] = await tf.broadcastTo<tf.Rank.R1>(\n    tf.squeeze(results[DETECTIONS_CLASSES_INDEX]),\n    [detectionsNum],\n  ).array();\n\n  const detectionScores: number[] = await tf.broadcastTo<tf.Rank.R1>(\n    tf.squeeze(results[DETECTIONS_SCORES_INDEX]),\n    [detectionsNum],\n  ).array();\n\n  // Each entry is [y1, x1, y2, x2], where (y1, x1) and (y2, x2) are\n  // the corners of the bounding box.\n  const detectionBoxes: number[][] = await tf.broadcastTo<tf.Rank.R2>(\n    tf.squeeze(results[DETECTIONS_BOXES_INDEX]),\n    [detectionsNum, 4],\n  ).array();\n\n  const importantBoxesIndicesTensor: tf.Tensor1D = await tf.image.nonMaxSuppressionAsync(\n    detectionBoxes,\n    detectionScores,\n    maxBoxesNum,\n    iouThreshold,\n    scoreThreshold,\n  );\n\n  const importantBoxesIndices: Int32Array = await importantBoxesIndicesTensor.data<'int32'>();\n\n  const boxes: DetectionBox[] = importantBoxesIndices.reduce<DetectionBox[]>(\n    (tmpBoxes: DetectionBox[], boxIndex: number) => {\n      tmpBoxes.push({\n        x1: detectionBoxes[boxIndex][1],\n        y1: detectionBoxes[boxIndex][0],\n        x2: detectionBoxes[boxIndex][3],\n        y2: detectionBoxes[boxIndex][2],\n        score: detectionScores[boxIndex],\n        categoryId: detectionClasses[boxIndex],\n      });\n      return tmpBoxes;\n    },\n    [],\n  );\n\n  const modelPredictions: ModelPredictions = {\n    detectionsNum,\n    detectionClasses,\n    detectionBoxes,\n    detectionScores,\n  };\n\n  logger.logDebug('executeModel: parsed results', {\n    modelPredictions,\n    importantBoxesIndices,\n    boxes,\n  });\n\n  return boxes;\n};\n"
  },
  {
    "path": "src/utils/image.ts",
    "content": "/* eslint-disable no-param-reassign */\n\nimport { SignedZeroOneRange, ZeroOneRange } from './types';\n\nexport type Pixels = HTMLImageElement | HTMLCanvasElement| HTMLVideoElement;\n\nexport type FilterFunc = (colors: Uint8ClampedArray, shift: number) => void;\n\nconst cutColor = (color: number): number => {\n  return Math.min(Math.floor(color), 255);\n};\n\n// Converts [0, 1] range to [-1, 1] range.\nconst normalizeFilterParam = (zeroOneRange: ZeroOneRange): SignedZeroOneRange => {\n  return zeroOneRange * 2 - 1;\n};\n\n// @see: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function\nexport const normalizeCSSFilterParam = (zeroOneRange: ZeroOneRange): number => {\n  return 1 + zeroOneRange;\n};\n\n// @see: http://thecryptmag.com/Online/56/imgproc_5.html\n// @see: https://css-tricks.com/manipulating-pixels-using-canvas/\nexport const contrastFilter = (contrastRange: ZeroOneRange): FilterFunc => (\n  colors: Uint8ClampedArray,\n  shift: number,\n): void => {\n  const contrast = normalizeFilterParam(contrastRange) * 100;\n  const factor = (259 * (contrast + 255)) / (255 * (259 - contrast));\n  for (let channel = 0; channel < 3; channel += 1) {\n    colors[shift + channel] = cutColor(factor * (colors[shift + channel] - 128) + 128);\n  }\n};\n\n// @see: https://css-tricks.com/manipulating-pixels-using-canvas/\nexport const brightnessFilter = (brightness: ZeroOneRange): FilterFunc => (\n  colors: Uint8ClampedArray,\n  shift: number,\n): void => {\n  const brightnessDelta = 255 * normalizeFilterParam(brightness);\n  for (let channel = 0; channel < 3; channel += 1) {\n    colors[shift + channel] = cutColor(colors[shift + channel] + brightnessDelta);\n  }\n};\n\n// @see: https://www.tutorialspoint.com/dip/grayscale_to_rgb_conversion.htm\nexport const greyscaleFilter = (): FilterFunc => (\n  colors: Uint8ClampedArray,\n  shift: number,\n): void => {\n  const average = cutColor(\n    0.3 * colors[shift] + 0.59 * colors[shift + 1] + 0.11 * colors[shift + 2],\n  );\n  for (let channel = 0; channel < 3; channel += 1) {\n    colors[shift + channel] = average;\n  }\n};\n\nexport const canvasFromPixels = (\n  pixels: Pixels,\n  size?: number | null,\n): HTMLCanvasElement | null => {\n  const canvas: HTMLCanvasElement = document.createElement<'canvas'>('canvas');\n  canvas.width = size || pixels.width;\n  canvas.height = size || pixels.height;\n\n  const context: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n  if (!context) {\n    return null;\n  }\n\n  context.drawImage(pixels, 0, 0, canvas.width, canvas.height);\n\n  return canvas;\n};\n\nexport type PreprocessPixelsProps = {\n  pixels: Pixels,\n  filters: FilterFunc[],\n  resizeToSize?: number | null,\n};\n\nexport const preprocessPixels = (props: PreprocessPixelsProps): Pixels => {\n  const { pixels, filters, resizeToSize } = props;\n\n  const canvas: HTMLCanvasElement | null = canvasFromPixels(pixels, resizeToSize);\n\n  if (!canvas) {\n    throw new Error('Canvas cannot be created');\n  }\n\n  const context: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n  if (!context) {\n    throw new Error('Empty canvas context');\n  }\n\n  const imageData: ImageData = context.getImageData(0, 0, canvas.width, canvas.height);\n\n  const COLORS_IN_PIXEL = 4; // RGBA\n  for (let shift = 0; shift < imageData.data.length; shift += COLORS_IN_PIXEL) {\n    filters.forEach((filter: FilterFunc) => {\n      filter(imageData.data, shift);\n    });\n  }\n\n  context.putImageData(imageData, 0, 0);\n\n  return canvas;\n};\n\nexport const relativeToAbsolute = (relativeCoordinate: ZeroOneRange, imageSize: number): number => {\n  return Math.max(\n    Math.min(\n      Math.round(relativeCoordinate * imageSize),\n      imageSize,\n    ),\n    0,\n  );\n};\n"
  },
  {
    "path": "src/utils/logger.ts",
    "content": "import { isDebugMode } from '../constants/debug';\nimport { gaErrorLog } from './analytics';\n\nexport type LoggerContext = string | null;\nexport type LoggerMessage = string;\nexport type LoggerMeta = Error | Object | null;\n\ninterface LinksDetectorConsole {\n  log(...data: any[]): void;\n  table(tabularData?: any, properties?: string[]): void;\n  warn(...data: any[]): void;\n  error(...data: any[]): void;\n}\n\nconst linksDetectorConsoleName: string = 'linksDetectorConsole';\n\nfunction getSystemLogger(): LinksDetectorConsole {\n  if (Object.prototype.hasOwnProperty.call(window, linksDetectorConsoleName)) {\n    return window[linksDetectorConsoleName];\n  }\n\n  const linksDetectorConsole: LinksDetectorConsole = {\n    log: window.console.log,\n    table: window.console.table,\n    warn: window.console.warn,\n    error: window.console.error,\n  };\n\n  Object.defineProperty(window, linksDetectorConsoleName, {\n    value: linksDetectorConsole,\n    writable: false,\n  });\n\n  return linksDetectorConsole;\n}\n\nconst logger: LinksDetectorConsole = getSystemLogger();\n\nexport type TableLogger = (\n  message: string,\n  tabularData: any,\n  properties?: string[],\n) => void;\n\nexport type Logger = (\n  message: LoggerMessage,\n  meta?: LoggerMeta,\n) => void;\n\nexport type Loggers = {\n  logDebugTable: TableLogger,\n  logDebug: Logger,\n  logInfo: Logger,\n  logWarn: Logger,\n  logError: Logger,\n};\n\nconst contextSeparator = '→';\n\ntype OnCallLoggerCallback =\n  (context: LoggerContext, message: LoggerMessage, meta?: LoggerMeta) => void;\n\ntype BuildLoggerProps = {\n  loggerFunc: (message?: any, ...optionalParams: any[]) => void,\n  onCall?: OnCallLoggerCallback,\n  context?: LoggerContext,\n  muted?: boolean,\n};\n\nconst buildLogger = (\n  props: BuildLoggerProps,\n): Logger => (message: LoggerMessage, meta?: LoggerMeta): void => {\n  const {\n    loggerFunc,\n    onCall,\n    context,\n    muted,\n  } = props;\n\n  if (muted) {\n    return;\n  }\n\n  const args: (LoggerMessage | LoggerContext | LoggerMeta)[] = [message];\n  if (context) {\n    const consoleColors: string[] = [\n      'green', 'orange', 'blue', 'brown', 'blueviolet', 'chocolate', 'coral', 'dodgerblue', 'olive', 'teal',\n    ];\n    const contextHash: number = context.length % consoleColors.length;\n    const contextColor: string = consoleColors[contextHash];\n    const contextStyles: string = `background: ${contextColor}; color: white; padding: 0 3px; border-radius: 3px;`;\n    args.unshift(\n      `%c${context}`,\n      contextStyles,\n      contextSeparator,\n    );\n  }\n\n  if (meta) {\n    args.push(meta);\n  }\n\n  loggerFunc(...args);\n\n  if (onCall) {\n    onCall(context || 'unknown', message, meta);\n  }\n};\n\ntype BuildTableLoggerProps = {\n  loggerFunc: (tabularData: any, properties?: string[]) => void,\n  context?: LoggerContext,\n  muted?: boolean,\n};\n\nconst buildTableLogger = (\n  props: BuildTableLoggerProps,\n): TableLogger => (message: string, tabularData: any, properties?: string[]): void => {\n  const { loggerFunc, muted } = props;\n  if (muted) {\n    return;\n  }\n  loggerFunc(tabularData, properties);\n};\n\nconst onGAError: OnCallLoggerCallback = (\n  context: LoggerContext,\n  message: LoggerMessage,\n): void => {\n  gaErrorLog(context || 'unknownContext', message);\n};\n\ntype BuildLoggersParams = {\n  context?: LoggerContext,\n};\n\nexport const buildLoggers = (params: BuildLoggersParams): Loggers => {\n  const { context } = params;\n  const muted = !isDebugMode();\n  return {\n    logDebugTable: buildTableLogger({\n      loggerFunc: logger.table,\n      context,\n      muted,\n    }),\n\n    logDebug: buildLogger({\n      loggerFunc: logger.log,\n      context,\n      muted,\n    }),\n\n    logInfo: buildLogger({\n      loggerFunc: logger.log,\n      context,\n      muted,\n    }),\n\n    logWarn: buildLogger({\n      loggerFunc: logger.warn,\n      context,\n    }),\n\n    logError: buildLogger({\n      loggerFunc: logger.error,\n      context,\n      onCall: onGAError,\n    }),\n  };\n};\n"
  },
  {
    "path": "src/utils/numbers.ts",
    "content": "export const toFloatFixed = (num: number, fractionDigits: number): number => {\n  const leverage: number = 10 ** fractionDigits;\n  return Math.round(num * leverage) / leverage;\n};\n\nexport const daysToSeconds = (days: number): number => {\n  const secondsInDay: number = 24 * 60 * 60;\n  return days * secondsInDay;\n};\n"
  },
  {
    "path": "src/utils/profiler.ts",
    "content": "import { toFloatFixed } from './numbers';\n\nexport type Profiler = {\n  start: () => void,\n  stop: (inSeconds?: boolean) => number,\n  avg: (inSeconds?: boolean) => number,\n  fps: () => number,\n  avgFps: () => number,\n};\n\nconst msToSs = (timeMs: number, fractionDigits: number = 2): number => {\n  return toFloatFixed(timeMs / 1000, fractionDigits);\n};\n\nexport const newProfiler = (): Profiler => {\n  let timeRangesSum: number = 0;\n  let timeRangesNum: number = 0;\n  let lastTimeRange: number = 0;\n\n  let startTimeMs: number = 0;\n\n  const start = (): void => {\n    startTimeMs = Date.now();\n  };\n\n  const stop = (inSeconds: boolean = true): number => {\n    const timeRange = Date.now() - startTimeMs;\n    lastTimeRange = timeRange;\n    timeRangesNum += 1;\n    timeRangesSum += timeRange;\n    if (inSeconds) {\n      return msToSs(timeRange);\n    }\n    return timeRange;\n  };\n\n  const avg = (inSeconds: boolean = true): number => {\n    const average = Math.ceil(timeRangesSum / timeRangesNum);\n    if (inSeconds) {\n      return msToSs(average);\n    }\n    return average;\n  };\n\n  const fps = (): number => {\n    return toFloatFixed(1 / msToSs(lastTimeRange), 2);\n  };\n\n  const avgFps = (): number => {\n    return toFloatFixed(1 / avg(), 2);\n  };\n\n  return {\n    start,\n    stop,\n    avg,\n    fps,\n    avgFps,\n  };\n};\n"
  },
  {
    "path": "src/utils/routes.ts",
    "content": "import { ROUTES, RouteType } from '../constants/routes';\n\nexport const routeFromPath = (path: string): RouteType | null => {\n  const route: RouteType | undefined = Object.values<RouteType>(ROUTES)\n    .find((currentRoute: RouteType) => currentRoute.path === path);\n  return route || null;\n};\n\nexport const routeTitleFromPath = (path: string): string | null => {\n  const route: RouteType | null = routeFromPath(path);\n  if (route) {\n    return route.title;\n  }\n  return null;\n};\n"
  },
  {
    "path": "src/utils/tesseract.ts",
    "content": "import {\n  createWorker,\n  createScheduler,\n  Scheduler,\n  Worker,\n  WorkerOptions,\n  WorkerParams,\n  PSM,\n} from 'tesseract.js';\nimport { buildLoggers } from './logger';\nimport { ZeroOneRange } from './types';\nimport { toFloatFixed } from './numbers';\n\nexport type InitSchedulerProps = {\n  workersNum: number,\n  language: string,\n  onError?: (error: any) => void,\n  onLoading?: (progress: ZeroOneRange) => void,\n};\n\nexport enum JobTypes {\n  Recognize = 'recognize',\n  Detect = 'detect',\n}\n\nexport enum WorkerLoadingStatuses {\n  LoadingCore = 'loading tesseract core',\n  Initializing = 'initializing tesseract',\n  Initialized = 'initialized tesseract',\n  LoadingLanguageTrainData = 'loading language traineddata',\n  LoadingLanguageTrainDataCached = 'loading language traineddata (from cache)',\n  LoadedLanguageTrainData = 'loaded language traineddata',\n  InitializingAPI = 'initializing api',\n  InitializedAPI = 'initialized api',\n  RecognizingText = 'recognizing text',\n}\n\nconst CORE_WORKER_ID = 'core';\n\ntype WorkerLoadingProgress = {\n  [loadingState: string]: ZeroOneRange | null,\n};\n\ntype WorkersLoadingProgress = {\n  [workerId: string]: WorkerLoadingProgress,\n};\n\nexport type WorkerLogEvent = {\n  status: WorkerLoadingStatuses,\n  workerId?: string,\n  progress?: ZeroOneRange,\n};\n\nconst getLoadingProgress = (\n  originalWorkersLoadingProgress: WorkersLoadingProgress,\n  workersNum: number,\n): ZeroOneRange => {\n  const workersLoadingProgress: WorkersLoadingProgress = { ...originalWorkersLoadingProgress };\n\n  // Detect core loading progress.\n  const coreNum: number = 1; // always 1\n  const rawCoreLoadingProgress: WorkerLoadingProgress = workersLoadingProgress[\n    CORE_WORKER_ID\n  ] || {};\n  const coreLoadingProgress: ZeroOneRange = rawCoreLoadingProgress[\n    WorkerLoadingStatuses.LoadingCore\n  ] || 0;\n  delete workersLoadingProgress[CORE_WORKER_ID];\n\n  // Detect workers loading progress.\n  const rawWorkerProgresses: WorkerLoadingProgress[] = Object.values<WorkerLoadingProgress>(\n    workersLoadingProgress,\n  );\n  if (!rawWorkerProgresses || !rawWorkerProgresses.length) {\n    return 0;\n  }\n  const workerProgresses: ZeroOneRange[] = rawWorkerProgresses.map(\n    (rawWorkerProgress: WorkerLoadingProgress) => {\n      const tesseractLoadingProgress: ZeroOneRange = rawWorkerProgress[\n        WorkerLoadingStatuses.Initialized\n      ] || 0;\n\n      const apiLoadingProgress: ZeroOneRange = rawWorkerProgress[\n        WorkerLoadingStatuses.InitializedAPI\n      ] || 0;\n\n      const trainDataLoadingProgress: ZeroOneRange = rawWorkerProgress[\n        WorkerLoadingStatuses.LoadedLanguageTrainData\n      ] || 0;\n\n      return (tesseractLoadingProgress + apiLoadingProgress + trainDataLoadingProgress) / 3;\n    },\n  );\n  const denormalizedLoadingProgress: number = workerProgresses.reduce(\n    (overallProgress: number, currentProgress: ZeroOneRange) => {\n      return overallProgress + currentProgress;\n    },\n    0,\n  );\n\n  // Calculate overall loading progress.\n  return toFloatFixed(\n    (coreLoadingProgress + denormalizedLoadingProgress) / (workersNum + coreNum),\n    2,\n  );\n};\n\nexport const initScheduler = async (props: InitSchedulerProps): Promise<Scheduler> => {\n  const {\n    workersNum,\n    language,\n    onError = (): void => {},\n    onLoading = (): void => {},\n  } = props;\n\n  const logger = buildLoggers({ context: 'initScheduler' });\n  logger.logDebug('initScheduler', { ...props });\n\n  const workerIDs: string[] = [];\n  const workersLoadingProgress: WorkersLoadingProgress = {};\n\n  const scheduler: Scheduler = createScheduler();\n\n  const onWorkerLog = (logEvent: WorkerLogEvent): void => {\n    // Register a new loading state in worker loading progress object.\n    const workerID: string = logEvent.workerId || CORE_WORKER_ID;\n    if (!workersLoadingProgress[workerID]) {\n      workersLoadingProgress[workerID] = {};\n    }\n    workersLoadingProgress[workerID][logEvent.status] = logEvent.progress || null;\n\n    // Calculate overall loading progress.\n    const progress: ZeroOneRange = getLoadingProgress(workersLoadingProgress, workersNum);\n    logger.logDebug('worker log', {\n      ...logEvent,\n      overallProgress: progress,\n      workersLoadingProgress: { ...workersLoadingProgress },\n      loadedWorkersNum: scheduler.getNumWorkers(),\n      workerIDs,\n    });\n    onLoading(progress);\n  };\n\n  const onWorkerError = (error: any): void => {\n    logger.logError('worker error', { ...error });\n    onError(error);\n  };\n\n  const workerOptions: Partial<WorkerOptions> = {\n    logger: onWorkerLog,\n    errorHandler: onWorkerError,\n  };\n\n  const initWorker = async (): Promise<Worker> => {\n    // @see: https://github.com/naptha/tesseract.js/blob/master/docs/api.md#workersetparametersparams-jobid-promise\n    const workerParams: Partial<WorkerParams> = {\n      // @ts-ignore\n      tessedit_pageseg_mode: PSM.SINGLE_LINE,\n      tessjs_create_hocr: '0',\n      tessjs_create_tsv: '0',\n    };\n\n    const worker: Worker = createWorker(workerOptions);\n    await worker.load();\n    await worker.loadLanguage(language);\n    await worker.initialize(language);\n    await worker.setParameters(workerParams);\n\n    return worker;\n  };\n\n  let workers: Worker[] = [];\n  try {\n    const workersPromises: Promise<Worker>[] = Array(workersNum)\n      .fill(null)\n      .map(() => initWorker());\n    workers = await Promise.all(workersPromises);\n  } catch (error) {\n    logger.logError('cannot init workers', { error });\n    onError(error);\n  }\n\n  workers.forEach((worker: Worker) => {\n    const workerID = scheduler.addWorker(worker);\n    workerIDs.push(workerID);\n    logger.logDebug('addWorker', { workerID });\n  });\n\n  return scheduler;\n};\n"
  },
  {
    "path": "src/utils/types.ts",
    "content": "// [0, 1]\nexport type ZeroOneRange = number;\n\n// [-1, 1]\nexport type SignedZeroOneRange = number;\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "// @see: https://tailwindcss.com/docs/configuration/\n// @see: https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js\n\nconst defaultTheme = require('tailwindcss/defaultTheme');\n\nconst fontFamily = { ...defaultTheme.fontFamily };\nfontFamily.sans = [\n  'Roboto',\n  'system-ui',\n  '-apple-system',\n  'BlinkMacSystemFont',\n  '\"Segoe UI\"',\n  '\"Helvetica Neue\"',\n  'Arial',\n  '\"Noto Sans\"',\n  'sans-serif',\n  '\"Apple Color Emoji\"',\n  '\"Segoe UI Emoji\"',\n  '\"Segoe UI Symbol\"',\n  '\"Noto Color Emoji\"',\n];\n\nmodule.exports = {\n  purge: [],\n  theme: {\n    fontFamily,\n    extend: {},\n  },\n  variants: {\n    margin: ['responsive', 'last'],\n  },\n  plugins: [],\n};\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react\",\n    \"noFallthroughCasesInSwitch\": true,\n    \"suppressImplicitAnyIndexErrors\": true\n  },\n  \"include\": [\n    \"src\"\n  ]\n}\n"
  }
]