<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tryolabs</title>
    <description>The latest articles on DEV Community by Tryolabs (@tryolabs).</description>
    <link>https://dev.to/tryolabs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F74572%2F2c5840af-e13e-430b-bd51-90db0b8fa2cc.jpg</url>
      <title>DEV Community: Tryolabs</title>
      <link>https://dev.to/tryolabs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tryolabs"/>
    <language>en</language>
    <item>
      <title>Benchmarking Machine Learning Edge Devices</title>
      <dc:creator>Tryolabs</dc:creator>
      <pubDate>Tue, 15 Oct 2019 20:32:11 +0000</pubDate>
      <link>https://dev.to/tryolabs/benchmarking-machine-learning-edge-devices-2fha</link>
      <guid>https://dev.to/tryolabs/benchmarking-machine-learning-edge-devices-2fha</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published &lt;a href="https://tryolabs.com/blog/machine-learning-on-edge-devices-benchmark-report"&gt;here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why edge computing?
&lt;/h2&gt;

&lt;p&gt;Humans are generating and &lt;strong&gt;collecting more data than ever&lt;/strong&gt;. We have devices in our pockets that facilitate the creation of huge amounts of data, such as photos, gps coordinates, audio, and all kinds of personal information we consciously and unconsciously reveal.&lt;/p&gt;

&lt;p&gt;Moreover, not only are we individuals generating data for personal reasons, but we’re also collecting data unbeknownst to us from traffic and mobility control systems, video surveillance units, satellites, smart cars, and an infinite array of smart devices.&lt;/p&gt;

&lt;p&gt;This trend is here to stay and will continue to rise exponentially. In terms of data points, the &lt;a href="https://www.forbes.com/sites/tomcoughlin/2018/11/27/175-zettabytes-by-2025/#6c72772d5459"&gt;International Data Corporation (IDC)&lt;/a&gt; predicts that the collective sum of the world’s data will grow from 33 zettabytes (ZB) in 2019 to 175 ZB by 2025, an &lt;strong&gt;annual growth rate of 61%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While we’ve been processing data, first in data centers and then in the cloud, these solutions are not suitable for highly demanding tasks with large data volumes. &lt;strong&gt;Network capacity and speed are pushed to the limit&lt;/strong&gt; and new solutions are required. This is the beginning of the era of edge computing and &lt;strong&gt;edge devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://tryolabs.com/blog/machine-learning-on-edge-devices-benchmark-report/#results-analysis"&gt;this report&lt;/a&gt;, we'll &lt;strong&gt;benchmark five novel edge devices&lt;/strong&gt;, using different frameworks and models, to see which combinations perform best. In particular, we'll focus on performance outcomes for &lt;strong&gt;machine learning on the edge&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to jump directly to the performance outcomes? See the results in the interactive dashboard in &lt;a href="https://tryolabs.com/blog/machine-learning-on-edge-devices-benchmark-report/#results-analysis"&gt;this interactive benchmark report&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is edge computing?
&lt;/h2&gt;

&lt;p&gt;Edge computing consists of delegating data processing tasks to devices on the edge of the network, as close as possible to the data sources. This enables real-time data processing at a very high speed, which is a must for complex IoT solutions with machine learning capabilities. On top of that, it mitigates network limitations, reduces energy consumption, increases security, and improves data privacy.&lt;/p&gt;

&lt;p&gt;Under this new paradigm, the combination of specialized hardware and software libraries optimized for machine learning on the edge results in cutting-edge applications and products ready for mass deployment.&lt;/p&gt;

&lt;p&gt;The biggest challenges to building these amazing applications are posed by audio, video, and &lt;a href="https://tryolabs.com/resources/introductory-guide-computer-vision/#distinguishing-computer-vision-from-related-fields"&gt;image processing&lt;/a&gt; tasks. &lt;a href="https://tryolabs.com/blog/2018/12/19/major-advancements-deep-learning-2018/"&gt;Deep learning techniques&lt;/a&gt; have proven to be highly successful in overcoming these difficulties.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling deep learning on the edge
&lt;/h2&gt;

&lt;p&gt;As an example, let’s take self-driving cars. Here, you need to quickly and consistently analyze incoming data, in order to &lt;a href="https://blogs.nvidia.com/blog/2019/05/07/self-driving-cars-make-decisions/"&gt;decipher the world around you and take action within a few milliseconds&lt;/a&gt;. Addressing that time constraint is why we cannot rely on the cloud to process the stream of data but instead must do it locally.&lt;/p&gt;

&lt;p&gt;The downside of doing it locally is that the hardware is not as powerful as a super computer in the cloud, and we cannot compromise on accuracy or speed.&lt;/p&gt;

&lt;p&gt;The solution to this is either stronger, more efficient hardware, or less complex deep neural networks. To obtain the best results, a balance of the two is essential.&lt;/p&gt;

&lt;p&gt;Therefore, the real question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which edge hardware and what type of network should we bring together in order to maximize the accuracy and speed of deep learning algorithms?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our quest to identify the optimal combination of the two, we compared several state-of-the-art edge devices in combination with different deep neural network models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking novel edge devices
&lt;/h2&gt;

&lt;p&gt;Based on what we think is the most innovative use case, we set out to measure inference throughput in real-time via a one-at-a-time image classification task, so as to get an approximate frames-per-second score.&lt;/p&gt;

