<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>personal notes (raw &amp; unedited)</title>
    <description></description>
    <link>https://surfertas.github.io/</link>
    <atom:link href="https://surfertas.github.io/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 15 Aug 2023 14:42:01 +0000</pubDate>
    <lastBuildDate>Tue, 15 Aug 2023 14:42:01 +0000</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>Notes on working with D435 realsense, OpenVino, ROS 2</title>
        <description>&lt;p&gt;WIP&lt;/p&gt;

&lt;h3 id=&quot;notes-on-working-with-d435-realsense-openvino-ros-2&quot;&gt;Notes on working with D435 realsense, OpenVino, ROS 2.&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt; &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Camera Model:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;D435&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;librealsense Version:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;v2.16.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Firmware Versions:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;05.12.06.00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;OS &amp;amp; Version:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Ubuntu 18.04.4 LTS&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Kernel Version:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;4.15.0-112-generic&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;ROS Distro: &lt;a href=&quot;https://www.ros.org/reps/rep-2000.html#dashing-diademata-may-2019-may-2021&quot;&gt;Dashing&lt;/a&gt;
note: lsb_release outputs LTS but MATE was installed on the NUC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: To publish 2d &amp;amp; 3d images from a D435 to a ros topic that would be consumed by an OpenVino machine vision pipeline with intentions to use with a Turtlebot2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Status/Results&lt;/strong&gt;: While I have been successful in working with 2d images, 3d is yet to work. [3/Aug/2020]&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$nuc@nuc: ros2 run realsense_ros2_camera realsense_ros2_camera
$remote_pc@remote_pc: ros2 launch pipeline_object_topic.launch.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember to update the &lt;a href=&quot;https://gist.github.com/surfertas/27091ee64c08240eace51fbd4007659e&quot;&gt;yaml file&lt;/a&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/params&lt;/code&gt; that the launch file loads with a path to the model, and associated labels.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;FPS&lt;/em&gt;: The fps is very unstable having a range of 4-15fps for 2D object detection when using the D435. The fps is unstable especially when compared with the IpCamera input where the system was much more stable.&lt;/p&gt;

&lt;p&gt;Getting the Intel Realsense camera D435 to work has been more involved then I thought, and a review of issues at the official repository suggests difficulties in integrating the device has not been as straightforward for others as well.&lt;/p&gt;

&lt;p&gt;Working toward a solution involved the following steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Downgrading kernel version to 4.15* after trying 5.3* unsuccessfully.&lt;/li&gt;
  &lt;li&gt;Update &lt;a href=&quot;https://dev.intelrealsense.com/docs/firmware-update-tool&quot;&gt;firmware&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Run &lt;a href=&quot;https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md&quot;&gt;patches&lt;/a&gt; and install dependencies.&lt;/li&gt;
  &lt;li&gt;Moving everything to work with Dashing and installing ros2 packages related to &lt;a href=&quot;https://github.com/intel/ros2_intel_realsense&quot;&gt;realsense&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;After device side was resolved to an acceptable point, remapping the camera topic to appropriate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INPUT_TOPIC&lt;/code&gt; &lt;a href=&quot;https://github.com/intel/ros2_openvino_toolkit/blob/master/dynamic_vino_lib/src/inputs/image_topic.cpp&quot;&gt;defined&lt;/a&gt; in the source was required.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;follow-up-items&quot;&gt;Follow up items&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Calibrate IMU: https://github.com/IntelRealSense/librealsense/issues/5166&lt;/li&gt;
  &lt;li&gt;Try with RealSenseCamera input in place of RealSenseCameraTopic by running OpenVino pipeline on the NUC.&lt;/li&gt;
  &lt;li&gt;Debug below warnings when running realsense-viewer with 3D.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; 03/08 15:01:39,022 WARNING [139875290420992] (sensor.cpp:338) Unregistered Media formats : [ UYVY ]; Supported: [ ]
 03/08 15:02:04,803 WARNING [139875103786752] (backend-v4l2.cpp:1013) Frames didn't arrived within 5 seconds
 03/08 15:02:09,809 WARNING [139875103786752] (backend-v4l2.cpp:1013) Frames didn't arrived within 5 seconds
 03/08 15:02:14,814 WARNING [139875103786752] (backend-v4l2.cpp:1013) Frames didn't arrived within 5 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;command-line-reminder&quot;&gt;Command line reminder:&lt;/h4&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsusb -v
usb-devices
uname -r
lsb_release -a
dmesg
rs-fw-update -l
v4l2-ctl --list-device
realsense-viewer
ros2 topic list -t
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;p&gt;https://kowalczyk.me/change-default-kernel-in-ubuntu-18-04/
https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md
https://github.com/IntelRealSense/librealsense/issues/1225
https://github.com/IntelRealSense/librealsense/issues/5598
https://github.com/intel/ros2_intel_realsense
https://dev.intelrealsense.com/docs/firmware-update-tool
https://qiita.com/t_kumazawa/items/eb3a60f0ca1fbca70bee
https://naonaorange.hatenablog.com/entry/2018/11/04/174745&lt;/p&gt;
</description>
        <pubDate>Mon, 03 Aug 2020 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros2/2020/08/03/realsense-openvino.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros2/2020/08/03/realsense-openvino.html</guid>
        
        
        <category>ros2</category>
        
      </item>
    
      <item>
        <title>Using RPLidar A2 with Turtlebot 2 running ROS Melodic with a Kobuki base</title>
        <description>&lt;p&gt;WORK IN PROGRESS
Last Edited: 18/7/2020&lt;/p&gt;

&lt;p&gt;The objective of this note is to document my steps in getting a Turtlebot2 with a Kobuki base localizing on a static map so that I can reference at a future date. The static map was created using the &lt;a href=&quot;https://github.com/SteveMacenski/slam_toolbox&quot;&gt;slam_toolbox&lt;/a&gt; package, and laser scans from a RPLidar A2 mounted on top of a Turtlebot2. I use the AMCL package for localization, as I haven’t been successful in getting the localization mode to work with the slam_toolbox package at the time of this writing. (11th/7/2020) I’ve placed all necessary launch files and robot descriptions at the following &lt;a href=&quot;https://github.com/surfertas/turtlebot2_lidar&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;robot-details&quot;&gt;Robot details&lt;/h4&gt;

&lt;p&gt;Constructing the Turtlebot 2 to run freely is not cheap as you can see from the list of hardware.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Cost&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Robot&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;https://store.clearpathrobotics.com/collections/robotics-kit/products/turtlebot-2-essentials&quot;&gt;Turtlebot2 w/ Kobuki base&lt;/a&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$1049.00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lidar&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;https://www.seeedstudio.com/RPLIDAR-A2M8-The-Thinest-LIDAR.html&quot;&gt;RPLidar A2M8&lt;/a&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$449.00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Computer&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;https://www.amazon.com/NUC8i7BEH-i7-8559U-Bluetooth-Thunderbolt-Support/dp/B07QH8CZWK/ref=sr_1_1_sspa?dchild=1&amp;amp;keywords=NUC8i7BEH&amp;amp;qid=1594451930&amp;amp;sr=8-1-spons&amp;amp;psc=1&amp;amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExWTBKTzVDUERBT05GJmVuY3J5cHRlZElkPUEwMjUxNzkyMlRVU0FQMjVBRVpDQSZlbmNyeXB0ZWRBZElkPUEwNDk4MzkwR01QTVFYQ0g4OEtFJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==&quot;&gt;NUC8i7BEH&lt;/a&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$729.99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Power&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;https://www.amazon.com/Portable-Charger-RAVPower-27000mAh-Indicator/dp/B07PBSH28H/ref=pb_allspark_session_sims_desktop_23_34?_encoding=UTF8&amp;amp;pd_rd_i=B07PBSH28H&amp;amp;pd_rd_r=8bf262c2-0c2c-4678-b9d9-b6a7800a7668&amp;amp;pd_rd_w=3m5Ag&amp;amp;pd_rd_wg=V3A3u&amp;amp;pf_rd_p=6dab4af8-14d2-4d59-b0a2-dd973ff1f166&amp;amp;pf_rd_r=KMXPAZY4T28BYBEZKSTJ&amp;amp;psc=1&amp;amp;refRID=KMXPAZY4T28BYBEZKSTJ&quot;&gt;Portable Charger RAVPower 27000mAh 85W(100W Max)&lt;/a&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$129.00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Controller&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;https://www.amazon.com/Controller-Wireless-Playstation-Shock-Black/dp/B087RK4VDX/ref=sr_1_1_sspa?dchild=1&amp;amp;keywords=PS3+Controller+sony&amp;amp;qid=1594452283&amp;amp;sr=8-1-spons&amp;amp;psc=1&amp;amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzR01BWVVWRTZPS1dOJmVuY3J5cHRlZElkPUEwMDEwNjg2QzhYOVFNNEdSV0YyJmVuY3J5cHRlZEFkSWQ9QTAyODA3ODMxN1lYUEYwMzAzU0ZXJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==&quot;&gt;PS3 Controller&lt;/a&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$30.99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;$2387.98&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;setup&quot;&gt;Setup&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;Install the necessary packages into your ROS workspace as turtlebot packages to support Turtlebot2 have not been released to Melodic and is a work in progress (22/6/2020). [1]&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install ros-melodic-laptop-battery-monitor
sudo apt install ros-melodic-openni2-camera
sudo apt install ros-melodic-openni2-launch
sudo apt install ros-melodic-gmapping
sudo apt install ros-melodic-yocs-msgs
sudo apt install ros-melodic-yujin-ocs

mkdir -p ros_ws/src
cd ros_ws/src
git clone https://github.com/turtlebot/turtlebot.git

cd turtlebot
git clone https://github.com/turtlebot/turtlebot_interactions.git
git clone https://github.com/turtlebot/turtlebot_apps
git clone https://github.com/turtlebot/turtlebot_msgs

cd ~/row_ws/src
git clone --single-branch --branch melodic https://github.com/yujinrobot/kobuki.git

### To work with this guide clone the turtlebot2_lidar repo.
git clone https://github.com/surfertas/turtlebot2_lidar.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;If you take a look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;turtlebot2_lidar&lt;/code&gt; repo, you can see that I have created a URDF representation of the lidar device and placed the file in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;urdf/sensors&lt;/code&gt; directory, e.g. in this case the file name is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rplidar_a2.urdf.xacro&lt;/code&gt;. The specifications of the RPLidar A2 were taken from the [device data sheet]. Add the device to the robot description. You can use Onshape to design a mount or feel free to use &lt;a href=&quot;https://cad.onshape.com/documents/004a3b4a35209210963e3e80/w/4836d6df38345f79b70ff7f4/e/202697d7ac59d46579c570f3&quot;&gt;mine&lt;/a&gt; for the RPLidar A2. The Turtlebot data sheet comes in handy as well. [2]&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;steps-to-create-a-map&quot;&gt;Steps to create a map&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Place your turtlebot on the power dock. It is recommended that the dock is fixed to a specific location free from obstruction. Boot up the NUC powered by the portable charger.&lt;/li&gt;
  &lt;li&gt;You will need to ssh from 4 panels, for 1) bringup 2) slam_toolbox 3) rviz 4) teleop. For panel 3) add the argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-X&lt;/code&gt; when using ssh to allow for forwarding. [3] Forwarding will be needed when using RVIZ from your remote pc.&lt;/li&gt;
  &lt;li&gt;Source the necessary environment from your working directory. Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source /opt/ros/melodic/setup.bash &amp;amp;&amp;amp; source devel/setup.bash&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Next on panel 1), check which port the lidar is connected to by executing the following command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls -l /dev | grep ttyUSB&lt;/code&gt;.  In my case, the lidar was required to be connected to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ttyUSB0&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ttyUSB1&lt;/code&gt; was being used by the connection to the Turtlebot. This paramater is set as a environment variable when your run the environment &lt;a href=&quot;https://github.com/surfertas/turtlebot2_lidar/blob/master/turtlebot_env.sh&quot;&gt;script&lt;/a&gt;. Once the NUC is powered on, unplug any USB cables, and make sure that the lidar is connected first, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ttyUSB0&lt;/code&gt; is assigned to the lidar.&lt;/li&gt;
  &lt;li&gt;Change permissions of the port by executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo chmod 666 /dev/ttyUSB0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch turtlebot2_lidar bringup_minimal.launch&lt;/code&gt; in panel 1). At this point you should see the lidar start to spin.&lt;/li&gt;
  &lt;li&gt;On panel 2) run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch turtlbot2_lidar slam_toolbox_lidar.launch&lt;/code&gt;. I had to add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static_transform_publisher&lt;/code&gt; to the launch file publish a transform from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser_link&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;laser&lt;/code&gt;. Note that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser_link&lt;/code&gt; was defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;urdf/sensors/rplidar_a2.urdf.xacro&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;On panel 3) start up RVIZ by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch turtlebot_rviz_launchers view_navigation.launch&lt;/code&gt; which will kick off RVIZ on your remote laptop. You should see a top down visual of the Turtlebot with scans picking up some nearby obstacles. Get the slam_toolbox panel open in rviz by selecting from the top left menu: Panels-&amp;gt;Add New Panel-&amp;gt; slam_toolbox-&amp;gt;SlamToolboxPlugin.&lt;/li&gt;
  &lt;li&gt;Finally on panel 4) run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch turtlebot_teleop ps3_teleop.launch&lt;/code&gt;. Make sure that the ps3 controller has been synced with the NUC. Steps to sync can be found &lt;a href=&quot;http://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&quot;&gt;here&lt;/a&gt; if you are having trouble. [4]&lt;/li&gt;
  &lt;li&gt;You are ready to create a map! Teleop around and continue until you are satisfied with the generated map.&lt;/li&gt;
  &lt;li&gt;To save the map we need to start by inputting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;path_to_directory&amp;gt;/&amp;lt;name&amp;gt;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;save map&lt;/code&gt; and also for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serialization&lt;/code&gt; (to be used with slam_toolbox localization mode). Note that the name doesn’t have the file type, just the prefix. (e.g. if you want files like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map.pgm&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map.yaml&lt;/code&gt;, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;path_to_directory&amp;gt;/map&lt;/code&gt;). If no path is specified, the files will be placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.ros&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Now you should have the necessary files needed for localization.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;steps-to-localize-using-the-new-created-map-and-the-amcl-package&quot;&gt;Steps to localize using the new created map and the AMCL package&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Open a terminal panel and ssh into the NUC. Go to the root of the workspace directory and source the ROS environment.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source /opt/ros/melodic/setup.bash &amp;amp;&amp;amp; source devel/setup.bash&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set the environment variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TURTLEBOT_MAP_FILE&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;turtlebot_env.sh&lt;/code&gt; with the path to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.yaml&lt;/code&gt; file that was created in the previous map creation process. Execute the bash file to update necessary environment variables.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;. turtlebot_env.sh&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Launch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bringup_minimal.launch&lt;/code&gt; to boot up the physical turtlebot. Make sure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TURTLEBOT_SERIAL_PORT&lt;/code&gt; is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/ttyUSB1&lt;/code&gt; or whatever port the turtlebot is connected to.&lt;/li&gt;
  &lt;li&gt;Launch RVIZ. Follow the aforementioned steps from launching RVIZ when creating a map.&lt;/li&gt;
  &lt;li&gt;Before launching the AMCL launch file, set the argument defaults for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initial_pose_x&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initial_pose_y&lt;/code&gt;,&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initial_pose_a&lt;/code&gt; with the position data obtained from the starting position in the mapping exercise (used the dock in my case).&lt;/li&gt;
  &lt;li&gt;Launch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rplidar_a2_amcl.launch&lt;/code&gt;. A couple things to point out here. First, I am using the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amcl.launch.xml&lt;/code&gt; file. This hasn’t been tuned for the RPLidar A2 specifically. Secondly, I’ve added the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static_transform_publisher&lt;/code&gt; to define the transform between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser_link&lt;/code&gt;and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;laser&lt;/code&gt; here as well, in addition to defining a parameter named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frame_id&lt;/code&gt; with value set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; which is passed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map_server&lt;/code&gt;. Without these 2 steps I was getting transform errors. Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rosrun rqt_tf_tree rqt_tf_tree&lt;/code&gt; to see if correct transforms are being published. In this case you the expected transforms are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map-&amp;gt;odom-&amp;gt;base_footprint-&amp;gt; base_link&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/tfframe.png&quot; alt=&quot;tftree&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If the laser scan isn’t really lining up with the map as you would expect, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2D Pose Estimate&lt;/code&gt; to publish a pose estimation. Repeat until the scan matches as expected.&lt;/li&gt;
  &lt;li&gt;Once the scans match up, you are ready to navigate. In RVIZ, use 2D Nav Goal to set a target goal and watch your turtlebot go.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/rvizamcl.png&quot; alt=&quot;rviz&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;localization-with-slam_toolbox-incomplete&quot;&gt;Localization with slam_toolbox (INCOMPLETE)&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Repeat steps 1.-4. of localization with AMCL package.&lt;/li&gt;
  &lt;li&gt;We need to modify the params yaml file that is passed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slam_toolbox&lt;/code&gt; package. The original config dir is located at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slam_toolbox/config&lt;/code&gt;. I moved the config directory under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;turltebot2_lidar&lt;/code&gt; for easy modification. The file that needs to be modified is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mapper_params_online_sync.yaml&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mode&lt;/code&gt; parameter to localization from mapping. Further you can set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map_file_name&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map_start_pose&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map_start_at_dock&lt;/code&gt;. Note for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map_file_name&lt;/code&gt; don’t include the file type. (e.g. /map.posegraph would just be /map)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TODO: debug
Failed to compute laser pose, aborting continue mapping (“laser” passed to lookupTransform argument source_frame does not exist. )
Tried publishing the transform via different launch file but still doesnt work but
Removing the / from /laser in the static_transform_publish made it so laser was recognized, but now getting different issue
Failed to compute laser pose, aborting continue mapping (Lookup would require extrapolation at time 1593875399.670327337, but only time 1593875399.833934289 is in the buffer, when looking up transform from frame [laser] to frame [base_footprint])&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://github.com/turtlebot/turtlebot/issues/272&lt;/li&gt;
  &lt;li&gt;https://clearpathrobotics.com/turtlebot-2-open-source-robot/&lt;/li&gt;
  &lt;li&gt;https://superuser.com/questions/310197/how-do-i-fix-a-cannot-open-display-error-when-opening-an-x-program-after-sshi&lt;/li&gt;
  &lt;li&gt;http://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 11 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2020/07/11/turtlebot2-lidar.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2020/07/11/turtlebot2-lidar.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Turtlepi: from ROS indigo to ROS melodic</title>
        <description>&lt;p&gt;Just went the through the exercise of updating a small ROS project I worked on about 3 years ago from ROS indigo to the latest ROS melodic.&lt;/p&gt;

&lt;p&gt;Original 2017 post: &lt;a href=&quot;http://surfertas.github.io/ros/2017/05/23/autotarget.html&quot;&gt;Turtlepi #7: Automatic Target Generation for the Turtlebot
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The port was rather straight forward. The main issue was that Turtlebot 2 has yet to be included in the official melodic release. [1,2] Using the scripts put together as a result of community discussions [3] with minor modifications for my use case, helped a lot.&lt;/p&gt;

&lt;p&gt;Working through old code is always enjoyable, and humbling. I was under the belief that I had shared a repository that was complete and working. Working through the 3 year old repository indicated otherwise.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;https://github.com/turtlebot/turtlebot/issues/272&lt;/li&gt;
  &lt;li&gt;https://answers.ros.org/question/294600/ros-melodic-does-it-support-turtlebot2/?answer=294603#post-id-294603&lt;/li&gt;
  &lt;li&gt;https://github.com/gaunthan/Turtlebot2-On-Melodic&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 11 Mar 2020 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2020/03/11/melodic-upgrade.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2020/03/11/melodic-upgrade.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Korabo: Getting users is tough</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;
&lt;p&gt;I spent the last couple months developing and deploying a progressive webapp, partially because I thought I had a ground breaking idea, and partially to sharpen my web development skills. The fully functioning web app can be found at: https://www.korabo.io. Note that the application is intended for users with a US bank account.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Building and deploying a functioning MVP/prototype is relatively easy when compared to attracting users.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The fact that I am having extreme amount of difficulty in getting users to even sign up raises flags for the viability of this project.&lt;/p&gt;

&lt;h3 id=&quot;context&quot;&gt;Context&lt;/h3&gt;
&lt;h4 id=&quot;problem&quot;&gt;Problem:&lt;/h4&gt;
&lt;p&gt;The problem being addressed is the hassles of splitting proceeds after the fact with collaborators. This idea came about as I watched my wife try to split proceeds from a yoga workshop she hosted with a few other instructors.&lt;/p&gt;

&lt;h4 id=&quot;solution&quot;&gt;Solution:&lt;/h4&gt;
&lt;p&gt;The solution consists of setting the percentage share allocation prior to the service being delivered, and splitting proceeds on a per-payment basis. The application allows the user to specify percentage splits and create a customized checkout (e.g. video message) to share with customers via different types of links (url, QRcode), which directs customers to a credit card checkout powered by Stripe.&lt;/p&gt;

&lt;p&gt;An example of a link to a checkout is a customized shield as the one shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.korabo.io/checkout-page/5e2815526ca5270022f1a858/5e23f0b31b70f70022ff5933&quot;&gt;
   &lt;img src=&quot;https://img.shields.io/badge/korabo-donate-blue&quot; alt=&quot;donate&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;tools--services&quot;&gt;Tools &amp;amp; Services&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Running Costs&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Front-end&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;materialUI , ReactJs&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Back-end&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;node, express, MongoDB&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Payments&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Stripe&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;*free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Deployment&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Heroku&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;7$ /month&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Versioning&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;GitHub&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CI&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;CircleCI&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Testing&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Jest&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Legal&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;iubenda&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$25/month&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Admin&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;gsuite, trello&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;$6/month&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;:&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;$38/month&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Stripe charges 2.9%+$0.3 per payment, additional 1% for international cards, and costs associated for maintaining and handling payouts for connected accounts.&lt;/p&gt;

&lt;h3 id=&quot;steps-taken-to-attract-users&quot;&gt;Steps Taken to Attract Users&lt;/h3&gt;
&lt;p&gt;I officially pushed master to production on Jan 18th, so its been less then a month since I launched at the time of this writing. The net results of my efforts thus far is a total of 7 sign ups including myself, of which 3/7 are complete strangers. Out of the 3 strangers, 1/3 of the strangers had fully completed the on-boarding process, which includes a stripe account set up. See the Google Analytics results since releasing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/ga-korabo.png&quot; alt=&quot;GA&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Jan 18th&lt;/em&gt;&lt;/strong&gt; : Reached out to 2 family/friends. 2/2 signed up, but both stopped at the Stripe account on-boarding step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Jan 21st&lt;/em&gt;&lt;/strong&gt;: Posted on some GT MSCS slack channels. The post was mostly ignored, but I did receive one inquiry about what makes this app different from Venmo or Cushion. The action resulted in 0 sign ups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Jan 28th&lt;/em&gt;&lt;/strong&gt; : Responded to Ask HN: “What interesting problems are you working on?” which resulted in a few page views and 2 sign ups. My reply got 3 up-votes, exciting for someone relatively new to the community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Jan 29th&lt;/em&gt;&lt;/strong&gt;: Reached out to 2 “friends” and prior work colleagues which resulted in 0/2 sign ups. The exercise was disappointing for different reasons, thus the “” around friends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feb 4th&lt;/em&gt;&lt;/strong&gt;: Posted an inquiry on reddit for design jobs as I needed proper logo design work to be done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feb 5th&lt;/em&gt;&lt;/strong&gt;:  Replied to a separate AskHN where a member was soliciting for logo design work coincidentally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feb 6th&lt;/em&gt;&lt;/strong&gt;: Posted a Job posting on UpWork for Logo Design work. This resulted in 48 views on UpWork, and 2 proposals. I wasn’t anticipating any sign ups, but the post resulted in 0 sign ups and 0 completed jobs as the professionals associated with the proposal weren’t a fit with the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feb 7th&lt;/em&gt;&lt;/strong&gt;: Used the Show HN functionality. Probably the most disappointing result against my personally set expectations (clearly misplaced and high), as I was expecting some sort of response in the form of comments or votes! Phrases like &lt;em&gt;reality is harsh&lt;/em&gt;, and &lt;em&gt;the truth hurts&lt;/em&gt; really hits home here. That said, the exercise did result in an uptick in page views albeit off a very low base. Final result: 0 sign ups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feb 9th&lt;/em&gt;&lt;/strong&gt;: Created a twitter account and started to follow members that used relevant hash tags, and members with what I viewed as engaging in a relevant profession. 0 sign ups.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;In reality its likely too soon to make any conclusions as its been only less then a month, but the preliminary results feels disappointing to say the least.&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Feb 2020 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/korabo/2020/02/14/korabo-users.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/korabo/2020/02/14/korabo-users.html</guid>
        
        
        <category>korabo</category>
        
      </item>
    
      <item>
        <title>Autonomous Intelligent Systems #3: Robot Mapping</title>
        <description>&lt;p&gt;Continuing the self-study exercise of working through the &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ss18/robotics/&quot;&gt;Robot Mapping&lt;/a&gt; course offered by the Autonomous Intelligent Systems lab at the University of Freiburg.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/06/01/ais.html&quot;&gt;Autonomous Intelligent Systems #1: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/10/07/ais.html&quot;&gt;Autonomous Intelligent Systems #2: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/ekf/2019/11/10/ais-ekf-slam.html&quot;&gt;Autonomous Intelligent Systems #3: Robot Mapping&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Similar to past related exercises, I am completing the programming tasks in python as opposed to matlab.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/surfertas/ais_robot_mapping/tree/master/sheet2&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before attempting the problem set (sheets) complete the slides+recording on the following topics.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;EKF SLAM [&lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws17/mapping/pdf/slam05-ekf-slam.pdf&quot;&gt;slides&lt;/a&gt;][&lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws17/mapping/videos/05-EKF.mp4&quot;&gt;recording&lt;/a&gt;]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws18/mapping/exercise/robotMappingSheet04.pdf&quot;&gt;Sheet 4&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;exercise-1-implement-the-prediction-step-of-the-ekf-slam-algorithm&quot;&gt;Exercise 1: Implement the prediction step of the EKF SLAM algorithm.&lt;/h4&gt;
&lt;p&gt;This was relatively straight forward as task just requires updating the respective indices of the state with the motion model and the covariance with the Jacobian of the motion model. This can be found in &lt;a href=&quot;https://github.com/surfertas/ais_robot_mapping/blob/master/sheet2/ekf_slam/prediction_step.py&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prediction_step.py&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;exercise-2-implement-the-correction-step&quot;&gt;Exercise 2: Implement the correction step.&lt;/h4&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.py&lt;/code&gt; which should generate an image for each time step. The figures
will be saved to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/plots&lt;/code&gt; directory. Next, from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/plots&lt;/code&gt; directory run
the following command to generate a video from the images.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ffmpeg -r 10 -start_number 0 -i 'odom_%d.png' -b 500000  odom.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should represent a stream of a robot in motion with the visualization of the
landmarks that the robot is sensing at each time step.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/pe9tHavg-w4&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;A couple things to note:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Possible the jacobian for the observation shown on &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws17/mapping/pdf/slam05-ekf-slam.pdf&quot;&gt;pg. 39&lt;/a&gt; is incorrect. Specifically the partial derivative of atan2(dy,dx)-mut,theta is -1 based on my derivation as opposed to -q shown on pg. 39. I am in the process of double checking with the author.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The suggested implementation by the assignment was to compute the Kalman gain after the stacked Jacobian of the observation was fully constructed for all observations for that time step. I found that this led to unstable results. Instead, computing the Kalman gain after each observation resulted in more stable results.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TODO: Implement the visualization of the probability ellipses.&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Nov 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ais/ekf/2019/11/10/ais-ekf-slam.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ais/ekf/2019/11/10/ais-ekf-slam.html</guid>
        
        
        <category>ais</category>
        
        <category>ekf</category>
        
      </item>
    
      <item>
        <title>ROScon2019: Follow up ToDo list</title>
        <description>&lt;p&gt;I was fortunate enough to attend &lt;a href=&quot;https://roscon.ros.org/2019/&quot;&gt;ROSCon2019&lt;/a&gt; held in Macau, China this year. I learned more about ROS and the community then I have in the past X years trying to learn ROS independently out of personal interest. Amazing how many companies there were working on cutting edge technology/applications. Two questions really stuck with me. First, was a question about robotics being driven by Roboticists or Software Engineers. The second, was related to hiring, where questions were posed to the audience asking who was hiring and who was looking. The number of hands raised for hiring significantly outnumbered the hands for looking. That aside always great to put a face to a name.&lt;/p&gt;

&lt;h4 id=&quot;raw--unedited-todo-list&quot;&gt;Raw &amp;amp; unedited todo list&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Walk through &lt;a href=&quot;https://github.com/ros2-realtime-demo/pendulum&quot;&gt;real time demo&lt;/a&gt; and papers shared by Victor at Alias Robotics in his &lt;a href=&quot;https://bit.ly/2pLNI4I&quot;&gt;presentation&lt;/a&gt;.
    &lt;ul&gt;
      &lt;li&gt;Towards a distributed and real-time framework for robots: Evaluation of ROS 2.0 communications for real-time robotic applications.&lt;/li&gt;
      &lt;li&gt;Real-time Linux communications: an evaluation of the Linux communication stack for real-time robotic applications.&lt;/li&gt;
      &lt;li&gt;Time-Sensitive Networking for robotics.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;DRAFT: Review https://micro-ros.github.io/ and demo&lt;/li&gt;
  &lt;li&gt;Review &lt;a href=&quot;https://github.com/boschresearch/ros2_response_time_analysis&quot;&gt;Response Time Analysis of ROS2 Processing Chains&lt;/a&gt; introduced by Igor at Bosch&lt;/li&gt;
  &lt;li&gt;Rewatch the Keynote by Ian Sherman at Formant where among other topics discussed bringing solutions found in backend micro services into the robotics space.&lt;/li&gt;
  &lt;li&gt;Reproduce the results obtained by iRobot engineers in running ROS2 on raspi. [&lt;a href=&quot;https://github.com/Irobot-ros/ros2-performance&quot;&gt;github&lt;/a&gt;]&lt;/li&gt;
  &lt;li&gt;DRAFT  Implement some of the suggestions made at “188 ROS bugs later: Where do we go from here?” by Christopher Timperly of CMU and Andrzej Wasowski of IT University of Copenhagen to write better ROS code.
    &lt;ul&gt;
      &lt;li&gt;CI -build passing&lt;/li&gt;
      &lt;li&gt;use smoke test to find missing run time&lt;/li&gt;
      &lt;li&gt;linters ament_lint&lt;/li&gt;
      &lt;li&gt;cppcheck, mypy&lt;/li&gt;
      &lt;li&gt;use sanitizers&lt;/li&gt;
      &lt;li&gt;mithra: oracle learning for simulation -based testing&lt;/li&gt;
      &lt;li&gt;HAROS&lt;/li&gt;
      &lt;li&gt;phryky-units&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Implement the one thing Nicolo from Cruise Automation wanted audience to remember; the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros::TransportHints().tcpNoDelay()&lt;/code&gt; and  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rosbag record –tcpnodelay &lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Look into &lt;a href=&quot;https://husarnet.com/&quot;&gt;Husarnet&lt;/a&gt; a P2P network layer for robots and IOTwith first class ROS support.&lt;/li&gt;
  &lt;li&gt;Since I missed day 2, watch day 2 live streams!&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 06 Nov 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros2/roscon2019/2019/11/06/roscon2019.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros2/roscon2019/2019/11/06/roscon2019.html</guid>
        
        
        <category>ros2</category>
        
        <category>ROScon2019</category>
        
      </item>
    
      <item>
        <title>ROS2: Cross compile package for Raspiberry Pi 3 B+</title>
        <description>&lt;p&gt;Notes related to cross compiling ros2 packages for a Raspiberry Pi 3 B+ running Ubuntu Mate 18.04.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt; I am trying to work on a DIY “see through wall” application where I mount an IP camera (e.g. Amcrest) in the family room, and view the image stream from the room next door, ideally keeping the perspective consistent across rooms.&lt;/p&gt;

&lt;p&gt;The set up I have in mind consists of an IP camera powered by POE. The &lt;a href=&quot;https://github.com/surfertas/ros2_ipcamera&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros2_ipcamera&lt;/code&gt;&lt;/a&gt; node would be running on a raspi in a different room, tasked to retrieve the images from the rtsp uri and publish them for viewing on a monitor or webapp.&lt;/p&gt;

&lt;p&gt;The following notes solves the task of getting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros2_ipcamera&lt;/code&gt; running on a raspi.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/alsora&quot;&gt;Alberto&lt;/a&gt;, the engineer that put the work into creating the cross-compile &lt;a href=&quot;https://github.com/alsora/cross_compile/tree/alsora/refactor_cross_compile&quot;&gt;GitHub repo&lt;/a&gt; (currently a PR to replace the original as of Oct.14, 2019) was extremely helpful in helping me work through my gaps in understanding of the cross-compile process. Thanks!!!&lt;/p&gt;

&lt;h4 id=&quot;preliminary-steps&quot;&gt;Preliminary Steps&lt;/h4&gt;
&lt;p&gt;Preliminary steps to be taken on the target system, in this case the raspi.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Flash Ubuntu Mate 18.04 onto a mini SD.&lt;/li&gt;
  &lt;li&gt;Install &lt;a href=&quot;https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Debians/&quot;&gt;ros2-dashing-desktop&lt;/a&gt;. &lt;em&gt;Note that base wont work in this particular case as we need some dependencies related to OpenCV.&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Install &lt;a href=&quot;https://index.ros.org/doc/ros2/Tutorials/Colcon-Tutorial/&quot;&gt;colcon&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source /opt/ros/dashing/setup.bash&lt;/code&gt;. We can quickly test by checking to see if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros2 topic list&lt;/code&gt; works.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;cross-compile&quot;&gt;Cross Compile&lt;/h4&gt;
&lt;p&gt;Follow steps outlined &lt;a href=&quot;https://github.com/alsora/cross_compile/tree/alsora/refactor_cross_compile&quot;&gt;here&lt;/a&gt; to cross compile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Since I was going to compile &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros2_ipcamera&lt;/code&gt; directly on the raspi, I needed to transfer the entire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install&lt;/code&gt; directory as opposed to just the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install/lib&lt;/code&gt; directory per the example given by Alberto.&lt;/p&gt;

&lt;p&gt;Further, since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vision_opencv&lt;/code&gt; depends on OpenCV I needed to include a line to the original &lt;a href=&quot;https://github.com/alsora/cross_compile/blob/alsora/refactor_cross_compile/sysroots/Dockerfile_ubuntu-arm64&quot;&gt;dockerfile&lt;/a&gt;. The modified dockerfile can be found &lt;a href=&quot;https://gist.github.com/surfertas/e4299de2241d5ff3f19159914fee482a&quot;&gt;here&lt;/a&gt;. &lt;strong&gt;If a reader is aware of an easier way to install opencv please leave me a note below.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this particular project, the steps modified for my specific use case were as follows.&lt;/p&gt;

&lt;p&gt;On host system:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git clone https://github.com/alsora/cross_compile/tree/alsora/refactor_cross_compile
$ mkdir -p ~/ros2_ws/src
$ cd ~/ros2_ws
$ wget https://raw.githubusercontent.com/ros2/ros2/dashing/ros2.repos
$ vcs import src &amp;lt; ros2.repos
$ git clone -b ros2 https://github.com/ros-perception/image_common src/ros-perception/image_common
$ git clone -b ros2 https://github.com/ros-perception/vision_opencv src/ros-perception/vision_opencv

$ cd ~/cross_compile

# Build all the docker images contained in the docker_environments directory.
$ bash build.sh

# Specify environment variable (e.g. ubuntu-arm64, raspbian).
$ source env.sh ubuntu-arm64

$ bash get_sysroot.sh

# Script to add COLCON_IGNORE to directories to be ignored and can modify as necessary.
$ bash ignore_pkgs.sh ~/ros2_cc_ws dashing

$ bash cc_workspace.sh ~/ros2_cc_ws

# Transfer install directory to target system.
$ rsync -avz --progress install/* user@address:~/ros2_install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On target system:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ source ~/ros2_install/install/setup.bash
$ mkdir -p ~/ros2_ws/src
$ cd ~/ros2_ws/src
$ git clone https://github.com/surfertas/ros2_ipcamera.git
$ cd ..
$ colcon build –symlink-install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;Overall this was a great exercise to learn more about ros2, cross compiling, IP cameras, POE, and general software development. That said, I am pretty sure that this is not the best set up for the “see through wall” application as a much simpler solution can be considered. Further, despite being able to compile the package on the raspi, the performance of the node is poor, which is more so the result of sub-optimal decisions made by my self.&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Oct 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros2/cross-compile/2019/10/14/crosscompile.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros2/cross-compile/2019/10/14/crosscompile.html</guid>
        
        
        <category>ros2</category>
        
        <category>cross-compile</category>
        
      </item>
    
      <item>
        <title>Autonomous Intelligent Systems #2: Robot Mapping</title>
        <description>&lt;p&gt;Continuing the documentation of a self-study exercise of working through the &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws18/mapping/&quot;&gt;Robot
Mapping&lt;/a&gt; course offered by Autonomous Intelligent Systems lab at the University of Freiburg.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/06/01/ais.html&quot;&gt;Autonomous Intelligent Systems #1: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/10/07/ais.html&quot;&gt;Autonomous Intelligent Systems #2: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/ekf/2019/11/10/ais-ekf-slam.html&quot;&gt;Autonomous Intelligent Systems #3: Robot Mapping&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: sheet 2 was skipped as it was just an example application of bayes theorem.&lt;/p&gt;

&lt;p&gt;Before attempting the problem set (sheets) complete the &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws17/mapping/pdf/slam04-ekf.pdf&quot;&gt;slides&lt;/a&gt; + &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws14/mapping/videos/04-EKF.mp4&quot;&gt;recording&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ws18/mapping/exercise/robotMappingSheet03.pdf&quot;&gt;Sheet 3&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;exercise-1a--describe-briefly-the-two-main-steps-of-the-bayes-filter-in-your-own-words&quot;&gt;&lt;strong&gt;Exercise 1.a&lt;/strong&gt;:  Describe briefly the two main steps of the Bayes filter in your own words.&lt;/h4&gt;

&lt;p&gt;The 2 main steps consists of a predict step and an update step. The &lt;strong&gt;predict step&lt;/strong&gt; propagates a belief of the state and error covariance through a system model to obtain an &lt;em&gt;a priori&lt;/em&gt; estimate for the next time step. [1] The &lt;strong&gt;update step&lt;/strong&gt; takes the &lt;em&gt;a priori&lt;/em&gt; estimate and corrects/updates with a measurement, incorporating new information to obtain the &lt;em&gt;a posteriori&lt;/em&gt; estimate.&lt;/p&gt;

&lt;h4 id=&quot;exercise-1b-describe-briefly-the-meaning-of-the-following-probability-density-functions&quot;&gt;&lt;strong&gt;Exercise 1.b&lt;/strong&gt;: Describe briefly the meaning of the following probability density functions.&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;\(p(x_t | u_t, x_{t-1})\) → distribution of the state at time,\(t\), given a control action applied from a state at time \(t-1\).&lt;/li&gt;
  &lt;li&gt;\(p(z_t | x_t)\) →  distribution of a given measurement at time \(t\), given the state at time \(t\).&lt;/li&gt;
  &lt;li&gt;\(bel(x_t)\) →  &lt;em&gt;a priori&lt;/em&gt; belief, and the current estimate of the distribution of the state at time \(t\).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;exercise-1c-specify-the-distributions-that-corresponds-to-the-above-mentioned-3-terms-in-the-ekf&quot;&gt;&lt;strong&gt;Exercise 1.c&lt;/strong&gt;: Specify the distributions that corresponds to the above mentioned 3 terms in the EKF.&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;\(p(x_t | u_t, x_{t-1})\) →  The mean is \(g(\mu_t, u_{t-1})\), while the covariance is the matrix &lt;strong&gt;Q&lt;/strong&gt; representing the process noise.&lt;/li&gt;
  &lt;li&gt;\(p(z_t | x_t)\) → The mean is \(h(\mu_t)\), while the covariance is the matrix &lt;strong&gt;R&lt;/strong&gt; representing the measurement noise.&lt;/li&gt;
  &lt;li&gt;\(bel(x_t)\) → \(\mu_t\) the state estimate at previous time step before putting through system model and covariance is \(\Sigma_t\).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;exercise-1d-explain-in-a-few-sentences-all-of-the-components-of-the-ekf-algorithm&quot;&gt;&lt;strong&gt;Exercise 1.d&lt;/strong&gt;: Explain in a few sentences all of the components of the EKF algorithm.&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;\(\mu_t\) → state estimate at time \(t\), (n,1)&lt;/li&gt;
  &lt;li&gt;\(\Sigma_t\) → covariance matrix at time \(t\), (n,n)&lt;/li&gt;
  &lt;li&gt;\(\bar{\mu_t}\) → state estimate propagated through time using the process model., (n,1)&lt;/li&gt;
  &lt;li&gt;\(\bar{\Sigma_t}\) → covariance matrix at time \(t\) updated with Jacobian, &lt;strong&gt;G&lt;/strong&gt;,  and process noise, &lt;strong&gt;Q&lt;/strong&gt;. (n,n)&lt;/li&gt;
  &lt;li&gt;\(g\) → function to update state space based on some motion/process/system model., (n,1)&lt;/li&gt;
  &lt;li&gt;\(G_t^x \) → Jacobian of the motion matrix. (n,n)&lt;/li&gt;
  &lt;li&gt;\(R_t\)  → measurement noise,  (m,m)&lt;/li&gt;
  &lt;li&gt;\(h\) → measurement function, (m,1)&lt;/li&gt;
  &lt;li&gt;\(H_t^x\) → Jacobian of h,  (n,m)&lt;/li&gt;
  &lt;li&gt;\(Q_t\) → process noise, (n,n)&lt;/li&gt;
  &lt;li&gt;\(K_t\) → Kalman gain&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;exercise-2a-derive-the-jacobian-matrix-g_tx--of-the-noise-free-motion-function-g-with-respect-to-the-pose-of-the-robot-use-the-odometry-motion-model-as-in-exercise-sheet-1&quot;&gt;&lt;strong&gt;Exercise 2.a&lt;/strong&gt;: Derive the Jacobian matrix \(G_t^x \) of the noise-free motion function \(g\) with respect to the pose of the robot. Use the odometry motion model as in exercise sheet 1.&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Apologies for the sloppy hand writing. Will port to latex at some point&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/J.png&quot; alt=&quot;J&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;exercise-2b-derive-the-jacobian-matrix-h_ti-of-the-noise-free-sensor-function-h-corresponding-to-the-ith-landmark&quot;&gt;&lt;strong&gt;Exercise 2.b&lt;/strong&gt;: Derive the Jacobian matrix \(H_t^i\) of the noise-free sensor function \(h\) corresponding to the \(i^{th}\) landmark.&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/H.png&quot; alt=&quot;H&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 07 Oct 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ais/2019/10/07/ais.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ais/2019/10/07/ais.html</guid>
        
        
        <category>ais</category>
        
      </item>
    
      <item>
        <title>ROS2: Quality of Service (QoS)</title>
        <description>&lt;h4 id=&quot;quality-of-service-qos&quot;&gt;Quality of Service (QoS)&lt;/h4&gt;

&lt;p&gt;12/8/2020: Edit to remind about a key concept from the &lt;a href=&quot;https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings/&quot;&gt;docs&lt;/a&gt; with respect to QoS.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;A connection between a publisher and a subscription is only made if the pair has compatible QoS profiles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ROS2 allows for granular management of the quality of service (QoS) by exposing the QoS profile. The profile is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; defined as follows in &lt;a href=&quot;https://github.com/ros2/rmw/blob/master/rmw/include/rmw/types.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;types.h&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/// ROS MiddleWare quality of service profile. *
typedef struct RMW_PUBLIC_TYPE rmw_qos_profile_t
{
  enum rmw_qos_history_policy_t history;
  size_t depth;
  enum rmw_qos_reliability_policy_t reliability;
  enum rmw_qos_durability_policy_t durability;
  struct rmw_time_t deadline;
  struct rmw_time_t lifespan;
  enum rmw_qos_liveliness_policy_t liveliness;
  struct rmw_time_t liveliness_lease_duration;
  bool avoid_ros_namespace_conventions;
} rmw_qos_profile_t;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Modified for readability&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If the QoS settings are not modified the default settings are applied. For example, the QoS defaults settings for publishers and subscribers are specified by the profile &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rmw_qos_profile_default&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;static const rmw_qos_profile_t rmw_qos_profile_default =
{
  RMW_QOS_POLICY_HISTORY_KEEP_LAST,
  10,
  RMW_QOS_POLICY_RELIABILITY_RELIABLE,
  RMW_QOS_POLICY_DURABILITY_VOLATILE,
  RMW_QOS_DEADLINE_DEFAULT,
  RMW_QOS_LIFESPAN_DEFAULT,
  RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
  RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT,
  false
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This profile isn’t particularly fitting for sensor data where in most use cases the priority is placed on receiving data in a timely fashion as opposed to receiving all the data. Reliability can be sacrificed. Default profiles are available, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rmw_qos_profile_sensor_data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example use cases:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//example1.hpp
  rmw_qos_profile_t qos_profile = rmw_qos_profile_sensor_data;

//example1.cpp
auto qos = rclcpp::QoS(
    rclcpp::QoSInitialization(
      qos_profile.history,
      qos_profile.depth
    ),
    qos_profile);

pub_ = create_publisher&amp;lt;sensor_msgs::msg::Image&amp;gt;(topic_, qos);


//example2.hpp
  rclcpp::QoS qos_;

//example2.cpp

RtspStreamer::RtspStreamer(const rclcpp::NodeOptions &amp;amp; options)
: Node(&quot;rtsp_streamer&quot;, options),
  qos_(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_sensor_data))
{
  ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://docs.ros2.org/latest/api/rclcpp/qos_8hpp_source.html&quot;&gt;QoS signature definition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A more complete example can be found in the &lt;a href=&quot;https://github.com/ros2/demos/blob/master/image_tools/src/cam2image.cpp&quot;&gt;cam2image&lt;/a&gt; demo.&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings/&lt;/li&gt;
  &lt;li&gt;http://design.ros2.org/articles/qos.html1&lt;/li&gt;
  &lt;li&gt;https://github.com/ros2/demos/blob/master/image_tools/src/cam2image.cpp&lt;/li&gt;
  &lt;li&gt;https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h&lt;/li&gt;
  &lt;li&gt;https://github.com/ros2/rmw/blob/master/rmw/include/rmw/types.h&lt;/li&gt;
  &lt;li&gt;https://answers.ros.org/question/298594/how-does-ros2-select-the-default-qos-profile/&lt;/li&gt;
  &lt;li&gt;https://docs.ros2.org/latest/api/rclcpp/qos_8hpp_source.html&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 17 Aug 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros2/2019/08/17/ros2-qos.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros2/2019/08/17/ros2-qos.html</guid>
        
        
        <category>ros2</category>
        
      </item>
    
      <item>
        <title>Autonomous Intelligent Systems #1: Robot Mapping</title>
        <description>&lt;p&gt;Documenting a self-study exercise of working through the &lt;a href=&quot;http://ais.informatik.uni-freiburg.de/teaching/ss18/robotics/&quot;&gt;Robot
Mapping&lt;/a&gt; course offered
by the Autonomous Intelligent Systems lab at the University of Freiburg.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/06/01/ais.html&quot;&gt;Autonomous Intelligent Systems #1: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/2019/10/07/ais.html&quot;&gt;Autonomous Intelligent Systems #2: Robot Mapping&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/ais/ekf/2019/11/10/ais-ekf-slam.html&quot;&gt;Autonomous Intelligent Systems #3: Robot Mapping&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The course uses Matlab but as an extra personal challenge I am porting the code
to work with Python3 as I proceed forward.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/surfertas/ais_robot_mapping/tree/master/sheet1&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before attempting the problem set (sheets) complete the slides+recording on the
following topics.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Course Introduction&lt;/li&gt;
  &lt;li&gt;Introduction to Robot Mapping&lt;/li&gt;
  &lt;li&gt;Homogeneous Coordinates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://ais.informatik.uni- freiburg.de/teaching/ws18/mapping/exercise/robotMappingSheet01.pdf&quot;&gt;Sheet 1&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;exercise-1-skipping-as-just-an-intro-to-octave&quot;&gt;Exercise 1: Skipping as just an intro to Octave.&lt;/h4&gt;
&lt;h4 id=&quot;exercise-2-implement-an-odometry-model&quot;&gt;Exercise 2: Implement an odometry model.&lt;/h4&gt;
&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.py&lt;/code&gt; which should generate an image for each time step. The figures
will be saved to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/plots&lt;/code&gt; directory. Next, from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/plots&lt;/code&gt; directory run
the following command to generate a video from the images.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ avconv -r 10 -start_number 0 -i 'odom_%d.png' -b 500000  odom.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should represent a stream of a robot in motion with the visualization of the
landmarks that the robot is sensing at each time step.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/b_0L9LwvAww&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;exercise-3&quot;&gt;Exercise 3:&lt;/h4&gt;
&lt;h5 id=&quot;3a&quot;&gt;3.a&lt;/h5&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v2t()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v()&lt;/code&gt; are defined &lt;a href=&quot;https://github.com/surfertas/ais_robot_mapping/blob/master/sheet1/robot_mapping/homogenous_transformation.py&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Chaining transformations is the result of applying the dot operator to each transformation matrix in order. An example of a composition can found &lt;a href=&quot;https://github.com/surfertas/ais_robot_mapping/blob/master/sheet1/tests/test_homogenous_transformation.py&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h5 id=&quot;3b-given-two-robot-poses-x_1-and-x_2-how-do-you-get-the-relative-transformation-from-x_1to-x_2&quot;&gt;3.b Given two robot poses \(x_1\), and \(x_2\) how do you get the relative transformation from \(x_1\)to \(x_2\)?&lt;/h5&gt;

&lt;h5 id=&quot;3c-given-a-robot-pose-and-observation-z-of-a-landmark-relative-to-x_t-compute-the-location-of-the-landmark&quot;&gt;3.c Given a robot pose and observation z of a landmark relative to \(x_t\) compute the location of the landmark.&lt;/h5&gt;

&lt;p&gt;We can complete the exercise by converting the robot pose to a homogeneous
transformation using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v2t()&lt;/code&gt; function and taking the dot product with the
homogeneous representation of observation \(z\). Note that if we were given the
location of the landmark in the world frame, we would need the inverse of the
transformed pose \(x_t\), to map the landmark location to a coordinate in the pose
frame.&lt;/p&gt;
</description>
        <pubDate>Sat, 01 Jun 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ais/2019/06/01/ais.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ais/2019/06/01/ais.html</guid>
        
        
        <category>ais</category>
        
      </item>
    
      <item>
        <title>Before I forget #1: FFT algorithm</title>
        <description>&lt;h3 id=&quot;fft-algorithm&quot;&gt;FFT Algorithm&lt;/h3&gt;

&lt;h4 id=&quot;intro&quot;&gt;Intro&lt;/h4&gt;
&lt;p&gt;A polynomial in coefficient form (e.g. \(1+x-x^2+x^5)\) can be converted to
point-value form in \(O(nlogn)\) time.&lt;/p&gt;

&lt;p&gt;Given two polynomials in coefficient form we can convert from coefficient
representation which would require \(O(n^2)\) time to point-value form through
&lt;strong&gt;evaluation&lt;/strong&gt; in \(O(nlogn)\) using whats known as the FFT algorithm.
Multiplication in point-value form requires \(O(n)\) time. Once the multiplication
has been complete we can &lt;strong&gt;interpolate&lt;/strong&gt; to retrieve the coefficient
representation of the polynomial.&lt;/p&gt;

&lt;h4 id=&quot;a-concrete-example-is-as-follows&quot;&gt;A concrete example is as follows.&lt;/h4&gt;

&lt;p&gt;Let:
\[A(x) = 1 + x + 2x^2\]
\[B(x) = 2 + 3x\]&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Find the degree of each \(A(x)\) and \(B(x)\). Let \(n=4\) which is equal to the minimum
power of 2 that is greater than the \(deg(A)\) and the \(deg(B)\).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use the \(n\)-th roots of unity. In this case we need the \(4\)-th roots of unity
which are \(w_4 = &amp;lt;1,i,-1,-i&amp;gt;\)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pass the coefficients of the polynomials of \(A(x)\), \(a=[1,1,2,0]\) and the 4-th
roots of unity, \(w_4\) to the FFT algorithm. Point-value form = \(FFT(a,
w_4)\). Repeat
for \(B(x)\).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once we have the results, use element-wise multiplication to obtain the
\(c\),
the point-value representation of \(C(x)\). To interpolate take the inverse of
\(w_4\),
\(w_4^-1 = &amp;lt;1,-i,-1,i&amp;gt;\), and \(c=[20, -5-i, -2, -5+i]\) and pass to \(1/n *FFT(c, w_4^-1)\)
to obtain the coefficients the \([2,5,7,6]\) which maps to the polynomial \(2+5x+7x^2+6x^3\).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;fft-a-divide--conquer-dc-approach&quot;&gt;FFT: a Divide &amp;amp; Conquer (D&amp;amp;C) approach&lt;/h4&gt;

&lt;p&gt;A recursive algorithm:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def FFT(a, w):
    if |w| = 1:
        return a

    a_even = even_indices_of_a
    a_odd = odd_indices_of_a

    S = FFT(a_even, w^2)
    O = FFT(a_odd, w^2)

    for i in 0 to n/2:
        r_i = S_i + w_i * O_i
        r_i+n/2 = S_i - w_i * O_i
    return [r_0...r_n]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A concrete example using the polynomials A(x) and B(x) introduced previously.
Sorry for the formatting but it will make sense if you stare at it long enough.&lt;/p&gt;

&lt;h5 id=&quot;level-1&quot;&gt;&lt;strong&gt;LEVEL 1&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;FFT(\(a=[1,1,2,0]\), \(w_4=[1,i,-1,i]\)):&lt;/p&gt;

&lt;p&gt;\(|w_4|\) \(\neq\) \(1\) so continue.&lt;/p&gt;

&lt;p&gt;a_even \(= [1,2]\)&lt;/p&gt;

&lt;p&gt;a_odd \(= [1,0]\)&lt;/p&gt;

&lt;p&gt;\(S\) = \(\color{blue}{FFTEVEN}\)(a_even\(=[1,2]\), \(w_4^2=w_2=[1,-1]\)) \(= [3,-1]\)&lt;/p&gt;

&lt;p&gt;\(O\) = \(\color{purple}{FFTODD}\)(a_odd\(=[1,0], w_4^2=w_2=[1,-1]\)) \(= [1, 1]\)&lt;/p&gt;

&lt;p&gt;return \([4, -1+i, 2,-1-i]\)&lt;/p&gt;

&lt;h5 id=&quot;level-2&quot;&gt;&lt;strong&gt;LEVEL 2&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;\(\color{blue}{FFTEVEN}\)(a_even\(=[1,2], w_4^2=w_2=[1,-1]\))&lt;/p&gt;

&lt;p&gt;\(|w_2|\) \(\neq\) \(1\) so continue.&lt;/p&gt;

&lt;p&gt;a_even \(= [1]\)&lt;/p&gt;

&lt;p&gt;a_odd \(= [2]\)&lt;/p&gt;

&lt;p&gt;\(S\) = \(\color{teal}{FFTEVENEVEN}\)(\(a_even=[1]\), \(w_2^2=w_1=[1]\)) \(= 1\)&lt;/p&gt;

&lt;p&gt;\(O\) = \(\color{fuchsia}{FFTEVENODD}\)(\(a_odd=[2]\), \(w_2^2=w_1=[1]\)) \(= 2\)&lt;/p&gt;

&lt;p&gt;return \([1+1&lt;em&gt;2=3, 1+ -1&lt;/em&gt;2=-1]\)&lt;/p&gt;

&lt;p&gt;\(\color{purple}{FFTODD}\)(a_odd\(=[1,0]\), \(w_4^2=w_2=[1,-1]\))&lt;/p&gt;

&lt;p&gt;\(|w_2|\) \(\neq\) \(1\) so continue.&lt;/p&gt;

&lt;p&gt;a_even \(= [1]\)&lt;/p&gt;

&lt;p&gt;a_odd \(= [0]\)&lt;/p&gt;

&lt;p&gt;\(S\) = \(\color{red}{FFTODDEVEN}\)(\(a_even=[1], w_2^2=w_1=[1]\)) \(= 1\)&lt;/p&gt;

&lt;p&gt;\(O\) = \(\color{green}{FFTODDODD}\)(\(a_odd=[0], w_2^2=w_1=[1]\)) \(= 0\)&lt;/p&gt;

&lt;p&gt;return \([1+1&lt;em&gt;0=1, 1+ -1&lt;/em&gt;0=1]\)&lt;/p&gt;

&lt;h5 id=&quot;level-3&quot;&gt;&lt;strong&gt;LEVEL 3&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;\(\color{teal}{FFTEVENEVEN}\)(a_even=\([1]\), \(w_2^2=w_1=[1]\))&lt;/p&gt;

&lt;p&gt;\(|w_1|\) \(= 1\) return \(1\)&lt;/p&gt;

&lt;p&gt;\(\color{fuchsia}{FFTEVENODD}\)(a_odd=\([2]\), \(w_2^2=w_1=[1]\))&lt;/p&gt;

&lt;p&gt;\(|w_1|\) \(= 1\) return \(2\)&lt;/p&gt;

&lt;p&gt;\(\color{red}{FFTODDEVEN}\)(a_even\(=[1]\), \(w_2^2=w_1=[1]\))&lt;/p&gt;

&lt;p&gt;\(|w_1|\) \(= 1\) return \(1\)&lt;/p&gt;

&lt;p&gt;\(\color{green}{FFTODDODD}\)(a_odd\(=[0]\), \(w_2^2=w_1=[1]\))&lt;/p&gt;

&lt;p&gt;\(|w_1|\) \(= 1\) return \(0\)&lt;/p&gt;

&lt;p&gt;Repeating for b, the results of FFT(\(b, w_4\)) \(= [5, 2+3i, -1, 2-3i]\)&lt;/p&gt;

&lt;p&gt;\(c = a * b\), element-wise multiplication results in \([20, -5-i,
-2,-5+i]\).&lt;/p&gt;

&lt;p&gt;To move from point-value representation back to coefficients, we can interpolate
by using the same FFT D&amp;amp;C algorithm by passing \(c\), and \(w_4^-1\) as inputs resulting
in the coefficents \([2,5,7,6]\) and a final solution \(2+5x+7x^2 + 6x^3\).&lt;/p&gt;

</description>
        <pubDate>Mon, 13 May 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/fft/2019/05/13/2019-fft.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/fft/2019/05/13/2019-fft.html</guid>
        
        
        <category>fft</category>
        
      </item>
    
      <item>
        <title>A minimal example using cmake to create a c++ shared library.</title>
        <description>&lt;p&gt;1# CMakeLists.txt for &lt;a href=&quot;https://github.com/surfertas/fun_with_cpp/tree/master/project_euler/PrimeUtil&quot;&gt;PrimUtil&lt;/a&gt;
a library for utilities related to working with prime numbers.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmake_minimum_required(VERSION 2.8.9)
project (PrimeUtil)
set(CMAKE_CXX_STANDARD 11)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(PrimeUtil SHARED src/primeutil.cpp)

install(TARGETS PrimeUtil DESTINATION /usr/lib)
install(FILES include/primeutil.h DESTINATION include)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2# Make the generator and build from the build directory.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd build
$ cmake ..
-- The C compiler identification is GNU 5.5.0
-- The CXX compiler identification is GNU 5.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to:
/home/tasuku/workspace/cpp/project_euler/PrimeUtil/build
$ make
Scanning dependencies of target PrimeUtil
[ 50%] Building CXX object CMakeFiles/PrimeUtil.dir/src/primeutil.cpp.o
[100%] Linking CXX shared library libPrimeUtil.so
[100%] Built target PrimeUtil
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3# Make the library available system wide. This will install and place in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/lib&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo make install
[100%] Built target PrimeUtil
Install the project...
-- Install configuration: &quot;&quot;
-- Installing: /usr/lib/libPrimeUtil.so
-- Up-to-date: /usr/local/include/primeutil.h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;4# CMakeLists.txt for example
&lt;a href=&quot;https://github.com/surfertas/fun_with_cpp/tree/master/project_euler/3-largest_prime_factor&quot;&gt;program&lt;/a&gt;
(solution to a Project Euler question) that links to PrimeUtil library.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmake_minimum_required(VERSION 2.8.9)
project (largest_prime_factor)
set(CMAKE_CXX_STANDARD 11)

find_library(PRIMEUTIL_LIB libPrimeUtil.so)
message(STATUS ${PRIMEUTIL_LIB})

add_executable(largest_prime_factor src/main.cpp)
target_link_libraries(largest_prime_factor PRIVATE ${PRIMEUTIL_LIB})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;5# Make the generator and build. A binary called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;largest_prime_factor&lt;/code&gt; should be found in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/build&lt;/code&gt; and executable.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./largest_prime_factor 5678899999
Largest prime factor is: 6217
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://cmake.org/cmake/help/v3.0/manual/cmake-language.7.html#line-comment&lt;/li&gt;
  &lt;li&gt;http://www.dillonbhuff.com/?p=15&lt;/li&gt;
  &lt;li&gt;http://derekmolloy.ie/hello-world-introductions-to-cmake/&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 01 May 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/cmake/cpp/projecteuler/2019/05/01/cmake.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/cmake/cpp/projecteuler/2019/05/01/cmake.html</guid>
        
        
        <category>cmake</category>
        
        <category>cpp</category>
        
        <category>projecteuler</category>
        
      </item>
    
      <item>
        <title>Autonomous Mobile Robot #4: Using GCP Storage</title>
        <description>&lt;p&gt;Series:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html&quot;&gt;Autonomous Mobile Robot #1: Data collection to a trained model&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html&quot;&gt;Autonomous Mobile Robot #2: Inference as a ROS service&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&quot;&gt;Autonomous Mobile Robot #3: Pairing with a PS3 Controller for teleop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html&quot;&gt;Autonomous Mobile Robot #4: Using GCP Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have fallen back to PyTorch (once again). The training environment is still integrated with Google Cloud Platform(GCP).&lt;/p&gt;

&lt;p&gt;The current process implemented to get the collected samples to the training
environment is notably manual as one can see in the walk through in the coming
paragraphs. I plan to automate the process as much as possible on iterations to follow.&lt;/p&gt;

&lt;h4 id=&quot;a-rough-outline-of-the-system-in-place&quot;&gt;A rough outline of the system in place&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The raw images from a monocular camera and associated controls are stored on an
external SSD connected to the Raspi via a USB cable. At a user specified
frequency a pickle file that contains samples (path to image, controls) is saved
to the SSD.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once data collection process is complete the data needs to be transferred to GCP storage.
Note that a GCP bucket is required. The following command will transfer the file from the SSD to the specified cloud storage.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ gsutil -m cp -r  [image_dir] gs://[bucket_name]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;It is worth highlighting that using the option -m speeds up the transfer considerably where gsutil help describes the flag as follows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Causes supported operations (acl ch, acl set, cp, mv, rm, rsync, and setmeta) to
run in parallel. This can significantly improve performance if you are
performing operations on a large number of files over a reasonably fast network
connection.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Next we need to move the training data from GCP storage to the VM instance
used for GPU training. We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gsutil -m cp -r gs://[bucket_name] [data_dir_on_vm_instance]&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once the data has been transferred, we can move to the training &lt;a href=&quot;https://github.com/surfertas/deep_learning/tree/master/projects/pilotnet_controller&quot;&gt;environment&lt;/a&gt; and generate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcs.csv&lt;/code&gt; file. Go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/gcs&lt;/code&gt; and run the following command.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$  ls [data_dir_on_vm_instance] &amp;gt;&amp;gt; gcs.csv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once complete, we can run the script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generate_csv_with_url.py&lt;/code&gt; and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path_to_data.csv&lt;/code&gt; will be generated.&lt;/p&gt;

&lt;h4 id=&quot;start-the-training&quot;&gt;Start the training&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Set the training configuration in the &lt;a href=&quot;https://github.com/surfertas/deep_learning/tree/master/projects/pilotnet_controller/config&quot;&gt;config/default.py&lt;/a&gt; file. Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python train.py&lt;/code&gt; and the training process should kick off.&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 31 Mar 2019 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html</guid>
        
        
        <category>amr</category>
        
        <category>deeplearning</category>
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Autonomous Mobile Robot #3: Pairing with a PS3 Controller for teleop</title>
        <description>&lt;p&gt;Series:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html&quot;&gt;Autonomous Mobile Robot #1: Data collection to a trained model&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html&quot;&gt;Autonomous Mobile Robot #2: Inference as a ROS service&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&quot;&gt;Autonomous Mobile Robot #3: Pairing with a PS3 Controller for teleop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html&quot;&gt;Autonomous Mobile Robot #4: Using GCP Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I ran into issues trying to pair a PS3 dual shock controller with a Raspberry Pi
to be used for training an autonomous mobile robot (e.g. Donkey) running on ROS. 
Note that I am using Ubuntu Mate as the OS as opposed to Raspbian, the de-facto
OS for the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;First try the ROS recommended &lt;a href=&quot;http://wiki.ros.org/ps3joy/Tutorials/PairingJoystickAndBluetoothDongle&quot;&gt;method&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If this does not work try the following:&lt;/p&gt;

&lt;p&gt;Start with the PS3 controller disconnected. If you see the PS3 Controller listed
as a device remove the device first using the remove command, otherwise you can
skip that step.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ surferta@surfertas: sudo bash
$ root@surfertas:~# bluetoothctl
$ [NEW] Controller B8:27:EB:05:90:2E surfertas [default]
$ [NEW] Device 28:A1:83:4B:3A:30 PLAYSTATION(R)3 Controller
$ [PLAYSTATION(R)3 Controller]# remove 28:A1:83:4B:3A:30
$ [bluetooth]# scan on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Connect PS3 controller to the Raspberry Pi.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ [PLAYSTATION(R)3 Controller]# power on
$ [bluetooth]# devices
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Disconnect the PS3 controller from the Raspberry Pi.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ [bluetooth]# agent on
$ [bluetooth]# trust 28:A1:83:4B:3A:30
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://wiki.debian.org/BluetoothUser&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sat, 22 Dec 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html</guid>
        
        
        <category>amr</category>
        
        <category>deeplearning</category>
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Medical imaging: playing with the ChestXray-14 dataset</title>
        <description>&lt;p&gt;I recently had the chance to work with the ChestX-ray14 image data-set [1],
consisting of 112,200 frontal X-ray images from 30,805 unique patients and 14
different thoracic disease labels. The dataset is imbalanced (e.g. 60,361
examples associated with “No Findings”). Imbalances appear to be common in the medical imaging domain and has driven
research to address the issue via augmentation techniques using GANs most
recently. [2]&lt;/p&gt;

&lt;p&gt;The classification task is multi-label with each X-ray image labeled with 0 or
more diseases, as opposed to a multi-class task where labels are mutually
exclusive. One can learn more about multi-label classification
in this &lt;a href=&quot;http://lpis.csd.auth.gr/publications/tsoumakas-ijdwm.pdf&quot;&gt;tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/surfertas/deep_learning/tree/master/projects/chestxray&quot;&gt;source code&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;objective&quot;&gt;Objective&lt;/h4&gt;
&lt;p&gt;The objective of the exercise was to train a number of multi-label classifiers on the
entire ChestX-ray14 dataset and compare to results presented in Wang et al. 2017.&lt;/p&gt;

&lt;h4 id=&quot;data-analysis&quot;&gt;Data Analysis&lt;/h4&gt;
&lt;p&gt;For EDA on the ChestX-ray14 dataset check out good work done
in a &lt;a href=&quot;https://www.kaggle.com/sbernadac/lung-deseases-data-analysis&quot;&gt;Kaggle kernel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this exercise I used GCP  (Google Cloud Platform) for storage and training.  Data
and meta data can be found &lt;a href=&quot;https://nihcc.app.box.com/v/ChestXray-NIHCC&quot;&gt;here&lt;/a&gt;.
In addition to storage, appropriate compute was necessary.  A &lt;a href=&quot;https://console.cloud.google.com/marketplace/details/click-to-deploy-images/deeplearning&quot;&gt;GCP Deep Learning
VM&lt;/a&gt;
was used for pre-processing and training.  \(\textbf{Note}\): dont forget to click
“Install NVIDIA GPU driver automatically on first startup?” and also select the
appropriate image. (When using Tensorflow you may run into CUDA version issues.)
I ended up using an image with CUDA 9.0.  Training is done using 1 NVIDIA Tesla
P100 and 16 CPUs with 104GB of memory collectively.&lt;/p&gt;

&lt;h4 id=&quot;preprocess&quot;&gt;Preprocess&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;Converted string labels, e.g. Effusion&lt;/td&gt;
          &lt;td&gt;Emphysema&lt;/td&gt;
          &lt;td&gt;Infiltration&lt;/td&gt;
          &lt;td&gt;Pneumothorax, to multi-hot encodings.&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;Converted raw images, and associated labels into TFRecords.&lt;/li&gt;
  &lt;li&gt;Standardized the images, subtracting mean and dividing by the standard deviation on a per image basis.&lt;/li&gt;
  &lt;li&gt;Resized images to dimensions 224x224x3.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;architectures&quot;&gt;Architectures&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;A base case simple CNN.&lt;/li&gt;
  &lt;li&gt;A pre-trained ResNet-v2-50 used as fixed feature extractor, with outputs fed
into 2 fully connected layers. (Backprop only through the FCs)&lt;/li&gt;
  &lt;li&gt;An ensemble of feature extractors with outputs put through a transition layer
before applying the add operator. Resulting vectors are passed through 2 fully
connected layers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feature extraction was done using pre-trained models found at &lt;a href=&quot;https://www.tensorflow.org/hub/&quot;&gt;tensorflow
hub&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;evaluation&quot;&gt;Evaluation&lt;/h4&gt;
&lt;p&gt;For evaluation, the AUC ROC metric was used as in Wang et. al. Googles
machine-learning crash course does a good job in explaining &lt;a href=&quot;https://developers.google.com/machine-learning/crash-course/classification/roc-and-auc&quot;&gt;ROC + AUC
ROC&lt;/a&gt;.
Further, though not applied in this exercise, accuracy measures used for
multi-label classification requires a different set of metrics. [4,5,6]&lt;/p&gt;

&lt;h4 id=&quot;results&quot;&gt;Results&lt;/h4&gt;

\[\begin{array}{rrr}
    \hline
            \textbf{Disease} &amp;amp;  \textbf{ResNetv2-50 FE AUC} &amp;amp; \textbf{Ensemble AUC} &amp;amp;
\textbf{Wang et. al} \\
    \hline
       Cardiomegaly &amp;amp; 0.6770 &amp;amp; 0.7980 &amp;amp; \textbf{0.8100} \\
          Emphysema &amp;amp; 0.7300  &amp;amp; 0.7950 &amp;amp; \textbf{0.8330} \\
           Effusion &amp;amp; 0.5710 &amp;amp; 0.6550 &amp;amp; \textbf{0.7585} \\
             Hernia &amp;amp; 0.6590 &amp;amp; 0.6930 &amp;amp; \textbf{0.8717} \\
             Nodule &amp;amp; 0.7210 &amp;amp; \textbf{0.7510} &amp;amp; 0.6687 \\
       Pneumothorax &amp;amp; 0.5210 &amp;amp; 0.6960 &amp;amp; \textbf{0.7993} \\
        Atelectasis &amp;amp; 0.6090 &amp;amp; \textbf{0.7920} &amp;amp; 0.7003 \\
 Pleural Thickening &amp;amp; 0.6440 &amp;amp; 0.6660 &amp;amp; \textbf{0.6835} \\
               Mass &amp;amp; 0.7720 &amp;amp; \textbf{0.8420} &amp;amp; 0.6933 \\
              Edema &amp;amp; 0.6390 &amp;amp; 0.6820 &amp;amp; \textbf{0.8052} \\
      Consolidation &amp;amp; 0.7630 &amp;amp; \textbf{0.8210} &amp;amp; 0.7032 \\
       Infiltration &amp;amp; 0.6130 &amp;amp; \textbf{0.7060} &amp;amp; 0.6614 \\
           Fibrosis &amp;amp; 0.6950 &amp;amp; 0.7480 &amp;amp; \textbf{0.7859} \\
          Pneumonia &amp;amp; 0.6640 &amp;amp; \textbf{0.7200} &amp;amp; 0.6580 \\
    \hline
\end{array}\]

&lt;ol&gt;
  &lt;li&gt;ResNet-v2-50 as a feature extractor takes about 50 minutes.&lt;/li&gt;
  &lt;li&gt;Ensemble of feature extractors takes about 90 minutes, for 10 epochs. Early
stopping is used after 5 epochs for results.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;further-studies&quot;&gt;Further Studies&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Address class imbalance using
&lt;a href=&quot;https://reference.wolfram.com/language/tutorial/NeuralNetworksExampleWeighting.html&quot;&gt;example-weighted&lt;/a&gt;
neural network training.&lt;/li&gt;
  &lt;li&gt;Use data augmentation to increase sample size as well as address class
imbalances.&lt;/li&gt;
  &lt;li&gt;Integrate more features (e.g. age, gender, etc.) as a embedding and
concatenate with the encoded images after feature extraction.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h4&gt;
&lt;p&gt;Training environment was based off code examples found at
&lt;a href=&quot;https://cs230-stanford.github.io/&quot;&gt;cs230-stanford&lt;/a&gt;. This is one of the better
starting points I have come across, in addition to walking through best
practices on data pipelines, and reproducibility. Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build_dataset.py&lt;/code&gt;
was heavily modified in my use case for use with GCP storage and TFRecords, as
well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;input_fn.py&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;train.py&lt;/code&gt; to work with the multi-label task.&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://nihcc.app.box.com/v/ChestXray-NIHCC/file/256057377774&lt;/li&gt;
  &lt;li&gt;https://github.com/xinario/awesome-gan-for-medical-imaging&lt;/li&gt;
  &lt;li&gt;http://lpis.csd.auth.gr/publications/tsoumakas-ijdwm.pdf&lt;/li&gt;
  &lt;li&gt;https://stats.stackexchange.com/questions/12702/what-are-the-measure-for-accuracy-of-multilabel-data&lt;/li&gt;
  &lt;li&gt;https://stackoverflow.com/questions/37746670/tensorflow-multi-label-accuracy-calculation&lt;/li&gt;
  &lt;li&gt;https://towardsdatascience.com/journey-to-the-center-of-multi-label-classification-384c40229bff&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 12 Dec 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2018/12/12/chestxray.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2018/12/12/chestxray.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Refresher: a few resources covering RNNs, trainable parameters + flops</title>
        <description>&lt;p&gt;A few topics/resources that I needed recently as a refresher. Need to summarize at a later date…&lt;/p&gt;

&lt;h4 id=&quot;rnns&quot;&gt;RNNs&lt;/h4&gt;
&lt;h5 id=&quot;improving-learning&quot;&gt;Improving learning&lt;/h5&gt;
&lt;ol&gt;
  &lt;li&gt;https://pytorch.org/docs/stable/_modules/torch/nn/modules/normalization.html&lt;/li&gt;
  &lt;li&gt;http://ceur-ws.org/Vol-2142/paper4.pdf&lt;/li&gt;
  &lt;li&gt;https://github.com/DingKe/pytorch_workplace/blob/master/rnn/modules.py#L122&lt;/li&gt;
  &lt;li&gt;https://discuss.pytorch.org/t/proper-way-to-do-gradient-clipping/191/14&lt;/li&gt;
  &lt;li&gt;https://github.com/yunjey/pytorch-tutorial/blob/master/tutorials/02-intermediate/language_model/main.py&lt;/li&gt;
  &lt;li&gt;https://forums.fast.ai/t/30-best-practices/12344&lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;variable-rnn&quot;&gt;Variable RNN&lt;/h5&gt;
&lt;ol&gt;
  &lt;li&gt;https://pytorch.org/docs/stable/nn.html#torch.nn.utils.rnn.pack_padded_sequence&lt;/li&gt;
  &lt;li&gt;https://towardsdatascience.com/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e&lt;/li&gt;
  &lt;li&gt;https://discuss.pytorch.org/t/understanding-pack-padded-sequence-and-pad-packed-sequence/4099/6&lt;/li&gt;
  &lt;li&gt;https://gist.github.com/Tushar-N/dfca335e370a2bc3bc79876e6270099e&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;calculating-trainable-parameters-and-flops&quot;&gt;Calculating trainable parameters and flops&lt;/h4&gt;
&lt;h5 id=&quot;flops&quot;&gt;Flops&lt;/h5&gt;
&lt;ol&gt;
  &lt;li&gt;http://machinethink.net/blog/how-fast-is-my-model/&lt;/li&gt;
  &lt;li&gt;https://stats.stackexchange.com/questions/328926/how-many-parameters-are-in-a-gated-recurrent-unit-gru-recurrent-neural-network&lt;/li&gt;
  &lt;li&gt;https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/&lt;/li&gt;
  &lt;li&gt;https://piazza.com/class/jjjilbkqk8m1r4?cid=1063&lt;/li&gt;
  &lt;li&gt;https://stats.stackexchange.com/questions/291843/how-to-understand-calculate-flops-of-the-neural-network-model&lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;trainable-parameters&quot;&gt;Trainable parameters&lt;/h5&gt;
&lt;ol&gt;
  &lt;li&gt;https://stackoverflow.com/questions/42786717/how-to-calculate-the-number-of-parameters-for-convolutional-neural-network&lt;/li&gt;
  &lt;li&gt;https://www.learnopencv.com/number-of-parameters-and-tensor-sizes-in-convolutional-neural-network/&lt;/li&gt;
  &lt;li&gt;https://stats.stackexchange.com/questions/328926/how-many-parameters-are-in-a-gated-recurrent-unit-gru-recurrent-neural-network&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;random&quot;&gt;Random&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://documents.epfl.ch/users/f/fl/fleuret/www/dlc/dlc-handout-6-going-deeper.pdf&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 07 Nov 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2018/11/07/notes.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2018/11/07/notes.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Protii #3: Integration of Yolov2 Object Detection</title>
        <description>&lt;p&gt;Protii #3: Integration of Yolov2 Object Detection&lt;/p&gt;

&lt;p&gt;One of the features that I am implementing is object detection and tracking.
Ultimately I would like to convert the algorithm from object detection to people
detection, classification, and tracking.&lt;/p&gt;

&lt;p&gt;As I had already integrated the Yolov2 in a previous exercise, the source code
was refactored for this particular project.&lt;/p&gt;

&lt;h4 id=&quot;move-to-ros-service&quot;&gt;Move to ROS Service&lt;/h4&gt;
&lt;p&gt;At the moment the the detector is subscribing to the stream topic and
continuously running the detection algorithm and publishing results. Considering
inference is relatively expensive, changing the system to use ROS service or
actions likely makes more sense. In other words, run the detection algorithm
when a trigger has been fired. The trigger can be an algorithm requiring less
compute, or a time based trigger.&lt;/p&gt;

&lt;p&gt;Inference is done on the TX2 and I get about 4.6~4.8 FPS, with raw images coming
in at about 30 FPS. These stats degrades when measured over the network, and
this degradation can be seen in the video below.&lt;/p&gt;

&lt;p&gt;Next steps would be to retrain, (transfer learning?) and tune the model to
detect humans only, and convert the ROS package to implement detection as a
service. Also, probably make sense to update the package to use Yolov3.&lt;/p&gt;

&lt;h4 id=&quot;results&quot;&gt;Results&lt;/h4&gt;
&lt;p&gt;The video shows the display that is connected to the Jetson TX2 via a HDMI
cable. I access the protii webapp via chrome and viewed through inspection and
used the simplescreenrecorder [1] for desktop recording.&lt;/p&gt;

&lt;iframe width=&quot;320&quot; height=&quot;240&quot; src=&quot;https://www.youtube.com/embed/LDkSdR85OtA?rel=0&quot; frameborder=&quot;0&quot; allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;https://www.ubuntupit.com/15-best-linux-screen-recorder-and-how-to-install-those-on-ubuntu/&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sun, 30 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/protii/2018/09/30/protii-0002.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/protii/2018/09/30/protii-0002.html</guid>
        
        
        <category>protii</category>
        
      </item>
    
      <item>
        <title>Protii #2: RTSP stream to ROS message</title>
        <description>&lt;p&gt;Getting a stream of images from a camera to a device for processing is easier
said then done, and with plethora of options available selecting the right
pipeline is a separate challenge in itself.&lt;/p&gt;

&lt;p&gt;For this particular project, after spending hours with the raspi camera module,
I settled on using a IP camera to stream images directly to a Jetson TX series
SOC, in this case a TX2.&lt;/p&gt;

&lt;p&gt;After some web surfing, and looking at options, I settled on the Amcrest series.&lt;/p&gt;

&lt;p&gt;Specifically the IP8M-2493EW, technically produced for use outdoors according to
the description, but figured indoor use was equally possible.&lt;/p&gt;

&lt;h4 id=&quot;image-capture-setup-and-pipeline&quot;&gt;Image Capture Setup and Pipeline&lt;/h4&gt;
&lt;p&gt;The setup would consist of streaming media from the IP camera using the real
time streaming protocol, RTSP, a ROS node running on the TX2 subscribing to the
URI and converting the stream to ROS image type, and publishing the ROS
consumable image over a virtual private network where a subscriber sits on the
server. (I plan to write on a separate note about how I got the images from the
server running on a Digital Ocean droplet to the webapp using socket.io)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/protiiipstreampipeline.png&quot; alt=&quot;Pipeline&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to accomplish this I needed to find the URI associated with the stream,
which sounds trivial but difficult when documentation is sparse, and coding up a
ROS package to consume the stream and publish results, with image processing
done using openCV3.3.1.&lt;/p&gt;

&lt;h4 id=&quot;rtsp-stream-uri&quot;&gt;RTSP stream URI&lt;/h4&gt;

&lt;p&gt;The URI needs to be in the form
‘rtsp://(username):(password)@(ip):(port)/cam/realmonitor?channel=1&amp;amp;subtype=0’
where the variables enclosed in () needs to be populated.&lt;/p&gt;

&lt;h4 id=&quot;conversion-to-ros-message&quot;&gt;Conversion to ROS message&lt;/h4&gt;
&lt;p&gt;This URI is then used as the source for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::VideoCapture&lt;/code&gt; object. The
frames are read, resized, and converted to a ROS image of type
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor_msgs::ImagePtr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Find the full code &lt;a href=&quot;https://github.com/surfertas/amr_core/blob/master/amr_worker/rtsp_streamer/src/streamer.cpp&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;summary&quot;&gt;Summary&lt;/h4&gt;
&lt;p&gt;The ROS package is still incomplete and just the bare minimum and sufficient for
this prototype project. The stream is relatively stable, and I have found no
issues with the pipeline running on the TX2 for multiple days. Next steps for
this particular component is to optimize for fps and consider security measures.&lt;/p&gt;

</description>
        <pubDate>Sun, 09 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/protii/2018/09/09/protii-0001.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/protii/2018/09/09/protii-0001.html</guid>
        
        
        <category>protii</category>
        
      </item>
    
      <item>
        <title>Protii #1: Documenting my efforts in developing a web based personal surveillance system</title>
        <description>&lt;p&gt;This series will be an attempt to document my attempt to build a web based
personal surveillance system that integrates technologies from different
domains including web based technologies, robotics, and machine learning.&lt;/p&gt;

&lt;p&gt;Its an ongoing and incomplete project that has been pushed to production at
&lt;a href=&quot;https://protii.com/home&quot;&gt;www.protii.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The experience thus far has been rewarding, and an opportunity to reflect on the
actual work that goes into developing a system that is functional and useful.&lt;/p&gt;

</description>
        <pubDate>Sun, 26 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/protii/2018/08/26/protii-0000.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/protii/2018/08/26/protii-0000.html</guid>
        
        
        <category>protii</category>
        
      </item>
    
      <item>
        <title>Notes on Bayesian Learning #1: Bayes Nets and Graphical Models</title>
        <description>&lt;ol&gt;
  &lt;li&gt;Bayes Nets and Graphical Models
    &lt;ol&gt;
      &lt;li&gt;What is bayes theorem?&lt;/li&gt;
      &lt;li&gt;Joint distributions are hard to deal with…&lt;/li&gt;
      &lt;li&gt;Bayes nets and graphical models.&lt;/li&gt;
      &lt;li&gt;Markov Blankets&lt;/li&gt;
      &lt;li&gt;D-separation&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Mixture Models
    &lt;ol&gt;
      &lt;li&gt;K-means&lt;/li&gt;
      &lt;li&gt;GMM&lt;/li&gt;
      &lt;li&gt;EM algorithm&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Sampling
    &lt;ol&gt;
      &lt;li&gt;Gibbs sampling&lt;/li&gt;
      &lt;li&gt;Metropolis-Hastings (MH) sampling&lt;/li&gt;
      &lt;li&gt;Hamiltonian Monte Carlo&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Marko Chains
    &lt;ol&gt;
      &lt;li&gt;HMM&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;what-is-bayes-theorem&quot;&gt;What is bayes theorem?&lt;/h3&gt;

&lt;p&gt;To understand Bayes theorem, lets start with the joint distribution between
random variables \(Y\), which we will designate as the cause, \(X\), as the
effect. The variables are binary taking on values of either \(0\) or\(1\).
\[P(X,Y)\]&lt;/p&gt;

&lt;p&gt;We can factor, or break apart, the joint in two different ways via the chain
rule. \[P(X,Y) = P(X|Y) P(Y) = P(Y|X)P(X)\]&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Thus in order to determine, \(P(Y&lt;/td&gt;
      &lt;td&gt;X)\), the probability of the cause given&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;the effect, we can reorder the above to obtain \[\frac{P(X&lt;/td&gt;
      &lt;td&gt;Y)P(Y)}{P(X)} =&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;P(Y&lt;/td&gt;
      &lt;td&gt;X)\]&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The above is often shown as \[\frac{(Likelihood)*(Prior)}{(Normalization)} =
(Posterior)\]&lt;/p&gt;

&lt;p&gt;Essentially, we are updating our prior belief of \(Y\) represented as
\(P(Y)\) by the likelihood effect given the cause divided by some
normalization constant to arrive upon a new belief of \(Y\) given \(X\).&lt;/p&gt;

&lt;h3 id=&quot;joint-distributions-are-hard-to-deal-with&quot;&gt;Joint distributions are hard to deal with…&lt;/h3&gt;

&lt;p&gt;Most often times the joint distribution is not practical to compute, in other
words intractable. Lets consider a set of random variables consisting of 2
random binary variables, \((X,Y)\), again. We know that there are \(2^2\)
possible outcomes, \((0,0), (1,0), (0,1), (1,1)\), allowing for effortless
computation of the joint probability of \(P(X=1, Y=0)\) as \(0.25\). This was easy as we
knew how many outcomes aligned with \(X=1\) and \(Y=0\) and also the set of
all possible outcomes.&lt;/p&gt;

&lt;p&gt;When is this process difficult? Well now consider a set of 20 random binary variables. The
set of all possible outcomes is \(2^20-1\) or \(1,048,575\) combinations. Now consider
random variables taking on an arbitrary number of values. You can quickly see
how the “all possible outcomes” statement becomes difficult.&lt;/p&gt;

&lt;p&gt;The joint distribution often represents an obstacle which has
resulted in the development of abstractions that help to address the
intractability of some joint distributions via graphical models and sampling
methods.&lt;/p&gt;

&lt;h3 id=&quot;bayes-nets-and-graphical-models&quot;&gt;Bayes nets and graphical models&lt;/h3&gt;

&lt;p&gt;Graphical models are ways to address the computation load of some joint
distributions by introducing domain expertise in the form of cause and effect
relationships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“A Bayesian network, Bayes network, belief network, Bayes(ian) model or
probabilistic directed acyclic graphical model is a probabilistic graphical
model (a type of statistical model) that represents a set of variables and their
conditional dependencies via a directed acyclic graph (DAG).”&lt;/strong&gt;- Wiki[1]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The first is to see the network as a representation of the joint probability
distribution.  The second is to view
it as an encoding of a collection of conditional independence statements.”&lt;/strong&gt; -
AIMA [2]&lt;/p&gt;

&lt;p&gt;Said simply its a graphical model defining conditional relationships between
random variables, with connecting arrows (not bi-directional as its acyclic (not
cyclical)) usually in the arrows flowing from causes to effects.&lt;/p&gt;

&lt;p&gt;Sticking with the example from Wikipedia, lets work with a small graphical model
represented by a set of three random boolean variables, \(s\), \(rain\),
\(wet\), where \(s\) stands for sprinkler.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/smallgraphmodel.png&quot; alt=&quot;png&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;in-words&quot;&gt;In words&lt;/h4&gt;
&lt;p&gt;The probabilities that this graphical represents is as follows:
\(P(s|rain)\), the probability of a given state of the sprinkler given whether
it rains or not,  \(P(rain)\), the probability of whether it rains or not, and
\(P(wet|s, rain)\), the probability that its wet, given the state of the
sprinkler and whether it rains or not.&lt;/p&gt;

&lt;p&gt;The joint distribution over \(s, rain, wet\) can be now be represented as
\(P(wet|s,rain)P(s|rain)P(rain)\)&lt;/p&gt;

&lt;h4 id=&quot;conditional-probability-tablecpt&quot;&gt;Conditional Probability Table(CPT)&lt;/h4&gt;
&lt;p&gt;We can derive a CPT, conditional probability table, from the graphical model.
This is where the domain knowledge comes into play as the CPT is typically
provided.&lt;/p&gt;

&lt;p&gt;Lets assume the below CPT (I set the probabilities using some common sense):&lt;/p&gt;

\[\begin{array}{rr}
P(s|r) \\ \hline
r &amp;amp; s &amp;amp;0.1  \\ \hline
r &amp;amp; \neg s &amp;amp;0.9  \\ \hline
\neg r &amp;amp;s &amp;amp;0.7  \\ \hline
\neg r &amp;amp;\neg s &amp;amp;0.3\\ \hline
\end{array}


\begin{array}{rr}
P(r) \\ \hline
r  &amp;amp;0.3 \\ \hline
\neg r  &amp;amp;0.7  \\ \hline
\end{array}

\begin{array}{rr}
P(w|s,r) \\ \hline
r &amp;amp; s &amp;amp; w &amp;amp; 0.99 \\ \hline
r &amp;amp; s &amp;amp; \neg w &amp;amp;0.01  \\ \hline
r &amp;amp; \neg s &amp;amp;  w &amp;amp;0.98  \\ \hline
r &amp;amp; \neg s &amp;amp; \neg w &amp;amp;0.02 \\ \hline
\neg r &amp;amp; s &amp;amp; w &amp;amp; 0.8 \\ \hline
\neg r &amp;amp; s &amp;amp; \neg w &amp;amp;0.2  \\ \hline
\neg r &amp;amp; \neg s &amp;amp;  w &amp;amp;0.05  \\ \hline
\neg r &amp;amp; \neg s &amp;amp; \neg w &amp;amp;0.95  \\ \hline
\end{array}\]

&lt;h4 id=&quot;example-probability-that-its-not-raining-given-the-evidence-that-the-sprinkler-is-on-and-its-not-wet&quot;&gt;Example: Probability that its not raining given the evidence that the sprinkler is on and its not wet.&lt;/h4&gt;

&lt;p&gt;\( P(\neg r | s, \neg w) = \frac{P(\neg r, s, \neg w)}{P(s,\neg w)}\) [ Apply chain rule and reorder. ]&lt;/p&gt;

&lt;p&gt;\(= \frac{P(\neg r, s, \neg w)}{\sum_r P(r=r,s,\neg w)}\) [ Marginalize the denominator for all values of \(r\). ]&lt;/p&gt;

&lt;p&gt;\(= \frac{P(\neg r)P(s | \neg r)P(\neg w | s,\neg r)}{\sum_r P(r=r)P(s | r=r)P(\neg w |s,r=r)}\) [ Factor using the CPT. ]&lt;/p&gt;

&lt;p&gt;\(= \frac{P(\neg r)P(s\ |\neg r)P(\neg w |s,\neg r)}{\sum_r P(r=r)P(s |r=r)P(\neg w |s,r=r)}\) [ Move terms not dependent on \(r\) out of the summation, in this
case no simplification! ]&lt;/p&gt;

&lt;p&gt;\(= \frac{P(\neg r)P(s |\neg r)P(\neg w |s,\neg r)}{P(r)P(s |r)P(\neg w |s,r) + P(\neg r)P(s |\neg r)P(\neg w|s,\neg r)}\) [ Expand. ]&lt;/p&gt;

&lt;p&gt;\(= \frac{(0.7)(0.7)(0.2)}{(0.3)(0.1)(0.01) +  (0.7)(0.7)(0.2)}\) [ Plug in values based on CPT, the domain knowledge. ]&lt;/p&gt;

&lt;p&gt;\(= 0.996948\)&lt;/p&gt;

&lt;p&gt;This value seems reasonable, as we would expect that it was not raining if the
sprinkler was on in addition if the grass was not wet.&lt;/p&gt;

&lt;p&gt;Resources:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.ics.uci.edu/~rickl/courses/cs-271/2011-fq-cs271/2011-fq-cs271-lecture-slides/2011fq271-17-BayesianNetworks.pdf&quot;&gt;http://www.ics.uci.edu/~rickl/courses/cs-271/2011-fq-cs271/2011-fq-cs271-lecture-slides/2011fq271-17-BayesianNetworks.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;markov-blankets&quot;&gt;Markov blankets&lt;/h3&gt;

&lt;p&gt;Markov blanket for a node in a Bayesian Network is a set of nodes that consists
of the nodes parents, children, and childrens parents.&lt;/p&gt;

&lt;p&gt;The Markov Blanket is a powerful tool in reducing the computational load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The Markov blanket of a node contains all the variables that shield the node
from the rest of the network. This means that the Markov blanket of a node is
the only knowledge needed to predict the behavior of that node.”&lt;/strong&gt; - Wiki&lt;/p&gt;

&lt;p&gt;Mathematically, \[P(A|MB(A),B) = P(A|MB(A))\]
where \(MB(A)\) is the Markov Blanket of A&lt;/p&gt;

&lt;p&gt;Resources:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Markov_blanket&quot;&gt;https://en.wikipedia.org/wiki/Markov_blanket&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;d-separation&quot;&gt;D-separation&lt;/h3&gt;

&lt;p&gt;D-seperation can be a tool to determine if there exists conditional independence
between variables. Resonating with the theme of simplifying the problem at hand,
conditional independence and thus D-separation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“play an important role in using probabilistic models for pattern recognition
by simplifying both the structure of a modle and the computations needed to
perform inference and leearning under that model.”&lt;/strong&gt; - Bishop [1]&lt;/p&gt;

&lt;p&gt;Rules as outlined below: [2]&lt;/p&gt;

&lt;p&gt;Rule 1: x and y are d-connected if there is an unblocked path between them.&lt;/p&gt;

&lt;p&gt;Rule 2: x and y are d-connected, conditioned on a set Z of nodes, if there is a
collider-free path between x and y that traverses no member of Z. If no such
path exists, we say that x and y are d-separated by Z, We also say then that
every path between x and y is “blocked” by Z.&lt;/p&gt;

&lt;p&gt;Rule 3: If a collider is a member of the conditioning set Z, or has a descendant
in Z, then it no longer blocks any path that traces this collider.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In summary, the introduction of knowledge &lt;strong&gt;kills dependence&lt;/strong&gt; in the case of
Rule 1 and Rule 2, while knowledge results in dependence in the case of Rule 3.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;e.g. \(P(C | A,B) = P(C | B)\) is really asking if \(C\) is orthogonal to
\(A\) given \(B\). If all paths are destroyed by this knowledge then \(C\)
and \(A\) are independent and the equivalence holds. If a path is created, for
example, if \(B\) is the point of collision on a path between \(A\) and
\(C\), then \(A\) and \(C\) are not independent and the equivalence does
not hold.&lt;/p&gt;

&lt;p&gt;Resources:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Bishop, Christopher, Pattern Recognition and Machine Learning&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://bayes.cs.ucla.edu/BOOK-2K/d-sep.html&quot;&gt;http://bayes.cs.ucla.edu/BOOK-2K/d-sep.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.andrew.cmu.edu/user/scheines/tutor/d-sep.html&quot;&gt;https://www.andrew.cmu.edu/user/scheines/tutor/d-sep.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 11 Apr 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/machinelearning/2018/04/11/bayes-1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/machinelearning/2018/04/11/bayes-1.html</guid>
        
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>IMDB-WIKI: notes on refactoring data preprocess pipeline</title>
        <description>&lt;p&gt;This note is an update to &lt;a href=&quot;http://surfertas.github.io/deeplearning/2017/04/18/imdbwiki.html&quot;&gt;IMDB-WIKI: trying a small model for age
classification&lt;/a&gt;
where I attempted to simplify the objective of age classification by reducing
the number of classes and applying a learning model with a relative smaller
capacity. That said, rather than modelling, the main focus of the exercise was
to handle data in relatively raw and unedited form to extract and load into a
format readily consumable by a deep learning model.&lt;/p&gt;

&lt;p&gt;The first iteration was sufficient for personal use, but the sloppiness of the
project quickly surfaced as others attempted to use the scripts that I had put
together.&lt;/p&gt;

&lt;p&gt;I had the opportunity to work on the repo again, and refactored the scripts to
allow for easier use by others, though some work still is required. See the
below points, related to the rework.&lt;/p&gt;

&lt;h3 id=&quot;a-few-takeaways&quot;&gt;A few takeaways&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The new implementation is using PyTorch, and the Dataset API to extract,
transform, and load the data after preprocessing. In contrast to the original
Chainer implementation, I needed paths to the images, so I added the option to
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;imdb_preprocess.py&lt;/code&gt; to return input features as paths to images, by setting
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--get-paths&lt;/code&gt; flag to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The model for this exercise was a pretrained VGG16 model with redefinition of
the classifier block.   [1] I had trouble extracting the input size to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nn.Sequential()&lt;/code&gt;  so had to reference the documentation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;512&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The faces only IMDB data set contains images of all sizes and dimensions,
with float values normalized between 0 and 1. As VGG16 takes in 3 channels, I
cropped and reduced dimensions to gray scale, then took an additional step to
rescale to 0-255 and apply &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;np.uint8()&lt;/code&gt;. [Questionable if this is the best way,
and would like to here other suggestions if any.]. The final step was to convert
to 3 channels, which is just copying the 1d image, across the 3 channels. The
source can be found
&lt;a href=&quot;https://github.com/surfertas/deep_learning/blob/master/projects/imdbwiki-challenge/pytorch/mydataloader.py&quot;&gt;here&lt;/a&gt;.
The conversion to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8&lt;/code&gt; is required as the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torchvision.transforms.ToPILImage()&lt;/code&gt; method used in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transformer.py&lt;/code&gt; does not
take floats at the time of this writing. [2]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;On a second pass of the data, I noticed ages well beyond the valid upper
range, and included a range check into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;imdb_preprocess.py&lt;/code&gt;. I would imagine a
closer investigation to surface further possible improvements.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;next-steps-at-some-point&quot;&gt;Next steps at some point&lt;/h3&gt;
&lt;p&gt;As this 2nd iteration was just refactoring the data extraction and loading
process, I have not spent much time on the modeling side and have included a
pre-trained VGG16 implementation as a starting point.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;http://pytorch.org/docs/0.2.0/_modules/torchvision/models/vgg.html&lt;/li&gt;
  &lt;li&gt;https://github.com/pytorch/vision/issues/4&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sat, 07 Apr 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/imdb/deeplearning/machinelearning/2018/04/07/imdb-update.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/imdb/deeplearning/machinelearning/2018/04/07/imdb-update.html</guid>
        
        
        <category>imdb</category>
        
        <category>deeplearning</category>
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Autonomous Mobile Robot #2: Inference as a ROS service</title>
        <description>&lt;p&gt;Series:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html&quot;&gt;Autonomous Mobile Robot #1: Data collection to a trained model&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html&quot;&gt;Autonomous Mobile Robot #2: Inference as a ROS service&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&quot;&gt;Autonomous Mobile Robot #3: Pairing with a PS3 Controller for teleop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html&quot;&gt;Autonomous Mobile Robot #4: Using GCP Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;inference-as-a-service&quot;&gt;Inference as a service&lt;/h3&gt;

&lt;p&gt;We ended the previous post with a trained model. The trained model now can be
integrated into a ROS system, and allow for inference given an input feature,
image in this case.&lt;/p&gt;

&lt;p&gt;Out of the possible options that we can consider, topics, services, actions,
using services seems to provide the functionality that fits for this particular
use case.&lt;/p&gt;

&lt;h4 id=&quot;ros-service&quot;&gt;ROS service&lt;/h4&gt;
&lt;p&gt;The ROS Wiki provides an adequate description of a ROS service. Note that calls
to services are blocking, in other words processes are blocked until the
requested service completes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Request / reply is done via a Service, which is defined by a pair of messages:
one for the request and one for the reply. A providing ROS node offers a service
under a string name, and a client calls the service by sending the request
message and awaiting the reply. Client libraries usually present this
interaction to the programmer as if it were a remote procedure call.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For detailed information and tutorials reference the wiki.[1,2]&lt;/p&gt;

&lt;h4 id=&quot;implementing-the-service-provider&quot;&gt;Implementing the service provider&lt;/h4&gt;

&lt;p&gt;The service we would like to provide is given an image, we would like to predict
the associated throttle and steering command. We can consider the serverside
implementation, waiting for a client to call the specified service. Since
prediction is based on a deep net, we assume that the service will be running on
hardware with access to GPU. Cuda should be available.&lt;/p&gt;

&lt;p&gt;In order to set up the service, we can follow the below steps.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Specify the service request message type and response message type as a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.srv&lt;/code&gt; file, and place in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/srv&lt;/code&gt; directory. &lt;a href=&quot;https://github.com/surfertas/amr_core/tree/master/amr_master/amr_nn_controller_service/srv&quot;&gt;PredictCommand.srv&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; by adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PredictCommand.srv&lt;/code&gt; to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_service_files()&lt;/code&gt;. &lt;a href=&quot;https://github.com/surfertas/amr_core/blob/master/amr_master/amr_nn_controller_service/CMakeLists.txt&quot;&gt;CMakeLists.txt&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Implement the service interface as found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nn_controller_service.py&lt;/code&gt; which
consists of initiating the service, and defining a handler as below: &lt;a href=&quot;https://github.com/surfertas/amr_core/blob/master/amr_master/amr_nn_controller_service/scripts/nn_controller_service.py&quot;&gt;nn_controller_service.py&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_init_nn_controller_service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Initialize nn controller service. &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_service_nn_controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'amr_nn_controller_service'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;PredictCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_nn_controller_handler&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;NN controller service initialized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_nn_controller_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Handler for nn controller service.
    Args:
        req - request
    Returns:
        res - ROS response, commands
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cv_img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imdecode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CvBridgeError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logerr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run_inference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Command2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;std_msgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lazy_publishing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# throttle
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# steer
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd_msg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the handle calls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_inference()&lt;/code&gt; method. This can be redefined to
match the training environment used. For example, the process will differ if the
training was done using TensorFlow as opposed to PyTorch. For this first pass,
we used PyTorch for training, thus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_inference()&lt;/code&gt; was defined per below.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run_inference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Runs inference given a PyTorch model.
    Args:
        model - pytorch model
        img - numpy darray
        use_cuda - 1 is True, 0 is False
    Returns:
        throttle - throttle command
        steer - steer command
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imagenet_transforms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'eval_transforms'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trans&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transpose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unsqueeze&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  
    &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autograd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Cuda tensor to numpy doesnt support GPU, use .cpu() to move to host mem. 
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;throttle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;steer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;throttle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;steer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;now-the-service-is-ready-to-be-called&quot;&gt;&lt;strong&gt;Now the service is ready to be called.&lt;/strong&gt;&lt;/h4&gt;

&lt;h3 id=&quot;implementing-the-client-side&quot;&gt;Implementing the client side&lt;/h3&gt;

&lt;p&gt;In our project, we are running the client on a Raspi, a relatively resource
constrained SoC. The packages running on the raspi is responsible for taking a
monocular image and publishing the image. We have placed the client in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_nn_controller&lt;/code&gt;
&lt;a href=&quot;https://github.com/surfertas/amr_core/tree/master/amr_worker/amr_nn_controller&quot;&gt;package&lt;/a&gt;.
We also need to define the service in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/srv&lt;/code&gt; directory, and update the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NNControllerClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    Given an image input, a dl model infers commands.
    Controller subscribes to raw image topic, and calls the
    'amr_nn_controller_service'.
    &quot;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_topic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_topic&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_topic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd_topic&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait_for_service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'amr_nn_controller_service'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Service 'amr_nn_controller_service' is available...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_serve_get_prediction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ServiceProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'amr_nn_controller_service'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;PredictCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;persistent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Initialize subscriber and publisher
&lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_image_sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CompressedImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_sub_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_pub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Publisher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Command2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queue_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_sub_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Handler for image subscriber.
        Args:
            img_msg - ROS image
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_serve_get_prediction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ServiceException&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logerr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Service call failed: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_pub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We initialize a subscriber to subscribe to the topic publishing the images.
Every time an image is published, the call back makes a request to the service to
get commands for control. Once the service returns with a valid response, the
publisher publishes the commands to the command topic, making the commands
public.&lt;/p&gt;

&lt;h3 id=&quot;instructions&quot;&gt;Instructions&lt;/h3&gt;

&lt;p&gt;Instructions on how to demo.&lt;/p&gt;

&lt;p&gt;On the hardware with GPU available (Jetson TX1, TX2, Cloud etc)&lt;/p&gt;

&lt;p&gt;Make sure you have placed the trained model in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;models&lt;/code&gt; directory in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_nn_controller_service&lt;/code&gt; package.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd amr_core/amr_master/amr_nn_controller_service/launch/
$ roslaunch amr_nn_controller_service.launch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the raspi:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd amr_core/amr_worker/amr_bringup/launch/
$ roslaunch amr_nn_bringup.launch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://wiki.ros.org/Services&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/rospy/Overview/Services&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sun, 01 Apr 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html</guid>
        
        
        <category>amr</category>
        
        <category>deeplearning</category>
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Autonomous Mobile Robot #1: Data collection to a trained model</title>
        <description>&lt;p&gt;Series:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html&quot;&gt;Autonomous Mobile Robot #1: Data collection to a trained model&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/04/01/amr-2.html&quot;&gt;Autonomous Mobile Robot #2: Inference as a ROS service&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/amr/deeplearning/machinelearning/2018/12/22/amr-3.html&quot;&gt;Autonomous Mobile Robot #3: Pairing with a PS3 Controller for teleop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/amr/deeplearning/machinelearning/2019/03/31/amr-4.html&quot;&gt;Autonomous Mobile Robot #4: Integrating with GCP&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;note&quot;&gt;Note&lt;/h3&gt;

&lt;p&gt;These notes will be to document the progress related to the AMR project found in
this &lt;a href=&quot;https://github.com/surfertas/amr_core&quot;&gt;repo&lt;/a&gt;, where AMR stands for
autonomous mobile robot. The base robot is assumed to be a Donkey at the time of
writing, the RC car based autonomous race car popularized by &lt;a href=&quot;https://diyrobocars.com/&quot;&gt;DIY
Robocars&lt;/a&gt; originating out of the US. &lt;strong&gt;Any advice on
system design, coding, anything is much appreciated.&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;the-objective-is-to-create-an-autonomous-mobile-robot-that-can-function-in-a-diverse-range-of-environments&quot;&gt;&lt;strong&gt;The objective is to create an autonomous mobile robot that can function in a diverse range of environments.&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;The assumed set up is that we have a raspi connected to a disassembled RC car as
specified in the Donkey documents. [1] In contrast to the Donkey software we
will be using primarily ROS (Kinetic) running on Ubuntu Mate 16.04.1.&lt;/p&gt;

&lt;p&gt;The following code will bring up the environment to allow for the teleoperation of the
mobile robot, and initiate the data collection and storage process.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git clone https://github.com/surfertas/amr_core.git
$ cd amr_worker/amr_bringup/launch/
$ roslaunch amr_teleop_bringup.launch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Make sure that the external packages &lt;a href=&quot;http://wiki.ros.org/joy&quot;&gt;joy package&lt;/a&gt; and
&lt;a href=&quot;http://wiki.ros.org/video_stream_opencv&quot;&gt;videostream_opencv&lt;/a&gt; are installed and
placed in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_worker&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Thanks to the below as some of the code in this repo has been influenced by them. (Licenses have been respected to
the best of my knowledge.)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/wroscoe/donkey&quot;&gt;wroscoe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://maeveautomation.org/&quot;&gt;Maeve Automation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/marvis/pytorch-yolo2&quot;&gt;marvis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;collecting-the-data-and-storing&quot;&gt;Collecting the data and storing&lt;/h3&gt;

&lt;p&gt;The project uses ROS middleware. In order to train a deep learning model, we
need to first collect data. ROS uses a pub/sub protocol which facilitates an
environment that is actually quite conducive for the data collection process.&lt;/p&gt;

&lt;p&gt;Sensor data is published over ROS topics. Any person interested in the data can
simply subscribe to the respective ROS topic, and obtain the data as it is
published. (Not really ideal from a safety perspective, though is addressed in
ROS2.)&lt;/p&gt;

&lt;p&gt;For this project, the data collection process is handled by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_data_processor&lt;/code&gt;
package. The script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_data_storage_node.py&lt;/code&gt; has the specific implementation. The required
configurations need to be set in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_storage.yaml&lt;/code&gt; found in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_data_processor/config&lt;/code&gt; directory before using.&lt;/p&gt;

&lt;p&gt;We throw away non-synced data and only collect synced data as the publishing
frequency for each sensor is likely to be different. We simplify the problem by
only storing data that is synchronized by using the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApproximateTimeSynchronizer()&lt;/code&gt; [1] method which allows for the synchronization of
different topics. See below for snippet showing an example usage of this method. I have
included the initialization of the synchronizer as well as the associated call
back function. The full source can be found
&lt;a href=&quot;https://github.com/surfertas/amr_core/blob/master/amr_worker/amr_data_processor/scripts/amr_data_storage_node.py&quot;&gt;here&lt;/a&gt;.
Details of the sync algorithm can be found at the ROS wiki site. [2]&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_init_subscribers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Set up subscribers and sync. &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Initialize subscribers.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;img_sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message_filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CompressedImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd_sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message_filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Command2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;subs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd_sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Sync subscribers
&lt;/span&gt;    &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_sync&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message_filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApproximateTimeSynchronizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;subs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;queue_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;slop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.2&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registerCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_sync_sub_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Synced subscribers initialized...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_sync_sub_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Call back for synchronize image and command subscribers.
    Args:
        img - image message of type CompressedImage
        cmd - velocity message of type TwistStamped
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_path_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_capacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cv_img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imdecode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_data_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'{}.png'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_rostime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imwrite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_path_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_save_frequency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_save_data_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case, each time the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CompressedImage&lt;/code&gt; message published by the topic
specified in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self._img_topic&lt;/code&gt; syncs with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command2D&lt;/code&gt; message published by the
topic specified in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self._cmd_topic&lt;/code&gt;, the call back function
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self._sync_sub_callback()&lt;/code&gt; is called with the synced messages passed as
parameters. The call back function converts the ROS image to a cv matrix format,
and stores the data to the specified path.&lt;/p&gt;

&lt;p&gt;Note that we are storing the data to an external SSD as the image files can consume material amount of memory quickly.&lt;/p&gt;

&lt;p&gt;We store the &lt;em&gt;path&lt;/em&gt; to the image as well, which will be used as features fed into a
learning algorithm and the commands, used as the target or label, as an array.
The data is saved to disk periodically by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self._save_data_info()&lt;/code&gt; presented
below.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_save_data_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Call periodically to save as input (path) and label to be used for
        training models.
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;images&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_img_path_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;control_commands&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_data_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;predictions.pickle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'w'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pickle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Predictions saved to {}...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_data_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;transforming-data-into-consumable-form&quot;&gt;Transforming data into consumable form&lt;/h3&gt;

&lt;p&gt;Once we are satisfied with the amount of data collected, we can turn to loading
and formatting the data to transform the raw data into something consumable by a
learning model for training.&lt;/p&gt;

&lt;p&gt;The PyTorch Dataset API is tremendously handy as PyTorch allows for almost
seamless integration of pandas allowing for the reformatting of the data to be a breeze. The
Dataset class is shown below. The repo page is found
&lt;a href=&quot;https://github.com/surfertas/amr_core/blob/master/amr_models/model_nn_controller_service/data_loader.py&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can simply load the pickle file and convert the dict to a pandas DataFrame
object. Note that the Dataset api requires the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__getitem__&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__len__&lt;/code&gt;. This can be customized for the task at hand. We can easily change the
number of input features or target variables used, as well as generate sequences
if necessary.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AMRControllerDataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    Custom dataset to handle amr controller.
    Input is an image taken from a monocular camera, with controller mapping
    image to steering and throttle commands.
    &quot;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pickle_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_pickle_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pickle_file&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_root_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_dir&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_transform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_frames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_get_frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getitem__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'images'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Get image name
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;img_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Create path to image
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;img_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_root_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Get actual image    
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_transform&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'image'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'commands'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'throttle'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'steer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_get_frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pickle_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_root_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_pickle_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pickle_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'rb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;pdict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pickle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;img_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pdict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'images'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'images'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;controls_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pdict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'control_commands'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'throttle'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'steer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controls_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;thats-it&quot;&gt;&lt;strong&gt;Thats it.&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;We can just initiate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AMRControllerDataset()&lt;/code&gt; from our training implementation
and the data will be ready to go.&lt;/p&gt;

&lt;h3 id=&quot;training-a-model-based-on-the-collected-data&quot;&gt;Training a model based on the collected data&lt;/h3&gt;

&lt;p&gt;Now that we have our raw data converted to a consumable form we can move on to
the training step.&lt;/p&gt;

&lt;p&gt;The work flow can be summarized as below and found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amr_models&lt;/code&gt;
&lt;a href=&quot;https://github.com/surfertas/amr_core/tree/master/amr_models/model_nn_controller_service&quot;&gt;directory&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Specify data set, done in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_loader.py&lt;/code&gt;. (Walk through above)&lt;/li&gt;
  &lt;li&gt;Specify data transformations, done in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transforms.py&lt;/code&gt; (Note: If using a pre-trained model that used imagenet, need to take care to use appropriate transformations when running inference.)&lt;/li&gt;
  &lt;li&gt;Specify learning architecture, done in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model.py&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Layout training, validation process in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;train.py&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To split the training data into a train and validation data set, I found the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SubsetRandomSampler()&lt;/code&gt;[4] extremely helpful. The training will save a model
every time the metric (MSE) is improved on the validation step.&lt;/p&gt;

&lt;p&gt;Once we are satisfied, we are finished with the training and we have a model
saved that can be loaded and used for inference.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;By simply calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch amr_teleop_bringup.launch&lt;/code&gt; we kick off a system
that records and stores synced sensor data that can be processed by a training
system to train a learning model. In the next update we will walk through how
to use the trained model.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://docs.donkeycar.com/guide/build_hardware/#parts-needed&lt;/li&gt;
  &lt;li&gt;https://docs.ros.org/api/message_filters/html/python/&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/message_filters/ApproximateTime&lt;/li&gt;
  &lt;li&gt;http://pytorch.org/docs/master/data.html&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sat, 31 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/amr/deeplearning/machinelearning/2018/03/31/amr-1.html</guid>
        
        
        <category>amr</category>
        
        <category>deeplearning</category>
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Notes on Decision Tree Learning #3: Boosted Trees</title>
        <description>&lt;h1 id=&quot;notes-on-trees&quot;&gt;Notes on Trees:&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/machinelearning/2018/03/21/dt-1.html&quot;&gt;Decision Trees&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary&lt;/li&gt;
      &lt;li&gt;Entropy, Info gain, Gini Coefficient, Gini gain&lt;/li&gt;
      &lt;li&gt;High Variance, tendency to overfit&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/23/dt-2.html&quot;&gt;Random Forest&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary / Pros of RF&lt;/li&gt;
      &lt;li&gt;Random Forest construction&lt;/li&gt;
      &lt;li&gt;Error rate&lt;/li&gt;
      &lt;li&gt;Feature (variable) importance&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/29/dt-3.html&quot;&gt;Boosted Trees (discrete adaboost)&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;Combining weak classifiers to create a strong classifier&lt;/li&gt;
      &lt;li&gt;Algorithm&lt;/li&gt;
      &lt;li&gt;Outlier detection&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;boosting&quot;&gt;Boosting&lt;/h3&gt;

&lt;h4 id=&quot;31-one-line-summary&quot;&gt;3.1 One line summary&lt;/h4&gt;
&lt;p&gt;A general algorithm that has the ability to improve the accuracy of a learning
algorithm. The following notes will discuss boosting in the context of tree
based learners. Boosting allows for the ensemble of weak classifiers to produce
a strong classifier, where weak and strong has references to the accuracy of the
classifier.&lt;/p&gt;

&lt;h4 id=&quot;32-algorithm&quot;&gt;3.2 Algorithm&lt;/h4&gt;
&lt;p&gt;The general idea is to generate an ensemble of trees sequentially, where each
iteration of tree creation focuses on samples that were misclassified in the
tree generation. This is done, by increasing the weight of the misclassified
sample, increasing the probability of being sampled in the next tree generation
round.&lt;/p&gt;

&lt;p&gt;As a result of the sequential nature, parallelization is difficult in contrast
to Random Forest, which is often considered easily parallized. Further, a
benefit of boosting, is that the algorithm has the ability to not only reduce
variance, but also bias, where as improvements from Random Forest is
concentrated in reducing variance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Indeed, it has been proved that AdaBoost’s combined classifier has an error
rate
that converges to the Bayes optimal provided that the algorithm is given enough
data, that it is run for enough but not too many rounds, and that the weak
hypothe-
ses come from a class of functions that is “sufficiently rich.&lt;/em&gt;&lt;/strong&gt; [2]&lt;/p&gt;

&lt;p&gt;The algorithm as introduced in &lt;em&gt;** Intro to Boosting **&lt;/em&gt; [1]:&lt;/p&gt;

&lt;p&gt;Given: \((x_1, y_1) … (x_m, y_m)\) where \(x_i \in X, y_i \in Y = {-1,
+1}\)&lt;/p&gt;

&lt;p&gt;Initialize: \(D_1(i) = \frac {1}{m}\)&lt;/p&gt;

&lt;p&gt;For \(t=1..T:\)&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Train weak learner using distribution \(D_t\)&lt;/li&gt;
  &lt;li&gt;Get weak hypothesis \(h_t: X \rightarrow {-1,+1}\) with error: \(\epsilon_t = P_{i~D_t}[h_t(x_i) \neq y_i]\)&lt;/li&gt;
  &lt;li&gt;Choose \(\alpha_t = 0.5 \ln(\frac{1-\epsilon_t}{\epsilon_t})\)&lt;/li&gt;
  &lt;li&gt;Update: \(D_{t+1}(i) = \frac{D_t(i)exp(-\alpha_ty_ih_t(x_i))}{Z_t}\)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally once \(T\) trees produced: \(H(x) =
sign(\sum_{t=1}^T\alpha_th_t(x))\)&lt;/p&gt;

&lt;p&gt;Note that the influence of the weak classifier \(h_t(x)\) is given by
\(\alpha\) which is a function of the error or frequency of misclassification
by the given tree. The lower the \(\epsilon\) the higher the influence.&lt;/p&gt;

&lt;h4 id=&quot;33-outlier-detection&quot;&gt;3.3 Outlier detection&lt;/h4&gt;

&lt;p&gt;As the algorithm iteratively assigns higher weights to misclassified samples,
the algorithm has the ability to detect outliers. &lt;strong&gt;&lt;em&gt;Adaboost focuses its weight
on the hardest examples, the examples with highest weights often turn to be
outliers.&lt;/em&gt;&lt;/strong&gt;[1]&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://cseweb.ucsd.edu/~yfreund/papers/IntroToBoosting.pdf&lt;/li&gt;
  &lt;li&gt;http://rob.schapire.net/papers/explaining-adaboost.pdf&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 29 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/machinelearning/2018/03/29/dt-3.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/machinelearning/2018/03/29/dt-3.html</guid>
        
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Notes on Decision Tree Learning #2: Random Forest</title>
        <description>&lt;h4 id=&quot;notes-on-trees&quot;&gt;Notes on Trees:&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/machinelearning/2018/03/21/dt-1.html&quot;&gt;Decision Trees&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary&lt;/li&gt;
      &lt;li&gt;Entropy, Info gain, Gini Coefficient, Gini gain&lt;/li&gt;
      &lt;li&gt;High Variance, tendency to overfit&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/23/dt-2.html&quot;&gt;Random Forest&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary / Pros of RF&lt;/li&gt;
      &lt;li&gt;Random Forest construction&lt;/li&gt;
      &lt;li&gt;Error rate&lt;/li&gt;
      &lt;li&gt;Feature (variable) importance&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/29/dt-3.html&quot;&gt;Boosted Trees (discrete adaboost)&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;Combining weak classifiers to create a strong classifier&lt;/li&gt;
      &lt;li&gt;Algorithm&lt;/li&gt;
      &lt;li&gt;Outlier detection&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;random-forest&quot;&gt;Random Forest&lt;/h3&gt;

&lt;h4 id=&quot;21-one-line-summary&quot;&gt;2.1 One line summary&lt;/h4&gt;
&lt;p&gt;As the name suggests, Random Forest, is a collection of decision trees which
represents the forest, with the details of each tree constructed randomly.&lt;/p&gt;

&lt;p&gt;The result of ensembling the randomly generated tree classifiers in a reduction
of variance, and improvement in generalization relative to a single decision
tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros of Random Forest&lt;/strong&gt; [1]:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;It is unexcelled in accuracy among current algorithms.&lt;/li&gt;
  &lt;li&gt;It runs efficiently on large data bases.&lt;/li&gt;
  &lt;li&gt;It can handle thousands of input variables without variable deletion.&lt;/li&gt;
  &lt;li&gt;It gives estimates of what variables are important in the classification.&lt;/li&gt;
  &lt;li&gt;It generates an internal unbiased estimate of the generalization error as the
forest building progresses.&lt;/li&gt;
  &lt;li&gt;It has an effective method for estimating missing data and maintains accuracy
when a large proportion of the data are missing.&lt;/li&gt;
  &lt;li&gt;It has methods for balancing error in class population unbalanced data sets.&lt;/li&gt;
  &lt;li&gt;Generated forests can be saved for future use on other data.&lt;/li&gt;
  &lt;li&gt;Prototypes are computed that give information about the relation between the
variables and the classification.&lt;/li&gt;
  &lt;li&gt;It computes proximities between pairs of cases that can be used in
clustering, locating outliers, or (by scaling) give interesting views of the
data.&lt;/li&gt;
  &lt;li&gt;The capabilities of the above can be extended to unlabeled data, leading to
unsupervised clustering, data views and outlier detection.&lt;/li&gt;
  &lt;li&gt;It offers an experimental method for detecting variable interactions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;22-random-forest-construction&quot;&gt;2.2 Random Forest construction&lt;/h4&gt;
&lt;p&gt;Randomness is present at a number of points in the construction of a forest. The
sample set, feature set, depth of tree, can all be set using a stochastic
process. If a random process is used when selecting which feature to use for
splitting, as opposed to using gini gain or information gain, we result in the
&lt;strong&gt;&lt;em&gt;ExtraTrees&lt;/em&gt;&lt;/strong&gt; learner, or extremely randomized trees.&lt;/p&gt;

&lt;p&gt;When constructing the learner, the &lt;strong&gt;&lt;em&gt;boostrap aggregating&lt;/em&gt;&lt;/strong&gt;, also known as
bagging, is applied to the tree learners. 
Given a training set \(X = x_1, …, x_n\) with responses \(Y = y_1, …, y_n\),
bagging repeatedly (B times) selects a random sample with replacement of the
training set and fits trees to these samples. [2]&lt;/p&gt;

&lt;p&gt;For the classification task, a majority vote is taken over the set of tree
learners.&lt;/p&gt;

&lt;p&gt;Using numpy we can implement the majority vote function as so:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;# Class method
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;majority_vote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Method to compute majority vote over a give set of tree classifiers.
    Args:
        samples - a set of samples for classification.
    Returns:
        final_predictions - prediction based on majority vote.
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Get classification based on each tree.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# For each sample, use majority vote for classification.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;final_predictions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bincount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_predictions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;23-error-rate&quot;&gt;2.3 Error rate&lt;/h4&gt;

&lt;p&gt;The error rate of the forest is dependent on how accurate the individual
classifiers are and the dependence between them. [3] Put another way, the
strength of each classifier and the correlation between said classifiers
contributes to the error rate.&lt;/p&gt;

&lt;p&gt;Breiman introduced an upperbound using strength and correlation as inputs:
\[generalization_error \leq \frac{\rho (1-s^2)}{s^2}\]&lt;/p&gt;

&lt;p&gt;An indepth analysis can be found in &lt;strong&gt;&lt;em&gt;A Study of Strength and Correlation in
Random Forests&lt;/em&gt;&lt;/strong&gt;. [4]&lt;/p&gt;

&lt;h4 id=&quot;24-feature-variable-importance&quot;&gt;2.4 Feature (variable) importance&lt;/h4&gt;

&lt;p&gt;Random forests are used to get estimates of importance of the features. sklearn
offers a easy way to obtain the importance of features. See a [5] for a
practical example. Breiman’s original paper provides a more detailed analysis of
the topic.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.ensemble&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomForestClassifier&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomForestClassifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;importances&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature_importances_&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sorted_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;importances&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm&lt;/li&gt;
  &lt;li&gt;https://en.wikipedia.org/wiki/Random_forest&lt;/li&gt;
  &lt;li&gt;https://www.stat.berkeley.edu/~breiman/randomforest2001.pdf&lt;/li&gt;
  &lt;li&gt;https://hal.archives-ouvertes.fr/hal-00598466/document&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 23 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/machinelearning/2018/03/23/dt-2.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/machinelearning/2018/03/23/dt-2.html</guid>
        
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Notes on Decision Tree Learning #1: Decision Trees</title>
        <description>&lt;h4 id=&quot;notes-on-trees&quot;&gt;Notes on Trees:&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://surfertas.github.io/machinelearning/2018/03/21/dt-1.html&quot;&gt;Decision
Trees&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary&lt;/li&gt;
      &lt;li&gt;Entropy, Info gain, Gini Coefficient, Gini gain&lt;/li&gt;
      &lt;li&gt;High Variance, tendency to overfit&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/23/dt-2.html&quot;&gt;Random Forest&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;One line summary / Pros of RF&lt;/li&gt;
      &lt;li&gt;Random Forest construction&lt;/li&gt;
      &lt;li&gt;Error rate&lt;/li&gt;
      &lt;li&gt;Feature (variable) importance&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/machinelearning/2018/03/29/dt-3.html&quot;&gt;Boosted Trees (discrete adaboost)&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;Combining weak classifiers to create a strong classifier&lt;/li&gt;
      &lt;li&gt;Algorithm&lt;/li&gt;
      &lt;li&gt;Outlier detection&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;decision-trees&quot;&gt;Decision Trees&lt;/h3&gt;
&lt;h4 id=&quot;11-one-line-summary&quot;&gt;1.1 One line summary&lt;/h4&gt;
&lt;p&gt;Decision trees is a learning algorithm that uses features to split observations
along branches to obtain a conclusion in the leaf nodes (nodes with no
children), where a conclusion is a classification of the input sample.&lt;/p&gt;

&lt;h4 id=&quot;12-entropy-information-gain-gini-coefficient-gini-gain&quot;&gt;1.2 Entropy, Information gain, Gini Coefficient, Gini gain&lt;/h4&gt;
&lt;p&gt;Given a sample with many features, the task is to find the feature, or
combination of features, that results in an architecture that classifies the
features efficiently.&lt;/p&gt;

&lt;p&gt;We can use the &lt;em&gt;information gain&lt;/em&gt; measure used by ID3, C4.5, C5.0 algorithms, or
&lt;em&gt;gini impurity&lt;/em&gt; to find available features that will result in the most
effective split at each given node. The general idea is that we want to find
features that increase the &lt;strong&gt;information&lt;/strong&gt; gained per node. We want to move from
a state of confusion to clarity, high entropy to low entropy, and said one final
way, from a heterogeneous state to a homogeneous state.&lt;/p&gt;

&lt;h5 id=&quot;information-gain&quot;&gt;Information Gain&lt;/h5&gt;
&lt;p&gt;Calculating the information gain algorithmically is a nice to way to introduce
the concept. In order to understand information gain, the concept of entropy
needs to be introduced first.&lt;/p&gt;

&lt;p&gt;\[entropy(p_1…p_n) = -\sum_{i=1}^n p_i\log_2(p_i)\]&lt;/p&gt;

&lt;p&gt;(e.g. considering a binary classification task, if the number of \(0\) and
number of \(1\) is equal the entropy is maximized where as if there are only
\(0\) or only \(1\), then entropy is minimized. We can quicky confirm this.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Need to handle case log2(0) = -inf
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Entropy of homogenous classification: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Entropy of even split classification: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Entropy of homogenous classification: 0
Entropy of even split classification: 1.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Entropy is also intepreted as the number of bits needed to explain the
classification. (e.g. when the classification is evenly split, we need 1 bit to
explain 2 classes.) [1]&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Calculate entropy for parent node. The higher the entropy the worse it is.&lt;/li&gt;
  &lt;li&gt;For each feature:
    &lt;ul&gt;
      &lt;li&gt;calculate the entropy for children nodes after splitting on the selected
feature.&lt;/li&gt;
      &lt;li&gt;calculate the weighted sum of entropies across children nodes.&lt;/li&gt;
      &lt;li&gt;calculate information gain as \(entropy(parent) - \sum_i
entropy(child_i)\)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select feature with highest information gain&lt;/li&gt;
  &lt;li&gt;Repeat 1-3 until all nodes are leafs (1 class), or a max depth limit is
reached.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;gini-gain&quot;&gt;Gini Gain&lt;/h4&gt;

&lt;p&gt;The gini gain is a similar concept to information gain, in that it provides an
evaluation metric to select features that create the best split. Gini is used in
the CART (Classification and Regression Trees) algorithm.&lt;/p&gt;

&lt;p&gt;Impurity, or Gini Coefficient, is computed using below equation:
\[impurity(p_1..p_n) = 1- \sum_{i=1}^n p_i^2\]&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;impurity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;impurity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_ones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;impurity&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Impurity of homogenous classification: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;impurity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Impurity of even split classification: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;impurity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Impurity of homogenous classification: 0.0
Impurity of even split classification: 0.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can quickly observe that the metric outputs similar results to the entropy
measure. Gini gain can be computed in the same way as was done for information
gain.&lt;/p&gt;

&lt;h3 id=&quot;13-high-variance-tendency-to-overfit&quot;&gt;1.3 High variance, tendency to overfit&lt;/h3&gt;

&lt;p&gt;Decision trees are often associated with high variance and the tendency to
overfit to the training data. Given a deep enough tree, and nodes, a decision
tree can perfectly fit the training data, but fail on validation and testing,
failing to generalize. Tree based algorithms introduced later, address the high
variance attribute of decision trees.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://www.cs.bc.edu/~alvarez/ML/id3&lt;/li&gt;
  &lt;li&gt;http://web.cs.ucdavis.edu/~vemuri/classes/ecs271/Decision%20Trees-Construction.htm&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 21 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/machinelearning/2018/03/21/dt-1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/machinelearning/2018/03/21/dt-1.html</guid>
        
        
        <category>machinelearning</category>
        
      </item>
    
      <item>
        <title>Monty Hall: Optimal strategy for a n-door game</title>
        <description>&lt;p&gt;The Monty Hall problem is an interesting problem having stumped experienced
mathematicians, despite the seemingly simple problem statement. The problem is
considered a paradox of the veridical type, because the solution is so
counterintuitive that some believe the conclusion is absurd. [1]&lt;/p&gt;

&lt;p&gt;The purpose of this note is to consider a derivative of the original problem
statement to build further intuition. I was recently introduced to a similar
iteration that helped to cement the intuition behind the logic to solve the
problem.&lt;/p&gt;

&lt;h3 id=&quot;monty-hall&quot;&gt;Monty Hall&lt;/h3&gt;
&lt;p&gt;The original problem statement had the following constraints: [1]&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The host must always open a door that was not picked by the contestant
(Mueser and Granberg 1999).&lt;/li&gt;
  &lt;li&gt;The host must always open a door to reveal a goat and never the car.&lt;/li&gt;
  &lt;li&gt;The host must always offer the chance to switch between the originally chosen
door and the remaining closed door. 
The question is should the player switch given the host has revealed a goat? The
answer is yes, the optimal strategy is to switch, as the remaining door has a
probability of \(\frac{2}{3}\) to contain the car. Given that any door has a
probability of \(\frac{1}{3}\) to contain the car prior to any information via
action by player, and the host, the probability of \(\frac{2}{3}\) is somewhat
counterintuitive.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;monty-hall-with-a-twist&quot;&gt;Monty Hall with a Twist&lt;/h3&gt;
&lt;p&gt;Adding a bit of a complexity to the original problem, actually helped in my
understanding and I hope will have a similar impact on the reader.&lt;/p&gt;

&lt;p&gt;In addition to the original constraints, assume the following constraints.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The player must select the number of doors.&lt;/li&gt;
  &lt;li&gt;The number of doors can range from \(3\) to \(15\) inclusive.&lt;/li&gt;
  &lt;li&gt;At each turn, the player has the option to switch.&lt;/li&gt;
  &lt;li&gt;If there are \(2\) doors remaining, the player is forced to make a final
decision on switching and the game ends.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now rephrase the problem statement to &lt;em&gt;what is the optimal strategy for this
game?&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;h4 id=&quot;lets-try-by-select-3-doors-which-gives-us-the-original-monty-hall&quot;&gt;Lets try by select \(3\) doors, which gives us the original Monty Hall&lt;/h4&gt;
&lt;p&gt;problem.&lt;/p&gt;

&lt;p&gt;The probability that an given door has the car is \(\frac{1}{3}\). After
player selection, and host action to reveal goat, the probability that the other
door contains a car is \(\frac{2}{3}\). &lt;strong&gt;Thinking about probability as an
object with mass helps with building intuition for this problem.&lt;/strong&gt; Since
\(\frac{1}{3}\) of mass is contained in the player selected door, the
remaining \(\frac{2}{3}\) has to be contained by the remaining doors. When
there are two doors remaining, it is evenly split. When the number of doors is
reduced by host action, the probability mass of \(\frac{2}{3}\) is contained
by the remaining door. Thus when given the choice, of \(\frac{2}{3}\) or
\(\frac{1}{3}\), of probability mass, it is logical to select the door with
more mass. Its ok to be greedy here. Thus we reach the solution that the player
should switch.&lt;/p&gt;

&lt;h4 id=&quot;lets-try-selecting-7-doors&quot;&gt;Lets try selecting \(7\) doors.&lt;/h4&gt;

&lt;p&gt;The player selects a door, and the host reveals a goat. The probability that any
given door has the car is \(\frac{1}{7}\), and thus the probability mass
contained in the player selected door is \(\frac{1}{7}\), while the remaining
\(5\) doors, remember the host has removed a door, equally share the remaining
probability mass of \(\frac{6}{7}\), thus each door has a probability of
\(\frac{6}{35}\), or \(0.1714\) vs. the \(0.1428\) of probability mass
currently held by the player. Should the player switch? Well if this was the end of the game then yes,
but the player still doesnt know what the result of other doors being revealed will have
on the probability masses contained in each remaining door.&lt;/p&gt;

&lt;p&gt;The host reveals another goat leaving \(4\) doors plus the \(1\) door the
player selected originally. Keep in mind that the probability mass of
\(\frac{1}{7}\) that the player currently has remains constant, thus the
remaining \(\frac{6}{7}\) of probability mass needs to be shared by the
remaining \(4\) doors. This equates to each door having \(
\frac{\frac{6}{7}}{4}\), or \(\frac{6}{28}\), \(0.2143\) in decimals. Ok
now we see that by waiting and staying put, the available probability mass by
switching has increased from \(0.1714\) to \(0.2143\). This is nice
discovery.&lt;/p&gt;

&lt;p&gt;Lets wait until there are \(2\) doors remaining in addition to the door the
originally selected by the player. Again, the same logic applies. The remaining
\(\frac{6}{7}\) of probability mass needs to be split between the \(2\)
doors, leaving \(\frac{6}{14}\), or \(0.4286\) of mass per door.&lt;/p&gt;

&lt;p&gt;I would guess that this pattern is consistent, in other words, the per door
probability mass contained by the other doors increases as more doors are
revealed.&lt;/p&gt;

&lt;p&gt;If this is true, we can easily show by computation that the optimal strategy
given an upper bound of \(n\) doors is to select the n-door game, and wait
until there is a total of \(2\) doors remaining before switching, as the
remaining \(1\) door will have \(\frac{n-1}{n}\) of probability mass.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Thinking about probabilities as an object with mass was really the key for me to
build intuition. I hope this walk through helps to build similar intuition for
others. In completing this note, the next question, is what happens when \(n\)
goes to infinity?&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://en.wikipedia.org/wiki/Monty_Hall_problem&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 12 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/probability/2018/03/12/montyhall-twist.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/probability/2018/03/12/montyhall-twist.html</guid>
        
        
        <category>probability</category>
        
      </item>
    
      <item>
        <title>Data Augmentation: a minimal example using TensorFlow Dataset API</title>
        <description>&lt;p&gt;In working with the &lt;a href=&quot;https://github.com/udacity/self-driving-car/tree/master/datasets/CH2&quot;&gt;Udacity’s Drive
data&lt;/a&gt;, I
wanted to augment the available data to increase the size of the data set in
hopes of improving the results of training PilotNet, an end to end deep learning
model, developed by Nvidia. [1]&lt;/p&gt;

&lt;p&gt;I decided to use TensorFlow’s Dataset API to create the data pipeline, a great
API that abstracts a lot while still allowing flexibility for the developer to
customize the pipeline to a given task. That said, I had a hard time finding
best practices on data augmentation and the associated pipeline using the
Dataset API. After some investigation of the TensorFlow documentation, I found
the definition to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;concatenate()&lt;/code&gt; method. [2] Unfortunately, there were no
examples of how to construct a pipeline for augmentation, thus will use this
post to introduce a minimal example. Please refer to a full working data
pipeline applied to the Udacity dataset
&lt;a href=&quot;https://github.com/surfertas/deep_learning/blob/master/projects/self_driving_car/1-pilot_net/data_pipeline.py&quot;&gt;here.&lt;/a&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataHandler&lt;/code&gt; class defined in the source code was quickly put together,
thus any advice on how to improve the pipeline or best practice tips would be
appreciated.&lt;/p&gt;

&lt;h3 id=&quot;minimal-example-using-concatenate-to-augment-original-data&quot;&gt;Minimal example: Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;concatenate()&lt;/code&gt; to augment original data&lt;/h3&gt;

&lt;p&gt;Please see this &lt;a href=&quot;https://github.com/surfertas/deep_learning/blob/master/projects/self_driving_car/1-pilot_net/3-1-feature_augmentation_pipeline.ipynb&quot;&gt;jupyter
notebook&lt;/a&gt;
for the minimal example.&lt;/p&gt;

&lt;p&gt;The notebook walks through the use of TensorFlow API to upload image based on
information found in csv file, and the use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;concatenate()&lt;/code&gt; method to
create an augmented dataset.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://arxiv.org/abs/1604.07316&lt;/li&gt;
  &lt;li&gt;https://www.tensorflow.org/api_docs/python/tf/data/Dataset#concatenate&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 24 Jan 2018 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/tensorflow/dl/2018/01/24/tf-data-augmentation.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/tensorflow/dl/2018/01/24/tf-data-augmentation.html</guid>
        
        
        <category>tensorflow</category>
        
        <category>dl</category>
        
      </item>
    
      <item>
        <title>A Review of XGBoost (eXtreme Gradient Boosting)</title>
        <description>&lt;p&gt;Gradient boosting is an ensemble technique, where prediction is done by an
ensemble of simple estimators. Realistically, gradient boosting can be done over
various estimators but in practice GBDT is used where gradient boosting is over
decision trees. Instead of heterogeneous grouping of estimators, the
grouping is homogeneous and consists of a variation of decision trees with
different parameter settings.  The tree is built greedily, thus the algorithm is
fast but at a cost. The greedy strategy often times results in sub-optimal
solutions. [1]&lt;/p&gt;

&lt;p&gt;The decision tree ensemble is a set of classification and regression trees
(CART). In contrast to standard decision trees where the leaf contains
decisions, the leaves found in CART are associated with real value scores which
provides a richer interpretation that go beyond classification. [3] The ensemble
can be mathematically represented as follows:&lt;/p&gt;

&lt;p&gt;\[\sum_{k=1}^K D_k\]&lt;/p&gt;

&lt;p&gt;The algorithm is trained by iteratively adding a decision tree trained to reduce
the residual of the target function and the current ensemble of trees,
\(D(x)\). At each iteration the hope is that the residual, the remaining
error, gets successively smaller. Though not realistic for a complex function,
if we were able to train a tree against \(R(x)\) where the residual was truly zero,
then the trained ensemble would have fit the distribution completely and
perfectly.&lt;/p&gt;

&lt;p&gt;\[R(x) = f(x) – D(x) \]
\[where D(x) = tree_1(x) + tree_2(x) + …\]&lt;/p&gt;

&lt;h3 id=&quot;objective-function-and-optimization&quot;&gt;Objective function and Optimization&lt;/h3&gt;
&lt;p&gt;Gradient boosting relies on regression trees, where the optimization step works
to reduce RMSE, while for binary classification the standard log loss,
\(-\frac{1}{N}\sum_{i=1}^Ny_i log(p_i) + (1+y_i) log(1-p_i)\) is used. For a
multi-class classification problem the cross entropy loss is the input to the
objective function to be optimized.&lt;/p&gt;

&lt;p&gt;Combining the loss function with a regularization term arrives at the objective function.
The regularization term controls the complexity and reduces the risk of
over-fitting. [2] XGBoost uses gradient descent for optimization improving the
predictive accuracy at each optimization step by following the negative of the
gradient as we are trying to find the “sink” in a n-dimensional plane. In
XGBoost, the regularization term is defined as:&lt;/p&gt;

&lt;p&gt;\[\Omega(f) = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^Tw_j^{2}\]&lt;/p&gt;

&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Learning rate, \(\eta\), is a factor that is applied to each individual tree
prior to adding to the ensemble.  In practice, a small learning rate is
preferred as large learning rates results in larger steps which increases the
frequency of discontinuities. A suggested learning rate range for grid search is
a range between \(0.01 &amp;lt; \eta &amp;lt; 0.1\).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Number of trees, and depth of each tree. Typically a larger number of trees
is preferred with a depth that is not excessive. As seen in the visualization
[1], we can see that an ensemble of deep trees can result in relatively lower
residuals, but at the cost of increased noise/discontinues in the surface of the
function approximation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;xgboost-parameters-going-deeper&quot;&gt;XGBoost Parameters (Going Deeper):&lt;/h3&gt;

&lt;p&gt;The authors of XGBoost have divided the parameters into three categories, general
parameters, booster parameters, and learning task parameters. I have highlighted
the majority of parameters to be considered when tuning parameters. For the full
list refer to the documentation. [5]&lt;/p&gt;

&lt;h4 id=&quot;general-parameters-parameters-to-defined-the-overall-functionality&quot;&gt;General Parameters: parameters to defined the overall functionality.&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{booster}\) (default = gbtree): can select the type of model
(gbtree or gblinear) to run at each iteration.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{silent}\) (default = 0): If set to one, silent mode is set and the
modeler will not receive any feedback after each iteration.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{nthread}\) (default = max # of threads): used to set the number
of cores to use for processing.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;booster-parameters-two-types-of-boosters-tree-and-linear-but-as-tree-typically-outperforms-linear-the-tree-boosters-is-only-considered-in-most-literature&quot;&gt;Booster Parameters: Two types of boosters, tree and linear, but as tree typically outperforms linear, the tree boosters is only considered in most literature.&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{eta}\) (default = 0.3):  Learning rate used to shrink weights on
each step. Typical final values fall in between 0.01 ~ 0.2. [4] Note this
differs from the recommendation from [1] suggesting the learning rate range best
set between 0.01 ~ 0.1.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{min_child_weight}\) (default = 1): Used to control overfitting
and defines the minimum sum of weights of all observations required in a child.
A larger number restricts models ability to learn finer details of training set.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{max_depth}\) (default = 6): Typical values 3-10, defines the
maximum depth of a tree.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;\(\textbf{max_leaf_nodes}\): the number of terminal nodes of leaves in a
tree. Has a mathematical relationship with depth of tree.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;\(\textbf{gamma}\) (default = 0): specifies the minimum loss reduction
required to make a split.&lt;/li&gt;
  &lt;li&gt;\(\textbf{subsample}\) (default = 1): Defines the fraction of observations
to be used when sampling randomly from each tree. Typically values use range
between 0.5 – 1.&lt;/li&gt;
  &lt;li&gt;\(\textbf{colsample_bytree}\) (default = 1):  Fraction of columns to be used
when random sampling for tree build out.&lt;/li&gt;
  &lt;li&gt;\(\textbf{lambda}\) (default = 1):  L2 regularization term.&lt;/li&gt;
  &lt;li&gt;\(\textbf{alpha}\) (default = 0): L1 regularization term.&lt;/li&gt;
  &lt;li&gt;\(\textbf{scale_pos_weight}\) (default = 1): A value greater than 0 should
be used in case of high class imbalances.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;learning-task-parameters-used-to-define-the-optimization-objective&quot;&gt;Learning Task Parameters: used to define the optimization objective.&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;\(\textbf{objective}\) (default = reg:linear): defines the loss function to
be minimized. Options include binary:logistic, multi:softmax, multi:softprob.&lt;/li&gt;
  &lt;li&gt;\(\textbf{eval_metric}\): Metric used for validation. Options include
rmse(default for regression), mae, logloss, error (default for classification),
merror, mlogloss, auc.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html&lt;/li&gt;
  &lt;li&gt;https://www.slideshare.net/ShangxuanZhang/kaggle-winning-solution-xgboost-algorithm-let-us-learn-from-its-author&lt;/li&gt;
  &lt;li&gt;http://xgboost.readthedocs.io/en/latest/model.html&lt;/li&gt;
  &lt;li&gt;https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/&lt;/li&gt;
  &lt;li&gt;http://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 14 Dec 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/xgboost/ml/2017/12/14/XGB.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/xgboost/ml/2017/12/14/XGB.html</guid>
        
        
        <category>xgboost</category>
        
        <category>ml</category>
        
      </item>
    
      <item>
        <title>ROS + RaspberryPi Camera Module #5: Yolo2 object detection on Raspberry Pi 3, with a bit of help from mother JetsonTX1</title>
        <description>&lt;p&gt;In a recent post, we discussed optimizing a face detection system based on
classical computer vision techniques to run on a GPU using OpenCV with
CUDA enabled. As a result of the optimization the performance improved from
3~4hz to ~10hz. As a recap of the system setup used in this exercise, the
Raspberry Pi camera took raw images and published the images to an image ROS topic. The
Jetson TX1 subscribed to the raw image topic and handled the heavy lifting
which included preprocessing the raw image and detecting any faces. The two machines
were connected over WIFI.&lt;/p&gt;

&lt;p&gt;We use a similar set up in this exercise allowing the Jetson TX1 to take care
of object detection using the Yolo2 algorithm while the Raspberry Pi was solely responsible
for streaming compressed raw RGB images. Once again I am amazed how ROS can help
to integrate different languages and frameworks (C++11, Python, OpenCV, PyTorch)
seamlessly.&lt;/p&gt;

&lt;p&gt;source: &lt;a href=&quot;https://github.com/surfertas/ros_custom_packages/tree/master/ros_object_detection&quot;&gt;ros_object_detection&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;yolo-you-only-look-once&quot;&gt;YOLO: You Only Look Once&lt;/h3&gt;
&lt;p&gt;This &lt;a href=&quot;https://www.youtube.com/watch?v=GBu2jofRJtk&quot;&gt;youtube recording&lt;/a&gt; of a
presentation given by the creators of YOLO, titled YOLO 9000: Better, Faster, Stronger
suffices in introducing the algorithm. Further, techniques used to
transfer learned weights from ImageNet for classification to a use in object
detection is covered as well. The combination of the ImageNet and COCO data set using a word tree
[28:00], and the discussion related to back propagating different errors based on which
data set the input was derived from, was informative.&lt;/p&gt;

&lt;h3 id=&quot;system-setup&quot;&gt;System Setup&lt;/h3&gt;
&lt;p&gt;The launch file loads the configuration details found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yolo2.yaml&lt;/code&gt; and stores
the path details on the parameter server. Next, the service
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_inference_yolo2&lt;/code&gt;, which is specified in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_inference_yolo2.py&lt;/code&gt; in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/scripts&lt;/code&gt; directory is initialized and launched. Finally, the object detection node is
initiated. The node will wait until the service is available before making a
request.&lt;/p&gt;

&lt;p&gt;The system is quite simple as the hard work of object detection is abstracted to
the service call.&lt;/p&gt;

&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;/h3&gt;
&lt;p&gt;Face detection using classical computer vision techniques with CUDA enabled resulted in 10fps
on the Jetson TX1. Object detection using Yolo2 obviously is a much more
difficult task as this implementation will be detecting 80 different classes.
The performance measured in publishing rates was between 3.3-3.8hz while
over-clocking increased the performance to 5hz.  Considering the number of
classes being covered this is amazing, and understandably why there is much hope
for deep learning technologies.  Here is a snap shot of the results.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/yolo2.png&quot; alt=&quot;Yolo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;This set up,  though not completely on the edge, uses a network set up and does
not require cloud access. The concept of having an agent worker with constrained
resources dependent on a mother machine is a concept that is worth exploring
further.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://www.youtube.com/watch?v=GBu2jofRJtk&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 13 Nov 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/tx1/opencv/pytorch/2017/11/13/pi-object-detection.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/tx1/opencv/pytorch/2017/11/13/pi-object-detection.html</guid>
        
        
        <category>ROS</category>
        
        <category>tx1</category>
        
        <category>opencv</category>
        
        <category>pytorch</category>
        
      </item>
    
      <item>
        <title>ROS + RaspberryPi Camera Module #4: Running ROS master on Jetson TX1 and OpenCV with CUDA enabled</title>
        <description>&lt;p&gt;ROS + RaspberryPi Camera Module #4: Running ROS master on Jetson TX1 and OpenCV with CUDA enabled&lt;/p&gt;

&lt;p&gt;source code: &lt;a href=&quot;https://github.com/surfertas/ros_face_detect/blob/master/src/face_detect_cuda.cpp&quot;&gt;ros_face_detect&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;opencv-with-cuda-enabled&quot;&gt;OpenCV with CUDA enabled&lt;/h3&gt;

&lt;p&gt;The current system setup uses a Raspberry Pi 3(Raspi) with Ubuntu 16.04.1 as the
operating system, and ROS, version Kinetic, as the middle ware. The Raspi publishes raw images taken
from a Raspberry Pi Camera Module V2.1 over the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/webcam/image_raw/compress&lt;/code&gt;
topic provided by the ROS package &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;video_stream_opencv&lt;/code&gt; which subscribes to
nodes running on a Jetson TX1 (Ubuntu 16.04.1, ROS Kinetic).&lt;/p&gt;

&lt;p&gt;Despite the Raspi being able to publish raw RGB images at close to 30fps, the
performance deteriorates as a result of the computational demands placed on the
hardware by the face detection algorithm purely relying on the CPU. The
publishing rates after detection was between 3-4hz.&lt;/p&gt;

&lt;p&gt;In order to increase the performance, a rewrite of the program to allow for GPU
acceleration of the computer vision algorithms heavily reliant on matrix
multiplication was required. The code changes were minimal as OpenCV3 offers a
user friendly API that allows for easy refactoring, while on the other hand the
environment set up took more time to set up unfortunately.&lt;/p&gt;

&lt;h3 id=&quot;setting-up-the-environment&quot;&gt;Setting up the environment&lt;/h3&gt;
&lt;p&gt;Prior to starting this exercise, I had previously installed OpenCV 3 along side
ROS Kinetic which caused some problems. The
problem was that the version included in ROS opencv package did not have cuda
enabled. To resolve this issue a build from source was required. Under the
directory path &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local&lt;/code&gt; , following the
instructions outlined at &lt;a href=&quot;https://docs.opencv.org/master/d6/d15/tutorial_building_tegra_cuda.html&quot;&gt;OpenCV with CUDA with
Tegra&lt;/a&gt;
, I was able to successfully build and install OpenCV with CUDA enabled.&lt;/p&gt;

&lt;p&gt;Despite a successful install, ROS was still having troubles dealing with two
versions of
OpenCV, and this required some redirection of CMAKE paths and rebuilds of OpenCV
dependent ROS packages. The problem and solution is discussed
&lt;a href=&quot;https://answers.ros.org/question/242376/having-trouble-using-cuda-enabled-opencv-with-kinetic/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;a-nice-api&quot;&gt;A nice API&lt;/h3&gt;
&lt;p&gt;The code changes were actually minimal, and the majority is displayed
below. The refactor was just making sure that I was passing the correct matrix
type to the methods defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::cuda&lt;/code&gt; .&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GpuMat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GpuMat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_cur_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Convert Mat to GpuMat&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;img_cur_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cur_img_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cvtColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_cur_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CV_BGR2GRAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;equalizeHist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GpuMat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Find faces in image that are greater than min size (10,10) and store in&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// vector&amp;lt;cv::Rect&amp;gt;.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fc_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;detectMultiScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_gray_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fc_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;faces_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Faces detected...: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;faces_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;
&lt;p&gt;As a result, the publishing rates improved roughly 3x, from 3-4hz to 9-10hz.
Considering “real-time” is considered to be somewhere between 10-12hz, this is
acceptable. I plan to implement a deep learning driven algorithm next to
see how much faster GPU accelerated inference can be in the task of face detection.&lt;/p&gt;

&lt;p&gt;###References&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;https://docs.opencv.org/master/d6/d15/tutorial_building_tegra_cuda.html&lt;/li&gt;
  &lt;li&gt;https://answers.ros.org/question/242376/having-trouble-using-cuda-enabled-opencv-with-kinetic/&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sat, 28 Oct 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/tx1/opencv/2017/10/28/pi-tx1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/tx1/opencv/2017/10/28/pi-tx1.html</guid>
        
        
        <category>ROS</category>
        
        <category>tx1</category>
        
        <category>opencv</category>
        
      </item>
    
      <item>
        <title>ROS + RaspberryPi Camera Module #3: An alternative package for publishing images from Raspi</title>
        <description>&lt;h3 id=&quot;streaming-images-from-raspi-over-network-video_stream_opencv&quot;&gt;Streaming images from Raspi over Network: video_stream_opencv&lt;/h3&gt;
&lt;p&gt;For this particular project, I originally started off by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspicam_node&lt;/code&gt; developed by Ubiquitous
Robotics, which handles JPEG compression on the RaspberryPi leveraging the
videocore found locally.
The publish rate tested on the Raspi was ~30hz, but over the network the
performance degrades and is unable to maintain a reasonable fps unless the dimensions are set to around 640x480. There is
also another ROS package &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;video_stream_opencv&lt;/code&gt; [1] that works on the Raspi pretty
much out of the box and provides ~25hz+ over the network as well with dimensions set at
640x480. The good thing with this package is that we can simply start by
installing using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt-get install ros-kinetic-video-stream-opencv&lt;/code&gt; and
then finish the installation process by building the package.&lt;/p&gt;

&lt;p&gt;After installing and building the package the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webcam.launch&lt;/code&gt; file can be
launched  which will publish the following topics.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/webcam/camera_info
/webcam/image_raw
/webcam/image_raw/compressed
/webcam/image_raw/compressed/parameter_descriptions
/webcam/image_raw/compressed/parameter_updates
/webcam/image_raw/compressedDepth
/webcam/image_raw/compressedDepth/parameter_descriptions
/webcam/image_raw/compressedDepth/parameter_updates
/webcam/image_raw/theora
/webcam/image_raw/theora/parameter_descriptions
/webcam/image_raw/theora/parameter_updates
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Checking the publishing rate over the network from the master computer results
in satisfactory results.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ rostopic hz /webcam/image_raw/compressed
subscribed to [/webcam/image_raw/compressed]
average rate: 31.105
    min: 0.020s max: 0.040s std dev: 0.00453s window: 27
average rate: 29.865
    min: 0.004s max: 0.153s std dev: 0.01801s window: 55
average rate: 29.978
    min: 0.000s max: 0.167s std dev: 0.02493s window: 86
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://wiki.ros.org/video_stream_opencv&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 08 Sep 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/raspberrypi/2017/09/08/detect-faces-3.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/raspberrypi/2017/09/08/detect-faces-3.html</guid>
        
        
        <category>ros</category>
        
        <category>raspberrypi</category>
        
      </item>
    
      <item>
        <title>ROS + RaspberryPi Camera Module #2: Setting up a Network and Detecting Faces</title>
        <description>&lt;h3 id=&quot;networking-the-raspi-with-the-master&quot;&gt;Networking the Raspi with the Master&lt;/h3&gt;
&lt;p&gt;Once we get the raspicamera to publish images, we need to set up our system so
that multiple machines can communicate with each other. 
http://wiki.ros.org/ROS/Tutorials/MultipleMachines&lt;/p&gt;

&lt;p&gt;Having enabled the raspi camera to publish images, I have moved to set up a
master/child system, where the Raspberry Pi will be publishing images to be processed
by the master sitting on the host machine. The concept is not unique, and
allocating the computationally intensive processes to a master with greater
capacity is quite common.&lt;/p&gt;

&lt;h3 id=&quot;ros-message-to-cvimage&quot;&gt;ROS Message to CVImage&lt;/h3&gt;
&lt;p&gt;The master has been tasked to detect faces, the first step in a multi step
project I am currently working on. In order to process the image, we require a
conversion from a ROS image type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor_msgs::Image&lt;/code&gt; to the opencv matrix
type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::Mat&lt;/code&gt;, which will enable us to use the opencv standard libraries. Since
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspicam_node&lt;/code&gt; only publishes compressed images, we need to make sure to
provide the proper “hint” to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const TransportHints
&amp;amp;transport_hints=TransportHints())&lt;/code&gt;. For this case, we can create an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;image_transport&lt;/code&gt; subscriber as so:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cam_img_sub_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;/raspicam_node/image&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FaceDetect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertImageCB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;image_transport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransportHints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;compressed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once we have the subscriber in place, we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv_bridge&lt;/code&gt; to convert from
ROS messages to opencv Matrices. [1]&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;cv_bridge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CvImagePtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cv_ptr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_bridge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toCvCopy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sensor_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image_encodings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BGR8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cv_bridge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cerr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cv_bridge exception: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;what&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;cur_img_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;detectFace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// A method that I defined to detect faces.        &lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We store the image in a private variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cur_img_&lt;/code&gt; of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::Mat&lt;/code&gt;. Note that
since we are not transferring all the class attributes of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv_ptr&lt;/code&gt; associated
with the class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CvImage&lt;/code&gt;, [2] we need to take extra care when converting back to
ROS messages, which I will touch upon later.&lt;/p&gt;

&lt;h3 id=&quot;detecting-faces&quot;&gt;Detecting Faces&lt;/h3&gt;
&lt;p&gt;To detect faces we can use the object classifier, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::CascadeClassifier&lt;/code&gt; found
in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opencv2/objdetect/objdetect.hpp&lt;/code&gt;. We need to make sure that we specify the
path to the cascade of interest and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load()&lt;/code&gt; the  cascade. If you get an error
along the lines of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error: Assertion failed (!empty()) in detectMultiScale&lt;/code&gt;,
check the file path was specified correctly. Faces isnt the only trained models
available. Body segments, facial parts (eyes), and expressions (smile) can be
found at github.com/opencv [3].&lt;/p&gt;

&lt;p&gt;The process of detecting faces has become common knowledge, thus doing a quick
google search will provide sufficient background information. I particularly
liked this post where facial recognition, is covered as well[4].&lt;/p&gt;

&lt;h3 id=&quot;convert-back-to-ros-message-type&quot;&gt;Convert back to ROS message type&lt;/h3&gt;
&lt;p&gt;Once we have our vector of faces, we can place bounding boxes(rectangles) around
the detected faces, and publish the processed image. In order to publish over a
ROS topic, we will need to convert from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::Mat&lt;/code&gt; type back to a ROS message
type. As we allocated the image earlier separately, we need to populate the
public attributes in the class CvImage[2], encoding, and header. We can use the
following code to convert:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// img_with_bounding_ is a private variable that I created. You should replace&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// with the image you would like to convert.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sensor_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImagePtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv_bridge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CvImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bgr8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;img_with_bounding_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toImageMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;detected_faces_pub_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once we have made the conversion, we can simply publish the message using the
publisher we initiated earlier.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://docs.ros.org/kinetic/api/cv_bridge/html/c++/namespacecv__bridge.html&lt;/li&gt;
  &lt;li&gt;http://docs.ros.org/kinetic/api/cv_bridge/html/c++/classcv__bridge_1_1CvImage.html&lt;/li&gt;
  &lt;li&gt;https://github.com/opencv/opencv/tree/master/data/haarcascades&lt;/li&gt;
  &lt;li&gt;https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 04 Sep 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/raspberrypi/2017/09/04/detect-faces.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/raspberrypi/2017/09/04/detect-faces.html</guid>
        
        
        <category>ros</category>
        
        <category>raspberrypi</category>
        
      </item>
    
      <item>
        <title>ROS + RaspberryPi Camera Module #1: Publishing image from raspi on different host machine.</title>
        <description>&lt;p&gt;TL;DR: Make sure your environment is setup correctly and remember (stating the
obvious) that you will be working on a ARM architecture as opposed to a x86 most
likely found on your laptop.&lt;/p&gt;

&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;/h3&gt;
&lt;p&gt;Environment: Raspi3 running &lt;a href=&quot;https://ubuntu-mate.org/raspberry-pi/&quot;&gt;UbuntuMATE
16.04.2&lt;/a&gt; using the Raspi Camera v2.1. ROS
Kinetic is used and one can install ROS Kinetic for Ubuntu running on ARM
architecture using instructions found
&lt;a href=&quot;http://wiki.ros.org/kinetic/Installation/Ubuntu&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These notes assumes you have enabled the camera through raspi-config. Make sure
raspistill and raspivid are functioning as expected. (ex. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspistill -o
test.png&lt;/code&gt; should result in an image named test.png placed in the current
directory.)&lt;/p&gt;

&lt;h3 id=&quot;using-the-raspicam_node&quot;&gt;Using the raspicam_node&lt;/h3&gt;
&lt;p&gt;One can take the time to program their own Raspi camera node, but for this
exercise we will be using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspicam_node&lt;/code&gt; created by UbiquityRobotics. The ROS
node can be installed following the instructions found
&lt;a href=&quot;https://github.com/UbiquityRobotics/raspicam_node&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;network-configuration&quot;&gt;Network configuration&lt;/h3&gt;
&lt;p&gt;Some steps need to be taken to address the network configuration, in order for
Raspi to communicate with a master on a different machine.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;http://wiki.ros.org/ROS/Tutorials/MultipleMachines&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/ROS/NetworkSetup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In summary,  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ROS_MASTER_URI&lt;/code&gt; that is set for the machine considered the master
(laptop in my case), needs to be set exactly the same for the child
(raspberry-pi in my case). In my particular case, the hostnames were not
resolving, and was getting an error message &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Couldn't find an AF_INET address
for&lt;/code&gt; on my master machine. To resolve this issue, I explicitly specified the
ROS_IP of the child. (Use ifconfig to find IP address of the child).&lt;/p&gt;

&lt;p&gt;Once the network is setup, roscore needs to be initialized on the master
(laptop), before launching the launch file related to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspicam_node&lt;/code&gt;, otherwise
you will get an error message indicating that the master can not be reached.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raspicam_node&lt;/code&gt; outputs the following topics:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/raspicam_node/camera_info
/raspicam_node/image/compressed
/raspicam_node/parameter_descriptions
/raspicam_node/parameter_updates
/rosout
/rosout_agg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that the  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/raspicam_node/image/compressed&lt;/code&gt; is only available, thus
without the appropriate conversion, the image will not be viewable using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rosrun
image_view image_view image:=/topic_name&lt;/code&gt;. Thus we will need to publish a
conversion from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/image/compressed&lt;/code&gt; topic to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/image&lt;/code&gt; by using `
rosrun image_transport republish compressed in:=/raspicam_node/image raw
out:=/raspicam_node/image&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;. Another way to access the image is by using
&lt;/code&gt;rqt_image_view` which starts a GUI and allows for the visualization of the
capture.&lt;/p&gt;

&lt;h3 id=&quot;next-steps&quot;&gt;Next steps&lt;/h3&gt;
&lt;p&gt;Now that we have the camera working on a child machine separate from the master,
we can work on more interesting robotics projects related to collaboration
across multiple machines.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://ubuntu-mate.org/raspberry-pi/&quot;&gt;https://ubuntu-mate.org/raspberry-pi/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wiki.ros.org/kinetic/Installation/Ubuntu&quot;&gt;http://wiki.ros.org/kinetic/Installation/Ubuntu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/UbiquityRobotics/raspicam_node&quot;&gt;https://github.com/UbiquityRobotics/raspicam_node)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wiki.ros.org/ROS/Tutorials/MultipleMachines&quot;&gt;http://wiki.ros.org/ROS/Tutorials/MultipleMachines&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wiki.ros.org/ROS/NetworkSetup&quot;&gt;http://wiki.ros.org/ROS/NetworkSetup&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Mon, 28 Aug 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/raspberrypi/2017/08/28/raspicamera.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/raspberrypi/2017/08/28/raspicamera.html</guid>
        
        
        <category>ros</category>
        
        <category>raspberrypi</category>
        
      </item>
    
      <item>
        <title>N-gram: Some more PyTorch tutorials</title>
        <description>&lt;p&gt;Working through tutorials to familiarize myself with PyTorch…&lt;/p&gt;

&lt;h3 id=&quot;key-points-from-the-tutorial&quot;&gt;Key points from the tutorial&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Word embeddings are dense vectors of real numbers where each word in a
vocabulary is represented by a vector.&lt;/li&gt;
  &lt;li&gt;One hot encoding is used to attribute a unique identifier to a word. The
encoding converts a word to a vector of |V| elements [0,0,…1,…0,0].  Word w
is in the location of where the 1 is within the vector.&lt;/li&gt;
  &lt;li&gt;The issue with one hot encoding is that each word is treated as an
independent entity and no relationships are represented.&lt;/li&gt;
  &lt;li&gt;To improve on this, we consider semantic relationships or attributes. If each
attribute is a dimension then we can find the similarity by using some linear
algebra. The similarity is defined by the angle between the vector of
attributes. The tutorial explanation was sufficient thus will cut and paste.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/similarity.png&quot; alt=&quot;similarity&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Since manually engineering the possible symantic attributes is tedious, we
allow for latent semantic attributes, where the neural network will learn the
semantic attributes. This results in practicality in exchange for transparency,
as we will not be able to see what the actual attributes the model has learnt.&lt;/li&gt;
  &lt;li&gt;Embeddings are stored as a |V| x D, number of words in vocabulary by
dimension of embedding.&lt;/li&gt;
  &lt;li&gt;Use torch.nn.Embedding(vocab size, dimension of embedding). We need to use
torch.LongTensor to index in as indices are integers and not floats.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NGramLanguageModeler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;embedding_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NGramLanguageModeler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embeddings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Embedding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;embedding_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linear1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;embedding_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linear2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;embeds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embeddings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linear1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embeds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linear2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;log_probs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_softmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_probs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;n-gram-language-modeling&quot;&gt;N-Gram Language Modeling&lt;/h3&gt;
&lt;p&gt;The example the tutorial walks through is the N-gram language model, where the
objective is to compute \[P(w_i | w_{i-1}, w_{i-2},…,w_{i-n+1})\]. In the case
of the example, a 2-gram language model is considered, where the previous 2
words is associated with a target of the following word. The model trains on a
test sentence, the author uses Shakespeare Sonnet 2, where the vocabulary is
defined as the set of words that can construct the test sentence. Running the
model we can see that the loss reduces over each epoch, but a test of the model
is not provided.&lt;/p&gt;

&lt;h3 id=&quot;checking-the-predictive-power&quot;&gt;Checking the predictive power&lt;/h3&gt;

&lt;p&gt;Again, just walking through a tutorial verbatim can be boring. Playing
around a bit is more rewarding, and I find that it helps with memory retention
as well.
Instead of basing the vocab on one sonnet, I decided to test with multiple
sonnets[2], and see if training on first 5 and testing on the 6th would result in
something interesting. The vocabulary set consists of 398 unique words used in
sonnets 1-6, derived from the original 647 words used.&lt;/p&gt;

&lt;p&gt;Training the model, not surprisingly, shows the loss decrease on each epoch
consistent with the tutorial, but
evaluating the model after training on 100 epochs results in 0% accuracy. Though
dissappointing, This probably isn’t surprising considering the limited data and capacity of the
model…&lt;/p&gt;

&lt;p&gt;Note to self: Remember that PyTorch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Variable&lt;/code&gt; cant be transformed to numpy,
because they’re wrappers around tensors that save the operation history. We can
retrieve a tensor held by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autograd.Variable&lt;/code&gt; by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.data&lt;/code&gt; and then using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.numpy()&lt;/code&gt;, to convert from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Variable&lt;/code&gt; to a numpy array. [3]&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://pytorch.org/tutorials/beginner/nlp/word_embeddings_tutorial.html#getting-dense-word-embeddings&lt;/li&gt;
  &lt;li&gt;http://nfs.sparknotes.com/sonnets/sonnet_6.html&lt;/li&gt;
  &lt;li&gt;https://discuss.pytorch.org/t/how-to-transform-variable-into-numpy/104/2&lt;/li&gt;
  &lt;li&gt;http://colah.github.io/posts/2014-07-NLP-RNNs-Representations/&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sun, 20 Aug 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/pytorch/2017/08/20/n-gram.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/pytorch/2017/08/20/n-gram.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>pytorch</category>
        
      </item>
    
      <item>
        <title>Raspimouse: Simple teleop program written in Rust</title>
        <description>&lt;p&gt;tl;dr: Great event, and hopefully we see more events like this.&lt;/p&gt;

&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;
&lt;p&gt;This is a quick write up of my work at the ROS Japan UG #12 Raspberry Pi
Mouseハッカソン, hosted by &lt;a href=&quot;http://www.rt-net.jp/company-page/?lang=en&quot;&gt;RT
Corporation&lt;/a&gt;, and &lt;a href=&quot;http://www.groove-x.com/&quot;&gt;Groove
X&lt;/a&gt;. RT Corporation kindly
provided the Raspimouse (20+ units), a differential drive robot powered by the
raspberry pi, allowing participants to hack with a live robot while Groove X is
a robotics company started by the “dad” of the Pepper robot.&lt;/p&gt;

&lt;p&gt;github repo: &lt;a href=&quot;https://github.com/surfertas/rustymouse&quot;&gt;https://github.com/surfertas/rustymouse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had two focuses today, with the first being rewriting the teleop code in the
Rust language. I was under the impression this would be trivial, but had some hiccups
that consumed some time to resolve. The second was to move from simulation to
the real world, though it appears I will not have sufficient time to complete
part two on this occasion.&lt;/p&gt;

&lt;h3 id=&quot;teleop-the-raspimouse-in-rust&quot;&gt;Teleop the Raspimouse in Rust&lt;/h3&gt;
&lt;p&gt;I started with the crate that Takashi Ogura [1] created, where he implements the “hello world”
of ROS, a subscriber and publisher nodes, based on rosrust being developed by
Adnan[2].&lt;/p&gt;

&lt;p&gt;Main steps taken:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geometry_msgs/Twist&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.rs&lt;/code&gt; file where the messages are defined
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rosmsg_main!(“std_msgs/String”, “geometry_msgs/Twist”)&lt;/code&gt;. Currently message
generation is being done through a build script, where the use of procedural
macros is preferred. If there is any one with experience in procedural macros,
please reach out to Adnan!&lt;/li&gt;
  &lt;li&gt;Add the name of the binary to be created, in this case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vel_publisher&lt;/code&gt; and
path &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/vel_publisher.rs&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cargo.toml&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Finally, it was really about programming, where simple io, and pattern
matching was sufficient. (In reality, I should remove the new line mark, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n&lt;/code&gt;,
from the pattern matching to make the code more elegant…)&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;#[macro_use]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rosrust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rosrust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Ros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;rosmsg_include!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;env_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Ros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;vel_publisher&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;publisher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cmd_vel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;w: forward, s: backward, a: left, d: right &amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;geometry_msgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Twist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.read_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.as_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;w&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.linear.x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.linear.x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.angular.z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.angular.z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;q&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;           &lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Command not recognized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;       &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;publisher&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vel_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/raspimouse.png&quot; alt=&quot;raspi_mouse&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;issues&quot;&gt;Issues&lt;/h3&gt;
&lt;p&gt;One issue I had was that I needed to publish to the topic
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/raspimouse/diff_drive_controller/cmd_vel&lt;/code&gt;, which would allow me to teleop the
mouse, but rosrust for some reason was not accepting this topic name. Reviewing the source code[3] I was not able to find an
immediate solution, thus resulted in writing a python script to remap between
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd_vel&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/raspimouse/diff_drive_controller/cmd_vel&lt;/code&gt; using the below python
script. This allowed me to successfully teleop the mouse in simulation.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rospy&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;geometry_msgs.msg&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Twist&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Publisher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'/raspimouse/diff_drive_controller/cmd_vel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Twist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;queue_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;topic_mapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'mapper'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anonymous&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/cmd_vel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Twist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rospy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;   &lt;/span&gt; &lt;span class=&quot;n&quot;&gt;topic_mapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/OTL/rosrust_tutorial&quot;&gt;https://github.com/OTL/rosrust_tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/adnanademovic/rosrust&quot;&gt;https://github.com/adnanademovic/rosrust&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/adnanademovic/rosrust/blob/master/src/api/naming/mod.rs&quot;&gt;https://github.com/adnanademovic/rosrust/blob/master/src/api/naming/mod.rs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sat, 19 Aug 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/rust/2017/08/19/teleop-raspimouse-rust.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/rust/2017/08/19/teleop-raspimouse-rust.html</guid>
        
        
        <category>ROS</category>
        
        <category>rust</category>
        
      </item>
    
      <item>
        <title>Bag of Words: Working through some pytorch tutorials</title>
        <description>&lt;h3 id=&quot;some-nlp-with-pytorch&quot;&gt;Some NLP with Pytorch&lt;/h3&gt;
&lt;p&gt;The pytorch tutorial on NLP, really introducing the features of pytorch, is a
great crash course introduction to NLP. This exercise for me, is more about
getting comfortable with a new frame work then anything (have to jump on the
Pytorch band wagon with the release of v2).&lt;/p&gt;

&lt;p&gt;The first section is using Bag of words, checkout the wiki for a decent intro
and rather comprehensive introduction. In short, in its naive form, the
frequency of each word is used as a feature for training a classifier.&lt;/p&gt;

&lt;p&gt;The first step is creating a vocabulary, and is done by taking the union of the
data sets under consideration. In the pytorch tutorial &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_data&lt;/code&gt;
are combined and used to create an index of words, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;word_to_ix&lt;/code&gt;. The simple
script provided does the job.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;word_to_ix = {}
for sent, _ in data + test_data:
    for word in sent:
        if word not in word_to_ix:
            word_to_ix[word] = len(word_to_ix)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The wiki example is rather clear so will introduce below:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;John likes to watch movies. Mary likes movies too.&lt;/li&gt;
  &lt;li&gt;John also likes to watch football games.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These two texts will describe the sample space, thus the list constructed is as
follows.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[
    &quot;John&quot;,
    &quot;likes&quot;,
    &quot;to&quot;,
    &quot;watch&quot;,
    &quot;movies&quot;,
    &quot;Mary&quot;,
    &quot;too&quot;,
    &quot;also&quot;,
    &quot;football&quot;,
    &quot;games&quot;
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We can get the bag of words representation by backing out the frequency of each
word for each text sample, thus we get:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[1, 2, 1, 1, 2, 1, 1, 0, 0, 0]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[1, 1, 1, 1, 0, 0, 0, 1, 1, 1]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;training-with-bow&quot;&gt;Training with BOW&lt;/h3&gt;
&lt;p&gt;I have left the original comments as they are helpful for a new comer. The texts
are converted to feature vectors with the appropriate type as inputs to
autograd.Variable() need to be of torch tensor type. The labels in string form
are converted to a torch.LongTensor, an integer tensor likewise. The data set is
used and trained for 100 epochs, and the results show that the model has learned
to classify between and english and spanish.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;c1&quot;&gt;# Step 1. Remember that Pytorch accumulates gradients.
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# We need to clear them out before each instance
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zero_grad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Step 2. Make our BOW vector and also we must wrap the target in a
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Variable as an integer. For example, if the target is SPANISH, then
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# we wrap the integer 0. The loss function then knows that the 0th
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# element of the log probabilities is the log probability
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# corresponding to SPANISH
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;bow_vec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;autograd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_bow_vector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_to_ix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;autograd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label_to_ix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Step 3. Run our forward pass.
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;log_probs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bow_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Step 4. Compute the loss, gradients, and update the parameters by
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# calling optimizer.step()
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_probs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The tutorial tests on the word “creo” . Before we find the log probabilities as
spanish: -0.1599 and english: -0.1411, while after 100 epochs of training on
such a small data set we find that the results are, spanish: 0.3315 and english:
-0.6325.&lt;/p&gt;

&lt;h3 id=&quot;recap&quot;&gt;Recap&lt;/h3&gt;
&lt;p&gt;Its always fun trying to change the tutorial in some form, to see how different
tweaks impact the results. Since we started with such a small data set, a quick
and easy adjust, is to add more examples, (in particular spanish text with the
use of creo). Increasing the data set by a few samples, quickly improves the
results with the log probabilities moving to spanish: 0.5855 and english: -7205.
In this case, its probably best to apply the softmax function to represent the
log probabilities as a probability distribution between 0 and 1*. The
probability of creo being spanish moves from 72.39% to 78.68%. Not bad of an
improvement for a small boost to the sample set, but more impressive is that we
were able to get such results with such a small data set to start with. *To convert from log probs to a
probability distribution between 0 and 1, simply exponentiate the log probs
values using a base e, and normalize by the sum for each case).&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://pytorch.org/tutorials/beginner/nlp/deep_learning_tutorial.html&lt;/li&gt;
  &lt;li&gt;https://en.wikipedia.org/wiki/Bag-of-words_model&lt;/li&gt;
  &lt;li&gt;https://en.wikipedia.org/wiki/Softmax_function&lt;/li&gt;
  &lt;li&gt;http://www.spanishdict.com/translate/yo%20creo&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Fri, 18 Aug 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/pytorch/2017/08/18/bag-of-words.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/pytorch/2017/08/18/bag-of-words.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>pytorch</category>
        
      </item>
    
      <item>
        <title>Transfer Learning: Working through the pytorch tutorial</title>
        <description>&lt;h3 id=&quot;quick-post-on-transfer-learning&quot;&gt;Quick post on Transfer Learning&lt;/h3&gt;

&lt;p&gt;A common situation that we encounter is the lack of data, which results in not
having sufficient data to properly train a high capacity architecture.  Thus,
often times, a pretrained model is used for initialization as opposed to
(fine-tuning) or as a fixed feature extractor, where all layers excluding the
final FC is frozen.&lt;/p&gt;

&lt;p&gt;The pytorch tutorial[1] provides a couple examples, one related to finetuning a
resnet18 model pre-trained on imagenet 1000 dataset. When finetuning, we use the
pre-train model as the initialization to our new architecture, where we have
redefined the final fully connected layer to take in they same number of in
features &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model_ft.fc.in_features&lt;/code&gt; while we reset the number of out features to
accommodate the number of labels, which in the case is set to two as we are
classifying between ants and bees, and train per usual on our smaller data set.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resnet18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pretrained&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;num_ftrs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_features&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_ftrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#nn.Linear(number of in_features, number of
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_gpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;criterion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CrossEntropyLoss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Observe that all parameters are being optimized
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer_ft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SGD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_ft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;momentum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;resnets&quot;&gt;Resnets&lt;/h3&gt;
&lt;p&gt;Deep Residual Learning is presented in “Deep Residual Learning for Image
Recognition”, and builds on the evidence that depth of a neural network plays a
significance role in the performance of a given model. A key excerpt from the
paper is quoted below:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Let us consider H(x) as an underlying mapping to be fit by a few stacked layers
(not necessarily the entire net), with x denoting the inputs to the first of
these layers. If one hypothesizes that multiple nonlinear layers can
asymptotically approximate complicated functions2 , then it is equivalent to
hypothesize that they can asymptotically approximate the residual functions,
i.e., H(x) − x (assuming that the input and output are of the same
dimensions). So rather than expect stacked layers to approximate H(x), we
explicitly let these layers approximate a residual function F(x) := H(x) −
x. The original function thus becomes F(x)+x. Although both forms should be
able to asymptotically approximate the desired functions (as hypothesized),
the ease of learning might be different.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The results are pretty impressive, considering the ants and bees data set only
consists of 120 training images, and 75 images for validation. As suggested in
the paper, this result is likely related to the ability for deep representations
having excellent generalization performance on recognition tasks.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Epoch 22/24
----------
train Loss: 0.0800 Acc: 0.8525
val Loss: 0.0429 Acc: 0.9542

Epoch 23/24
----------
train Loss: 0.0714 Acc: 0.8730
val Loss: 0.0425 Acc: 0.9477

Epoch 24/24
----------
train Loss: 0.0620 Acc: 0.9016
val Loss: 0.0434 Acc: 0.9412

Training complete in 51m 51s
Best val Acc: 0.954248
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;As for next steps, would be interesting to see finetuning on the resnet model
performs on a data set consisting of larger number of labels.&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html&lt;/li&gt;
  &lt;li&gt;https://arxiv.org/pdf/1512.03385.pdf&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 17 Aug 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/pytorch/2017/08/17/transfer-learning.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/pytorch/2017/08/17/transfer-learning.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>pytorch</category>
        
      </item>
    
      <item>
        <title>Rust-Docker: Speeding up compile times when using docker + rust</title>
        <description>&lt;p&gt;Recently, have been trying to have a go at ROS using the rust language. As
launch files aren’t available, a clear alternative is using docker containers
with docker compose.&lt;/p&gt;

&lt;p&gt;In order to accomplish the above, I first need to be able to create containers
that can compile the rust language. Do a bit of searching on the internet, I
came across &lt;a href=&quot;https://github.com/emk/rust-musl-builder&quot;&gt;Docker container for easily building static Rust
binaries&lt;/a&gt;, which seemed perfect for
this particular exercise.&lt;/p&gt;

&lt;p&gt;Simply running allows for the compilation of a static Rust binary with no
external dependencies:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ alias rust-musl-builder='docker run --rm -it -v &quot;$(pwd)&quot;:/home/rust/src ekidd/rust-musl-builder'
$ rust-musl-builder cargo build --release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One suggestion that was made to me to improve the build times, was to cache the
dependencies necessary by creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cargo/registry&lt;/code&gt; in the rust project.&lt;/p&gt;

&lt;p&gt;Going to the root of the rust project directory:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ mkdir .cargo/registry -p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and add the mounting command as follows when creating the alias:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ alias rust-musl-builder='docker run --rm -it -v &quot;$(pwd)&quot;:/home/rust/src -v &quot;$(pwd)/.cargo/registry&quot;:/home/rust/.cargo/registrye kidd/rust-musl-builder'
$ rust-musl-builder cargo build --release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first build will take the usual expected time, while the next builds will be
faster with any dependencies having been cached.&lt;/p&gt;

&lt;p&gt;Thanks @yasuyuky!&lt;/p&gt;

</description>
        <pubDate>Thu, 22 Jun 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rust/docker/2017/06/22/rust-docker.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rust/docker/2017/06/22/rust-docker.html</guid>
        
        
        <category>rust</category>
        
        <category>docker</category>
        
      </item>
    
      <item>
        <title>Turtlepi #7: Automatic Target Generation for the Turtlebot</title>
        <description>&lt;p&gt;Source: &lt;a href=&quot;https://github.com/surfertas/turtlepi&quot;&gt;https://github.com/surfertas/turtlepi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a quick note to update the work done thus far while here at &lt;a href=&quot;https://idein.jp/&quot;&gt;Idein
Inc&lt;/a&gt;. One of the short term objective was to create an
environment that would allow for the collection of data of a robot navigating in
a simulation environment based on a given policy. The expert policy was provided
by the ROS navigation stack, specifically the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move_base&lt;/code&gt; found in the ROS
node. Since the robot will have access to a static map, we will be using the
AMCL, adaptive monte carlo localization algorithm as opposed to SLAM. [1] See
the figure below for the navigation stack setup. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move_base&lt;/code&gt; given the below setup
publishes control commands to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd_vel&lt;/code&gt; topic as messages of type
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geometry_msgs/Twist&lt;/code&gt; allowing the robot to follow a path computed by
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;global_planner&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_planner&lt;/code&gt; to a goal specified independently.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/rosnavstack.png&quot; alt=&quot;nav_stack&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A typical way of generating a target for navigation is by using RViz to specify a goal
explicitly using the Navigation 2d feature. This is fine in the case
where only a few sample runs are needed, but in our case we would like to
automate the target generation process in order to efficiently generate a large
amount of data in simulation.&lt;/p&gt;

&lt;h3 id=&quot;automated-target-generation-system&quot;&gt;Automated Target Generation System&lt;/h3&gt;
&lt;p&gt;The program logic associated with the automated target generation service
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generate_nav_target&lt;/code&gt; is quite simple, though the integration requires work.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We start by obtaining the meta data related to the map. In this case we are
using a static map, and assume that the map environment does not change during
an episode, where an episode is defined as a run from current location to the
target. The ROS framework already provides a service &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static_map&lt;/code&gt; that is of
type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nav_msgs::GetMap&lt;/code&gt; and returns  a response of type
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nav_msgs/OccupancyGrid&lt;/code&gt;. We can observe the raw message
definition defined per below. In particular, we want to copy over the MapMetaData
info and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int8[]&lt;/code&gt; data for later use. Luckily &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int8[]&lt;/code&gt; is of type
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;int8_t&amp;gt;&lt;/code&gt; in c++ thus the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; is overloaded and copying the vector
is easy. NOTE: the data is in row-major form so we need to be sensitive when
using the data. The map gets initialized once when the target generator service
is launched.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# This represents a 2-D grid map, in which each cell represents the probability of
# occupancy.

Header header 

#MetaData for the map
MapMetaData info

# The map data, in row-major order, starts with (0,0).  Occupancy
# probabilities are in the range [0,100].  Unknown is -1.
int8[] data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol&gt;
  &lt;li&gt;When the service is initiated, the callback &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generateTargetService&lt;/code&gt; is called,
and generates a new target. The service uses the
cost map that was saved at initialization and randomly selects a point on the
cost map. The grid point is converted to the world coordinates via a conversion
as per below:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TargetGenerator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mapToWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;wy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;wx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map_origin_x_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map_resolution_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;wy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map_origin_y_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map_resolution_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With the world coordinates in hand, a distance check is made against a threshold
which I have set to 8m. We want to avoid targets that are too close to the
current location. If and only if the threshold check passes and the selected
point on grid is in the free space, which is associated with a cost map value of
0, then the generated point is selected as a valid target.&lt;/p&gt;

&lt;p&gt;A couple of additional notes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I have used visualization markers to make target visualization in RViz easier.
You need to add a marker, and specify the appropriate topic to subscribe to.
In this case the topic is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/turtlepi_navigate/visualization_marker&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;The implementation has much room for optimization. This implementation is a
first pass. When considering a large number of calls to this service. It would
be inefficient to randomly select a point from the entire cost map, when the
valid points are only contained to the free space. I look to implement an algorithm that would
return the free space points only, and the service can randomly select a point
from the set of free points.&lt;/li&gt;
  &lt;li&gt;Once the target goal is obtained the action server is used to communicate the
goal and follow on communication with the robot until the target is reached or
  a failure event occurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;

&lt;p&gt;See the results of an example run below.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/bP-OWmqL1qU&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone  https://github.com/surfertas/turtlepi.git
// On first terminal
cd ~/turtlepi_gazebo/launch/
roslaunch turtlepi.launch
// Wait until you see that odom received message.
// On second terminal
cd ~/turtlepi_navigate/launch/
roslaunch turtlepi_gentarget.launch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://robots.stanford.edu/papers/fox.aaai99.pdf&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Tue, 23 May 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/05/23/autotarget.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/05/23/autotarget.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Turtlepi #6: Dealing with Quaternions, no not GANs</title>
        <description>&lt;p&gt;This is a quick post to better understand the concept of quaternions and its
relation to robotics. The catalyst for this particular post was the use of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf::Quaternion&lt;/code&gt; in a recent ROS implementation, and a self directed question
inquiring whether or not I truly understood and remember the concept of a quaternion. The
answer was no, and is still no, but I can definitely say that I remember more now
than I did the day before.&lt;/p&gt;

&lt;h3 id=&quot;advantages-of-quaternions&quot;&gt;Advantages of Quaternions&lt;/h3&gt;
&lt;p&gt;Quaternions are used to represent rotations and is an alternative to the often
referenced Euler angles. Despite the elevated complexity with respect to the
learning curve, the benefits warrant the effort. Some benefits cited included:
[1]&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Dont have to worry about &lt;a href=&quot;https://en.wikipedia.org/wiki/Gimbal_lock&quot;&gt;Gimbal lock&lt;/a&gt; a property specific to Euler
angles.&lt;/li&gt;
  &lt;li&gt;Greater efficiency in terms of memory foot print and computation relative to
matrix and angle/axis representation.&lt;/li&gt;
  &lt;li&gt;Depends on the use case, but quaternions only contain a rotation as opposed
to a translation and scaling.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;what-is-a-quaternion&quot;&gt;What is a Quaternion&lt;/h3&gt;
&lt;p&gt;Mathematically, a quaternion is represented by a scalar and a vector, \((a_0.
\textbf{a})\), and in the expanded form as a linear combination: \[ a = a_0 +
a_1i + a_2j + a_3k \]&lt;/p&gt;

&lt;p&gt;The scalar component represents the magnitude of the rotation, while the vector
component represents the axis of rotation.&lt;/p&gt;

&lt;h3 id=&quot;using-quaternions-and-related-properties&quot;&gt;Using Quaternions and related Properties&lt;/h3&gt;
&lt;p&gt;The quaternion under consideration represents a rotation in 3 dimensions. A
property of a rotation in 3 dimensions is that any combination of rotations can
be represented by a rotation along a given axis. Thus if we are given two
rotations represented by quaternions,\(r\), and \(s\), that are applied
to a particular axis represented by \(\textbf{v_1}\), we can get the new
representation, \(\textbf{v_2}\) , by considering the following equation: \[\textbf{v_2}
= (rs) (0 \ \textbf{v_1})^T(rs)^{-1}\]&lt;/p&gt;

&lt;p&gt;Before moving forward, at this point we need to review a few properties related
to quaternions to understand what operations are taking place.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The inverse of a quaternion, \(r^{-1}\)  is not as simple as just taking
the inverse, but is actually the representations conjugate, which simply means
that the vector elements of the quaternion are negated. Thus the quaternion
inverse of \((r_0, \textbf{r})\) is equivalent to \(r_0, -\textbf{r})\).&lt;/li&gt;
  &lt;li&gt;Multiplication when considering quaternions, is again, not particularly
straightforward, in the common sense. Multiplication represents the composition
of two rotations, thus \(rs\), actually is representing one rotation
followed by another rotation.&lt;/li&gt;
  &lt;li&gt;Rotations are not communicative. This means that \(rs \neq sr\),
and in words, the order of rotations matters. This can be quickly confirmed
using your right hand and applying two rotations in different order.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;quaternion-multiplication&quot;&gt;Quaternion Multiplication&lt;/h3&gt;
&lt;p&gt;Now back to the equation \[\textbf{v_2} = (rs) (0 \ \textbf{v_1})^T(rs)^{-1}\]. Obtaining the inverse is somewhat self explained, thus
will focus on quaternion multiplication.&lt;/p&gt;

&lt;p&gt;If we expand, \(r\), and represent the
rotation as a linear combination, we get \[r = r_0 + r_1i + r_2j + r_3k\] and
likewise for \(s\) we get \[s = s_0 + s_1i + s_2j + s_3k\]&lt;/p&gt;

&lt;p&gt;Before we proceed lets consider the fundamental formula of quaternion algebra
discovered by William Rowan Hamilton . For some context this formula just happened to
occur to Mr. Hamilton as he was walking along some river. [2] Impressive to say
the least.
\[ i^2 = j^2 = k^2 = ijk = -1\]&lt;/p&gt;

&lt;p&gt;From the fundamental formula we can further derive a few other identies,
specifically:
\[ i^2 = j^2 = k^2 = -1\]
\[ ij = -ji = k\]
\[ jk = -kj = i\]
\[ ki = -ik = j\]&lt;/p&gt;

&lt;p&gt;which can be used along side the associated multiplication table[2]:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/quaternion.png&quot; alt=&quot;quaternion&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Using the identities and the multiplication we can compute the result of
\(rs\) as \(n = r \times  s =  n_0 + n_1i + n_2j + n_3k\) where 
\[n_0=(r_0s_0−r_1s_1−r_2s_2−r_3s_3)\]
\[n_1=(r_0s_1+r_1s_0−r_2s_3+r_3s_2)\]
\[n_2=(r_0s_2+r_1s_3+r_2s_0−r_3s_1)\]
\[n_3=(r_0s_3−r_1s_2+r_2s_1+r_3s_0)\]&lt;/p&gt;

&lt;p&gt;I will refrain from writing out all the computations but the calculations is
really as simple as aligning the first rotation along the y-axis of the
multiplication table and the second rotation along the x-axis of the
multiplication table and applying the identities to simplify.&lt;/p&gt;

&lt;h3 id=&quot;result&quot;&gt;Result&lt;/h3&gt;
&lt;p&gt;Now that we have the inverse and multiplication results in hand, we can simply
relay on plain matrix multiplication to compute the new axis, given the original
from and two rotations.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://stackoverflow.com/questions/1840314/when-do-i-need-to-use-quaternions&lt;/li&gt;
  &lt;li&gt;http://mathworld.wolfram.com/Quaternion.html&lt;/li&gt;
  &lt;li&gt;https://www.mathworks.com/help/aerotbx/ug/quatmultiply.html&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 18 May 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/05/18/quaternion.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/05/18/quaternion.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Turtlepi #5: Getting familiar with boost and its relation to ROS</title>
        <description>&lt;p&gt;Having been reading a lot more ROS related code in recent days, I am starting to see a lot more use of the boost library,
thus writing a quick post as a reminder to myself of the different functionality
that boost offers. Will keep this an open post as I will sure to be adding new functions as I progress.&lt;/p&gt;

&lt;h2 id=&quot;boostbind&quot;&gt;boost::bind()&lt;/h2&gt;

&lt;p&gt;Taken from the documentation the purpose of boost::bind is introduced as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;boost::bind is a generalization of the standard functions std::bind1st and
std::bind2nd. It supports arbitrary function objects, &amp;gt;functions, function
pointers, and member function pointers, and is able to bind any argument to a
specific value or route input arguments into 
arbitrary positions. bind does not place any requirements on the function
object; in particular, it does not need the result_type, &amp;gt;first_argument_type
and second_argument_type standard typedefs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few examples helps to clarify and move us from abstraction to concreteness.&lt;/p&gt;

&lt;p&gt;Consider the standard library functions std::bind1st(), and std::bind2nd()
presented below. Note that we will stick with the same examples presented in the documentation.&lt;/p&gt;

&lt;h4 id=&quot;boost-vs-standard-library&quot;&gt;Boost vs. Standard Library&lt;/h4&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// standard library&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind2nd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// f(x, 5)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// boost&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;              &lt;span class=&quot;c1&quot;&gt;// f(x, 5)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// standard library&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind1st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// f(5, x)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// boost&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// f(5,x)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Thus in boost, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_1&lt;/code&gt;, acts as a place holder for the first input to the function
call that is not “bound”. The docs indicate that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::bind&lt;/code&gt; is more flexible,
and the examples given definitely makes you think that is the case.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// f(y, x)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// g(x, 9, x)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// g(z, z, z)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// g(x, x, x)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;relation-to-ros&quot;&gt;Relation to ROS&lt;/h4&gt;
&lt;p&gt;Why does this matter in relation to ROS. One use case we can consider is when one wants to pass
arguments to a callback.&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;imageCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sensor_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageConstPtr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;additional_arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// some code&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subscriber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;nh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sensor_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/topic&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imageCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;additional_arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;important&quot;&gt;Important&lt;/h4&gt;
&lt;p&gt;One thing to note, is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_1&lt;/code&gt; indicates the target location of where the
message of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor_msgs::Image&lt;/code&gt; will be directed. In this, if we observe
the function definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;imageCallback()&lt;/code&gt;, we can see that the message is
located in the first slot.&lt;/p&gt;

&lt;h2 id=&quot;boostshared_ptr&quot;&gt;boost::shared_ptr&lt;/h2&gt;
&lt;p&gt;boost::shared_ptr is a wrapper for a raw C++ pointer which helps to manage the
lifetime of the pointer. There is a preference to use a “smart” pointer in place
of the typical method which leaves the responsibility of deleting the object to the programmer,
which obviously raises the risk of memory leaks. Since c++ 11, the standard
library has included this functionality, thus we can be using std::shared_ptr in
place of boost in our own coding if necessary.&lt;/p&gt;

&lt;p&gt;The use of smart pointers allows for the automatic deletion of objects, thus is
generally considered safer and the preferred way of implementation. An example using the std::shared_ptr is presented below: [3]&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shared_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyObjectPtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// nice short alias&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Empty&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MyObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// There is now one &quot;reference&quot; to the created object&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Copy the pointer.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// There are now two references to the object.&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// p2 is destroyed, leaving one reference to the object.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// p1 is destroyed, leaving a reference count of zero. &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// The object is deleted.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I like the idea that with a bit more code, we can guarantee safe programming, at
least with respect to pointers.&lt;/p&gt;

&lt;h4 id=&quot;shared-pointers-and-ros&quot;&gt;Shared pointers and ROS&lt;/h4&gt;
&lt;p&gt;How does shared pointers come in to play when programming with ROS? The use of
shared pointers is apparent when dealing with intraprocess publishing, i.e. when
the publisher and subscriber to a particular topic exist in the same node. If we
want to skip the serialize/deserialize step when considering intraprocess
publishing, which is process intensive and reasons for latency, we need to
publish the message as a shared pointer. See th example from the ROS Wiki: [4]&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Publisher&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;advertise&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;topic_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringPtr&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Note that std_msgs::StringPtr is a redefinition of boost::shared_ptr.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// From the docs [5]:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  typedef boost::shared_ptr&amp;lt; ::std_msgs::String&amp;gt; std_msgs::StringPtr&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;This form of publishing is what can make nodelets such a large win over nodes
in separate processes. 
Note that when publishing in this fashion, there is an implicit contract
between you and roscpp: &amp;gt;you may not modify the message you’ve sent after you
send it, since that pointer will be passed &amp;gt;directly to any intraprocess
subscribers. If you want to send another message, you must allocate a &amp;gt;new one
and send that. - ROS WIKI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://www.boost.org/doc/libs/1_64_0/libs/bind/doc/html/bind.html&lt;/li&gt;
  &lt;li&gt;http://answers.ros.org/question/12045/how-to-deliver-arguments-to-a-callback-function/&lt;/li&gt;
  &lt;li&gt;http://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one?rq=1&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/roscpp/Overview/Publishers%20and%20Subscribers&lt;/li&gt;
  &lt;li&gt;http://docs.ros.org/electric/api/std_msgs/html/String_8h.html&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 11 May 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/05/11/ros-boost.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/05/11/ros-boost.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Turtlepi #4: Resolving the spinning Turtlebot in RViz when using the navigation stack</title>
        <description>&lt;h3 id=&quot;turtlebot-spins-out-of-control&quot;&gt;Turtlebot spins out of control&lt;/h3&gt;

&lt;p&gt;Not sure if others have had similar issues, but when trying to use the
navigation stack I found that the turtlebot had the tendency to spin out of
control when given a target that required rotation as a first move.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/iNyqzGzs_M8?rel=0&quot; frameborder=&quot;0&quot; allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;p&gt;In order to resolve this issue, we need to first inspect the relevant configuration file for the DWS planner,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwa_local_planner_params.yaml&lt;/code&gt; found in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt/ros/kinetic/share/turtlebot_navigation/param&lt;/code&gt; directory.  The parameters
that need to be considered are specified as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DWAPlannerROS:

# Robot Configuration Parameters - Kobuki
  max_vel_x: 0.5  # 0.55
  min_vel_x: 0.0

  max_vel_y: 0.0  # diff drive robot
  min_vel_y: 0.0  # diff drive robot

  max_trans_vel: 0.5  # choose slightly less than the base's capability
  min_trans_vel: 0.1  # this is the min trans velocity when there is negligible rotational velocity
  trans_stopped_vel: 0.1

  # Warning!
  #   do not set min_trans_vel to 0.0 otherwise dwa will always think
  #   translational velocities
  #   are non-negligible and small in place rotational velocities will be
  #   created.

  max_rot_vel: 5.0  # choose slightly less than the base's capability
  min_rot_vel: 0.4  # this is the min angular velocity when there is negligible translational velocity
  rot_stopped_vel: 0.4

  acc_lim_x: 1.0 # maximum is theoretically 2.0.
  acc_lim_theta: 2.0
  acc_lim_y: 0.0  # diff drive robot
…
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The current solution offered is capping the maximum rotation velocity by setting
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_rot_vel&lt;/code&gt; parameter to a smaller value then the default specification of
5.0. Reducing this value to 1.0 resolved the issue. [1]&lt;/p&gt;

&lt;p&gt;In order to this, we can either directly amend the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwa_local_planner_params.yaml&lt;/code&gt; file to set a
new default or, we can redefine the parameter by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;param
name=&quot;move_base/DWAPlannerROS/max_rot_vel&quot; value=&quot;1.0&quot;/&amp;gt;&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;include&amp;gt;&lt;/code&gt; tag
that launches the&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{move.base.launch.xml&lt;/code&gt; file as mentioned
&lt;a href=&quot;http://answers.ros.org/question/239340/turtlebot-spinning/&quot;&gt;here&lt;/a&gt;.[2]&lt;/p&gt;

&lt;h3 id=&quot;result&quot;&gt;Result&lt;/h3&gt;
&lt;p&gt;We can see that with the redefinition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_rot_vel&lt;/code&gt; the spinning issue has
been resolved.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/esL_YW-dmvg&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://github.com/turtlebot/turtlebot_apps/pull/140&lt;/li&gt;
  &lt;li&gt;http://answers.ros.org/question/239340/turtlebot-spinning/&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Mon, 08 May 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rviz/turtlebot/2017/05/08/turtlepi-spin.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rviz/turtlebot/2017/05/08/turtlepi-spin.html</guid>
        
        
        <category>RViz</category>
        
        <category>turtlebot</category>
        
      </item>
    
      <item>
        <title>Turtlepi #3: Getting RGB image to display in RViz using the Astra Pro Camera</title>
        <description>&lt;p&gt;Update: 2020/1/22&lt;/p&gt;

&lt;p&gt;If you find this article at all helpful, please consider a supportive contribution.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/koraboblogqrcode.png&quot; alt=&quot;qrcode&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.korabo.io/checkout-page/5e2815526ca5270022f1a858/5e23f0b31b70f70022ff5933&quot;&gt;
  &lt;img src=&quot;https://img.shields.io/badge/Korabo-Contribute-blue&quot; alt=&quot;Contribute&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is somewhat specific to the Turtlebot 2 that is being shipped with the
Astra Pro by Clearpath Robotics.&lt;/p&gt;

&lt;p&gt;At least in my case, there were some obstacles in getting the
RGB camera and depth camera working simultaneously out of the box. This post is
an attempt to document a working solution.&lt;/p&gt;

&lt;p&gt;Appears that others have had similar issues
&lt;a href=&quot;http://answers.ros.org/question/246595/astra_launch-and-astra_camera-packages-problems-with-rgb/#260862&quot;&gt;fwiw&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;getting-the-launch-file&quot;&gt;Getting the Launch file&lt;/h3&gt;
&lt;p&gt;I will quickly outline the solution to get the Astra Pro working such that depth
and RGB image topics are recognized by RViz. (I specify the objective as getting
RViz to recognize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/camera/rgb/image_raw&lt;/code&gt; topic as this is a result that was
necessary for the current ongoing project.&lt;/p&gt;

&lt;p&gt;First get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;astra_pro.launch&lt;/code&gt; file following the below steps:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p turtlebot_ws/src
cd turtlebot_ws/src
catkin_init_ws
git clone https://github.com/tonybaltovski/ros_astra_launch.git --branch
upstream
git clone https://github.com/tonybaltovski/ros_astra_camera.git --branch
upstream
cd ..
rosdep install --from-paths src --ignore-src --rosdistro=indigo -y
catkin_make
source devel/setup.bash
rosrun astra_camera create_udev_rules
(you may need to reboot here)
roslaunch astra_launch astra_pro.launch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can investigate the launch file to get a better idea of what is being
called, and what parameters are being set.&lt;/p&gt;

&lt;p&gt;This will allow for the depth camera to function as well as the RGB camera.
After launching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roslaunch astra_pro.launch&lt;/code&gt;, we can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rostopic list&lt;/code&gt; and the list of
all available topics will be outputted to the terminal.&lt;/p&gt;

&lt;p&gt;We should be able to confirm that the below topics related to the depth camera and
RGB image camera are available as well.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/camera/depth/camera_info
/camera/depth/image
/camera/depth/image/compressed
/camera/depth/image/compressed/parameter_descriptions
/camera/depth/image/compressed/parameter_updates
/camera/depth/image_raw
…

/camera/rgb/astra_pro_uvc/parameter_descriptions
/camera/rgb/astra_pro_uvc/parameter_updates
/camera/rgb/camera_info
/camera/rgb/image_raw
/camera/rgb/image_raw/compressed
/camera/rgb/image_raw/compressed/parameter_descriptions
/camera/rgb/image_raw/compressed/parameter_updates
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rosrun image_view image_view image:=/camera/rgb/image_raw&lt;/code&gt; works
but trying to subscribe to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/camera/rgb/image_raw&lt;/code&gt; topic in RViz will result in the
following status error message:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;CameraInfo/P resulted in an invalid position calculation (nans or infs)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This requires a relatively manual step that is most likely not obvious to new
comers. To resolve this we need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a yaml file related to the RGB camera calibrations, which will be named
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rgb_Astra_Orbbec.yaml&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Edit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;astra_pro.launch&lt;/code&gt; to reflect the location of the yaml file.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;camera-calibration&quot;&gt;Camera calibration&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/astracamera.png&quot; alt=&quot;camera&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to generate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rgb_Astra_Orbbec.yaml&lt;/code&gt; file we can follow the tutorial
“How to Calibrate a Monocular Camera”.[1]  A couple points to note:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;They use a large checker board for calibration, with the checker dimensions set
at 108mm. You can use a smaller checker board but make sure that you set the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--square&lt;/code&gt; argument to reflect the size that you use. A checker board printed to
A4 printing paper will be associated with 2.5cm sized checkers, based on my
measurements. Note that a checker board template is made available in the
tutorial.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;After calibrating hit commit, (it does really take a minute or so, and the
screen does appear to freeze temporarily), and this should create a directory in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ros&lt;/code&gt; called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;camera_info&lt;/code&gt; if it doesn’t exist already and place a file named
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rgb_Astra_Orbbec.yaml&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;edits-to-launch-file&quot;&gt;Edits to Launch file&lt;/h3&gt;
&lt;p&gt;Before making the amends, launch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;astra_pro.launch&lt;/code&gt; and run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rostopic echo
/camera/rgb/camera_info&lt;/code&gt;. You should notice that the values are not populated
and filled with zeros.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;---
header:
  seq: 416
  stamp:
    secs: 1493810620
    nsecs:  89788527
  frame_id: camera_rgb_optical_frame
height: 0
width: 0
distortion_model: ''
D: []
K: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
R: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
P: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
binning_x: 0
binning_y: 0
roi:
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open the launch file and direct your attention to 19-23:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;!-- By default, calibrations are stored to
file://${ROS_HOME}/camera_info/${NAME}.yaml,
where ${NAME} is of the form &quot;[rgb|depth]_[serial#]&quot;, e.g.
&quot;depth_B00367707227042B&quot;.
See camera_info_manager docs for calibration URL details. --&amp;gt;
&amp;lt;arg name=&quot;rgb_camera_info_url&quot; default=&quot;&quot; /&amp;gt;
&amp;lt;arg name=&quot;depth_camera_info_url&quot; default=&quot;&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Set the default argument for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rgb_camera_info_url&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file:///$HOME/.ros/camera_info/rgb_Astra_Orbbec.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now go to line 132, where you should see&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;!-- &amp;lt;param name=&quot;camera_info_url&quot; value=&quot;file:///tmp/cam.yaml&quot;/&amp;gt; --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Uncomment and replace with:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;param name=&quot;camera_info_url&quot; value=&quot;$(arg rgb_camera_info_url)&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This should resolve the issue and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rostopic echo /camera/rgb/camera_info&lt;/code&gt;
should output the correct values derived from the calibration yaml file we
generated earlier.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;---
header:
  seq: 44
  stamp:
    secs: 1493810762
    nsecs: 374881266
  frame_id: camera_rgb_optical_frame
height: 480
width: 640
distortion_model: plumb_bob
D: [0.1924862242666659, -0.1428745350678355, -0.008005953314755045,
-0.01514558091529794, 0.0]
K: [631.9627446307516, 0.0, 292.3340769022051, 0.0, 626.7628503190605,
231.5643918983762, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [663.3839721679688, 0.0, 285.5615141729359, 0.0, 0.0, 662.3782348632812,
228.5056059693034, 0.0, 0.0, 0.0, 1.0, 0.0]
binning_x: 0
binning_y: 0
roi:
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Further, subscribing to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/camera/rgb/image_raw&lt;/code&gt; should not output a status
error in RViz, and you should be able to visualize the RGB image properly.&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 03 May 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rviz/turtlebot/2017/05/03/turtlebot-astrapro.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rviz/turtlebot/2017/05/03/turtlebot-astrapro.html</guid>
        
        
        <category>RViz</category>
        
        <category>turtlebot</category>
        
      </item>
    
      <item>
        <title>Turtlepi #2: Collecting data from simulation</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro:&lt;/h3&gt;
&lt;p&gt;I am in the process of setting up an environment in Gazebo+RViz+ROS to collect
navigation related data of a Turtlebot. Given a target, I need to record the
data related to sensor input, controls, the relative target location, and the
current location of the Turtlebot within a given map.&lt;/p&gt;

&lt;h3 id=&quot;plan&quot;&gt;Plan:&lt;/h3&gt;
&lt;p&gt;The logic that I plan to implement initially is to send a generic target as a
goal, and record the relevant data until the task is complete, where completion
is defined as success, or some error where a reset is necessary.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleActionClient&lt;/code&gt; presented here, &lt;a href=&quot;wiki.ros.org/actionlib&quot;&gt;actionlib&lt;/a&gt;,
is the relevant class and exposes the topics that I require for this exercise.
The action client subscribes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move_base/goal&lt;/code&gt; which translates to a goal for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move_base&lt;/code&gt; to pursue in a given map.&lt;/p&gt;

&lt;p&gt;The message type associated with the topic is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move_base_msgs/MoveBaseActionGoal&lt;/code&gt;  which is defined as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
actionlib_msgs/GoalID goal_id
  time stamp
  string id
move_base_msgs/MoveBaseGoal goal
  geometry_msgs/PoseStamped target_pose
    std_msgs/Header header
      uint32 seq
      time stamp
      string frame_id
    geometry_msgs/Pose pose
      geometry_msgs/Point position
        float64 x
        float64 y
        float64 z
      geometry_msgs/Quaternion orientation
        float64 x
        float64 y
        float64 z
        float64 w
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;functions&quot;&gt;Functions&lt;/h3&gt;
&lt;p&gt;Many of the functions that will come in handy are declared
&lt;a href=&quot;https://github.com/ros/actionlib/blob/indigo-devel/include/actionlib/client/simple_action_client.h&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The functions that will be specifically used are as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;sendGoal()&lt;/li&gt;
  &lt;li&gt;waitForResult()&lt;/li&gt;
  &lt;li&gt;getState()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;with the declarations displayed below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void sendGoal(const Goal&amp;amp; goal,
    SimpleDoneCallback done_cb = SimpleDoneCallback(),
    SimpleActiveCallback active_cb = SimpleActiveCallback(),
    SimpleFeedbackCallback feedback_cb = SimpleFeedbackCallback());

bool waitForResult(const ros::Duration&amp;amp; timeout = ros::Duration(0,0) );

ResultConstPtr getResult() const;

SimpleClientGoalState getState() const;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;psuedo-code&quot;&gt;Psuedo-code&lt;/h3&gt;
&lt;p&gt;The logic can be quickly shown with psuedo-code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;while ( true )
    sendGoal();
    while( waitForResult() )
        collect data mentioned previously and store.
    elihw
    GetState() → Log if success or not.
elihw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;remarks&quot;&gt;Remarks&lt;/h3&gt;
&lt;p&gt;Will post on the results once completed.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;https://github.com/ros/actionlib/blob/indigo-devel/include/actionlib/client/simple_action_client.h&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/move_base&lt;/li&gt;
  &lt;li&gt;http://wiki.ros.org/navigation/Tutorials/SendingSimpleGoals&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Fri, 28 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/gazebo/turtlebot/2017/04/28/rviz-gazebo-2.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/gazebo/turtlebot/2017/04/28/rviz-gazebo-2.html</guid>
        
        
        <category>gazebo</category>
        
        <category>turtlebot</category>
        
      </item>
    
      <item>
        <title>Turtlepi #1: RViz + Gazebo-Turtlebot localization in simulation</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;
&lt;p&gt;Posting on some results related to working with Gazebo + RViz. The task at hand
was importing a new world model into gazebo, building a map, and using
localization and navigation packages to allow for the Turtlebot to navigate to a
given target. I am currently working on a larger project, as part of my work at
&lt;a href=&quot;http://idein.jp/&quot;&gt;Idein Inc.&lt;/a&gt;  which requires data
generated from simulation, thus my venture into Gazebo + RViz.&lt;/p&gt;

&lt;p&gt;The general feeling I have is that RViz + Gazebo is not so friendly to a new
comer, and requires a decent amount of head banging to get things to work. That
said, since we are dealing with a lot of moving parts, the complexity of the
system and the API should be somewhat expected. To consider that this is the
case after ALOT has already been abstracted is quite impressive.&lt;/p&gt;

&lt;p&gt;source:
&lt;a href=&quot;https://github.com/surfertas/turtlepi&quot;&gt;https://github.com/surfertas/turtlepi&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;map-generation&quot;&gt;Map Generation&lt;/h3&gt;
&lt;p&gt;Gazebo has a &lt;a href=&quot;http://gazebosim.org/tutorials?cat=build_world&amp;amp;tut=building_editor&quot;&gt;build
editor&lt;/a&gt;
which allows one to create a “world”. This will clearly come in use at some
point later, but considering the time constraints, instead of creating a new
world model, I relied on models created by erlerobot found
&lt;a href=&quot;https://github.com/erlerobot/gym-gazebo/tree/master/gym_gazebo/envs/assets/models/Circuit_ql_2&quot;&gt;here&lt;/a&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model.config&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model.sdf&lt;/code&gt; were placed into a directory called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/circuit2&lt;/code&gt; and
this was placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~./gazebo/models&lt;/code&gt;.  The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;circuit2.world &lt;/code&gt; file was placed in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/worlds&lt;/code&gt; directory under a ros package that I created called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;turtlepi_gazebo&lt;/code&gt;, which
allows for easier access by other programs.&lt;/p&gt;

&lt;p&gt;Now that we have a world environment we can generate a map.
&lt;a href=&quot;&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generate_map.launch&lt;/code&gt;&lt;/a&gt;, was constructed to handle the launch of files related to teleop, gmapping, and RViz.&lt;/p&gt;

&lt;p&gt;After a painstakingly manual task of teleoping the turtlebot around, we get two
outputs, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pgm&lt;/code&gt; image, and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.yaml&lt;/code&gt; file referencing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pgm&lt;/code&gt; image. In
term of steps:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ roslaunch generate_map.launch 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use the teleop keypad to move around the map. You can confirm the construction
of the map in RViz which should have loaded as a result of roslaunch.&lt;/p&gt;

&lt;p&gt;Once you are satisfied with the constructed map, run map_server.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ rosrun map_server map_saver -f &amp;lt;file_name_to_save_to&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You should now see the previously mentioned files generated.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/turtlepimap.png&quot; alt=&quot;Map&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;localization&quot;&gt;Localization&lt;/h3&gt;
&lt;p&gt;This is really all we need to see the turtlebot in action, localizing and navigating
its way based on the generated map and given target.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ rosrun turtlepi_localize.launch map_file:=&amp;lt;location_of_.yaml_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not sure for others, but it took awhile for the map to load and set up which in
the meantime ROS was streaming the following warning:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ WARN] …:Timed out waiting for transform from base_footprint to map to become
available before running costmap, tf error:…
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Setting the Global options-&amp;gt; Fixed Frame from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_link&lt;/code&gt; resolved the
issue. (Though subsequently flipping back made the localization and navigation
task function seemingly better)&lt;/p&gt;

&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/turtlepirviz.png&quot; alt=&quot;rviz&quot; /&gt;
&lt;img src=&quot;/static/img/posts/turtlepigazebo.png&quot; alt=&quot;gazebo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;thoughts&quot;&gt;Thoughts&lt;/h3&gt;
&lt;p&gt;I am just happy I got this working, but clearly a lot of road blocks ahead.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;http://gazebosim.org/tutorials?cat=build_world&amp;amp;tut=building_editor&lt;/li&gt;
  &lt;li&gt;http://learn.turtlebot.com/2015/02/03/8/&lt;/li&gt;
  &lt;li&gt;https://github.com/erlerobot/gym-gazebo/blob/master/gym_gazebo/envs/assets/worlds/circuit2.world&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Thu, 27 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/gazebo/turtlebot/2017/04/27/rviz-gazebo.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/gazebo/turtlebot/2017/04/27/rviz-gazebo.html</guid>
        
        
        <category>gazebo</category>
        
        <category>turtlebot</category>
        
      </item>
    
      <item>
        <title>IMDB-WIKI: trying a small model for age classification</title>
        <description>&lt;p&gt;Update: 2020/1/22&lt;/p&gt;

&lt;p&gt;If you find this article at all helpful, please consider a supportive contribution.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/koraboblogqrcode.png&quot; alt=&quot;qrcode&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.korabo.io/checkout-page/5e2815526ca5270022f1a858/5e23f0b31b70f70022ff5933&quot;&gt;
  &lt;img src=&quot;https://img.shields.io/badge/Korabo-Contribute-blue&quot; alt=&quot;Contribute&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;In the paper, &lt;a href=&quot;https://www.vision.ee.ethz.ch/en/publications/papers/proceedings/eth_biwi_01229.pdf&quot;&gt;“DEX: Deep EXpectation of apparent age from a single
image”&lt;/a&gt;,
the authors were able to display remarkable results in classifying the age of
an individual based on a given single image. The results were obtained using an
ensemble of convolutional neural networks. The model design process consisted of starting with a VGG-16 architecture
pre-trained on image-net which was fine-tuned on the IMDB-WIKI data set. This is
followed by training on the ChaLearn LAP data set. The data set is split in 20
sub data sets. Though a random process was followed in the paper the authors
were careful in maintaining the distribution of the original data set for each
subset. This results in 20 different trained
models where the final prediction used was the average of the ensemble of 20
networks trained. See the paper for the exact details, as this is just a high level
summary.&lt;/p&gt;

&lt;p&gt;The data set is large enough to the extent that in memory management is
non-trivial. The IMDB data set is 269GB while the face-crop version is 7GB. Trying to pre-process
this data set, let alone train, is beyond the scope/capacity of an individual
with limited resources. The challenge for this particular exercise is to see the results of using a
small subset of the original data and using a lower capacity architecture.&lt;/p&gt;

&lt;p&gt;For some perspective, training on the architecture proposed by the authors took 5 days to train on the
entire IMDB + WIKI data set.&lt;/p&gt;

&lt;p&gt;source: &lt;a href=&quot;https://github.com/surfertas/deep_learning/tree/master/projects&quot;&gt;https://github.com/surfertas/deep_learning/tree/master/projects&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UPDATES:
Apr/07/2018: &lt;a href=&quot;http://surfertas.github.io/imdb/deeplearning/machinelearning/2018/04/07/imdb-update.html&quot;&gt;IMDB-WIKI: notes on refactoring data preprocess pipeline&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;data-faces-only-7gb&quot;&gt;Data: faces only (7GB)&lt;/h3&gt;
&lt;p&gt;The data is relatively “raw” as the provided data (at least the face-crop
version) was inconsistent in dimensions, and color channels. The authors
suggest this was the case as the data was collected using a web-crawler. Just to
give an example, the dimensions of a few samples from the training set are
listed below. We can see that some are colored and some are gray scale, while
the sizes are not consistent. The formatting steps taken here were to convert all
images to gray scale, and resize images to dimensions of \(128\times128\). A simple
python script can handle this processing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/imdbwikidatadim.png&quot; alt=&quot;data&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That was just handling the images. Now we need the labels, which again was not
easily obtained. The meta data is stored separately and unfortunately in a .mat file. (Yes,
matlab). The meta information stored is as follows:
dob: date of birth (Matlab serial date number)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;photo_taken: year when the photo was taken&lt;/li&gt;
  &lt;li&gt;full_path: path to file&lt;/li&gt;
  &lt;li&gt;gender: 0 for female and 1 for male, NaN if unknown&lt;/li&gt;
  &lt;li&gt;name: name of the celebrity&lt;/li&gt;
  &lt;li&gt;face_location: location of the face. To crop the face in Matlab run
img(face_location(2):face_location(4),face_location(1):face_location(3),:))&lt;/li&gt;
  &lt;li&gt;face_score: detector score (the higher the better). Inf implies that no face was
found in the image and the face_location then just returns the entire image&lt;/li&gt;
  &lt;li&gt;second_face_score: detector score of the face with the second highest score.
This is useful to ignore images with more than one face. second_face_score is
NaN if no second face was detected.&lt;/li&gt;
  &lt;li&gt;celeb_names (IMDB only): list of all celebrity names&lt;/li&gt;
  &lt;li&gt;celeb_id (IMDB only): index of celebrity name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The label that we require for training is the age parameter, which is not
stored as meta information, and requires some calculation. The age value can be
obtained by taking the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;photo_taken&lt;/code&gt; and subtracting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dob&lt;/code&gt;, the date of birth. Sounds easy? No…as the
dob is stored as a Matlab serial number.&lt;/p&gt;

&lt;p&gt;Luckily we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scipy.io.loadmat&lt;/code&gt; to load the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.mat&lt;/code&gt; file to a python
consumable (kind of) format. We can access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dob&lt;/code&gt; by some proper indexing,
and convert the Matlab serial number to a usable format by using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;datetime.date.fromordinal( serial_number ).year&lt;/code&gt;. Ok, so now we have the dates
in a consistent format thus extracting the age is now trivial.&lt;/p&gt;

&lt;p&gt;Now the inputs, \(128\times128\) gray scale images, and labels, estimated age, can be
packaged together and dumped to a pickle file. The script can be found
&lt;a href=&quot;https://github.com/surfertas/deep_learning/blob/master/projects/imdbwiki-challenge/imdb_preprocess.py&quot;&gt;here&lt;/a&gt;.
The script allows the user to specify the size of the training set, by setting
the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--partial&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;training&quot;&gt;Training&lt;/h3&gt;
&lt;p&gt;Now we are ready for training. Keep in mind, we are using only a subset of the data, and
using an experimental self-designed model that has a much smaller
capacity. Further, the model was not pre-trained on Imagenet thus we need to take steps to
adjust accordingly to increase the odds of success.&lt;/p&gt;

&lt;p&gt;The original paper uses \(101\) age classes, which was appropriate for the
data set size and learning architecture used. As we are only using a subset of
the data and a very simple model, the number of possible classes was reduced and set to 4, {Young,
Middle, Old, Very Old}, with the bucketing defined by Young \((30yrs &amp;lt; age)\),
Middle \((30 \leq age &amp;lt; 45)\), Old \((45 \leq age &amp;lt; 60)\), and Very Old
\((60 \leq age)\). The
distribution of the data gets concentrated around \(30-60\), see the below image for
the distribution of the ages for each data set. [2] The images were preprocessed
using ZCA Whitening.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/imdbwikiage.png&quot; alt=&quot;AgeDist&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The model used for this exercise is shown below (the Chainer framework was used for
implementation). Basically the model consisted of 3 convolution layers, with
ReLU activition, batch normalization, max-pooling, and dropouts applied, basically any
form of regularization was used that might help in reducing training time, and
risk of overfitting, and as a result increase learning ability to compensate for the lack of data and capacity of the
model.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CNN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CNN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Convolution2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bn1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BatchNormalization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Convolution2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bn2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BatchNormalization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fc3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;625&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fc4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;625&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__call__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bn1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_pooling_2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bn2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_pooling_2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fc3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fc4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;
&lt;p&gt;The first 10,000 images were used with the distribution of data is as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;YOUNG: 0.1381&lt;/li&gt;
  &lt;li&gt;MIDDLE: 0.4439&lt;/li&gt;
  &lt;li&gt;OLD: 0.3386&lt;/li&gt;
  &lt;li&gt;VERY OLD: 0.0794
&lt;img src=&quot;/static/img/posts/imdbacc.png&quot; alt=&quot;DQN&quot; /&gt;
&lt;img src=&quot;/static/img/posts/imdbloss.png&quot; alt=&quot;DQN&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well as one would expect, the results are quite poor on this first pass. The model used
fitted(over) to
the dataset well, while the test accuracy shows really no improvement and
seemingly cant
do much better than random guessing. Realistically this was fully expected as
the capacity of the model, and size of the data set was extremely constrained.
Lack of pre-training on image-net is a consideration that likely impacted as
well. The exercise was really just an exercise, and a good lesson about how data
is not always in consumable form, and the importance of the general
infrastructure necessary to properly train and learn on data of any meaningful
size.&lt;/p&gt;

&lt;p&gt;That said, it is likely too early to form a conclusion. Will make further attempts
with different architectures.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;p&gt;[1] Rothe, R., Radu, T., Van Gool, L.  DEX: Deep EXpectation of apparent age
from a single image.
[2] https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/&lt;/p&gt;
</description>
        <pubDate>Tue, 18 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2017/04/18/imdbwiki.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2017/04/18/imdbwiki.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Denoising Autoencoder</title>
        <description>&lt;h3 id=&quot;dae-and-chainer&quot;&gt;DAE and Chainer&lt;/h3&gt;
&lt;p&gt;Getting up to speed with Chainer has been quite rewarding as I am finding the
framework quite intuitive and the source code of the framework user friendly,
where any roadblocks can be smoothly resolved with a bit of source code mining.
I have found porting implementations in one frame work to another framework
efficient in learning a new tool, thus have been working to port a TensorFlow
tutorial to a Chainer tutorial. The latest addition is a Denoising Auto-Encoder.&lt;/p&gt;

&lt;p&gt;source: &lt;a href=&quot;https://github.com/surfertas/chainer-tutorials/blob/master/06_autoencoder.py&quot;&gt;06_autoencoder.py&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;auto-encoder-auto-associator-diabolo-network&quot;&gt;Auto-Encoder (Auto-associator, Diabolo Network)&lt;/h3&gt;
&lt;p&gt;Just to provide context, an Auto-Encoder is an unsupervised neural network, and
in the kindly simplified wording by Mr. Y. Bengio, the neural network is trained
to encode the input \(x\), into some representation \(c(x)\) so that the
input can be reconstructed from that representation. Hence the target of the
neural network is the input itself. [1]&lt;/p&gt;

&lt;p&gt;Literature commonly introduces the concept of the encoder, which maps the inputs
to a hidden layer, typically of smaller dimension than the inputs, to create a
“bottle-neck”. (If hidden layer is linear, and MSE criterion is used to train,
then the units of the hidden layer can be associated with the principal
components under PCA. Simply, the model is finding a best representation of the
inputs constrained to the number of hidden units.)&lt;/p&gt;

&lt;p&gt;The deeplearning.net tutorial [2], quickly introduces the key concepts necessary
to understand the tutorial. The encoder is defined by a deterministic mapping,
\[y =\sigma(Wx + b)\]&lt;/p&gt;

&lt;p&gt;The latent representation \(y\), or code is then mapped back (with a decoder)
into a reconstruction \(z\) of the same shape as \(x\). The mapping happens
through a similar transformation, \[z=\sigma(W’y+b’)\]&lt;/p&gt;

&lt;h3 id=&quot;tied-weights&quot;&gt;Tied Weights&lt;/h3&gt;
&lt;p&gt;Further, the tutorial implementation uses tied weights, where the weight matrix,
\(W’\) , of the decoder, is related to the weight matrix, \(W\), of the
encoder by \[W’ =W^T\]The model trains to optimize the parameters, \(W, b,
b’\), to minimize the average reconstruction error.&lt;/p&gt;

&lt;h3 id=&quot;denoising&quot;&gt;Denoising&lt;/h3&gt;
&lt;p&gt;The denoising introduces stochasticity by “corrupting” the input in a
probabilistic manner. This translates to adding noise to the input to try to
confuse the model, with the idea to create a more robust model capable of
reconstruction. The tutorial implementation uses a corruption level parameter
that adjusts the amount of noise, and is input to a binomial distribution used
for sampling.&lt;/p&gt;

&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;
&lt;p&gt;After 1 epoch, the model has yet to learn the reconstruction of the MNIST
digits, while after 100 epochs we can observe that the model has learned to
reconstruct the inputs relatively well.&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/epoch1dae.png&quot; width=&quot;350&quot; height=&quot;350&quot; /&gt;
&lt;img src=&quot;/static/img/posts/epoch100dae.png&quot; width=&quot;350&quot; height=&quot;350&quot; /&gt;
&lt;/div&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Bengio,Y., Learning deep architectures for AI, Foundations and Trends in
Machine Learning 1(2) pages 1-127.&lt;/li&gt;
  &lt;li&gt;Denoising Autoencoders(dA), http://deeplearning.net/tutorial/dA.html&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 12 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2017/04/12/autoencoder.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2017/04/12/autoencoder.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Creating your own robot: GAZEBO</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;
&lt;p&gt;The current project I am working on will require data generation, collection,
and processing of events that occur with in a simulated environment, thus I plan
to use Gazebo + ROS heavily. The base robot model will be a Turtlebot 2, though
the model definition will require some modifications. The modifications will
require similar edits to the simulated Turtlebot, thus will require some
modifications to the robot model defined in the .sdf file (Simulator Description
Format).&lt;/p&gt;

&lt;h3 id=&quot;model-database-structure&quot;&gt;Model Database Structure&lt;/h3&gt;
&lt;p&gt;Gazebo has a nice step by step intro to building your own robot, which I will
quickly introduce here. Before getting started with the construction, a brief
detour, (well worth the read
&lt;a href=&quot;http://gazebosim.org/tutorials?tut=model_structure&amp;amp;cat=build_robot&quot;&gt;here&lt;/a&gt;),
discusses the best practices for the construction of the file directory related
to the robot models.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/robotmodeldir.png&quot; alt=&quot;modeldir&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Further, the writers of the tutorial have kindly provided a
&lt;a href=&quot;https://bitbucket.org/osrf/gazebo_models/src/edd450e39e1f/turtlebot/?at=default&quot;&gt;link&lt;/a&gt;
to a repository that has many models defined, which comes in great use for those
getting initially involved. Each model is a self contained tutorial to a certain
extent.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/turtlemodeldir.png&quot; alt=&quot;turtledir&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;robot-construction&quot;&gt;Robot Construction&lt;/h3&gt;
&lt;p&gt;In terms of creating the robot model, the tutorial is self contained, and very
straightforward. By the end of the tutorial, you should have a model of a robot
with 2 wheels + 1 caster. A couple of concepts to direct attention:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Keep &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;static&amp;gt;True&amp;lt;/static&amp;gt;&lt;/code&gt; while building out the robot, as this will allow
the robot to be ignored by the physics engine, and will be easier to visualize
the intermediate result, instead of having parts falling apart having succumbed
to gravitational forces.&lt;/li&gt;
  &lt;li&gt;With respect to the orientation of axis, the right hand rule is followed. The
robot front facing surface is in the positive x direction, left facing being in
the positive y direction, top facing being in the positive z direction and so
forth.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;recap&quot;&gt;Recap&lt;/h3&gt;
&lt;p&gt;Here is a snapshot of the final result after messing around with the file. I
also copy/pasted the turtlebot model and loaded a couple into the Gazebo
environment. Overall, the take away thus far, is that this will be a relatively
straightforward process to build out a personal robot to use in the coming
experimentation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/finalturtlegazebo.png&quot; alt=&quot;finalturtlegazebo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Make a Mobile Robot,http://gazebosim.org/tutorials?tut=build_robot&amp;amp;cat=build_robot&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 10 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/04/10/gazebo-robot.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/04/10/gazebo-robot.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Y.A.DQN.P: Yet another DQN Post</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro:&lt;/h3&gt;
&lt;p&gt;Another great exercise &lt;a href=&quot;http://rll.berkeley.edu/deeprlcourse/docs/hw3.pdf&quot;&gt;assignment
#3&lt;/a&gt;[1] presented by
Berkeley’s DRL course, 
where the assignment pushes students to implement(kind of) and train
the DQN algorithm presented in 2013, by Mnih et al, in the paper “Playing Atari
with Deep Reinforcement Learning”. [2] The implementation uses off-policy
training,
with experience replay, epsilon greedy exploration, and the use of an additional
target network for stabilization (introduced in later papers). The relevant
lectures by John Schulman can be found at &lt;a href=&quot;https://youtu.be/h1-pj4Y9-kM?list=PLkFD6_40KJIwTmSbCv9OVJB3YaO4sFwkX&quot;&gt;CS294-112 2/15/2017 and CS294
2/22/2017&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;source: &lt;a href=&quot;https://github.com/surfertas/rldm/blob/master/drl-berkeley-cs294/dqn/dqn.py&quot;&gt;DQN&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;review&quot;&gt;Review:&lt;/h3&gt;
&lt;p&gt;A considerable amount of the code was provided(kudos to Szymon Sidor from
OpenAI), and the student is left to implement a few key portions in tensorflow.
Specifically, the student is left to implement the update of the replay buffer,
sampling of the replay buffer, definition of the error value used for
optimization, target network updates, and set up of the training step to train
the deep convolutional neural network used to approximate the Q-function that
generates an estimate of the state-value function for a given state and action.&lt;/p&gt;

&lt;p&gt;The implementation was more of an exercise in getting a handle on the starter
code, and understanding the API of the relevant objects found in the system. As
a result, one should derive in an increased understanding of tensorflow, (numpy + python to say the least), in addition to a greater appreciation for the
abstraction that Keras + other frameworks provides.&lt;/p&gt;

&lt;p&gt;Further, knowing that training the model would require 1 million + steps, GPU
acceleration is pretty much a must for fast experimentation. This GPU access was
not provided, and is left to the student to source. (May be different for
enrolled Berkeley students.) I decided on using the AMI provided by
bitfusion.io, “&lt;a href=&quot;https://aws.amazon.com/marketplace/pp/B01EYKBEQ0?qid=1491136276858&amp;amp;sr=0-1&amp;amp;ref_=srh_res_product_title&quot;&gt;Bitfusion Ubuntu 14
Tensorflow&lt;/a&gt;”
where a g2.2xlarge costs $0.715/hr (includes software costs of $0.065). Wanting
to initially avoid paying up for the $0.065 cost of software, I attempted a
supposed cheaper route by starting with a bare bones Ubuntu 14.04 AMI, and
building necessary software myself. I failed miserably and crawled back to
bitfusion.io. (Lesson here is dont be a “@#@$ for a tick”)&lt;/p&gt;

&lt;p&gt;Thank you &lt;a href=&quot;http://www.bitfusion.io/&quot;&gt;bitfusion.io&lt;/a&gt;! as the AMI is decked…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ubuntu 14 AMI pre-installed with Nvidia Drivers, Cuda 7.5 Toolkit, cuDNN 5.1,
TensorFlow 1.0.0, TFLearn, TensorFlow Serving, TensorFlow TensorBoard, Keras,
Magenta, scikit-learn, Python 2 &amp;amp; 3 support, Hyperas, PyCuda, Pandas, NumPy,
SciPy, Matplotlib, h5py, Enum34, SymPy, OpenCV and Jupyter to leverage Nvidia
GPU as well as CPU instances.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After gaining access to the instance through an ssh via my command-line, all
that was left was a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo -H pip install gym[atari]&lt;/code&gt; and copying the relevant
files over. I really wish I would have started with this in hindsight. (I am in
no way associated with bitfusion.io fwiw, nor Berkeley for that matter.)&lt;/p&gt;

&lt;p&gt;Once the required code was implemented and the GPU access set up appropriately,
the rest was just about hitting the start button to initiate training.&lt;/p&gt;

&lt;h3 id=&quot;dqn-algorithm&quot;&gt;DQN algorithm:&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/dqnalgo.png&quot; alt=&quot;DQN&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;cnn-model&quot;&gt;CNN model:&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/dqnmodel.png&quot; alt=&quot;DQNCNN&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;key-pointsconcepts&quot;&gt;Key Points/Concepts:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Algorithm is hybrid of online and batch Q-value iteration, interleaves
optimization with data collection.&lt;/li&gt;
  &lt;li&gt;Replay memory for increased data efficiency, increased stability, reward
propagation beyond 1-step, 
and addresses the concerns around i.i.d breakdown associated with purely online
updates.&lt;/li&gt;
  &lt;li&gt;Target network fixed over timesteps (~10k steps) to approximate
\(Q(s_{t+1},a_{t+1})\). John comments that this allows \(Q\) to chase a
relatively non-moving target (\(Q\) chases \(TQ\)). 
Another way to think about this in my own words is that:
\(r + \gamma * max Q(s_{t+1},a_{t+1})\)  has 1 time step of real world data
derived from \(r\), when compared to \(Q(s,a)\), and is a better estimate of
the expected return under a
given policy at time step \(t\) from a particular state,\(s\) after taking
action \(a\). We
want \(Q(s_t,a_t)\) to better approximate the expected return, or said
differently catch up to
\(r+ \gamma * max Q(s_{t+1},a_{t+1})\), thus as in any situation, a slow
moving target is
easier to catch than a fast moving target.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;results&quot;&gt;Results:&lt;/h3&gt;
&lt;p&gt;Ideally testing different parameter settings is recommended, but considering
personal time constraints, I left the parameters at default values.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Replay buffer size: 1m&lt;/li&gt;
  &lt;li&gt;Exploration: epsilon linear decay, floor at 0.1&lt;/li&gt;
  &lt;li&gt;Target network: 10k step updates&lt;/li&gt;
  &lt;li&gt;Gamma: 0.99&lt;/li&gt;
  &lt;li&gt;Batch size: 32&lt;/li&gt;
  &lt;li&gt;Frame history length: 4&lt;/li&gt;
  &lt;li&gt;Gradient norm clipping: 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default settings were sufficient to produce acceptable results, as we see
the AI agent is able to start scoring against the opponent.
&lt;img src=&quot;/static/img/posts/dqncnn.png&quot; alt=&quot;DQNCNN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The following video is after the agent had consistently starting scoring on
average.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/kyPaDo0XlwE&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;h3 id=&quot;modifications&quot;&gt;Modifications:&lt;/h3&gt;
&lt;p&gt;A few suggestions were made based off subsequent published papers that have
shown to speed up training times and general performance. (Note: not implemented.)&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Double DQN:[3] use \(r + \gamma * Q^{target}(s’,Q(s’,a’))\) for the target
Q-value.&lt;/li&gt;
  &lt;li&gt;Dueling nets:[4] parameterize \(Q\) as \(Q_\theta(s,a) = V_{\theta}(s) +
F_{\theta}(s,a) - mean_{a’}F_{\theta}(s,a’)\)&lt;/li&gt;
  &lt;li&gt;Prioritized Experience:[5] Use last bellman error to estimate gradient step,
and use update value for either proportional, \(p_i =|\delta_i| + \epsilon\)
or rank, \(p_i = \frac{1}{rank_i}\) weighting.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts:&lt;/h3&gt;
&lt;p&gt;With relatively cheap access to GPU acceleration, very accessible starter code,
and great insight from publicly available lectures, any one can implement a
history making algorithm, given the time and patience. This is great, and I hope
that more first class institutions continue to share such high quality material
to the general public.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Deep RL Assignment 3: Q-Learning on Atari.
&lt;a href=&quot;http://rll.berkeley.edu/deeprlcourse/docs/hw3.pdf&quot;&gt;http://rll.berkeley.edu/deeprlcourse/docs/hw3.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mnih, Volodymyr, Kavukcuoglu, Koray, Silver, David, Graves, Alex, Antonoglou,
Ioannis, Wierstra, Daan, and Riedmiller, Martin. Playing atari with deep
reinforcement learning. arXiv:1312.5602, 2013.&lt;/li&gt;
  &lt;li&gt;Van Hasselt, H., Guez, A., and Silver, D. Deep reinforcement learning with
double Q-learning, 2015&lt;/li&gt;
  &lt;li&gt;Wang, Z., de Freitas, N., Lanctot, M. Dueling network architectures for deep
reinforcement learning arXiv preprint arXiv: 1511.06581&lt;/li&gt;
  &lt;li&gt;Schaul, T., Quan, J., Antonoglou, I., and Silver, D., Prioritized experience
replay. arXiv preprint arXiv:1511.05952(2015)&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sun, 02 Apr 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/04/02/DQN.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/04/02/DQN.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Behavioral Cloning</title>
        <description>&lt;p&gt;This post is a quick summary of findings from working on assignment 1 from &lt;a href=&quot;http://rll.berkeley.edu/deeprlcourse/#lecture-videos&quot;&gt;CS
294: Deep Reinforcement
Learning&lt;/a&gt;, Spring 2017,
open sourced by Berkeley. [1]
Reviewing the material, I have to say the quality and depth is overwhelming, and
despite being one sample, attests to the education provided by Berkeley and the
professors employed. I envy the
students that have the opportunity to engage and participate live in a course
structured by Professor Levine and team. Making this lecture accessible is a
great service, and I can only share my appreciation through a simple virtual
“Thank you”.&lt;/p&gt;

&lt;p&gt;source code: &lt;a href=&quot;https://github.com/surfertas/rldm/tree/master/drl-berkeley-cs294/behavioral-clone&quot;&gt;behavioral
cloning&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;problem-definition&quot;&gt;Problem Definition&lt;/h3&gt;
&lt;p&gt;In part 1 of the assignment, we are tasked with finding a policy for a selection
of agents, with each agent having their own definition of an observation space,
\(o \in R^{n_{o}}\), and action space, \(a \in R^{n_{a}}\),. The
policy in the deterministic case is defined as \(a =
\pi(o)\), and in the
stochastic case is a distribution, \(\pi(a | o)\), over the observation space. We want to learn the policy that results
in the largest return on evaluation, which in this case is defined as \(\sum_{t=0}^n r_t\), but difficult in
practice. The lecture introduces the concept of behavioral cloning, which
addresses the question, given examples derived from an expert, can we learn a
sufficient policy. Note that I don’t describe the policy as optimal, as the
policy learned is only good as the input, in other words the so called expert in
this case. The expert can be formulated in many ways, such as human control, MPC (Model
Predictive Control), or even a simple logic based control algorithm. Its clear the term
expert is subjective, and we can easily see how the resulting policy learned is
really only good as the expert provided.&lt;/p&gt;

&lt;p&gt;For this particular case, an expert policy is provided, and we are essentially
left to solve a supervised learning problem, finding the function approximator
that best fits the given data, where the data is defined by the expert, and the
amount of samples generated for training is specified by the user. The problem simplifies to a
matching game, where we need to find and match the function approximator used by
the expert.&lt;/p&gt;

&lt;h3 id=&quot;experimentation-hopper-v1&quot;&gt;Experimentation Hopper-v1&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/hopperv1.png&quot; alt=&quot;Hopper&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Wanting to start with a relatively easy environment provided by OpenAI gym, based on the
simulation engine Mujoco, I chose the Hopper-v1 environment which is
composed of an observation space of 11 dimensions and actions space of 3
dimensions. A simple 2 layer NN was constructed, with the hidden layer composed of 64 units,
ReLU as the activation function, with the rest of the relevant parameters
defaulted to the default values specified in Keras. Using a batch size of 128,
and training on 10 epochs, we can see that the neural net is able to learn the policy of
the expert given enough samples, where samples is defined as the number of roll outs. The
only pre-processing done was a normalization of the data set, using the
mean, \(\mu_{train}\) and
standard deviation, \(\sigma_{train}\) of the training data, with the same
normalization procedure used on the
test set, using \(\mu_{train}\) and \(\sigma_{train}\). Further, to
handle the edge case of a zero deviation, small gaussian noise was added to
any zero-valued \(\sigma\). A quick exercise confirms the sensitivity to the amount of
data, as we train on roll out samples of 5, 10, 20, 40, 200, and 400. Each
roll out is of variable length but consists of multiple tuples of \((o,a)\).
Provided enough data, the capacity of this neural network was sufficient to
“clone” the policy implicit in the training data supplied by the expert.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Hopper-v1.png&quot; alt=&quot;Hopper&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Hopper-v1-loss.png&quot; alt=&quot;Hopper&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;experimentation-humanoid-v1&quot;&gt;Experimentation Humanoid-v1&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/posts/humanoidv1.png&quot; alt=&quot;Humanoid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Lets see if we can try and generate a fail case. We can test the capacity of this particular neural
net, on a more complex environment. The Humanoid-v1 seems to be a
good test, with the environment consisting of an observation space of 376
dimensions, and action space of 17 dimensions. The capacity of the simple
neural net was sufficient, provided that enough samples of the expert policy
was supplied.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Humanoid-v1-2layer.png&quot; alt=&quot;Humanoid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Humanoid-v1-2layer-loss.png&quot; alt=&quot;Humanoid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Just as an exercise we can increase the capacity of the model, using a deeper neural network defined by 2 hidden layers with 512 units
each, with some regularization via dropouts (30%) after each layer, results in
relatively satisfactory results, again given enough data, but such capacity is
clearly unnecessary when given samples from an expert policy in this particular
situation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Humanoid-v1-3layer.png&quot; alt=&quot;Humanoid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/Humanoid-v1-3layer-loss.png&quot; alt=&quot;Humanoid&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion:&lt;/h3&gt;
&lt;p&gt;In summary, access to enough data samples from an expert policy, and given a model with large
enough capacity, we can find a pretty good policy that defines the actions at a given state, provided
with a certain observation. The problem is finding that expert in the real
world and collecting enough data samples to train a high capacity model.&lt;/p&gt;

&lt;p&gt;(All mistakes are mine. Please kindly contact me on any mistakes found.)&lt;/p&gt;

&lt;p&gt;Note:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Hopper-v1 and Humanoid-v1 images credited to [2]&lt;/li&gt;
  &lt;li&gt;Experiments were based on a trial version of Mujoco [3]&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Deep RL Assignment 1: Imitation Learning.
&lt;a href=&quot;http://rll.berkeley.edu/deeprlcourse/docs/hw1.pdf&quot;&gt;http://rll.berkeley.edu/deeprlcourse/docs/hw1.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;OpenAI, Hopper-v1.
&lt;a href=&quot;https://gym.openai.com/envs/Hopper-v1&quot;&gt;https://gym.openai.com/envs/Hopper-v1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;MuJoCo advanced physics simulation.
&lt;a href=&quot;https://www.roboti.us/index.html&quot;&gt;https://www.roboti.us/index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 24 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/03/24/behavior-clone.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/03/24/behavior-clone.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>ROS+RViz: Husky p-controller #2</title>
        <description>&lt;p&gt;The marker location is determined from the laser scan data which is in the reference
frame of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser&lt;/code&gt;. Technically, RViz will do the conversion for us, but
as an exercise, was worth transforming the location in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser&lt;/code&gt; frame to
that of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odom&lt;/code&gt; before publishing data for use by RViz.&lt;/p&gt;

&lt;p&gt;The steps taken were as follows:&lt;/p&gt;

&lt;h3 id=&quot;include-the-necessary-headers&quot;&gt;Include the necessary headers&lt;/h3&gt;
&lt;p&gt;Include relevant header files declaring the necessary message types.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;geometry_msgs/TransformStamped.h&amp;gt;
#include &amp;lt;geometry_msgs/PoseStamped.h&amp;gt;
#include &amp;lt;tf2_geometry_msgs/tf2_geometry_msgs.h&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;declare-the-buffer-for-storage&quot;&gt;Declare the buffer for storage&lt;/h3&gt;
&lt;p&gt;Declare the buffer, and listener in the header file. The buffer stores the
transform related data, and has the public member function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lookupTransform&lt;/code&gt;
that we will be using to get the transform between two frames.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;tf2_ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Buffer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfBuffer_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf2_ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformListner&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;listener_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tfBuffer_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;declare-relevant-messages&quot;&gt;Declare relevant messages&lt;/h3&gt;
&lt;p&gt;Declare a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geometry_msgs::TransformStamped&lt;/code&gt; message, transformStamped, and
use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lookupTransform()&lt;/code&gt; function to get the transform. The point here is
that the frames dont need the ‘/’ in front, and the first parameter is the frame
that we want to transform to or said differently, the target frame. The full
specification of the function can be found
&lt;a href=&quot;http://docs.ros.org/indigo/api/tf2_ros/html/c++/classtf2__ros_1_1BufferClient.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;geometry_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Transformed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformStamped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;transformStamped&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfBuffer_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lookupTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;odom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;base_laser&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformExcetion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ROS_WARN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;what&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;stamp-the-data&quot;&gt;“Stamp” the data&lt;/h3&gt;
&lt;p&gt;Finally we need to “stamp” the source point before passing to the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transform()&lt;/code&gt;
function. The api of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geometry_msgs/PoseStamped&lt;/code&gt; can be found
&lt;a href=&quot;http://docs.ros.org/api/geometry_msgs/html/msg/PoseStamped.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;geometry_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PoseStamped&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;geometry_msgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PoseStamped&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pose_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;theta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;theta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ros&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;base_laser&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tfBuffer_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pose_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pose_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;odom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we have the location of the pillar originally in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/base_laser&lt;/code&gt; frame
transformed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/odom&lt;/code&gt; frame.&lt;/p&gt;

&lt;p&gt;The full source code can be found
&lt;a href=&quot;https://github.com/surfertas/ros_pkg/tree/master/git/husky_highlevel_controller&quot;&gt;here&lt;/a&gt;,
under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ros_pkg/git/husky_highlevel_controller/src/HuskyHighlevelController.cpp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Dont forget to make the necessary changes to the CMakefile and package.xml
files.&lt;/p&gt;

&lt;h3 id=&quot;ros-wiki&quot;&gt;ROS Wiki&lt;/h3&gt;
&lt;p&gt;Also, found small issues with the &lt;a href=&quot;http://wiki.ros.org/tf2/Tutorials/Writing%20a%20tf2%20listener%20%28C%2B%2B%29&quot;&gt;ROS
Wiki&lt;/a&gt;
thus made a quick edit. Basically the prior post had
the specifications of the parameters to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lookupTransform()&lt;/code&gt; described
incorrectly.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;ROS Wiki, tf2 Tutorials. Writing a tf2 listener.&lt;/li&gt;
  &lt;li&gt;Fankhauser, P., Dominic, J., and Wermelinger, Martin.(2017) Course 3, Programming for Robotics (ROS).&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 22 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/03/22/ros-husky-pcontroller.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/03/22/ros-husky-pcontroller.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>ROS+RViz: Husky p-controller #1</title>
        <description>&lt;p&gt;A simple proportional controller implemented in C++ using ROS and simulated in
Gazebo with visualization done through Rviz…package available
&lt;a href=&quot;https://github.com/liana1215/ros_pkg/tree/master/git/husky_highlevel_controller&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a result of working through exercise 3, provided by the &lt;a href=&quot;http://www.rsl.ethz.ch/education-students/lectures/ros.html&quot;&gt;introductory
course&lt;/a&gt; on ROS at
ETZH. My personal opinion is that this is one of the most clear and concise
introductions that I have come across, and also provides a guide post on best practices, which I
surely will look to implement in my own work.&lt;/p&gt;

&lt;p&gt;The p-controller, is a control that simply adjusts velocity in proportion to the
distance to the target, in this case the pillar. Despite the controller working, I had to make
some on-the-fly hacks.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/huskylaserscan.png&quot; alt=&quot;Husky&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The main factors that need to be resolved:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Distance to Pillar. Since the pillar is the only object in the world, problem
clearly simplified for us (thanks!), the distance is simply the minimum range
that the laser scan returns and is found in ranges[].&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Orientation of Pillar from the perspective of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base_laser&lt;/code&gt; (see above
figure)
is alpha, and can be determined quickly, as in the discovery of the minimum
distance, we also get the index, or number of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;angle_increments&lt;/code&gt; for free, and can
use this in calculating the orientation.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The linear velocity in x and y direction, was set as to be the distance to
the pillar, thus the velocity would decrease as the proximity to the Pillar
increased. Further, to avoid a collision, the velocity was set to 0, if Husky
was within 0.5m of the pillar. The linear velocity and angular velocity (which
is was simply set to alpha), is pumped into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geometry_msgs::Twist&lt;/code&gt; message and
published for listening by gazebo and Rviz.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In order to place the marker in the correct position (here is a tutorial on
&lt;a href=&quot;http://wiki.ros.org/rviz/DisplayTypes/Marker&quot;&gt;markers&lt;/a&gt; btw), we need the cartesian coordinates, which again can be quickly
determined with some trivial geometry. The x, y coordinates are then set in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visualization_msgs::Marker&lt;/code&gt; message and subsequently published using the
appropriate publisher.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thats really it…and you get a pretty cool looking simulation running. This is
a snapshot of Husky running in RViz, with laser scan, marker, robot model, and tf all set
accordingly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/huskyrviz.png&quot; alt=&quot;Husky&quot; /&gt;&lt;/p&gt;

</description>
        <pubDate>Tue, 14 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/03/14/ros-husky-pcontroller.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/03/14/ros-husky-pcontroller.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Laplacian pyramids, application to blends #2</title>
        <description>&lt;h3 id=&quot;related-posts&quot;&gt;Related Posts:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/computervision/2017/02/28/laplacian.html&quot;&gt;Laplacian pyramids, application to blends #1&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the previous post we covered the construction of the Gaussian Pyramid,
followed by a brief overview of the procedure to construct the Laplacian
Pyramid. In this post, we will relate the procedure to the application of
blending two different surfaces, or images in the case of photography.&lt;/p&gt;

&lt;h3 id=&quot;blending-procedure-outline&quot;&gt;Blending procedure outline&lt;/h3&gt;
&lt;p&gt;A simple outline of the blending procedure, is as follows.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Construct the Laplacian Pyramid for each image.&lt;/li&gt;
  &lt;li&gt;Construct a Gaussian Pyramid for the mask.&lt;/li&gt;
  &lt;li&gt;Apply the respective mask with the appropriate dimensions and blend the two
images, repeating this step for each layer.&lt;/li&gt;
  &lt;li&gt;Collapse the pyramid by expanding the layer with the smallest dimensions, to
that of the next layer, and adding the two layers together. This procedure
should be applied recursively, until the base is hit and all layers have been
accumulated.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;mask-generation&quot;&gt;Mask generation&lt;/h3&gt;
&lt;p&gt;Once we have the Laplacian Pyramid, the only step remaining is to create an
appropriate mask for blending the two images together. The mask will determine
how natural the blend appears, as the mask will determine how much of each image
to use per pixel location. The transformation is a simple weighted average,
where \(\alpha\) determines the weighting.
\[\alpha(image A) + (1-\alpha)(image B)\]&lt;/p&gt;

&lt;p&gt;In order to create a blend that appears natural, a mask that allows for a smooth
transition is necessary, thus a continuous function along a particular axis is
desired as opposed to a step function. The sigmoid function is a decent starting
point, as the input domain is squashed into the range of \(0\) to \(1\), which is
exactly what we need. That said, the sigmoid function in its raw form results in
a mask that is too “steep” of a slope, which will result in a rather abrupt
transition from image A to image B.&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/sigmask.png&quot; width=&quot;150&quot; height=&quot;150&quot; /&gt;  
&lt;img src=&quot;/static/img/posts/sigplot.png&quot; width=&quot;150&quot; height=&quot;150&quot; /&gt; 
&lt;/div&gt;

&lt;p&gt;In order to mold the mask into something more applicable, we can add a “fatness”
parameter to control the slope, and speed of the transition.&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/fatmask.png&quot; width=&quot;150&quot; height=&quot;150&quot; /&gt;  
&lt;img src=&quot;/static/img/posts/fatplot.png&quot; width=&quot;150&quot; height=&quot;150&quot; /&gt; 
&lt;/div&gt;

&lt;p&gt;Just from the mask alone we can visually confirm the smooth transition from the
left to the right side. Applying this kind of mask to blend each layer of the
Laplacian results in rather favorable results. The masks can be quickly
generated using the below functions written in python.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sigmask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;special&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fatmask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;hand-eye-mask-template&quot;&gt;Hand-eye mask template&lt;/h3&gt;
&lt;p&gt;Now to produce the hand eye blend, we need a mask with the shape of an ellipse,
or some shape that matches the general characteristics of the shape of a human
eye, in addition to maintaining the above properties that results in a smooth
transition. The 2D Gaussian function is close to ideal for generating a mask
suitable for this particular task, with a greater deviation along the x-axis
resulting in an elliptical shape resembling that of an eye.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/lapleye.png&quot; alt=&quot;Laplacian eye&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/gpyrmask.png&quot; alt=&quot;Gaussian mask&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/lpyramid.png&quot; alt=&quot;Laplacian hand&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once we have the mask template in hand, we can generate the Gaussian Pyramid and
apply the blending operation at each layer of the Laplacian, followed by the
collapse of the pyramid to generate the final image. Note the images were
rescaled for visualization. Each layer has successively smaller dimensions than
the dimensions of the prior layer.&lt;/p&gt;

&lt;p&gt;The blended result for each layer.
&lt;img src=&quot;/static/img/posts/outpyr.png&quot; alt=&quot;Laplacian eye&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;final-blended-product&quot;&gt;Final blended product&lt;/h3&gt;
&lt;p&gt;The final collapsed image.&lt;/p&gt;
&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/handeye.png&quot; width=&quot;200&quot; height=&quot;300&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;(All mistakes are mine, any corrections appreciated.)&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Burt, Peter J and Adelson, Edward H. A Multiresolution Spline with
Application to Image Mosiacs&lt;/li&gt;
  &lt;li&gt;Burt, Peter J and Adelson, Edward H. The Laplacian Pyramid as a Compact Image
Code&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 09 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/computervision/2017/03/09/laplacian.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/computervision/2017/03/09/laplacian.html</guid>
        
        
        <category>computervision</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #6</title>
        <description>&lt;h3 id=&quot;previous-posts&quot;&gt;Previous Posts:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/22/actor-critic-1.html&quot;&gt;Actor-Critic and Policy Gradient Methods #1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/24/actor-critic-2.html&quot;&gt;Actor-Critic and Policy Gradient Methods #2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/29/actor-critic-3.html&quot;&gt;Actor-Critic and Policy Gradient Methods #3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/31/actor-critic-4.html&quot;&gt;Actor-Critic and Policy Gradient Methods #4&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/03/2/actor-critic-5.html&quot;&gt;Actor-Critic and Policy Gradient Methods #5&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, after discussing the policy gradient method, and variance derived from a
Monte-Carlo driven algorithm, we can trek into the space of Actor-Critic
algorithms.&lt;/p&gt;

&lt;p&gt;To quickly recap, the derivation of a policy gradient requires the calculation
of an integral, which can be estimated via Monte-Carlo techniques, which
transforms the integration problem to one of calculating a weighted average
samples.[1] In the case of a RL agent, the samples equate to the episodes, thus
the agent can obtain an estimate through acting in the environment. As we
discussed previously, a small sample set can misrepresent the expected value, thus a
large number of episodes are required to counter the variance.&lt;/p&gt;

&lt;p&gt;To address the scope for high variance, the literature indicates that a general approach
to reducing the variance associated with a Monte-Carlo approach is to introduce
a control variate, a base-line or a parameterized function approximator that has
zero mean. The Actor-Critic algorithm introduces a “critic”, which to frame
intuitively is a judge that judges the actions of the actor. If the actor is the
source of high variance, the critic supplies some sanity, and provides
low-variance feedback on the quality of the performance.[2]&lt;/p&gt;

&lt;p&gt;The introduction of a critic, not only reduces variance, but also maintains
favorable convergence properties of the policy gradient methods, where
convergence is obtained if the estimated gradients are unbiased and if the
learning rates satisfy: 
\[\sum^{\infty}\alpha_{a,k} = \infty\]
\[\sum^{\infty}{\alpha^2_{a,k}}&amp;lt;\infty\]&lt;/p&gt;

&lt;p&gt;As suggested earlier, the introduced term has zero mean which guarantees that
the expected value of the estimator is unchanged, and the “biasedness” is not
impacted, while the same can not be said for the variance.&lt;/p&gt;

&lt;p&gt;This is assuming the term is independent of the action space.   We can do a
quick work through of the math to show that the introduction of a control
variate does not in fact affect the expected value.&lt;/p&gt;

&lt;p&gt;Introduce the variate:
\[\nabla_{\theta}J(\theta) =
E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)(Q^{\pi_{\theta}}(s,a)-B(s)]\]&lt;/p&gt;

&lt;p&gt;By linearity we can break up the expected value:
\[\nabla_{\theta}J(\theta) =
E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)(Q^{\pi_{\theta}}(s,a)]-E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)B(s)]\]&lt;/p&gt;

&lt;p&gt;Focus on the operand on the right side:
\[E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)B(s)]\]&lt;/p&gt;

&lt;p&gt;Using the ratio trick, in reverse:
\[\sum_Sd^{\pi_{\theta}}(s)\sum_A\nabla_{\theta}\pi_{\theta}(s,a)B(s)\]&lt;/p&gt;

&lt;p&gt;Pull out \(B(s)\) as independent of actions and \(\nabla\) under linearity:
\[\sum_Sd^{\pi_{\theta}}(s)B(s)\nabla_{\theta}\sum_A\pi_{\theta}(s,a)\]&lt;/p&gt;

&lt;p&gt;We know that that PMFs satisfy \(\sum_x p(x) = 1\) and the derivative of a
constant is 0:
\[\sum_Sd^{\pi_{\theta}}(s)B(s)0 = 0\]&lt;/p&gt;

&lt;p&gt;Thus we derive that the expected value is unchanged:
\[\nabla_{\theta}J(\theta) =
E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)(Q^{\pi_{\theta}}(s,a)-0]\]&lt;/p&gt;

&lt;p&gt;In summary, an algorithm that uses the policy gradient method  enjoys
convergence if certain conditions are satisfied with regards to bias and the
learning rate, though remains exposed to high variance. This translates directly to high
sample complexity, a large number of episodes needed to derive a satisfiable estimate using Monte Carlo methods.
Variance can be reduced using a zero mean term, Critic, which supplies low
variance knowledge, without impacting the expected value, and thus is capable of
maintaining convergence properties inherited from the policy gradient method. In
the next post, will cover different critics followed by current state of the art
algorithms.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Grondman et.al. A Survey of Actor-Critic Reinforcement Learning: Standard and
Natural Policy Gradients&lt;/li&gt;
  &lt;li&gt;E. Greensmith, P. L. Bartlett, and J. Baxter. Variance Reduction Techniques for Gradient Estimates in Reinforcement Learning&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Wed, 08 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/03/08/actor-critic-6.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/03/08/actor-critic-6.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>ROS+Gazebo: Husky teleop in Robocup World</title>
        <description>&lt;p&gt;A quick post to show how to get a teleop capable husky simulation working in a
robocup environment. This was presented as an exercise in the lecture
material as part of the &lt;a href=&quot;http://www.rsl.ethz.ch/education-students/lectures/ros.html&quot;&gt;Programming for Robotics –
ROS&lt;/a&gt; series, which is a
great set of introductory material to ROS using C++. (Highly recommended)&lt;/p&gt;

&lt;p&gt;The specific exercise asks to get the husky simulation working with teleop
capabilities in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;robocup14_spl_field.world&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The exercise is straight forward, with any road blocks easily resolved by searching ROS Answers.&lt;/p&gt;

&lt;p&gt;To run, construct the below launch file first, and place the file in the launch folder
of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;teleop_twist_keyboard&lt;/code&gt; package.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;launch&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;arg&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;world&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;default=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;robocup14_spl_field&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;include&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;file=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$(find husky_gazebo)/launch/husky_empty_world.launch&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;arg&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;world_name&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/usr/share/gazebo-2.2/worlds/$(arg world).world&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;/include&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;node&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;teleop&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;pkg=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;teleop_twist_keyboard&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;teleop_twist_keyboard.py&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;output=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;screen&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/launch&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A few points to consider:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;husky_empty_world.launch&lt;/code&gt; file is found in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;husky_gazebo&lt;/code&gt; package
thus need to specify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find husky_gazebo&lt;/code&gt; or specify the path explicitly.&lt;/li&gt;
  &lt;li&gt;Despite indicating this was a C++ based series, the teleop_twist_keyboard is
a python script thus need to set type as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;teleop_twist_keyboard.py&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;After launching, if you encounter the below output, follow
&lt;a href=&quot;http://answers.ros.org/question/199401/problem-with-indigo-and-gazebo-22/&quot;&gt;these&lt;/a&gt;
instructions to resolve. Gazebo should launch rather quickly.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Warning [gazebo.cc:215] Waited 1seconds for namespaces.
Warning [gazebo.cc:215] Waited 1seconds for namespaces.
Error [gazebo.cc:220] Waited 11 seconds for namespaces. Giving up.
Error [Node.cc:90] No namespace found
Error [Node.cc:90] No namespace found

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If successful you should see Gazebo launch with the Husky robot centered in the
Robocup world. After teleoping a bit, you too can send the Husky into the
goal…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/huskygazebo1.png&quot; alt=&quot;Husky&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/ros/2017/03/06/ros-husky-robocup.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/ros/2017/03/06/ros-husky-robocup.html</guid>
        
        
        <category>ros</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #5</title>
        <description>&lt;h3 id=&quot;previous-posts&quot;&gt;Previous Posts:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/22/actor-critic-1.html&quot;&gt;Actor-Critic and Policy Gradient Methods #1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/24/actor-critic-2.html&quot;&gt;Actor-Critic and Policy Gradient Methods #2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/29/actor-critic-3.html&quot;&gt;Actor-Critic and Policy Gradient Methods #3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/31/actor-critic-4.html&quot;&gt;Actor-Critic and Policy Gradient Methods #4&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having developed a decent understanding of the policy gradient method in the
derivation of the gradient of the objective function, \(\nabla J(\theta)\), we can
use the gradient ascent algorithm to optimize an objective function,
parameterized by \(\theta\), with the \(J(\theta)\) representing the quality of a
policy.&lt;/p&gt;

&lt;p&gt;Before we step ahead to the Actor-Critic algorithm, best to introduce the
REINFORCE algorithm, which only has an actor, and uses PGM to optimize the
objective function. The lack of the critic, which has variance reducing
properties, exposes the algorithm to high variance. The psuedo-code is taken
from D.Silvers lectures on Policy Gradient Methods.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/pgmreinforce.png&quot; alt=&quot;REINFORCE&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Lets consider the Policy Gradient Theorem.&lt;/p&gt;

\[\nabla_{\theta}J(\theta) =
E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)]\]

&lt;p&gt;\(Q^{\pi_{\theta}}(s,a)\), is the action-value function, or the expected return of
discounted rewards, after taking action,\(a\), and following policy \(\pi\), there
on after. This value can be swapped for some other estimates, and does seem like
the path of research has been to experiment with different estimations. In the
case of REINFORCE, the simple episodic case, where no Critic, or base-line, is
considered the total reward at the end of an episode is used, and represents an
unbiased estimate of \(Q^{\pi_{\theta}}(s,a)\) where an episode is a sequence such
that \( {s_1,a_1,r_2,s_2,a_2,r_3…s_{t-1},a_{t-1},r_T} \). This has two
implications, one is that training is done off-policy and the second implication
that high variance can not be avoided, at least without the introduction of a
base-line. Will talk about critics, base-lines, and its role in variance
reduction and convergence in the following post.&lt;/p&gt;

&lt;p&gt;To understand the concept of variance, we can consider the overly simplistic
exercise. Lets assume that the true expected value of a given policy,
\(E_{\pi_{\theta}}[.]\), is \(10\), and consider episodes of length
\(10\).
As \(n \rightarrow \infty\), where \(n\) is the number episodes, the sampled expected
value should converge to the true expected value. Lets consider the case where
we have \(1\) sample, \( {1,1,…10} \), and for illustration purposes assume no
discounting. The sampled average over \(1\) episode, is \(19\), where
\(19\) is equal to
\(\sum_t r_t\) We can see that this greatly differs from the true expected value,
and thus impacts the speed at which the algorithm converges.&lt;/p&gt;

</description>
        <pubDate>Thu, 02 Mar 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/03/02/actor-critic-5.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/03/02/actor-critic-5.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Laplacian pyramids, application to blends #1</title>
        <description>&lt;p&gt;Update: 2020/Feb/3rd
Hi thanks for stopping by. Why not checkout https://www.korabo.io.
The app allows you to set percentage share with collaborators and generate different types of entry points to a checkout like the shield below.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.korabo.io/checkout-page/5e2815526ca5270022f1a858/5e23f0b31b70f70022ff5933&quot;&gt;
    &lt;img src=&quot;https://img.shields.io/badge/Korabo-donate-blue&quot; alt=&quot;donate&quot; /&gt;
 &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;+++++++&lt;/p&gt;

&lt;p&gt;Working through some classic CV algorithms to refresh the memory, I am
constantly reminded of the ingenuity of the algorithms and the researchers
behind the work. In this memory refresh (post), I plan to work through the
algorithm related to Laplacian Pyramids and its application to image
composition, or equivalently blending stated differently.&lt;/p&gt;

&lt;p&gt;The objective of the procedure is to produce a seamless image, given two images
as inputs, or as Burt and Adelson stated,&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;How can the two surfaces be gently distorted so that they can be joined together with a smooth seam?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The location of the blend is variable and is case dependent. The mask, controls the location
and degree of the blend, and the set of possible masks that one can contrive is
large.&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/eye.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;  
&lt;img src=&quot;/static/img/posts/mask.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;
&lt;img src=&quot;/static/img/posts/hand.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;Taking two images A(left), and B(right), and a mask, M(center), presented above, we can blend the
images utilizing Laplacian pyramids to construct a blend that results in the
following image. There is scope for automation, but for this exercise, the
location of eye was manually engineered to “work”.&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/handeye.png&quot; width=&quot;200&quot; height=&quot;300&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;In the following section I will introduce the procedure that underlies the
Laplacian Pyramid, and discuss the relevance and importance of engineering an
appropriate mask.&lt;/p&gt;

&lt;h3 id=&quot;constructing-the-laplacian-pyramid&quot;&gt;Constructing the Laplacian Pyramid&lt;/h3&gt;
&lt;p&gt;The details of the algorithm can be found in the publications by Burt and Adelson
[1,2], thus I will skimp on the details, and recommend the reader to work through the
paper. A top level overview of the algorithm is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Construct the gaussian pyramids.&lt;/li&gt;
  &lt;li&gt;Construct the laplacian pyramids.&lt;/li&gt;
  &lt;li&gt;Create the blended pyramids.&lt;/li&gt;
  &lt;li&gt;Collapse the blended pyramids to reconstruct the original image exactly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start, we need to determine the number of layers of the pyramid, which can be
done given the dimensions of the original image, and kernel, and satisfying the
following equations. \[C = M_c2^{N}+1\] \[R = M_r2^N + 1\]
where C is the columns size, R is the row size, \(M_c\) and \(M_r\) are
equivalent to \(\frac{1}{2}\) (kernel size - 1), and N being the number of
layers. Thus, if we have the dimensions of the image, and kernel, we can
calculate the number of layers:
\[N = floor(\log_2(\frac{R-1}{M_r})\]&lt;/p&gt;

&lt;p&gt;Once we have determined the number layers we can construct the gaussian pyramid,
using the $reduce()$ function to convolve and then downsample over the given
number of layers.
The open source OpenCV library[3] has the pyrDown() function which uses a
\(5\times5\) kernel shown below, to convolve, and downsamples by rejecting the
even number rows and columns at each successive layer.&lt;/p&gt;

\[\frac{1}{256}\begin{bmatrix}
1 &amp;amp; 4 &amp;amp; 6 &amp;amp; 4 &amp;amp; 1 \\
4 &amp;amp; 16 &amp;amp; 24 &amp;amp; 16 &amp;amp; 4 \\
6 &amp;amp; 24 &amp;amp; 36 &amp;amp; 24 &amp;amp; 6 \\
4 &amp;amp; 16 &amp;amp; 24 &amp;amp; 16 &amp;amp; 4 \\
1 &amp;amp; 4 &amp;amp; 6 &amp;amp; 4 &amp;amp; 1 \\
\end{bmatrix}\]

&lt;p&gt;The algorithm itself is rather trivial to implement, using the filter2D()
function found in the OpenCV library, which handles the padding and convolution
step.&lt;/p&gt;

&lt;p&gt;A personal rendition of the reduce function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mypyrDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;borderType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BORDER_REFLECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This should leave us with N - 1 downsampled images, with the original image used as
the base of the “pyramid”. The effect of the reduce operation is in effect
applying a low-pass filter. The convolve step is an averaging operation, which
takes pixels in the neighborhood and applies a linear transformation.
This basically has the effect of dispersing the local per pixel information. The
downsample, reduces redundancy and correlation of the pixels. This works on the
idea that neighbor pixels are correlated. The following image is the gaussian
pyramid, with each layer scaled to match original. We can see clearly how the
fine features are removed and we are left with a rather course representation in
the final layer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/gpyramid.png&quot; alt=&quot;Gaussian Pyramid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Construction of the Laplacian Pyramid involves upsampling, padding then
convolving with the same kernel used in the downsample. pyrUp() can be used for
this. The construction itself is recursively applying pyrUp() to a layer in the
Gaussian Pyramid and subtracting from the next layer. The procedure starts with
the smallest layer. At each step, the procedure effectively is isolating the
error between two images, the original image and the averaged image, with the
error interpreted as the high frequency information lost in the convolution and
downsample step. Again, the implementation is relatively trivial, and really
highlights the ingenuity of the designers. Simple yet powerful.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#The code was written for clarity over efficiency
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mypyrUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;borderType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BORDER_REFLECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mygaussPyramid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reduce_layer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lst&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mylaplacianPyramid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;retlst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;retlst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expand_layer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])[:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;retlst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussPyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retlst&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/lpyramid.png&quot; alt=&quot;Laplacian Pyramid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Just to expand on the concept of the effect of a low pass filter, we can
consider the unsharp masking method used to sharpen images. \[g_{sharp} = f +
\gamma(f-h_{blur}\star f)\] The process extracts the difference, error, between an
image, and the average image, and adds back some proportion of this difference.
The idea is that the error represents areas of high intensity, and accentuates
the given area by doubling(not literally) down. The following images displays
the results of the unsharp mask operation. [Original, Blurred, Sharpened]&lt;/p&gt;

&lt;div style=&quot;text-align=center&quot;&gt;
&lt;img src=&quot;/static/img/posts/beach.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;  
&lt;img src=&quot;/static/img/posts/blurbeach.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;
&lt;img src=&quot;/static/img/posts/sharpbeach.png&quot; width=&quot;100&quot; height=&quot;150&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;See the associated code for completeness.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;gbeach&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GaussianBlur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sharp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addWeighted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gbeach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Will cover blending and collapsing in the next post, followed by a brief
discussion on masks…&lt;/p&gt;

&lt;p&gt;(All mistakes are mine, any corrections appreciated.)&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Burt, Peter J and Adelson, Edward H. A Multiresolution Spline with
Application to Image Mosiacs&lt;/li&gt;
  &lt;li&gt;Burt, Peter J and Adelson, Edward H. The Laplacian Pyramid as a Compact Image
Code&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 28 Feb 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/computervision/2017/02/28/laplacian.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/computervision/2017/02/28/laplacian.html</guid>
        
        
        <category>computervision</category>
        
      </item>
    
      <item>
        <title>Overflow in Image Processing</title>
        <description>&lt;p&gt;Something that I found simple yet profound is the idea of overflow encountered
in image processing which really is a by-product of how image pixels are represented in
computation.&lt;/p&gt;

&lt;p&gt;Typically the intensity of a pixel is represented by 8 bits, or 1 byte which has
the capacity to represent \(256\) values, \(2^8\), ranging from \(0\) to \(255\).&lt;/p&gt;

&lt;p&gt;One example of an issue that arises as a result is apparent when implementing
an operation as simple as averaging.&lt;/p&gt;

&lt;p&gt;For the purpose of discussion, lets say we have a gray scale image represented by a
\(2\times2\) matrix as such:&lt;/p&gt;

\[\begin{bmatrix} 240 &amp;amp; 240 \\ 10 &amp;amp; 120 \end{bmatrix}\]

&lt;p&gt;The average function applied to two identical images should obviously result in
mapping to the same matrix, and is equivalent to applying the identity matrix.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; import numpy as np 
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; image &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; np.array&lt;span class=&quot;o&quot;&gt;([[&lt;/span&gt;240,240],[10,120]]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;image + image&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; / 2  
array&lt;span class=&quot;o&quot;&gt;([[&lt;/span&gt;240, 240],
       &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; 10, 120]]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is not particular surprising and one has to wonder what the point of this
post is at this point, which is fine.&lt;/p&gt;

&lt;p&gt;First, the above matrix calculation used values represented by the type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt;, which
has 64 bits to switch and the capacity to represent a large quantity of values,
specifically \(-2^{63}\) to \(2^{63}-1\). A bit of an overkill for this
exercise, but serves the purpose.&lt;/p&gt;

&lt;p&gt;For images represented by 8 bits, or specifically &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8&lt;/code&gt; in numpy, the problem
of overflow becomes apparent very quickly. Working through the same exercise as
above, but constraining the capacity to one associated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8&lt;/code&gt; we discover that
the calculations fail to produce the correct results.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; image &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; np.array&lt;span class=&quot;o&quot;&gt;([[&lt;/span&gt;240,240],[10,120]]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.astype&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'uint8'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;image + image&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; / 2  
array&lt;span class=&quot;o&quot;&gt;([[&lt;/span&gt;112, 112],
       &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; 10, 120]], &lt;span class=&quot;nv&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;uint8&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What happened? If we break down the calculations, the issue becomes clear.
First the averaging function adds two numbers of type unsigned integer
represented by 8 bits. \(240 + 240\) would equal \(480\), but because of the
capacity constraints, the operation is equivalent to applying a modulo 255 after
the addition operator, \((240 + 240) % 255 \). The result wraps around and
outputs 225, then dividing this by 2 results in 112 after rounding. A completely
expected but undesired result. This can be easily resolved by increasing the
capacity of the representation, by converting from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt;, for
example.&lt;/p&gt;

&lt;p&gt;Why does this matter? Simply, unattended the results will be visually apparent,
in addition to the intensity of the pixels being artificially undervalued.&lt;/p&gt;

&lt;p&gt;A visualization exercise will make the result more clear.&lt;/p&gt;

&lt;p&gt;We start by introducing the original, as a disclaimer this a private picture
taken of a original &lt;a href=&quot;https://www.heatherbrownart.com/&quot;&gt;Heather Brown&lt;/a&gt; painting 
that I purchased a while back. 
&lt;img src=&quot;/static/img/posts/sunoriginal.png&quot; alt=&quot;Original&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To make the difference more apparent, we use two identical image and take the
average, which should result in the same image, and equivalent to applying the
identity matrix. Its clear even visually that the result is what we want.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/sunave.png&quot; alt=&quot;No overflow with int64&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The image below is applying the same operation but this time using unsigned
integer with 8 bit representation. The result is clear if we compare with the
desired output above, and visually can confirm the under valuation of the
intensity of the pixel values.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/sunoverflow.png&quot; alt=&quot;Overflow with uint8&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This can easily be averted if we pay attention to the transitive operations, and
remain sensitive to the types involved.&lt;/p&gt;

&lt;p&gt;A very simple concept, easily overlooked, but a basic concept worth knowing.&lt;/p&gt;

</description>
        <pubDate>Tue, 14 Feb 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/computervision/2017/02/14/overflow.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/computervision/2017/02/14/overflow.html</guid>
        
        
        <category>computervision</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #4</title>
        <description>&lt;h3 id=&quot;previous-posts&quot;&gt;Previous Posts:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/22/actor-critic-1.html&quot;&gt;Actor-Critic and Policy Gradient Methods #1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/24/actor-critic-2.html&quot;&gt;Actor-Critic and Policy Gradient Methods #2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/rldm/2017/01/29/actor-critic-3.html&quot;&gt;Actor-Critic and Policy Gradient Methods #3&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post, we will break down the ratio trick that helped us in the previous post
to digest the policy gradient theorem, using the steps outlined by D.
Meyer[1].&lt;/p&gt;

&lt;p&gt;First-off lets recall the identity \(\nabla_{\theta}\log(w) =
\frac{1}{w}\nabla_{\theta}w\). Lets remember this as the identity will come in use later.&lt;/p&gt;

&lt;p&gt;Start with a function: \[y=\pi(s,a;\theta)\]
Take the log of both sides and link to new variable \(z\):
\[z=\log y=\log \pi(s,a;\theta)\]
Take the derivative, recalling the chain rule definition:
\[\frac{\partial z}{\partial\theta}=\frac{\partial z}{\partial y}\frac{\partial
y}{\partial \theta}\]
where
\[\frac{\partial z}{\partial y}=\frac{1}{\pi(s,a;\theta)}\]
\[\frac{\partial y}{\partial \theta}=\frac{\partial \pi(s,a;\theta)}{\partial
\theta}=\nabla_{\theta}\pi(s,a;\theta)\]
thus
\[\frac{\partial
z}{\partial\theta}=\frac{\nabla_{\theta}\pi(s,a;\theta)}{\pi(s,a;\theta)}\]
and using the identity we introduced earlier, we arrive upon:
\[\frac{\partial
z}{\partial\theta}=\frac{\nabla_{\theta}\pi(s,a;\theta)}{\pi(s,a;\theta)}=
\nabla_{\theta}\log\pi_{\theta}(s,a)\]&lt;/p&gt;

&lt;p&gt;Finally:
\[\nabla_{\theta}\pi(s,a;\theta)=\pi(s,a;\theta)\nabla_{\theta}\log\pi_{\theta}(s,a)\]&lt;/p&gt;

&lt;p&gt;which is the final result that we were after, and the “trick” that helps make
the policy gradient method palatable to a certain extent.&lt;/p&gt;

&lt;p&gt;At last we can move on to looking at some algorithms…&lt;/p&gt;

&lt;p&gt;(All mistakes are mine, corrections appreciated.)&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Meyer, David. Notes on policy gradients and the log derivative trick for reinforcement learning&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Tue, 31 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/01/31/actor-critic-4.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/01/31/actor-critic-4.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #3</title>
        <description>&lt;p&gt;Ok, so now that we got the objective function defined, \(J(\theta)\), which to
remind ourselves is a function that is evaluating the quality of the policy,
where higher is better. We also have an update rule that is basically hill “climbing” as
we attempt an ascend to an optima, preferably a global but most likely will be
local; \(\theta’ = \theta + \alpha\nabla_{\theta}J(\theta)\).&lt;/p&gt;

&lt;p&gt;Now lets get a grip on the \(\nabla_{\theta}J(\theta)\). We talked about gradients
in a separate series “Gradient Descent with a dash of Linear Algebra”, and
understand that the gradient is a column vector of partial derivatives with
respect to each parameter that parameterizes the policy, \(\pi(a|s, \theta)\).&lt;/p&gt;

&lt;p&gt;The policy gradient theorem states: for any differentiable policy, for any
policy objective function \(J(\theta)\), the policy gradient is given by:&lt;/p&gt;

\[\nabla_{\theta}J(\theta)=\mathbf{E}_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)]\]

&lt;p&gt;The question is how do we get from  \(\nabla_{\theta}J(\theta)\) to
\(E_{\pi_{\theta}}[\nabla_{\theta}\log\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)]\)?
Will work backwards step by step, starting from the end result stated above.&lt;/p&gt;

&lt;p&gt;First, rewrite the expected value over policies,
\(E_{\pi_{\theta}}[..]\)
as \(\sum_{s}d(s)\sum_{a}\pi_{\theta}(s,a)\) to get:
\[\nabla_{\theta}J(\theta)=\sum_{s}d(s)\sum_{a}\pi_{\theta}(s,a)\nabla_{\theta}\log\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)\]
The \(Q^{\pi_{\theta}}(s,a)\) is the state-action value function, and an estimate
of the return obtained from taking action, \(a\), from state \(s\), and following
policy, \(\pi\), there after. We’ll leave this as is.&lt;/p&gt;

&lt;p&gt;Next use the \(\textbf{so-called ratio trick}\), \(\nabla_{\theta}\pi_{\theta}(s,a) =
\pi_{\theta}(s,a)\frac{\nabla_{\theta}\pi_{\theta}(s,a)}{\pi_{\theta}(s,a)}=\pi_{\theta}(s,a)\nabla\log\pi_{\theta}(s,a)\)
, which we will break down in the next post, to unwind further. This leaves us
with:
\[\nabla_{\theta}J(\theta)=\sum_{s}d(s)\sum_{a}\nabla_{\theta}\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)\]&lt;/p&gt;

&lt;p&gt;As a result of linearity, we can push out the \(\nabla\) outside the
summations:\[\nabla_{\theta}J(\theta)=\nabla_{\theta}\sum_{s}d(s)\sum_{a}\pi_{\theta}(s,a)Q^{\pi_{\theta}}(s,a)\]&lt;/p&gt;

&lt;p&gt;We can re-introduce the expectation over policies for clarity.&lt;/p&gt;

\[\nabla_{\theta}J(\theta)=\nabla_{\theta}\mathbf{E}_{\pi_{\theta}}[Q^{\pi_{\theta}}(s,a)]\]

&lt;p&gt;What does this mean?! I guess it makes some intuitive sense in that
we are trying to find the direction, given by the gradient, in which the
expected value of the Q function for a given policy is higher. The reason that
researchers want to work away from this formulation is that the gradient of the
expected value could be relatively difficult to compute.&lt;/p&gt;

&lt;p&gt;Now we need to just get a handle on this ratio trick that is used often when
talking of policy gradient methods.&lt;/p&gt;

&lt;p&gt;(All mistakes are mine, corrections appreciated.)&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References:&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/D.Silver/web/Teaching_files/pg.pdf&quot;&gt;Silver, David. Lecture 7: Policy Gradient&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Meyer, David. Notes on policy gradients and the log derivative trick for reinforcement learning&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.shakirm.com/2015/11/machine-learning-trick-of-the-day-5-log-derivative-trick/&quot;&gt;Mohamed, Shakir. Machine Learning Trick of the Day (5): Log Derivative
Trick&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Sun, 29 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/01/29/actor-critic-3.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/01/29/actor-critic-3.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #2</title>
        <description>&lt;p&gt;This is a continuation of a series of posts to assess the actor-critic policy
gradient algorithm. In the previous post we left off by introducing the gradient
ascent update \[\Delta\theta=\alpha\nabla_{\theta}J(\theta)\], and left a couple
questions unanswered. Specifically, what is the \(J(\theta)\) function, and how do
we calculate the value associated with the gradient of \(J(\theta)\).&lt;/p&gt;

&lt;p&gt;tl;dr: \(J(\theta)\) is the objective function and represents the quality of a
given policy. There are three variations typically introduced but the policy
gradient method is uniformly applicable.&lt;/p&gt;

&lt;p&gt;First, in terms of \(J(\theta)\), which is evaluating the quality or “goodness” of
a particular policy, \(\pi(a|s,\theta)\), is typically presented in three forms,
one for the episodic case, continuous case, and a case where the average reward
per time step is considered.&lt;/p&gt;

&lt;p&gt;For the episodic case, the start value can be used, thus&lt;/p&gt;

\[J_1(\theta) = V^{\pi_{\theta}}(s_1) = \mathbf{E}_{\pi_{\theta}}[v_1]\]

&lt;p&gt;In English, assuming my understanding is correct, what this is indicating is
that the policy objective function \(J(\theta)\) is defined by the expected
return, cumulative discounted rewards, starting from \(s_1\) for a given policy.&lt;/p&gt;

&lt;p&gt;For the continuous case, the average value is typically considered, where the
objective function is defined
as:\[J_{aaV}(\theta)=\sum_sd^{\pi_{\theta}}(s)V^{\pi_{\theta}}(s)\]&lt;/p&gt;

&lt;p&gt;\(d^{\pi_{\theta}}\), is the the probability of being in state, \(s\), under policy,
\(\pi_{\theta}\). Thus \(J_{aaV}(\theta)\) is just the probability of being in
state, \(s\), multiplied by the expected return from state, \(s\), given a
particular policy, \(\pi\). Basically as the name indicates, its the
\(\textit{average}\) expected returns over all possible states, with the probability
of each state being drawn from a stationary distribution,
\(d^{\pi_{\theta}}(s)\).&lt;/p&gt;

&lt;p&gt;Finally, the average reward per time step is defined as: \[J_{avR}(\theta) =
\sum_{s}d^{\pi_{\theta}}(s)\sum_{a}\pi_{\theta}(s,a)\mathbf{R}_s^a\]&lt;/p&gt;

&lt;p&gt;Breaking down the symbols, starting from the right side, we are taking the
rewards obtained for taking a particular action, discounted by the probability
of that action given a policy, and this is evaluated and summed over all
actions, and finally evaluated and summed for all possible states.&lt;/p&gt;

&lt;p&gt;As defining the objective functions took a bit longer than expected, I will
continue the interpretation in the next post.&lt;/p&gt;

</description>
        <pubDate>Tue, 24 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/01/24/actor-critic-2.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/01/24/actor-critic-2.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Actor-Critic and Policy Gradient Methods #1</title>
        <description>&lt;p&gt;In the following posts, I will attempt to breakdown the Actor-Critic Policy
Gradient Algorithm.&lt;/p&gt;

&lt;p&gt;Research often highlights the practicality of the policy
gradient method in evaluating models with high dimensions, and continuous action
spaces, as opposed to discrete and limited action space where some iteration of
Q-learning, or more generally a function approximation has been applied. In contrast to value function approximation where
convergence is not guaranteed, albeit in practice displaying significant results
(DQN), the variants of the policy gradient method offers guarantees on convergence to at least a
local optima. The downsides are, likewise the risk of converging to a local optima,
inefficiencies (sample complexity high), and the fact that stand alone, the
associated variance is high as well.&lt;/p&gt;

&lt;p&gt;In terms of progression, in the coming posts I will:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Break down the policy gradient method, and introduce the associated algorithm.&lt;/li&gt;
  &lt;li&gt;Attempt to address the so-called “likelihood ratio” trick that is often time
just rushed through in the material, which will require a detour in understanding the chain
rule, and the likelihood estimator.&lt;/li&gt;
  &lt;li&gt;Touch on the topic of variance, what this actually means, and a comparison
to an algorithm that exhibits high bias.&lt;/li&gt;
  &lt;li&gt;Wrap back around to the Actor-Critic algorithm which introduces the base-line
to address the issue of high variance that the policy gradient method exhibits
on a stand alone basis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So why go through this, and take notes? The current so-called state of the art
in Deep Reinforcement Learning is a variant of the Actor-Critic architecture and
has been given the name of Asynchronous Advantage Actor-Critic, or A3C, and
presented &lt;a href=&quot;https://arxiv.org/abs/1602.01783&quot;&gt;here&lt;/a&gt; by Mnih et al.&lt;/p&gt;

&lt;p&gt;So lets begin…
The policy gradient method essentially is using the gradient approach in the optimization problem to find
the \(\theta\) that maximizes \(J(\theta)\). If your background has been in
dealing with neural nets or some optimization problem where the objective is to
minimize the cost function, you may be used to seeing the gradient
\(\textit{descent}\) update used. In this case we are trying to
\(\textbf{maximize}\) the value of the policy as a goal, thus need to
ascend or increase which leads us to the (approximate) gradient ascent update rule. 
  \[\theta’ = \theta + \alpha\frac{\partial J(\theta)}{\partial \theta}\]
  or equivalently:
  \[\Delta\theta=\alpha\nabla_{\theta}J(\theta)\]&lt;/p&gt;

&lt;p&gt;For clarity, we are trying to find the best \(\theta\), that maximizes the
“quality” of \(\pi(a |s;\theta)\).&lt;/p&gt;

&lt;p&gt;A couple questions should be considered now. First, what is \(J(\theta)\), the
quality of the policy, and secondly, how can we obtain the gradient of this
particular function?&lt;/p&gt;

&lt;p&gt;Will answer in the following post…&lt;/p&gt;

</description>
        <pubDate>Sun, 22 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rldm/2017/01/22/actor-critic-1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rldm/2017/01/22/actor-critic-1.html</guid>
        
        
        <category>rldm</category>
        
      </item>
    
      <item>
        <title>Rust lifetime #3</title>
        <description>&lt;p&gt;Following on in my dive into the concept of ownership in Rust, will assess the
idea of lifetimes. I will follow the documentation at
&lt;a href=&quot;https://doc.rust-lang.org/book/references-and-borrowing.html&quot;&gt;rust-lang.org&lt;/a&gt;. The tutorial breaks down the concept in three chunks:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Ownership (Covered in a previous post)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;References and Borrowing (Covered in a previous post)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Lifetimes&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post will summarize my general understanding of lifetimes.&lt;/p&gt;

&lt;p&gt;tl;dr: the concept of lifetimes seems quiet complex, but makes “lifetimes” of
values transparent and promotes safer programming.&lt;/p&gt;

&lt;h1 id=&quot;point-1-use-after-free-prevention&quot;&gt;Point #1: “use after free” prevention&lt;/h1&gt;
&lt;p&gt;The documentation provides a rather intuitive break down of an example of what
the concept of lifetimes is attempting to prevent.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;I acquires a handle to some kind of resource.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I lend a reference to the resource to you.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I free the resource, as I am done with the resource, and decide to
deallocate.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You decide to use the resource.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This would cause an error. The reference you have been lent is now pointing at
an invalid resource. The ‘use after free’ concept should be familiar and applies
to this scenario.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;you&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;c&quot;&gt;//introduce you&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;me&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c&quot;&gt;//introduce scope value, me&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;me&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;//me lends the reference to &quot;resource&quot; to you&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;you&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;//you is still referencing resource of me&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The above would fail, as a you is referecing a resource that has gone out of
scope. The rust compiler is able to catch this as a result of having visibility
on the “lifetimes” of different values.&lt;/p&gt;

&lt;h1 id=&quot;point-2-syntax&quot;&gt;Point #2: syntax&lt;/h1&gt;
&lt;p&gt;Some syntax to keep in mind. Rust allows functions to have generic parameters
placed between &amp;lt;&amp;gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;             &lt;span class=&quot;c&quot;&gt;//foo has one lifetime, 'a&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;         &lt;span class=&quot;c&quot;&gt;//bar has two lifetimes, in the case we had two reference&lt;/span&gt;
                            &lt;span class=&quot;c&quot;&gt;//parameters with different lifetimes. &lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;//a reference to an i32, with a lifetime 'a&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;//a mutable reference to an i32, with a lifetime 'a&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;//when dealing with structs, need to ensure&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'a&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;//that any reference to Foo doesnt outlive a&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;                           &lt;span class=&quot;c&quot;&gt;//reference to the i32 the struct it contains&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;point-3-static-lifetime&quot;&gt;Point #3: ‘static lifetime&lt;/h1&gt;
&lt;p&gt;Static lifetime is a special type of lifetime that has a lifetime over the
entire program.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FOO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;//adds an i32 to the data segment of the binary.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FOO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;//x refers to the i32&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Fri, 20 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rust/2017/01/20/rust-lifetime.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rust/2017/01/20/rust-lifetime.html</guid>
        
        
        <category>rust</category>
        
      </item>
    
      <item>
        <title>LSTM cell break down</title>
        <description>&lt;p&gt;I came across a video by Martin Gorner, which can viewed
&lt;a href=&quot;https://www.youtube.com/watch?v=vq2nnJ4g6N0&quot;&gt;here&lt;/a&gt;. The presentation provides a
top level, yet self contained overview of deep learning and tensorflow.&lt;/p&gt;

&lt;p&gt;I found his presentation of the LSTM cell informative, in particular, the way he
chose to present the concept had impact on my learning process.&lt;/p&gt;

&lt;p&gt;The specific segment on the LSTM cell contained a walk through of the components
of the cell, stepping through each gate.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/posts/lstmbreakdown.png&quot; alt=&quot;LSTM&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Concatenate: \(X= X_t | H_{t-1}\)&lt;/li&gt;
  &lt;li&gt;Forget gate: \(f = \sigma(XW_f + b_f)\)&lt;/li&gt;
  &lt;li&gt;Update gate: \(u = \sigma(XW_u + b_u)\)&lt;/li&gt;
  &lt;li&gt;Result gate: \(r = \sigma(XW_r + b_r)\)&lt;/li&gt;
  &lt;li&gt;Input:       \(X’ = \tanh(XW_c + b_c)\)&lt;/li&gt;
  &lt;li&gt;new C:       \(C_t = f * C_{t-1}+u*X’\)&lt;/li&gt;
  &lt;li&gt;new H:       \(H_t = r * tanh(C_t) \)&lt;/li&gt;
  &lt;li&gt;Output:      \(Y_t = softmax(H_tW +b)\)&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;The concatenate step takes \(X_t\) and concatenates with \(H_{t-1}\)
resulting in a vector with dimensions \(p+n\). As the other gates are
working in dimension
\(n\), we need a transformation that maps \(\mathbf{R}^{p+n} \rightarrow
\mathbf{R}^{n}\), thus need to apply \(W_i\) where \(i\in {f,u,r,c}\).&lt;/li&gt;
  &lt;li&gt;\(C_t\) is the result of applying the forget gate, \(f\), which regulates
what is forgotten and what remains. The result of applying \(f\), element
wise, is summed with the update gate, \(u\), applied to \(X’\) elementwise.
The internal state of the cell is updated in this manner.&lt;/li&gt;
  &lt;li&gt;Note that the sigmoid non-linearity, \(\sigma\), applied in the forget,
update, and result gate, squashes the result between 0 and 1, thus acting as a
discount factor.&lt;/li&gt;
  &lt;li&gt;Another point raised, is the reason we apply the \(\tanh\), non-linear
function. Note that \(C_t\) is the sum of two positive
operands, thus easily can result in divergence. By applying \(\tanh\) the
result is squeezed between -1 and 1, thus helping to mitigate the risk of
divergence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind that this is one possible structure for an LSTM cell…the
possibilities of combinations are limitless though, in contrast, the differentiation on performance as a result of
cell structure appears limited.&lt;/p&gt;

</description>
        <pubDate>Mon, 16 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2017/01/16/lstm-breakdown.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2017/01/16/lstm-breakdown.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Gradient descent with a dash of Linear Algebra #4</title>
        <description>&lt;p&gt;This is #4 of a series where I am trying to digest the
&lt;a href=&quot;http://www.deeplearningbook.org/slides/sgd_and_cost_structure.pdf&quot;&gt;presentation&lt;/a&gt;,
by Ian Goodfellow.&lt;/p&gt;

&lt;p&gt;In the last post, we assessed the impact of a gradient step on the cost
function, \(J(\theta)\). Now we consider the types of destinations that the
method will encounter as the gradient steps progress.&lt;/p&gt;

&lt;p&gt;In the following slides he talks on critical points. From single variate
calculus, we know that if a function, \(f\), is differentiable and \(x\) is an optima
then \(f’(x) = 0\), and \(x\) is a critical point associated with the
function, \(f\).&lt;/p&gt;

&lt;p&gt;Since the gradient is the first derivative, and a zero gradient implies a
critical point, with the Hessian matrix, \(\textbf{H}\), in hand we can classify
the optima as a minima, maxima, or saddle point.&lt;/p&gt;

&lt;p&gt;If all the eigenvalues, \(\lambda_i &amp;gt; 0\), then the critical point is a minima,
which he short hands as \(\lambda_{min} &amp;gt; 0\). If all eigenvalues, \(\lambda_i &amp;lt;
0\), then critical point is a maxima, while if mixed then classified as a saddle
point.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Is there is a way to back out the same information without calculating eigenvalues?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we take advantage of a couple properties we can.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;\(\det(H) = \lambda_1\lambda_2…\lambda_n\)&lt;/li&gt;
  &lt;li&gt;\(\text{tr}(H) = \lambda_1 + \lambda_2 +…+\lambda_n\)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;where the \(\det(H)\) can be found without calculating eigenvalues and the tr\((H)
= \sum_{i=1}^nh_{ii}\) where \(h_{ii}\) represents the components of
\(\textbf{H}\)
along the diagonal.&lt;/p&gt;

&lt;p&gt;Thus we can use the commonly defined rules as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;if \(\det(H) &amp;gt; 0 \wedge \text{tr}(H) &amp;gt; 0 \rightarrow \text{Minima}\)&lt;/li&gt;
  &lt;li&gt;if \(\det(H) &amp;gt; 0 \wedge \text{tr}(H) &amp;lt; 0 \rightarrow \text{Maxima}\)&lt;/li&gt;
  &lt;li&gt;else \(\rightarrow \text{Saddlepoint}\)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and we are done…for now.&lt;/p&gt;
</description>
        <pubDate>Mon, 16 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/math/2017/01/16/gradient-4.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/math/2017/01/16/gradient-4.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>math</category>
        
      </item>
    
      <item>
        <title>Rust borrowing #2</title>
        <description>&lt;p&gt;Following on in my dive into the concept of ownership in Rust, will assess the
idea of references and borrowing. I will follow the documentation at
&lt;a href=&quot;https://doc.rust-lang.org/book/references-and-borrowing.html&quot;&gt;rust-lang.org&lt;/a&gt;. The tutorial breaks down the concept in three chunks:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Ownership (Covered in the previous post)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;References and Borrowing&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Lifetimes&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post will summarize my general understanding of borrowing.&lt;/p&gt;

&lt;p&gt;tl;dr:  The concept of borrowing, prevents iterator invalidation, and use after
free, helping to create a safer environment. If you want to mutate a passed
variable, need to utilize a mutable reference.&lt;/p&gt;

&lt;h1 id=&quot;point-1&quot;&gt;Point #1:&lt;/h1&gt;
&lt;p&gt;Essentially, under references and borrowing, a resource is lent by the owner and
“borrowed” by the function.&lt;/p&gt;

&lt;p&gt;For example, consider the below as example given:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;//v1 has ownership&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;//v2 has ownership&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;//ownership is lent to foo&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;//foo consumes and returns the borrowed resource.&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;       &lt;span class=&quot;c&quot;&gt;//This is ok! as owenership has been returned back to v1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;point-2&quot;&gt;Point #2&lt;/h1&gt;
&lt;p&gt;References are immutable. Thus a variable passed by reference, lets say v1 in
the above case, can not be amended within foo. Will give an error.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;//illegal operation, v is borrowed, cant mutate.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;//v has ownership&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;//foo borrows&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;point-3&quot;&gt;Point #3&lt;/h1&gt;
&lt;p&gt;If we want to mutate a borrowed variable, need to use a “mutable reference”. The example
given is as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;//x has ownership and x is mutable.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;//y borrows a mutable reference.&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;//y can now mutate x, but needs to use '*' operator&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;//x returns 6 &lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The rules defined in the documentation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;First, any borow must last for a scope no greater than that of the owner.
Second, you may have one or the other of these two kinds of borrows, but not
both at the same time. 1) one or more references (&amp;amp;T) to a resource, 2) exactly
one mutable reference (&amp;amp;mut T).&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Sat, 14 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rust/2017/01/14/rust-borrowing.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rust/2017/01/14/rust-borrowing.html</guid>
        
        
        <category>rust</category>
        
      </item>
    
      <item>
        <title>Rust ownership #1</title>
        <description>&lt;p&gt;I will follow the documentation at
&lt;a href=&quot;https://doc.rust-lang.org/book/ownership.html&quot;&gt;rust-lang.org&lt;/a&gt; to get a better
grip on ownership. The tutorial breaks down the concept in three chunks:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Ownership&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;References and Borrowing&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Lifetimes&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post will summarize my general understanding of ownership.&lt;/p&gt;

&lt;p&gt;tl;dr: Keep in mind the ownership concept when reassigning variables with
existing bindings. If not a primitive, an error will occur at compile time.&lt;/p&gt;

&lt;h1 id=&quot;point-1&quot;&gt;Point #1:&lt;/h1&gt;
&lt;p&gt;Basically that variable bindings have ownership of what the variable is bound
to. The example given is that:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ok, to have “ownership” means that v basically owns vec![1,2,3]. Thus if we
decide set a new variable, y = v, then v no longer has ownership, and will
result in a compile time error. This addresses the idea that Rust gaurantees
that bindings to resources are unique.&lt;/p&gt;

&lt;p&gt;This is not allowed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The phrase used is “move”, as in the error will be related to the attempt to
accessing, the use of the “moved” value v.&lt;/p&gt;

&lt;h1 id=&quot;point-2&quot;&gt;Point #2:&lt;/h1&gt;
&lt;p&gt;The trait, Copy, is introduced, where a trait is feature that adds incremental
behavior.&lt;/p&gt;

&lt;p&gt;Basic concept is that if its a primitive type that is bound, then the Copy trait
comes in to play and we can reassign ownership and still address the original
the original variable.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ok, this is fine now and will compile as 5 is a primitive. Essentially the Copy
trait invokes a deep copy, and y does not reference the object pointed to by v.&lt;/p&gt;

</description>
        <pubDate>Thu, 12 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rust/2017/01/12/rust-ownership.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rust/2017/01/12/rust-ownership.html</guid>
        
        
        <category>rust</category>
        
      </item>
    
      <item>
        <title>Gradient descent with a dash of Linear Algebra #3</title>
        <description>&lt;p&gt;This is #3 of a series where I am trying to digest the
&lt;a href=&quot;http://www.deeplearningbook.org/slides/sgd_and_cost_structure.pdf&quot;&gt;presentation&lt;/a&gt;,
by Ian Goodfellow.&lt;/p&gt;

&lt;p&gt;In the last post, we broke down and assessed the Hessian matrix, \(H\). We
continue on in this post by analyzing the impact of a gradient step on the cost
function and finding the optimal gradient step with respect to cost reduction.&lt;/p&gt;

&lt;p&gt;This is followed by the introduction of the Taylor series approximation, and the
expansion of the cost function, \(J(\theta)\). The taylor series is typically defined
as \[\sum_{n=0}^{\inf}\frac{f^{(n)}(a)}{n!}(x-a)^n\]
and in the expansion would look like: \[f(x)= f(a) + \frac{f’(a)}{(x-a)} +
\frac{f’‘(a)}{2!}(x-a)^2…\]&lt;/p&gt;

&lt;p&gt;When applied to the cost function case, keeping in mind that
\((\vec{\theta}-\vec{\theta)_0}\cdot(\vec{\theta}-\vec{\theta}_0)=(\vec{\theta}-\vec{\theta_0})^T(\vec{\theta}-\vec{\theta}_0)\).
Note, that I use the vector symbol, to make it clear that we are dealing with
vectors. This is applicable to all \(\theta\) when referring generally to
parameters.&lt;/p&gt;

&lt;p&gt;\[J(\theta) = J(\theta_0) +
(\theta-\theta_0)^T\textbf{g}+\frac{1}{2}(\theta-\theta_0)^T\textbf{H}(\theta-\theta_0)+…\]&lt;/p&gt;

&lt;p&gt;Specifically, Ian approximates the cost function, \(J(\theta)\) out to the 2nd
order in order to assess the sensitivity of the cost to a gradient step,
resulting in: \[J(\theta-\epsilon \textbf{g}) \approx J(\theta) -\epsilon
\textbf{g}^T\textbf{g} +
\frac{1}{2}\epsilon^2\textbf{g}^T\textbf{H}\textbf{g}\]&lt;/p&gt;

&lt;p&gt;For easier comprehension, we can move the minus sign out:
\[J(\theta-\epsilon \textbf{g}) \approx J(\theta) -(\epsilon
\textbf{g}^T\textbf{g} -
\frac{1}{2}\epsilon^2\textbf{g}^T\textbf{H}\textbf{g})\]&lt;/p&gt;

&lt;p&gt;and break down the equation as:
\[\text{new} J(\theta)  \approx \text{old} J(\theta) - \text{adjustment to cost
as a result of gradient step}, \ \epsilon\]&lt;/p&gt;

&lt;p&gt;Now if \(\textbf{g}^T\textbf{H}\textbf{g} \leq 0\), its guaranteed that the term
\((\epsilon \textbf{g}^T\textbf{g} -
\frac{1}{2}\epsilon^2\textbf{g}^T\textbf{H}\textbf{g})\) is positive, thus we are
reducing the old \(J(\theta)\) by some amount.&lt;/p&gt;

&lt;p&gt;So the question is what is the optimal step size, or the \(\epsilon\) that results
in the largest cost reduction? We can just take the derivative, set to 0, and solve for
\(\epsilon\).
 \[\frac{\partial}{\partial \epsilon}J(\theta) =( \textbf{g}^T\textbf{g} -
\epsilon\textbf{g}^T\textbf{H}\textbf{g})=0\]
\[\epsilon^* =
\frac{\textbf{g}^T\textbf{g}}{\textbf{g}^T\textbf{H}\textbf{g}}\]&lt;/p&gt;

&lt;p&gt;He also touches upon the worst case scenario when \(\textbf{g}\) aligns
with \(\lambda_{max}\). This goes back to the previous post, where if the direction
aligns with the direction of eigenvalue, i.e, the eigenvector, \(\textbf{g}\), and
gradient run parallel, the angle between is 0, thus \(\cos^2(0) = 1\), and we
are left with subtracting \(\lambda_{max}\) with out any discounting, thus the
“adjustment to cost as a result of gradient step” will be the smallest when
\(\textbf{g}\) aligns with \(\lambda_{max}\) and below holds: \[(\epsilon -
\frac{1}{2}\epsilon^2\lambda_{max})\textbf{g}^T\textbf{g}\]&lt;/p&gt;

&lt;p&gt;Will continue on the next post…all mistakes are mine, if any please point out
and I will amend.&lt;/p&gt;

</description>
        <pubDate>Thu, 12 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/math/2017/01/12/gradient-3.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/math/2017/01/12/gradient-3.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>math</category>
        
      </item>
    
      <item>
        <title>Gradient descent with a dash of Linear Algebra #2</title>
        <description>&lt;p&gt;This is #2 of a series where I am trying to digest the
&lt;a href=&quot;http://www.deeplearningbook.org/slides/sgd_and_cost_structure.pdf&quot;&gt;presentation&lt;/a&gt;,
Ian Goodfellow.&lt;/p&gt;

&lt;p&gt;We left off, having defined the cost function, \(J(\theta)\), the gradient,
\(\nabla_{\theta}J(\theta)\), and the Hessian, \(\textbf{H}\).&lt;/p&gt;

&lt;p&gt;The \(\textbf{H}\), can be diagonalized, as \(\textbf{H}\) is symmetric, and
requires that the \(\det{H} \neq 0\).
\[\textbf{H}=\textbf{Q}\Lambda\textbf{Q}^T\]
where \(\textbf{Q}\) is the matrix of eigenvectors, \(v_i\), and
\(\Lambda\) is the
diagonal matrix containing the eigenvalues, \(\lambda_i\). Thus for example, a
\(2\times2\) Hessian matrix with unique eigenvalues,\(\lambda_1,\lambda_2\) the
expansion would be:&lt;/p&gt;

\[\textbf{H}=\begin{bmatrix}v_1 &amp;amp; v_2 \end{bmatrix}\begin{bmatrix}\lambda_1 &amp;amp; 0
\\ 0 &amp;amp; \lambda_2 \end{bmatrix}\begin{bmatrix}v_1 \\ v_2 \end{bmatrix}\]

&lt;p&gt;Further, he defines the \(\textbf{H}\), applied in the direction \(d\), as
\(d^T\textbf{H}d=\sum_i\lambda_i\cos^2(\theta_i)\) where \(\theta\) in this case is
defined as the angle between the eigenvector, \(v_i\), and direction vector
\(d\).
\(\textit{This is important, as its used in the simplification to follow}\). Just
remember that if directions aligned and \(v_i\) is just a translation of
\(d\), the
vectors run parallel, thus angle between is \(0\), and \(\cos^2(\theta_i) =
1\)&lt;/p&gt;

&lt;p&gt;Will continue on the next post…all mistakes are mine, if any please point out
and I will amend.&lt;/p&gt;

</description>
        <pubDate>Wed, 11 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/math/2017/01/11/gradient-2.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/math/2017/01/11/gradient-2.html</guid>
        
        
        <category>deeplearning</category>
        
        <category>math</category>
        
      </item>
    
      <item>
        <title>Gradient descent with a dash of Linear Algebra #1</title>
        <description>&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/deeplearning/2017/01/10/gradient-1.html&quot;&gt;Gradient descent with a dash of Linear Algebra #1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/deeplearning/math/2017/01/11/gradient-2.html&quot;&gt;Gradient descent with a dash of Linear Algebra #2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/deeplearning/math/2017/01/12/gradient-3.html&quot;&gt;Gradient descent with a dash of Linear Algebra #3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://surfertas.github.io/deeplearning/math/2017/01/16/gradient-4.html&quot;&gt;Gradient descent with a dash of Linear Algebra #4&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Updates:
Dec/10/2019: with links and fixed grammar.&lt;/p&gt;

&lt;p&gt;In this series of posts I am trying to digest the presentation by Ian Goodfellow
found in the deep learning resource &lt;a href=&quot;http://www.deeplearningbook.org/slides/sgd_and_cost_structure.pdf&quot;&gt;deep learning
book&lt;/a&gt;, as its sparse in
details (which I am sure was expanded on in the live session) and dense in
mathematical notation, at least from the perspective of a non-math person.
The purpose of this post is to breakdown the math, and reinforce my understanding.&lt;/p&gt;

&lt;p&gt;Ian starts by introducing the cost function, \(J(\theta)\), that we want to
minimize, the “gradient”, \(g=\nabla_{\theta}J(\theta)\), which is just basically
a column vector of partial derivatives with respect to each
parameter,\(\frac{\partial J(\theta)}{\partial \theta_i}\), applied to
\(\vec{\theta}\), and \(\textbf{H}\), the Hessian matrix, which is the partial
derivatives with respect to each component of the gradient, resulting in a
\(i\times j\) matrix.&lt;/p&gt;

&lt;p&gt;A quick example to move away from abstraction and to crystallize what we are
dealing with… Consider a hypothetical cost function \(J(\theta_1,\theta_2) =
\theta_1^2 + \theta_1\theta_2\). In this case the gradient vector would be
\[\begin{bmatrix}\frac{\partial J(\theta)}{\partial \theta_1} &amp;amp;   \frac{\partial
J(\theta)}{\partial \theta_2}\end{bmatrix}=\begin{bmatrix}2\theta_1+\theta_2 &amp;amp;
\theta_1\end{bmatrix}\]
The Hessian matrix, \(\textbf{H}\), in this case would be:&lt;/p&gt;

\[\begin{bmatrix} \frac{\partial}{\partial\theta_1}\frac{\partial}{\partial
\theta_1}J(\theta) &amp;amp; \frac{\partial}{\partial \theta_1}\frac{\partial}{\partial
\theta_2}J(\theta)\\ \frac{\partial}{\partial\theta_2}\frac{\partial}{\partial
\theta_1}J(\theta) &amp;amp; \frac{\partial}{\partial \theta_2}\frac{\partial}{\partial
\theta_2}J(\theta) \end{bmatrix}= \begin{bmatrix}2 &amp;amp; 1\\ 1 &amp;amp; 0 \end{bmatrix}\]

&lt;p&gt;Ok…one post to handle one slide..this may take a series of posts…&lt;/p&gt;
</description>
        <pubDate>Tue, 10 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2017/01/10/gradient-1.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2017/01/10/gradient-1.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>Select sort in Rust</title>
        <description>&lt;p&gt;A first pass at using rust, an implementation of select sort algorithm…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr_len&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sm_ind&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr_len&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.lt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sm_ind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sm_ind&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sm_ind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr_len&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{} &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A few things learned in this excercise:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Need to use mut ahead of variable declaration as default is for immutable
declaration.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Type check used at compile time, as a lot of errors were a result of
mismatched types.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Feels like I just translated an implementation done in C, thus would be
interested in seeing what a veteran &lt;a href=&quot;http://www.rustaceans.org/&quot;&gt;rustecean&lt;/a&gt; implementation would look like.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 09 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/rust/algorithms/2017/01/09/rust-practice.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/rust/algorithms/2017/01/09/rust-practice.html</guid>
        
        
        <category>rust</category>
        
        <category>algorithms</category>
        
      </item>
    
      <item>
        <title>LSTM with dropout</title>
        <description>&lt;p&gt;Working through the a &lt;a href=&quot;https://www.tensorflow.org/tutorials/recurrent/&quot;&gt;tf
tutorial&lt;/a&gt;, the authors
introduce a paper by &lt;a href=&quot;https://arxiv.org/abs/1409.2329&quot;&gt;Zaremba et al. 2014&lt;/a&gt;,
which addresses the issues of applying dropout as a form of regularization to
RNN. A naive application results in unsatisfactory outcomes, thus they propose
the application of dropouts only to the non-recurring inputs, \(h_t^{l-1}\),
where a LSTM is defined as: 
\[\textbf{LSTM}: h_t^{l-1}, h_{t-1}^{l}, c_{t-1}^l \rightarrow h_t^l,c_t^l\]
\(h_{t-1}^{l}\), is the recurring input, the current layer, \(l\), from
previous time step, and \(c_{t-1}^l\), is the memory unit from previous time step.&lt;/p&gt;

&lt;p&gt;A graphical representation introduced by the paper:
&lt;img src=&quot;/static/img/posts/lstm.png&quot; alt=&quot;LSTM&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The main contribution was applying dropout function, \(D\), to the
non-recurring input, thus \(D(h_t^{l-1})\).&lt;/p&gt;

&lt;p&gt;This comment stuck with me and basically sums up nicely.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Standard dropout perturbs the recurrent connections, which makes it difficult
for LSTM to learn to store information for long periods of time. By not using
dropout on the recurrent connections, the LSTM can benefit from dropout
regularization without sacraficing its valuable memorization ability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wishing that I had a few LSTMs to embed into my brain…&lt;/p&gt;

</description>
        <pubDate>Mon, 09 Jan 2017 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/deeplearning/2017/01/09/lstm-dropout.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/deeplearning/2017/01/09/lstm-dropout.html</guid>
        
        
        <category>deeplearning</category>
        
      </item>
    
      <item>
        <title>The Random Walker</title>
        <description>&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;In the following exercise, a simple random walk in one-dimension will be defined
and assessed. An analytical approach formulated and a solution presented.
Specifically, a random walk with a partially reflecting barrier at \(0\) will be considered,
with an empirical comparison suggesting convergence to the analytical
description of the solution occuring as large number of trials are considered.&lt;/p&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Random walks is a well studied subject matter with applications arising across
many fields. Random walks are commonly utilized to model topic specific
behaviours, despite the phenomena appearing unique to the particular field. A
typical random walk is a &lt;a href=&quot;http://www.stat.berkeley.edu/~mgoldman/Section0227.pdf&quot;&gt;special kind of Markov
chain&lt;/a&gt;, where states are all
integers, largest move per transition is one step in either direction, and there
is no probability assigned to remaining in the current state.&lt;/p&gt;

&lt;h3 id=&quot;simple-random-walk&quot;&gt;Simple Random Walk&lt;/h3&gt;
&lt;p&gt;A random walk is commonly defined as a stochastic sequence, defined by&lt;/p&gt;

&lt;p&gt;\[S_n = i + \sum_{k=1}^n X_k \ s.t \ (n \in \Bbb{N}) \]&lt;/p&gt;

&lt;p&gt;where \(\{S_n\}\) is a stochastic sequence and \(\{X_k\}\) are \(i.i.d\) random
variables. Specifically, a simple random walk is defined as a sequence of \(X_k\)
where the random variables take a value of \(1\) or \(-1\) with probability \(p \in
[0,1]\) and \(1-p\), respectively. Let \(S = \{S_0,S_1,S_2…\}\) be the partial sum
process associated with \(X\). The sequence \(S\) is the simple random walk with
parameter \(p\). Further context can be found &lt;a href=&quot;http://www.math.uah.edu/stat/bernoulli/Walk.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Further, a simple random walk can be considered symmetric if \(Pr(X_k=1) =
Pr(X_k=-1)\) when considering the one dimension case.&lt;/p&gt;

&lt;h3 id=&quot;random-walks-with-additional-properties&quot;&gt;Random walks with additional properties&lt;/h3&gt;
&lt;p&gt;Random walks with absorption barriers are commonly studied in applications to
the “The Gambler’s ruin” or the “The monkey at the cliff” problems. Consider
a discrete random walk confined to a range \([a,b]\) and absorbing barriers at \(a\)
and \(b\). In this example, \(a\) and \(b\) are considered absorbing states and 
characterized by the walk ending when either state is reached.&lt;/p&gt;

&lt;p&gt;When considering reflecting barriers, \(a\) is a reflecting barrier means that as
soon as the walk reaches \(a\) in the next step the walk returns with probability
\(1\).&lt;/p&gt;

&lt;p&gt;In the following example, a discrete random walk with a partially reflecting
barrier at 0 and absorbing barrier at a user defined \(n\) will be considered.
Specifically, if \(x = 0\), the probability we remain in the current state is \(Pr(x=0) = \frac{1}{2} \)
and \(Pr(x=1) = \frac{1}{2}\), otherwise \(x=k\) and \(Pr(x=k+1) = \frac{1}{2}\)
and \(Pr(x=k-1) = \frac{1}{2}\)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The question we look to answer is what is the expected number \(E_n\) of steps to
reach \(n\) from \(i\) considering the prior mentioned probabilities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A recurrence can be set up to solve for \(E_n\).&lt;/p&gt;

&lt;p&gt;Initial values:&lt;/p&gt;

&lt;p&gt;\[E_n = 0 \tag{1} \]&lt;/p&gt;

&lt;p&gt;\[E_0 = 1 + 0.5E_0 + 0.5E_1 \tag{2} \]&lt;/p&gt;

&lt;p&gt;\[E_i = 1 + 0.5E_{i-1} + 0.5E_{i+1} \tag{3} \]&lt;/p&gt;

&lt;p&gt;Note that \((3)\) simplifies to \(E_{i+1} = 2E_i - E_{i-1} - 2\) with the associated
characteristic equation defined as \(x^2-2x+1\). Solving for the roots results in
a double root at \(1\), thus the homogenous solution has the form \(E_i = a + bi\). In
order to find the associated particular solution use 
\[E_i = c + di + ei^2 \tag{4} \]&lt;/p&gt;

&lt;p&gt;Plug in \((4)\) into \((3)\) to solve for \(e = -1\), and setting \(c,d=0\), we find that
\(E_i = -i^2\). Thus the general solution is defined as&lt;/p&gt;

&lt;p&gt;\[E_i = a + bi - i^2 \tag{5} \].&lt;/p&gt;

&lt;p&gt;Finally, using \((1)\) and \((5)\), we find that \(0 = a+bn-n^2\) and using \((2)\) and \((5)\) we
find that \(b = -1\), which is followed by \(a= n + n^2\). Thus generally, the
expected number, \(E_n\), of steps to reach \(n\) from \(i\) is defined by&lt;/p&gt;

&lt;p&gt;\[E_i = n + n^2 - i - i^2 \tag{6} \]&lt;/p&gt;

&lt;h3 id=&quot;a-random-walk-with-partially-reflecting-barrier-and-absorbing-barrier&quot;&gt;A random walk with partially reflecting barrier and absorbing barrier&lt;/h3&gt;
&lt;p&gt;In the below application, the analytical solution to the random walk with a
partial reflecting barrier at \(0\) and absorbing barrier at \(n\) is calculated and
compared to an empirical solution resulting from the mean derived from the user
defined number of trials. The accepted \(n\) values is restricted to \(n &amp;lt; 30\) and the
difference between \(n\) and \(i\) is restricted to \(n-i &amp;lt; 10\) for practical
reasons. The application is initialized as follows: \(trials = 100\), \(n =
10\), \(i = 5 \).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2016/05/10/app-randomwalk.html&quot;&gt;RandomWalker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The web application was constructed using html, css, javascript, with bulk of
application written in Elm. Github repository can be found
&lt;a href=&quot;https://github.com/liana1215/randomwalk&quot;&gt;here&lt;/a&gt;. All feedback will be
appreciated!&lt;/p&gt;
</description>
        <pubDate>Tue, 10 May 2016 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/2016/05/10/randomwalk.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/2016/05/10/randomwalk.html</guid>
        
        
      </item>
    
      <item>
        <title>Random Walk</title>
        <description>&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/randombundle.js&quot;&gt;&lt;/script&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://surfertas.github.io/assets/css/style.css&quot; /&gt;
&lt;/head&gt;
&lt;!--test--&gt;
&lt;body&gt;
    &lt;div id=&quot;container&quot;&gt;
    &lt;h1&gt; Random Walk with Reflecting Boundries &lt;/h1&gt;
        &lt;form onsubmit=&quot;return sendComment(this);&quot;&gt;
            &lt;input placeholder=&quot;trials&quot; id=&quot;trials&quot; type=&quot;number&quot; required=&quot;&quot; /&gt;
            &lt;input placeholder=&quot;n&quot; id=&quot;n&quot; type=&quot;number&quot; required=&quot;&quot; /&gt;
            &lt;input placeholder=&quot;i&quot; id=&quot;i&quot; type=&quot;number&quot; required=&quot;&quot; /&gt;
            &lt;input type=&quot;submit&quot; name=&quot;button&quot; id=&quot;button&quot; required=&quot;&quot; /&gt;
        &lt;/form&gt;
        &lt;p id=&quot;message&quot;&gt;&amp;nbsp;&lt;/p&gt;
      &lt;div style=&quot;height:1000px; width: 1000px;&quot; id=&quot;walker&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;

&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var walkerDiv = document.getElementById(&quot;walker&quot;);
    var app = Elm.embed(Elm.Walker, walkerDiv, {inputs: {n:0, i:0, trials:0}});
    
    function sendComment(form) {
        var n = parseInt(form.n.value)
        var i = parseInt(form.i.value)
        var trials = parseInt(form.trials.value)
        
        if (n &lt; i) {
            text = &quot;'n' needs to be greater than 'i'.&quot;
        } else {
            if (n &gt; 30) {
                text = &quot;'n' is too large, needs to be less than 30.&quot; 
            } else if (n - i &gt; 10) {
                text = &quot;'n' and 'i' difference needs to be &lt; 10.&quot;
            }else {
                app.ports.inputs.send({n: n, i: i, trials: trials});
                form.reset();
                text = &quot;&amp;nbsp&quot;;
            }
        } 
        document.getElementById(&quot;message&quot;).innerHTML = text;
        return false;
    }
&lt;/script&gt;
&lt;/html&gt;

</description>
        <pubDate>Tue, 10 May 2016 00:00:00 +0000</pubDate>
        <link>https://surfertas.github.io/2016/05/10/app-randomwalk.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/2016/05/10/app-randomwalk.html</guid>
        
        
      </item>
    
      <item>
        <title>journey with elm</title>
        <description>&lt;p&gt;An attempt to log my journey through learning elm. Will work through tutorials
found on the net, with an attempt to tweak each provided example so that I can
get a better grip on the material. The examples will be in reverse chronological
order, with the top displaying the most recent challenge.&lt;/p&gt;

&lt;p&gt;Tutorials:
\&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://elm-by-example.org/&quot;&gt;elm-by-example&lt;/a&gt;\&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.classes.cs.uchicago.edu/archive/2015/winter/22300-1/Schedule.html&quot;&gt;cs223&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;A random walk, continuing on with the use of the Random module…&lt;/p&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/randomwalk.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;randomball&quot; style=&quot;width: 60%; height: 500px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;randomball&quot;);

    Elm.embed(Elm.Randomwalk, div);

&lt;/script&gt;
&lt;/html&gt;

&lt;hr /&gt;

&lt;p&gt;Estimating pi…&lt;/p&gt;

&lt;p&gt;The approximation is based on the idea that:
\[\lim_{n \to \infty} \frac{t}{n} = \frac{Area \ of \ Circle \ Quad}{Area \ of \ Circumscribed \ Square \ Quad} = \frac{\frac{\pi r^2}{4}}{r^2} = \frac{\pi}{4}\]&lt;/p&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/pi.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;pi&quot; style=&quot;width: 300px; height: 300px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;pi&quot;);

    Elm.embed(Elm.Pi, div);

&lt;/script&gt;
&lt;/html&gt;

&lt;hr /&gt;

&lt;p&gt;Admittedly took a bit of brute force to get this one done. Constrained the
movement of the eyes by adjusting the related R values on the x,y-axis.&lt;/p&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/daruma.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;daruma&quot; style=&quot;width: 60%; height: 300px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;daruma&quot;);

    Elm.embed(Elm.Daruma, div);

&lt;/script&gt;
&lt;/html&gt;

&lt;hr /&gt;
&lt;p&gt;Learnt a bit about signals, and some work to get the coordinates to track mouse
moves…&lt;/p&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/mousesignals.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;mouse&quot; style=&quot;width: 50%; height: 400px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;mouse&quot;);

    // embed our Elm program in that &lt;div&gt;
    Elm.embed(Elm.MouseSignals, div);

&lt;/script&gt;
&lt;/html&gt;

&lt;hr /&gt;

&lt;p&gt;Instead of calculating and displaying the fibonacci sequence, I chose to pump
out the sequence of perfect numbers up to 1000.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Perfect number, a positive integer that is equal to the sum of its proper
divisors. The smallest perfect number is 6, which is the sum of 1, 2, and 3.
Other perfect numbers are 28, 496, and 8,128. The discovery of such numbers is
lost in prehistory. It is known, however, that the Pythagoreans (founded c. 525
bc) studied perfect numbers for their “mystical” properties.
&lt;br /&gt;
-Encyclopedia Britannica&lt;/p&gt;
&lt;/blockquote&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/perfnumBars.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;bars&quot; style=&quot;width: 50%; height:500px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;bars&quot;);

    // embed our Elm program in that &lt;div&gt;
    Elm.embed(Elm.PerfnumBars, div);

&lt;/script&gt;
&lt;/html&gt;

&lt;p&gt;If anyone has suggestions on improving the properDivisor implementation please
advise.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;PerfnumBars&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lightBlue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lightGrey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lightPurple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;purple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yellow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Graphics.Collage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Graphics.Element&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;down&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;withDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;properDivisors&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;properDivisors&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;perfectNum&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;perfectNum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;properDivisors&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;indexedPerfectNum&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;indexedPerfectNum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(,)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;perfectNum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lightBlue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lightGrey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lightPurple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withDefault&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;red&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;flow&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;collage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filled&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rect&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toFloat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flow&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;down&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indexedPerfectNum&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;
&lt;p&gt;Really no additional explanation required here, just changed the wording a bit.&lt;/p&gt;

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://surfertas.github.io/static/js/elm-source/helloelm.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;hello&quot; style=&quot;width: 50%; height: 400px&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    var div = document.getElementById(&quot;hello&quot;);

    // embed our Elm program in that &lt;div&gt;
    Elm.embed(Elm.Helloworld1, div);

&lt;/script&gt;
&lt;/html&gt;

</description>
        <pubDate>Wed, 09 Mar 2016 17:08:56 +0000</pubDate>
        <link>https://surfertas.github.io/elm/2016/03/09/elm-journey.html</link>
        <guid isPermaLink="true">https://surfertas.github.io/elm/2016/03/09/elm-journey.html</guid>
        
        
        <category>elm</category>
        
      </item>
    
  </channel>
</rss>
