{
    "componentChunkName": "component---src-components-page-template-jsx",
    "path": "/guides/tools/visualmesh",
    "result": {"data":{"mdx":{"id":"0d51fe19-db0c-57f2-b25b-caac5bea85a6","body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"section\": \"Guides\",\n  \"chapter\": \"Tools\",\n  \"title\": \"Visual Mesh Getting Started\",\n  \"description\": \"How to get started with the Visual Mesh.\",\n  \"slug\": \"/guides/tools/visualmesh\",\n  \"authors\": [\"Joel Wong (@wongjoel)\"]\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar Alert = makeShortcode(\"Alert\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"This guide compliments the quickstart guide on the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/VisualMesh\"\n  }, \"main Visual Mesh repo\"), \" by being geared towards those with little experience of the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://ubuntu.com/tutorials/command-line-for-beginners#1-overview\"\n  }, \"Linux command line (i.e. bash)\"), \" or of Machine Learning workflows. If you are already familiar with bash and machine learning, you may prefer to work off the Quickstart guide on the Visual Mesh repo as it is briefer than this guide.\"), mdx(\"p\", null, \"To get started, run this line to check the installation and version of the required programs.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"python3 --version && pip3 --version && git --version && docker --version\\n\")), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, \"This should provide a result similar to that listed below, possibly with higher version numbers. Run through the relevant installation guides if this doesn't appear\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"Python 3.8.5\\npip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)\\ngit version 2.25.1\\nDocker version 20.10.3, build 48d30b5\\n\")), mdx(\"details\", null, mdx(\"summary\", null, \"Installing Python3\"), mdx(\"p\", null, \"The script to build the dataset is written in Python. When using Ubuntu, the simplest way to install Python is to use the APT package manager. Run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo apt install python3\"), \" to have APT install to the most recent version of Python 3 for your system.\")), mdx(\"details\", null, mdx(\"summary\", null, \"Installing pip\"), mdx(\"p\", null, \"Pip is the default package manager for Python. In systems with both Python2 and Python3, the pip3 specifically invokes the pip tied to the Python3. Because Ubuntu packages pip separately from Python, you may have to install it specifically by running \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo apt install python3-pip\"), \".\")), mdx(\"details\", null, mdx(\"summary\", null, \"Installing Git\"), mdx(\"p\", null, \"While you don't strictly need to use git to download the Visual Mesh repo (e.g. you could just download it from github's web interface), git is the recommended way to get and manage the code from the repo. The git command line interface is installed on Ubuntu with APT by running \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo apt install git\"), \". If you prefer a GUI for git, try \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://help.gitkraken.com/gitkraken-desktop/how-to-install/\"\n  }, \"GitKraken\"), \".\")), mdx(\"details\", null, mdx(\"summary\", null, \"Installing Docker\"), mdx(\"p\", null, \"Docker is the container system that we use for standardised software environments at NUbots, to install it, \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.docker.com/engine/install/\"\n  }, \"check out the documentation\"), \", as the version packaged by Ubuntu often lags behind the official version. Be sure to ask on Slack if you've got any questions.\")), mdx(\"h2\", {\n    \"id\": \"clone-the-visual-mesh-repo\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#clone-the-visual-mesh-repo\",\n    \"aria-label\": \"clone the visual mesh repo permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Clone the Visual Mesh Repo\"), mdx(\"p\", null, \"Use git to clone the Visual mesh repo. When using git on the commandline, git will default to cloning the repo into a folder under your current working directory. Start by navigating to the folder where you want to store the repo: for example, if you wanted to store the visual mesh under \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"~/code/\"), \", run:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~\\nmkdir code\\ncd code\\n\")), mdx(\"p\", null, \"Once you're in the folder you wanted to be in (e.g. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"~/code/\"), \"), clone the repository with the following command:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"git clone https://github.com/NUbots/VisualMesh.git\\n\")), mdx(\"h2\", {\n    \"id\": \"build-the-docker-image\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#build-the-docker-image\",\n    \"aria-label\": \"build the docker image permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Build the docker image\"), mdx(\"p\", null, \"We specify build steps for docker using a file named \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dockerfile\"), \". This uses similar syntax to a bash script, but is a format specifically used by docker. Open the dockerfile in a text editor/reader, and take note of the last line that starts with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"WORKDIR\"), \" (At the time of writing, the last line of the file). This line tells us that the working directory of the container will be the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/workspace\"), \" directory within the container (not the host). Take note of this as it will be the directory from which the program will run.\"), mdx(\"p\", null, \"Having done a quick check of the dockerfile, we can now tell docker to build the image according to the dockerfile with the following command:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"docker build . --pull -t visualmesh:latest\\n\")), mdx(\"details\", null, mdx(\"summary\", null, \"What does this command do?\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"docker\"), \" is the call to docker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"build\"), \" is the main command being sent to docker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \".\"), \" is telling docker that the build context is the current directory. Docker will look for a file named \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"Dockerfile\"), \" in the build context telling it what to build (so in this case, the current directory).\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--pull\"), \" tells docker to always attempt to pull a newer version of the image\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"-t visualmesh:latest\"), \" tells docker that we want to tag the built image as \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"visualmesh:latest\"), \". We'll see later that when we tell docker to run a container, that we tell docker which image to use by referencing this tag.\"))), mdx(\"h2\", {\n    \"id\": \"make-a-dummy-dataset\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#make-a-dummy-dataset\",\n    \"aria-label\": \"make a dummy dataset permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Make a dummy dataset\"), mdx(\"p\", null, \"For the sake of this guide, we'll use a dummy dataset containing the same image repeated over and over again. \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"While this will lead to extreme overfitting, it's an easy way to quickly check that the code is running correctly.\"), \" Download the example image, mask, and lens file \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/d7ffd0a18db936ec08eb09cfe924f70d/dummy_data.zip\"\n  }, \"dummy_data.zip\"), \" to your downloads folder.\"), mdx(\"p\", null, \"Now, we're going to make a dummy dataset by repeating these files. We can do this using a bash loop. Assuming that we have the dummy data in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"~/Downloads/dummy_data\"), \", and we're going to put the repeated data in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"~/Downloads/repeated_data\"), \", run the four commands below:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~/Downloads\\n\\nunzip dummy_data.zip\\n\\nmkdir repeated_data\\n\\nfor i in {1..1000}; do cp ./dummy_data/image.jpg ./repeated_data/image${i}.jpg && cp ./dummy_data/mask.png ./repeated_data/mask${i}.png && cp ./dummy_data/lens.yaml ./repeated_data/lens${i}.yaml; done\\n\")), mdx(\"p\", null, \"To ensure that the data was copied sucessfully run the command below which will print all the filenames to the terminal window. If you would like to clean up your display, you can use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"clear\"), \" command.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"ls ~/Downloads/repeated_data\\nclear\\n\")), mdx(\"h3\", {\n    \"id\": \"install-the-prerequisites-to-make-a-tfrecord\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#install-the-prerequisites-to-make-a-tfrecord\",\n    \"aria-label\": \"install the prerequisites to make a tfrecord permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Install the prerequisites to make a tfrecord\"), mdx(\"p\", null, \"We want to convert our dataset from image and text files to the tfrecord format that the visual mesh expects, but to do this we need to install some python libraries to allow python to work with tfrecords. Feel free to use something like conda or virtualenv if you're concerned about ending up with conflicting library versions.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"pip3 install tensorflow tqdm\\n\")), mdx(\"h3\", {\n    \"id\": \"make-a-set-of-tfrecord\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#make-a-set-of-tfrecord\",\n    \"aria-label\": \"make a set of tfrecord permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Make a set of tfrecord\"), mdx(\"p\", null, \"Having made the repeated dataset and installed the libraries required to work with tfrecords, we can now put it into the tfrecord format the visual mesh wants using the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"make_dataset.py\"), \" script. By default, the visual mesh will look for the dataset inside a folder named \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"dataset\"), \", so we'll navigate back to the visual mesh repo, make the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"dataset\"), \" folder, then make the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".tfrecord\"), \" files required using the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"make_dataset.py\"), \" script:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~/code/VisualMesh\\nmkdir dataset\\n./training/make_dataset.py ~/Downloads/repeated_data ./dataset\\n\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"make_dataset.py\"), \" script won't complain if you give it an empty folder, so make sure that the created tfrecord files are not empty.\")), mdx(\"h2\", {\n    \"id\": \"configure-the-training\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#configure-the-training\",\n    \"aria-label\": \"configure the training permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Configure the training\"), mdx(\"p\", null, \"The visual mesh looks for a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"config.yaml\"), \" file in the output folder to set the training parameters. An example file \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"example_net.yaml\"), \" can be found in the root of the repo. We'll create an output folder and copy the example parameters into it:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~/code/VisualMesh\\nmkdir output\\ncp example_net.yaml ./output/config.yaml\\n\")), mdx(\"p\", null, \"With that, we're almost ready to train the network. To save time, change the configuration to run less training epochs (500 epochs can easily take 30 hours to complete on CPU). Open the config file in a text editor, (e.g. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nano output/config.yaml\"), \") and change the line that says \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"epochs: 500\"), \" to say \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"epochs: 5\"), \". Also note that the paths for the training, testing and validation tfrecords are set in the config file. \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"If you have accidentally started training 500 epochs hit \", mdx(\"inlineCode\", {\n    parentName: \"em\"\n  }, \"ctrl+c\"), \" to keyboard interrupt training, if that doesn't work, open another bash terminal, type \", mdx(\"inlineCode\", {\n    parentName: \"em\"\n  }, \"xkill\"), \" then click on the training terminal window\")), mdx(\"h2\", {\n    \"id\": \"train-the-network\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#train-the-network\",\n    \"aria-label\": \"train the network permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Train the network\"), mdx(\"p\", null, \"The command to train the network is as below. It's a long command, but it's straightforward if we break it down into the individual parts:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~/code/VisualMesh\\ndocker run --gpus all -u $(id -u):$(id -g) -it --rm --volume $(pwd):/workspace visualmesh:latest ./mesh.py train output\\n\")), mdx(\"details\", null, mdx(\"summary\", null, \"What does this command do?\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"docker\"), \" is the call to docker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"run\"), \" is the main command being sent to docker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--gpus all\"), \" tells docker to use the gpus from your system (remove \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--gpus all\"), \" if you're running on a system without a GPU)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"-it\"), \" tells docker to run in interactive mode with a terminal\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--rm\"), \" tells docker to automatically clean up the temporary files associated with this container\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--volume $(pwd):/workspace\"), \" tells docker to mount the current working directory as \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"/workspace\"), \" inside the container\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"visualmesh:latest\"), \" tells docker which image we want to run (note that we built this image and gave it this name in an earlier step)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"./mesh.py train output\"), \" is the command to run inside the container, so we're passing the command \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"train\"), \" with the path \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"output\"), \" to the \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"mesh.py\"), \" script. Note that the filesystem inside the container is different to the filesystem outside of the container, but that due to the \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"--volume\"), \" flag, the current working directory is mounted at \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"/workspace\"), \", so in this example, the \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"output\"), \" folder ends up being the one in the code directory.\"))), mdx(\"h2\", {\n    \"id\": \"test-the-network\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#test-the-network\",\n    \"aria-label\": \"test the network permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Test the network\"), mdx(\"p\", null, \"Testing the network is a very similar command to training, we just replace \\\"train\\\" with \\\"test\\\":\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"cd ~/code/VisualMesh\\ndocker run --gpus all -u $(id -u):$(id -g) -it --rm --volume $(pwd):/workspace visualmesh:latest ./mesh.py test output\\n\")), mdx(\"p\", null, \"Once the test has finished running, you can inspect the output in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"output/test/metrics\"), \".\"), mdx(\"h2\", {\n    \"id\": \"using-tensorboard-to-inspect-the-process\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#using-tensorboard-to-inspect-the-process\",\n    \"aria-label\": \"using tensorboard to inspect the process permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Using Tensorboard to inspect the process\"), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.tensorflow.org/tensorboard\"\n  }, \"Tensorboard\"), \" is a tool that provides a dashboard for visualising of the training process that runs in the browser. For tensorflow, we just pass the output directory to tensorboard: (Note: You may have to install TensorBoard separately if your TensorFlow install didn't bundle it.)\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"tensorboard --logdir output\")), mdx(\"p\", null, \"You should see something like the following:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all\\nTensorBoard 2.4.1 at http://localhost:6006/ (Press CTRL+C to quit)\\n\")), mdx(\"p\", null, \"Go to the url specified on your terminal to see the tensorboard dashboard.\"));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#clone-the-visual-mesh-repo","title":"Clone the Visual Mesh Repo"},{"url":"#build-the-docker-image","title":"Build the docker image"},{"url":"#make-a-dummy-dataset","title":"Make a dummy dataset","items":[{"url":"#install-the-prerequisites-to-make-a-tfrecord","title":"Install the prerequisites to make a tfrecord"},{"url":"#make-a-set-of-tfrecord","title":"Make a set of tfrecord"}]},{"url":"#configure-the-training","title":"Configure the training"},{"url":"#train-the-network","title":"Train the network"},{"url":"#test-the-network","title":"Test the network"},{"url":"#using-tensorboard-to-inspect-the-process","title":"Using Tensorboard to inspect the process"}]},"frontmatter":{"section":"Guides","chapter":"Tools","title":"Visual Mesh Getting Started","description":"How to get started with the Visual Mesh.","keywords":null,"slug":"/guides/tools/visualmesh","hidden":null},"childNUbookContributions":{"authors":[{"name":"Joel Wong","username":"wongjoel"}],"lastCommit":{"date":"2024-10-06T00:43:48.000Z","hash":"092ed4d086a639f36881702b6d6790285d813e52"}}}},"pageContext":{"mdxPath":"src/book/03-guides/02-tools/03-visualmesh.mdx","id":"0d51fe19-db0c-57f2-b25b-caac5bea85a6","next":{"chapter":"Tools","title":"Using NUpbr","description":"How to set up and run NUpbr","slug":"/guides/tools/nupbr-guide","hidden":null},"previous":{"chapter":"Tools","title":"Setting Up Webots","description":"Setup instructions for Webots.","slug":"/guides/tools/webots-setup","hidden":null},"menu":[{"title":"Team","slug":"/team/introduction","chapters":[{"title":"Introduction","slug":"/team/introduction","pages":[{"title":"Introduction to NUbots","slug":"/team/introduction","hidden":null},{"title":"Areas of Research","slug":"/team/areas-of-research","hidden":null},{"title":"Current Team","slug":"/team/current-members","hidden":null}],"hidden":false},{"title":"Joining the Team","slug":"/team/how-we-work","pages":[{"title":"How We Work","slug":"/team/how-we-work","hidden":null},{"title":"How to Join NUbots","slug":"/team/how-to-join","hidden":null},{"title":"Lab Induction","slug":"/team/induction","hidden":null}],"hidden":false},{"title":"Community","slug":"/team/sponsors","pages":[{"title":"Sponsors","slug":"/team/sponsors","hidden":null},{"title":"Connect","slug":"/team/connect","hidden":null}],"hidden":false},{"title":"History","slug":"/team/history","pages":[{"title":"Team History","slug":"/team/history","hidden":null},{"title":"Past Members","slug":"/team/past-members","hidden":null},{"title":"Publications","slug":"/team/publications","hidden":null}],"hidden":false},{"title":"RoboCup","slug":"/team/robocup","pages":[{"title":"RoboCup","slug":"/team/robocup","hidden":null},{"title":"Resources","slug":"/team/robocup/resources","hidden":null},{"title":"Debriefs","slug":"/team/robocup/debriefs","hidden":null}],"hidden":false}],"hidden":false},{"title":"System","slug":"/system/foundations/overview","chapters":[{"title":"Foundations","slug":"/system/foundations/overview","pages":[{"title":"Overview","slug":"/system/foundations/overview","hidden":null},{"title":"Build System","slug":"/system/foundations/build-system","hidden":null},{"title":"Continuous Integration","slug":"/system/foundations/ci-system","hidden":null},{"title":"NUClear","slug":"/system/foundations/nuclear","hidden":null},{"title":"Mathematics","slug":"/system/foundations/mathematics","hidden":null},{"title":"Configuration and Script System","slug":"/system/foundations/config-script","hidden":null},{"title":"Director","slug":"/system/foundations/director","hidden":null}],"hidden":false},{"title":"Subsystems","slug":"/system/subsystems/input","pages":[{"title":"Input","slug":"/system/subsystems/input","hidden":null},{"title":"Odometry","slug":"/system/subsystems/odometry","hidden":null},{"title":"Localisation","slug":"/system/subsystems/localisation","hidden":null},{"title":"Motion","slug":"/system/subsystems/motion","hidden":null},{"title":"Vision","slug":"/system/subsystems/vision","hidden":null},{"title":"Behaviour","slug":"/system/subsystems/behaviour","hidden":null},{"title":"Logging","slug":"/system/subsystems/logging","hidden":null}],"hidden":false},{"title":"Tools","slug":"/system/tools/nusight","pages":[{"title":"NUsight","slug":"/system/tools/nusight","hidden":null},{"title":"NUbook","slug":"/system/tools/nubook","hidden":null},{"title":"NUpbr","slug":"/system/tools/nupbr","hidden":null},{"title":"NUgan","slug":"/system/tools/nugan","hidden":null},{"title":"System Configuration","slug":"/system/tools/system_configuration","hidden":null},{"title":"NatNet SDK","slug":"/system/tools/natnet_sdk","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/system/hardware/overview","pages":[{"title":"Overview and Specifications","slug":"/system/hardware/overview","hidden":null}],"hidden":false},{"title":"Modules","slug":"/system/modules/actuation/","pages":[{"title":"Actuation","slug":"/system/modules/actuation/","hidden":null},{"title":"Extension","slug":"/system/modules/extension/","hidden":null},{"title":"Input","slug":"/system/modules/input/","hidden":null},{"title":"Localisation","slug":"/system/modules/localisation/","hidden":null},{"title":"Nbs","slug":"/system/modules/nbs/","hidden":null},{"title":"Network","slug":"/system/modules/network/","hidden":null},{"title":"Output","slug":"/system/modules/output/","hidden":null},{"title":"Planning","slug":"/system/modules/planning/","hidden":null},{"title":"Platform","slug":"/system/modules/platform/","hidden":null},{"title":"Purpose","slug":"/system/modules/purpose/","hidden":null},{"title":"Skill","slug":"/system/modules/skill/","hidden":null},{"title":"Strategy","slug":"/system/modules/strategy/","hidden":null},{"title":"Support","slug":"/system/modules/support/","hidden":null},{"title":"Tools","slug":"/system/modules/tools/","hidden":null},{"title":"Vision","slug":"/system/modules/vision/","hidden":null}],"hidden":false}],"hidden":false},{"title":"Guides","slug":"/guides/main/getting-started","chapters":[{"title":"Main Codebase","slug":"/guides/main/getting-started","pages":[{"title":"Getting Started","slug":"/guides/main/getting-started","hidden":null},{"title":"NUClear","slug":"/guides/main/nuclear-tutorial","hidden":null},{"title":"Running and Tuning Scripts","slug":"/guides/main/tuning-and-running-scripts","hidden":null},{"title":"Maintaining Subsystems","slug":"/guides/main/maintaining-subsystems","hidden":null},{"title":"Data Recording and Playback","slug":"/guides/main/data-recording-playback","hidden":null},{"title":"Camera Calibration","slug":"/guides/main/camera-calibration","hidden":null},{"title":"Onboarding Workshop","slug":"/guides/main/onboarding","hidden":null}],"hidden":false},{"title":"Tools","slug":"/guides/tools/nusight-contribution","pages":[{"title":"Contributing to NUsight","slug":"/guides/tools/nusight-contribution","hidden":null},{"title":"Setting Up Webots","slug":"/guides/tools/webots-setup","hidden":null},{"title":"Visual Mesh Getting Started","slug":"/guides/tools/visualmesh","hidden":null},{"title":"Using NUpbr","slug":"/guides/tools/nupbr-guide","hidden":null},{"title":"GameController Setup","slug":"/guides/tools/gamecontroller","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/guides/hardware/working-with-robots","pages":[{"title":"Working with Robots","slug":"/guides/hardware/working-with-robots","hidden":null},{"title":"Flashing a Robot","slug":"/guides/hardware/flashing","hidden":null},{"title":"Servo Setup and Calibration","slug":"/guides/hardware/servo-calibration","hidden":null},{"title":"Batteries","slug":"/guides/hardware/batteries","hidden":null},{"title":"DARwIn Op2 Robot Restoration and Calibration Guide","slug":"/guides/hardware/darwin-op2-guide","hidden":null}],"hidden":false},{"title":"General","slug":"/guides/general/learning-resources","pages":[{"title":"Learning Resources","slug":"/guides/general/learning-resources","hidden":null},{"title":"Contribution Workflow","slug":"/guides/general/contribute","hidden":null},{"title":"RoboCup Setup","slug":"/guides/general/robocup-setup","hidden":null},{"title":"Troubleshooting","slug":"/guides/general/troubleshooting","hidden":null},{"title":"Code Conventions","slug":"/guides/general/code-conventions","hidden":null},{"title":"Glossary","slug":"/guides/general/glossary","hidden":null}],"hidden":false}],"hidden":false},{"title":"Kitchen Sink","slug":"/kitchen-sink/headers","chapters":[{"title":"Markdown","slug":"/kitchen-sink/headers","pages":[{"title":"Headers","slug":"/kitchen-sink/headers","hidden":true},{"title":"Formatting and Paragraphs","slug":"/kitchen-sink/formatting-and-paragraphs","hidden":true},{"title":"Blockquotes","slug":"/kitchen-sink/blockquotes","hidden":true},{"title":"Alerts","slug":"/kitchen-sink/alerts","hidden":true},{"title":"Images","slug":"/kitchen-sink/images","hidden":true},{"title":"Lists","slug":"/kitchen-sink/lists","hidden":true},{"title":"Code","slug":"/kitchen-sink/code","hidden":true},{"title":"Math","slug":"/kitchen-sink/math","hidden":true},{"title":"Table of Contents","slug":"/kitchen-sink/table-of-contents","hidden":true},{"title":"Tables","slug":"/kitchen-sink/tables","hidden":true},{"title":"Collapsible Content","slug":"/kitchen-sink/collapsible","hidden":true},{"title":"GraphViz Diagrams","slug":"/kitchen-sink/graphviz-diagrams","hidden":true},{"title":"Referencing","slug":"/kitchen-sink/referencing","hidden":true}],"hidden":true}],"hidden":true}],"references":null,"hidden":null}},
    "staticQueryHashes": ["3715292327","445096115","466146812"]}