&lt;p&gt;To accomplish this, we evaluated top-1 inference accuracy across all categories of a specific subset of &lt;a href="https://github.com/modestyachts/ImageNetV2"&gt;ImagenetV2&lt;/a&gt; comparing them to some &lt;a href="http://cs231n.github.io/convolutional-networks/"&gt;ConvNets&lt;/a&gt; models and, when possible, using different frameworks and optimized versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware accelerators
&lt;/h3&gt;

&lt;p&gt;While there has been much effort invested over the last few years to improve existing edge hardware, we chose to experiment with these edge devices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.nvidia.com/embedded/jetson-nano-developer-kit"&gt;Nvidia Jetson Nano&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://coral.withgoogle.com/products/dev-board/"&gt;Google Coral Dev Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://software.intel.com/en-us/neural-compute-stick"&gt;Intel Neural Compute Stick&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/"&gt;Raspberry Pi&lt;/a&gt; (upper bound reference)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.nvidia.com/en-us/geforce/graphics-cards/rtx-2080-ti/"&gt;2080ti NVIDIA GPU&lt;/a&gt; (lower bound reference)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We included the Raspberry Pi and the Nvidia 2080ti so as to be able to compare the tested hardware against well-known systems, one cloud-based and one edge-based.&lt;/p&gt;

&lt;p&gt;The lower bound was a no-brainer. At &lt;a href="https://tryolabs.com/"&gt;Tryolabs&lt;/a&gt;, we design and train our own deep learning models. Because of this, we have a lot of computing power at our disposal. So, we used it. To set this lower bound on inference times, we ran the tests on a 2080ti NVIDIA GPU. However, because we were only going to use it as a reference point, we ran the tests using basic models, with no optimizations.&lt;/p&gt;

&lt;p&gt;For the upper bound, we went with the defending champion, the most popular single-board computer: the &lt;a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b/"&gt;Raspberry Pi 3B&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Neural network models
&lt;/h3&gt;

&lt;p&gt;There are two main networks we wanted to include in this benchmark: the old, well-known, seasoned &lt;a href="https://arxiv.org/abs/1512.03385"&gt;Resnet-50&lt;/a&gt; and the novel &lt;a href="https://ai.googleblog.com/2019/05/efficientnet-improving-accuracy-and.html"&gt;EfficientNets&lt;/a&gt; released by Google this year. &lt;/p&gt;

&lt;p&gt;For all benchmarks, we used publicly available pre-trained models, which we run with different frameworks. With respect to the Nvidia Jetson, we tried the &lt;a href="https://developer.nvidia.com/tensorrt"&gt;TensorRT&lt;/a&gt; optimization; for the Raspberry, we used &lt;a href="https://www.tensorflow.org"&gt;Tensor Flow&lt;/a&gt; and &lt;a href="https://pytorch.org"&gt;PyTorch&lt;/a&gt; variants; while for Coral devices, we implemented the Edge TPU engine versions of the S, M, and L EfficientNets models; and finally, regarding Intel devices, we used the Resnet-50 compiled with &lt;a href="https://docs.openvinotoolkit.org"&gt;OpenVINO&lt;/a&gt; Toolkit.&lt;/p&gt;

&lt;h3&gt;
  
  
  The dataset
&lt;/h3&gt;

&lt;p&gt;Because all models were trained on an &lt;a href="http://people.csail.mit.edu/ludwigs/papers/imagenet.pdf"&gt;ImageNet&lt;/a&gt; dataset, we use &lt;a href="https://github.com/modestyachts/ImageNetV2"&gt;ImageNet V2&lt;/a&gt; MatchedFrequency. It consists of 10,000 images in 1,000 categories.&lt;/p&gt;

&lt;p&gt;We ran the inference on each image once, saved the inference time, and then found the average. We calculated the &lt;em&gt;top-1 accuracy&lt;/em&gt; from all tests, as well as the &lt;em&gt;top-5 accuracy&lt;/em&gt; for certain models.&lt;/p&gt;

&lt;p&gt;Top-1 accuracy: this is conventional accuracy, meaning that the model’s answer (the one with the highest probability) must equal the exact expected answer.&lt;/p&gt;

&lt;p&gt;Top-5 accuracy: means that &lt;em&gt;any&lt;/em&gt; one of the model’s top five highest-probability answers must match the expected answer.&lt;/p&gt;

&lt;p&gt;Something to keep in mind when comparing the results: for fast device-model combinations, we ran the tests incorporating the entire dataset, whereas we only used parts of datasets for the slower combinations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results &amp;amp; analysis
&lt;/h2&gt;

&lt;p&gt;The interactive dashboards display the metrics obtained from the experiments. Due to the large difference in inference times across models and devices, the parameters are shown in logarithmic scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tryolabs.com/blog/machine-learning-on-edge-devices-benchmark-report/#results-analysis"&gt;GO TO DASHBOARDS&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>edgecomputing</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>How we used IoT and computer vision to build a stand-in robot for remote workers</title>
      <dc:creator>Tryolabs</dc:creator>
      <pubDate>Thu, 13 Dec 2018 15:52:18 +0000</pubDate>
      <link>https://dev.to/tryolabs/how-we-built-a-stand-in-robot-for-remote-workers-using-iot-and-computer-vision-350b</link>
      <guid>https://dev.to/tryolabs/how-we-built-a-stand-in-robot-for-remote-workers-using-iot-and-computer-vision-350b</guid>
      <description>&lt;p&gt;&lt;em&gt;By Lucas Micol. The article has originally been published &lt;a href="https://tryolabs.com/blog/hackathon-robot-remote-work-iot-computer-vision/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With clients and partners located around the globe, we've always had a culture of remote collaboration here at Tryolabs. We are used to joining meetings no matter where we are, using tools such as &lt;a href="https://slack.com/" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;, &lt;a href="https://hangouts.google.com/webchat/start" rel="noopener noreferrer"&gt;Google Hangouts&lt;/a&gt;, and &lt;a href="https://zoom.us/" rel="noopener noreferrer"&gt;Zoom&lt;/a&gt;. A sweet consequence of this is a generous work from home policy, allowing us to work from home whenever we want.&lt;/p&gt;

&lt;p&gt;Trouble is, working remotely leads to us missing out on all the fun that takes place outside of meetings when we’re not connected. Wouldn’t it be cool to have a robot representing us at the office, showing us what goes on while we’re not there?&lt;/p&gt;

&lt;p&gt;As a group of computer vision, IoT, and full-stack specialists, we got really enthusiastic about the idea and went on a mission to create a robot that could be remotely controlled from home and show us what takes place at the office.&lt;/p&gt;

&lt;p&gt;We spent the 2018 edition of the Tryolabs Hackathon facing that challenge with only three rules in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;⏰ Hours to complete the project: 48&lt;/li&gt;
&lt;li&gt;👫 Number of team members: 4&lt;/li&gt;
&lt;li&gt;☕️ Coffee provided: Unlimited&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fid9qrvvxuhmu5c689gvp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fid9qrvvxuhmu5c689gvp.jpg" alt="Hackathon team: Joaquín, Braulio, Javier and Lucas."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Hackathon team: Joaquín, Braulio, Javier and Lucas.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the hardware of a mini-robot
&lt;/h2&gt;

&lt;p&gt;It all started with the design of the mini-robot’s mechanical structure, which is present at the office while the remote worker isn't.&lt;/p&gt;

&lt;p&gt;To have a robot that can easily move around the office, it must be mobile, stable, small enough to pass through doors, and big enough to not be overseen and trampled on by the team working at the office.&lt;/p&gt;

&lt;p&gt;We went through several iterations of its structural design before settling on this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5zsada03krxrn07lbe1b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5zsada03krxrn07lbe1b.jpg" alt="Sketch drawn during hackathon to define main hardware components of the robot and its communication with the remote worker."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Sketch drawn during hackathon to define main hardware components of the robot and its communication with the remote worker.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We chose aluminum as the main material for the components since it's light, robust, and cheap.&lt;/p&gt;

&lt;p&gt;Once we defined the design and selected the materials, we cut the aluminum parts and put them together with small screws. Since we had to work with the tools available at the office and from the store around the corner, this was a rather improvised and humorous process. We used heavy books to shape the aluminum and sunglasses as safety glasses while drilling into the components, just to give you an idea. 🙈&lt;/p&gt;

&lt;p&gt;The main hardware components we settled on were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layers of aluminum sheets to build the structural backbone&lt;/li&gt;
&lt;li&gt;Screws&lt;/li&gt;
&lt;li&gt;RaspberryPi&lt;/li&gt;
&lt;li&gt;PiCamera&lt;/li&gt;
&lt;li&gt;1 Servo motor SG90&lt;/li&gt;
&lt;li&gt;H-bridge to control the motors&lt;/li&gt;
&lt;li&gt;2 DC motors&lt;/li&gt;
&lt;li&gt;2 wheels&lt;/li&gt;
&lt;li&gt;Swivel Casters&lt;/li&gt;
&lt;li&gt;Wire&lt;/li&gt;
&lt;li&gt;PowerBank&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enabling the robot to communicate in real-time
&lt;/h2&gt;

&lt;p&gt;While some of us continued working on the hardware and assembling the pieces, the rest of the team started building the software that would control all the components mentioned above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing WebRTC
&lt;/h3&gt;

&lt;p&gt;The aim of the robot's software was to enable real-time communication between the remote workers and the teams at the office. In other words, the robot needed to be able to transmit video and audio from the office to the people working remotely and vice versa.&lt;/p&gt;

&lt;p&gt;While evaluating various approaches to solving this problem, we came across &lt;a href="https://webrtc.org/" rel="noopener noreferrer"&gt;WebRTC&lt;/a&gt;, which promised to be the tool we were looking for: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WebRTC is ideal for telepresence, intercom, VoIP software in general as it has a very powerful standard and modern protocol which has a number of features and is compatible with various browsers, including Firefox, Chrome, Opera, etc.&lt;/p&gt;

&lt;p&gt;The WebRTC extension for the UV4L Streaming Server allows for streaming of multimedia content from audio, video, and data sources in real-time as defined by the WebRTC protocol.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Specifically, we used the &lt;a href="https://www.linux-projects.org/uv4l/webrtc-extension/" rel="noopener noreferrer"&gt;WebRTC extension&lt;/a&gt; included in &lt;a href="https://www.linux-projects.org/uv4l/" rel="noopener noreferrer"&gt;UV4L&lt;/a&gt;. This tool allowed us to create bidirectional communication with extremely low latency between the robot and the remote worker’s computer.&lt;/p&gt;

&lt;p&gt;Running the UV4L server with the WebRTC extension enabled, we were able to serve a web app from the RaspberryPi, then simply access it from the remote worker’s browser establishing real-time bidirectional communication; amazing!&lt;/p&gt;

&lt;p&gt;This allowed us to set up a unidirectional channel for the video from the PiCamera to the browser, a bidirectional channel for the audio, and an extra unidirectional channel to send the commands from the browser to the robot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building a UI to manage communication
&lt;/h3&gt;

&lt;p&gt;To be able to see the data and send the commands in a user-friendly way for the remote worker, we researched how to integrate those functionalities into an accessible and practical front-end.&lt;/p&gt;

&lt;p&gt;Inspired by the &lt;a href="https://www.linux-projects.org/uv4l/tutorials/custom-webapp-with-face-detection/" rel="noopener noreferrer"&gt;web app example&lt;/a&gt; from the UV4L project, we integrated the data channels mentioned above into a basic but functional front-end, including the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;index.html:&lt;/em&gt; the HTML5 page, which contains the UI elements (mainly &lt;em&gt;video)&lt;/em&gt; to show the incoming streaming and *&lt;em&gt;the *canvas&lt;/em&gt; to show the pose estimation key-points&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;main.js:&lt;/em&gt; defines the callbacks triggered by user actions like “start streaming”, "load net", "toggle pose estimation", etc&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;signalling.js:&lt;/em&gt; implements the &lt;a href="https://www.linux-projects.org/webrtc-signalling/" rel="noopener noreferrer"&gt;WebRTC signaling protocol over WebSocket&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ecI1tK6ILns"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Time lapse shot during the hackathon.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Remotely control the robot's movements
&lt;/h2&gt;

&lt;p&gt;To handle the movement commands the robot would receive from the remote worker, we developed a controller written in Python, that runs like a system service. This service translates commands that control the robot’s motors by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting the pins, connected to the H-bridge wheel motors, to &lt;a href="https://learn.sparkfun.com/tutorials/raspberry-gpio/python-rpigpio-api" rel="noopener noreferrer"&gt;high or low&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Establishing the &lt;a href="http://abyz.me.uk/rpi/pigpio/python.html#hardware_PWM" rel="noopener noreferrer"&gt;PWM frequency and duty-cycle&lt;/a&gt; for the Servo, which adjusts the PiCamera's orientation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a snippet of the controller classes: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MotorsWheels:

    def __init__(
            self, r_wheel_forward=6, r_wheel_backward=13, l_wheel_forward=19, l_wheel_backward=26):
                self.r_wheel_forward = r_wheel_forward
                ...
                GPIO.setmode(GPIO.BCM)
        GPIO.setup(r_wheel_forward, GPIO.OUT)
                GPIO.setup(r_wheel_backward, GPIO.OUT)
                ...
                # Turn all motors off
        GPIO.output(r_wheel_forward, GPIO.LOW)
        GPIO.output(r_wheel_backward, GPIO.LOW)

    def _spin_right_wheel_forward(self):
        GPIO.output(self.r_wheel_forward, GPIO.HIGH)
        GPIO.output(self.r_wheel_backward, GPIO.LOW)

    def _stop_right_wheel(self):
        GPIO.output(self.r_wheel_backward, GPIO.LOW)
        GPIO.output(self.r_wheel_forward, GPIO.LOW)

    def go_fw(self):
        self._spin_left_wheel_forward()
        self._spin_right_wheel_forward()

class ServoCamera:
    CENTER = 40000
    UP_LIMIT = 80000
    DOWN_LIMIT = 30000
    STEP = 5000

    def __init__(self, servo=18, freq=50):
        self.servo = servo
        self.freq = freq
        self.pi = pigpio.pi()

        self.angle = self.CENTER
        self._set_angle()

    def _set_angle(self):
        self.pi.hardware_PWM(self.servo, self.freq, self.angle)

    def up(self):
        if self.angle + self.STEP &amp;lt; self.UP_LIMIT:
            self.angle += self.STEP
            self._set_angle()

    def down(self):
        if self.angle - self.STEP &amp;gt; self.DOWN_LIMIT:
            self.angle -= self.STEP
            self._set_angle()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As a result, we were able to control the robot, “walk” it through the office, and enable remote workers to see their teams and approach them via the robot.&lt;/p&gt;

&lt;p&gt;However, it wasn’t enough for our enthusiastic team and we continued to pursue the ultimate goal: having an autonomous robot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding computer vision to the robot
&lt;/h2&gt;

&lt;p&gt;We thought, wouldn't it be awesome if the robot could recognize people and react to their gestures and actions (and in this way have a certain amount of personality)?&lt;/p&gt;

&lt;p&gt;A recently released project called &lt;a href="https://github.com/tensorflow/tfjs-models/tree/master/posenet" rel="noopener noreferrer"&gt;PoseNet&lt;/a&gt; surfaced fast. It’s presented as a &lt;a href="https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5" rel="noopener noreferrer"&gt;"machine learning model, which allows for real-time human pose estimation in the browser"&lt;/a&gt;. So, we dug deeper into that.&lt;/p&gt;

&lt;p&gt;The performance of that neural net was astounding and it was really attractive as we ran it over TensorFlowJS in the browser. This way, we were able to get a higher accuracy and FPS rate than by running it from the RaspberryPi, and also less latency than if we had run it on a third server instead.&lt;/p&gt;

&lt;p&gt;Rushed by the parameters of the hackathon, we skimmed the project’s documentation and &lt;a href="https://storage.googleapis.com/tfjs-models/demos/posenet/camera.html" rel="noopener noreferrer"&gt;demo web app&lt;/a&gt; source code. Once we identified which files we were going to need, we imported them and immediately jumped to integrating these functionalities into our web app.&lt;/p&gt;

&lt;p&gt;We wrote a basic &lt;code&gt;detectBody&lt;/code&gt; function to infer the pose estimation key points that invoked the&lt;code&gt;net.estimateMultiplePoses&lt;/code&gt; with these params:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function detectBody(canvas, net) {
    if (net){
        var ctx = canvas.getContext('2d');
        var imageElement = ctx.getImageData(0, 0, canvas.width, canvas.height);

        var imageScaleFactor = 0.3;
        var flipHorizontal = false;
        var outputStride = 16;
        var maxPoseDetections = 2;
        var poses = await net.estimateMultiplePoses(
            imageElement,
            imageScaleFactor,
            flipHorizontal,
            outputStride,
            maxPoseDetections
        )
        return poses;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Said &lt;code&gt;detectBody&lt;/code&gt; was invoked at a rate of 3 times per second to refresh the pose estimation key points.&lt;/p&gt;

&lt;p&gt;Then, we adapted some util functions in order to print the detected body key points and plot its skeleton above the video, arriving at a demo like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3DhSR67Uj4Q"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Soledad and Lucas showing off pose detection algorithm.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was a very quick proof of concept which added a wonderful feature and hugely expanded the potential capabilities of our robot.&lt;/p&gt;

&lt;p&gt;If you’d like to know how this model works under the hood, you can read more &lt;a href="https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;48 hours and an unknown amount of coffee led to the construction of a mini-robot with the ability to walk through the office, enable real-time communication between the remote worker and their office mates, and even transport an LP. 😜&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ujTBNP5BuRQ"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Stand-in robot walking through the office, controlled by a remote worker.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/lKbGat8Bfus"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Interface that shows the remote worker in a browser how the robot is controlled.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We managed to build the hardware, implement the communication software, and build a PoC for an additional feature using computer vision, which facilitates the robot's interaction with people. Future enhancements could include &lt;a href="https://tryolabs.com/blog/2017/08/30/object-detection-an-overview-in-the-age-of-deep-learning/" rel="noopener noreferrer"&gt;object detection&lt;/a&gt; features that would allow the robot to recognize objects and interact with them without human help using &lt;a href="https://github.com/tryolabs/luminoth" rel="noopener noreferrer"&gt;Luminoth&lt;/a&gt;, our open source toolkit for computer vision, for example.&lt;/p&gt;

&lt;p&gt;Though we normally prototype for longer than two days, this hackathon project reflects how we work at Tryolabs. We often build prototypes and solutions with state-of-the-art technologies to enhance operational and organizational processes.&lt;/p&gt;

&lt;p&gt;Thinking of a robot for your business? &lt;a href="https://tryolabs.com/" rel="noopener noreferrer"&gt;Get in touch with us!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>computervision</category>
      <category>iot</category>
      <category>remotework</category>
    </item>
    <item>
      <title>Getting Started with AWS: Open Source Workshop</title>
      <dc:creator>Tryolabs</dc:creator>
      <pubDate>Tue, 10 Jul 2018 15:11:00 +0000</pubDate>
      <link>https://dev.to/tryolabs/getting-started-with-aws-open-source-workshop-757</link>
      <guid>https://dev.to/tryolabs/getting-started-with-aws-open-source-workshop-757</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of our strengths at &lt;a href="https://tryolabs.com/"&gt;Tryolabs&lt;/a&gt; is that we have people coming from diverse technological backgrounds. In order to make sure that everyone who joins the company, no matter their previous experience, can be up to speed with developing apps with the stack we usually use, we have an extensive onboarding process that involves the development of a real application (frontend, backend and some data science), with a coach, code reviews, and iterative improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why using cloud services?
&lt;/h2&gt;

&lt;p&gt;An interesting skill that sometimes is neglected (especially with junior devs) is how to put apps into production in a robust and scalable way. It is desirable that our apps are highly available (meaning they are very rarely &lt;em&gt;down&lt;/em&gt;), and have mechanisms so they can tolerate load of concurrent users without crashing or slowing down.&lt;/p&gt;

&lt;p&gt;For doing this, we use cloud providers, such as &lt;a href="https://aws.amazon.com/"&gt;Amazon Web Services (AWS) &lt;/a&gt;, &lt;a href="https://cloud.google.com/"&gt;Google Cloud Platform&lt;/a&gt; or &lt;a href="https://azure.microsoft.com/"&gt;Microsoft Azure&lt;/a&gt;. Eeach provider offers its own services to make the deployment of our apps easier. Some, for example, offer different types of databases as a service, so we don't need to handle database administration or scaling. Scalable file storage solutions are very common, too.&lt;/p&gt;

&lt;p&gt;It is interesting to note that the services offered by these cloud providers can affect the design (e.g. the database you use) of your app. Very scalable apps that some years ago were very difficult to develop are now almost trivial to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started with AWS?
&lt;/h2&gt;

&lt;p&gt;So, given the importance of cloud providers and AWS in particular, we've created – and are now open sourcing – a guide we call &lt;a href="https://github.com/tryolabs/aws-workshop"&gt;AWS Workshop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this workshop, a developer learns how to deploy a demo application using several services available in the AWS stack. As the demo app to be deployed, we chose an open source test application called Conduit, which is handy to learn new frameworks because the same app has implementations in multiple frameworks for backend and frontend. In particular, we use the version built with&lt;a href="https://reactjs.org/"&gt; React&lt;/a&gt; and &lt;a href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt; + &lt;a href="http://www.django-rest-framework.org/"&gt;Django-Rest-Framework&lt;/a&gt; backend, which most resembles the technologies we use for several of our projects.&lt;/p&gt;

&lt;p&gt;In the workshop, developers learn:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up users in your AWS account.&lt;/li&gt;
&lt;li&gt;Deploying a website on&lt;a href="https://aws.amazon.com/s3/"&gt; S3&lt;/a&gt;, a backend in&lt;a href="https://aws.amazon.com/ec2/"&gt; EC2&lt;/a&gt; and a database in &lt;a href="https://aws.amazon.com/rds/"&gt;RDS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Setting up &lt;a href="https://aws.amazon.com/elasticloadbalancing/"&gt;Load Balancing&lt;/a&gt; and &lt;a href="https://aws.amazon.com/autoscaling/"&gt;Auto Scaling Groups&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Setting up a &lt;a href="https://aws.amazon.com/vpc/"&gt;VPC&lt;/a&gt; and a &lt;a href="https://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html"&gt;bastion instance&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Deploying the application using &lt;a href="https://aws.amazon.com/elasticbeanstalk/"&gt;Elastic Beanstalk&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Are you new to AWS and want to use its essential services to deploy your app? Get started with the open source workshop right &lt;a href="https://github.com/tryolabs/aws-workshop"&gt;here&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the future, we'll add other services such as a deployment using&lt;a href="https://aws.amazon.com/lambda/"&gt; AWS Lambda&lt;/a&gt; (pull requests are welcome!)&lt;/p&gt;

&lt;p&gt;This article was originally published &lt;a href="https://tryolabs.com/blog/2018/06/21/getting-started-with-aws-open-source-workshop/"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>deployment</category>
      <category>workshop</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Luminoth 0.1: Open source Computer Vision toolkit</title>
      <dc:creator>Tryolabs</dc:creator>
      <pubDate>Mon, 28 May 2018 21:00:51 +0000</pubDate>
      <link>https://dev.to/tryolabs/luminoth-open-source-computer-vision-toolkit-4dhe</link>
      <guid>https://dev.to/tryolabs/luminoth-open-source-computer-vision-toolkit-4dhe</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/tryolabs/luminoth" rel="noopener noreferrer"&gt;Luminoth&lt;/a&gt; is an open-source computer vision toolkit, built upon Tensorflow and Sonnet. We just released a new version, so this is a good time as any to dive into it!&lt;/p&gt;

&lt;p&gt;Version 0.1 brings several very exciting improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An &lt;strong&gt;implementation of the &lt;a href="https://arxiv.org/abs/1512.02325" rel="noopener noreferrer"&gt;Single Shot Multibox Detector (SSD)&lt;/a&gt; model&lt;/strong&gt; was added, a much faster (although less accurate) object detector than the already-included &lt;a href="https://arxiv.org/abs/1506.01497" rel="noopener noreferrer"&gt;Faster R-CNN&lt;/a&gt;. This allows performing object detection in real-time on most modern GPUs, allowing the processing of, for instance, video streams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some &lt;strong&gt;tweaks to the Faster R-CNN model&lt;/strong&gt;, as well as a new base configuration, making it reach results comparable to other existing implementations when training on the COCO and Pascal datasets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Checkpoints for both SSD and Faster R-CNN models&lt;/strong&gt; are now provided, trained on the Pascal and COCO datasets, respectively, and providing state-of-the-art results. This makes performing object detection in an image extremely straightforward, as these checkpoints will be downloaded automatically by the library, even when just using the command-line interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;General &lt;strong&gt;usability improvements&lt;/strong&gt;, such as a cleaner command-line interface for most commands, as well as supporting videos on prediction, and a redesign of the included web frontend to easily play around with the models.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll now explore each of these features through examples, by incrementally&lt;br&gt;
building our own detector.&lt;/p&gt;
&lt;h2&gt;
  
  
  First things first: testing it out
&lt;/h2&gt;

&lt;p&gt;First of all, of course, we should install Luminoth. Inside your virtualenv,&lt;br&gt;
run:&lt;/p&gt;

&lt;pre&gt;&lt;span&gt;&lt;code&gt;$ pip install luminoth&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
(N.B.: If you have a GPU available and want to use it, run `pip install tensorflow-gpu` first, and then the above command.)
&lt;/p&gt;
&lt;p&gt;
Since the addition of the checkpoint functionality, we now offer pre-trained models for both Faster R-CNN and SSD out of the box. Effectively, this means that by issuing a couple commands, you can download a fully-trained object detection model for your use. Let’s start by refreshing the checkpoint
repository using Luminoth’s CLI tool, &lt;code&gt;lumi&lt;code&gt;:

&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;$ lumi checkpoint refresh
Retrieving remote index... done.
2 new remote checkpoints added.
$ lumi checkpoint list&lt;br&gt;
================================================================================&lt;br&gt;
|           id |                  name |       alias | source |         status |&lt;br&gt;
================================================================================&lt;br&gt;
| 48ed2350f5b2 |   Faster R-CNN w/COCO |    accurate | remote | NOT_DOWNLOADED |&lt;br&gt;
| e3256ffb7e29 |      SSD w/Pascal VOC |        fast |  local | NOT_DOWNLOADED |
================================================================================

&lt;/pre&gt;
&lt;p&gt;The output shows all the available pre-trained checkpoints. Each checkpoint is identified with the &lt;code&gt;id&lt;/code&gt; field (in this example, &lt;code&gt;48ed2350f5b2&lt;/code&gt; and &lt;code&gt;e3256ffb7e29&lt;/code&gt;) and with a possible &lt;code&gt;alias&lt;/code&gt; (e.g., &lt;code&gt;accurate&lt;/code&gt; and &lt;code&gt;fast&lt;/code&gt;). You can check other information with the command &lt;code&gt;lumi checkpoint detail &amp;lt;checkpoint_id_or_alias&amp;gt;&lt;/code&gt;. We're going to try out the Faster R-CNN checkpoint, so we'll download it (by using the alias instead of the ID) and then use the &lt;code&gt;lumi predict&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;$ lumi checkpoint download accurate&lt;br&gt;
Downloading checkpoint...  [####################################]  100%&lt;br&gt;
Importing checkpoint... done.
Checkpoint imported successfully.
$ lumi predict image.png
Found 1 files to predict.
Neither checkpoint not config specified, assuming `accurate`.
Predicting image.jpg... done.
{
  "file": "image.jpg",
  "objects": [
    {"bbox": [294, 231, 468, 536], "label": "person", "prob": 0.9997},
    {"bbox": [494, 289, 578, 439], "label": "person", "prob": 0.9971},
    {"bbox": [727, 303, 800, 465], "label": "person", "prob": 0.997},
    {"bbox": [555, 315, 652, 560], "label": "person", "prob": 0.9965},
    {"bbox": [569, 425, 636, 600], "label": "bicycle", "prob": 0.9934},
    {"bbox": [326, 410, 426, 582], "label": "bicycle", "prob": 0.9933},
    {"bbox": [744, 380, 784, 482], "label": "bicycle", "prob": 0.9334},
    {"bbox": [506, 360, 565, 480], "label": "bicycle", "prob": 0.8724},
    {"bbox": [848, 319, 858, 342], "label": "person", "prob": 0.8142},
    {"bbox": [534, 298, 633, 473], "label": "person", "prob": 0.4089}
  ]
}&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;lumi predict&lt;/code&gt; command defaults to using the checkpoint with alias &lt;code&gt;accurate&lt;/code&gt;, but we could specify otherwise using the option &lt;code&gt;--checkpoint=&amp;lt;alias_or_id&amp;gt;&lt;/code&gt;. After about 30 seconds on a modern CPU, here is the output:

&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faqtczuhu3lgjoanj2gya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faqtczuhu3lgjoanj2gya.png" title="People and bikes detected with the Faster R-CNN model."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also write the JSON output to a file (through the &lt;code&gt;--output&lt;/code&gt; or &lt;code&gt;-f&lt;/code&gt; option) and make Luminoth store the image with the bounding boxes drawn (through the &lt;code&gt;--save-media-to&lt;/code&gt; or the &lt;code&gt;-d&lt;/code&gt; option).&lt;/p&gt;
&lt;h2&gt;
  
  
  Now in real-time!
&lt;/h2&gt;

&lt;p&gt;Unless you’re reading this several years into the future (hello from the past!),&lt;br&gt;
you probably noticed Faster R-CNN took quite a while to detect the objects in the image. That is because this model favors prediction accuracy over computational efficiency, so it’s not really feasible to use it, e.g., for real-time processing of videos (especially if you’re not in possession of modern hardware): even on a pretty fast GPU, Faster R-CNN won’t do more than 2-5 images per second.&lt;/p&gt;

&lt;p&gt;Enter SSD, the single-shot multibox detector. This model provides a lower accuracy (which accentuates with the more classes you want to detect) while being, well, much faster. On the same GPU you get a couple images per second on Faster, SSD will achieve around 60 images per second, making it much more suitable for running over video streams or just videos in general.&lt;/p&gt;

&lt;p&gt;Let’s do just that, then! Run the &lt;code&gt;lumi predict&lt;/code&gt; again, but this time using the &lt;code&gt;fast&lt;/code&gt; checkpoint. Also, notice how we didn’t download it beforehand; the CLI will notice that and look for it in the remote repository.&lt;/p&gt;

&lt;pre&gt;$ lumi predict video.mp4 --checkpoint=fast --save-media-to=.
Found 1 files to predict.
Predicting video.mp4  [####################################]  100%     fps: 45.9&lt;/pre&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxowsrbzctqaqoiqkkun4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxowsrbzctqaqoiqkkun4.gif" alt="SSD model applied to dog playing fetch."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's, much faster! The command will generate a video by running SSD on a frame-by-frame basis, so no fancy temporal-prediction models (at least for now). In practice, this means you’ll probably see some jittering in the boxes, as well as some predictions appearing and disappearing out of nowhere, but nothing some post-processing can’t fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  And of course, train your own
&lt;/h2&gt;

&lt;p&gt;Say you just want to detect cars from out of your window, and you aren’t interested in the 80 classes present in COCO. Training your model to detect a lower number of classes may improve the detection quality, so let’s do just that. Note, however, that training on a CPU may take quite a while, so be sure to use a GPU or a cloud service such as Google’s ML Engine (read more about Luminoth’s integration with it &lt;a href="https://luminoth.readthedocs.io/en/latest/usage/training.html#google-cloud" rel="noopener noreferrer"&gt;here&lt;/a&gt;), or just skip this section altogether and look at the pretty pictures instead.&lt;/p&gt;

&lt;p&gt;Luminoth contains tools to prepare and build a custom dataset from standard formats, such as the ones used by COCO or Pascal VOC. You can also build your own dataset transformer to support your own format, but that’s for another blog post. For now, we’ll use the &lt;code&gt;lumi dataset&lt;/code&gt; CLI tool to build a dataset containing only cars, taken from both COCO and Pascal (2007 and 2012).&lt;/p&gt;

&lt;p&gt;Start by downloading the datasets from &lt;a href="http://host.robots.ox.ac.uk/pascal/VOC/voc2007/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, &lt;a href="http://host.robots.ox.ac.uk/pascal/VOC/voc2012/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="http://cocodataset.org/#download" rel="noopener noreferrer"&gt;here&lt;/a&gt; and storing them into a &lt;code&gt;datasets/&lt;/code&gt; directory created on your working directory (specifically, into &lt;code&gt;datasets/pascal/2007/&lt;/code&gt;, &lt;code&gt;datasets/pascal/2012/&lt;/code&gt; and &lt;code&gt;datasets/coco/&lt;/code&gt;). Then merge all the data into a single &lt;code&gt;.tfrecords&lt;/code&gt; file ready to be consumed by Luminoth by running the following commands:&lt;/p&gt;

&lt;pre&gt;$ lumi dataset transform \
        --type pascal \
        --data-dir datasets/pascal/VOCdevkit/VOC2007/ \
        --output-dir datasets/pascal/tf/2007/ \
        --split train --split val --split test \
        --only-classes=car
$ lumi dataset transform \
        --type pascal \
        --data-dir datasets/pascal/VOCdevkit/VOC2012/ \
        --output-dir datasets/pascal/tf/2012/ \
        --split train --split val \
        --only-classes=car
$ lumi dataset transform \
        --type coco \
        --data-dir datasets/coco/ \
        --output-dir datasets/coco/tf/ \
        --split train --split val \
        --only-classes=car
$ lumi dataset merge \
        datasets/pascal/tf/2007/classes-car/train.tfrecords \
        datasets/pascal/tf/2012/classes-car/train.tfrecords \
        datasets/coco/tf/classes-car/train.tfrecords \
        datasets/tf/train.tfrecords
$ lumi dataset merge \
        datasets/pascal/tf/2007/classes-car/val.tfrecords \
        datasets/pascal/tf/2012/classes-car/val.tfrecords \
        datasets/coco/tf/classes-car/val.tfrecords \
        datasets/tf/val.tfrecords&lt;/pre&gt;
&lt;p&gt;

Now we’re ready to start training. In order to train a model using Luminoth, you must create a configuration file specifying some required information (such as a run name, the dataset location and the model to use, as well as a battery of model-dependent hyperparameters). Since we provide base configuration files already, something like this will be enough:
&lt;/p&gt;
&lt;pre&gt;train:
  run_name: ssd-cars
  # Directory in which model checkpoints &amp;amp; summaries (for Tensorboard) will be saved.
  job_dir: jobs/
  # Specify the learning rate schedule to use. These defaults should be good enough.
  learning_rate:
    decay_method: piecewise_constant
    boundaries: [1000000, 1200000]
    values: [0.0003, 0.0001, 0.00001]
dataset:
  type: object_detection
  # Directory from which to read the dataset.
  dir: datasets/tf/
model:
  type: ssd
  network:
    # Total number of classes to predict. One, in this case.
    num_classes: 1&lt;/pre&gt;
&lt;p&gt;

Store it in your working directory (same place where `datasets/` is located) as `config.yml`. As you can see, we’re going to train an SSD model. You can start running as follows: &lt;/p&gt;
&lt;pre&gt;$ lumi train -c config.yml
INFO:tensorflow:Starting training for SSD
INFO:tensorflow:Constructing op to load 32 variables from pretrained checkpoint
INFO:tensorflow:ImageVisHook was created with mode = "debug"
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into jobs/ssd-cars/model.ckpt.
INFO:tensorflow:step: 1, file: b'000004.jpg', train_loss: 20.626895904541016, in 0.07s
INFO:tensorflow:step: 2, file: b'000082.jpg', train_loss: 12.471542358398438, in 0.07s
INFO:tensorflow:step: 3, file: b'000074.jpg', train_loss: 7.3356428146362305, in 0.06s
INFO:tensorflow:step: 4, file: b'000137.jpg', train_loss: 8.618950843811035, in 0.07s
(ad infinitum)&lt;/pre&gt;
&lt;p&gt;

Many hours later, the model should have some reasonable results (you can just stop it when it goes beyond one million or so steps). You can test it right away using the built-in web interface by running the following command and going to
&lt;/p&gt;
&lt;pre&gt;$ lumi server web -c config.yml
Neither checkpoint not config specified, assuming 'accurate'.
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)&lt;/pre&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwuv53da8pord9z1e89xk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwuv53da8pord9z1e89xk.jpg" alt="Luminoth's frontend with cars being detected."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since Luminoth is built upon Tensorflow, you can also leverage&lt;br&gt;
&lt;a href="https://www.tensorflow.org/programmers_guide/summaries_and_tensorboard" rel="noopener noreferrer"&gt;Tensorboard&lt;/a&gt; by running it on the &lt;code&gt;job_dir&lt;/code&gt; specified in the config, in order to see the training progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that’s it! This concludes our overview of the new (and old) features of Luminoth: we’ve detected objects in images and videos using pre-trained models, and even trained our own in a couple of commands. We limited ourselves to the CLI tool and didn’t even get to mention the Python API, from which you can use your trained models as part of a larger system. Next time!&lt;/p&gt;

&lt;p&gt;This is the most feature-packed release of Luminoth yet, so we hope you get to try it out. Since we’re still at 0.1, you may hit some rough edges here and there. Please, feel free to write up some issues in our GitHub, or even contribute! All feedback is more than welcome in our road to make Luminoth better. You can also check out the &lt;strong&gt;documentation&lt;/strong&gt; &lt;a href="http://luminoth.readthedocs.io/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, which contains some more usage examples.&lt;/p&gt;

&lt;p&gt;And again, if you hit any roadblocks, hit us up!&lt;/p&gt;

&lt;p&gt;This article was originally published &lt;a href="https://tryolabs.com/blog/2018/04/17/announcing-luminoth-0-1/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>machinelearning</category>
      <category>deeplearning</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
