<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhruv</title>
    <description>The latest articles on DEV Community by Dhruv (@unography).</description>
    <link>https://dev.to/unography</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170170%2F0eabc663-0698-44aa-a2a8-53a1bffc9f8c.jpg</url>
      <title>DEV Community: Dhruv</title>
      <link>https://dev.to/unography</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/unography"/>
    <language>en</language>
    <item>
      <title>Recreating paintings with Generative Art, using p5.js</title>
      <dc:creator>Dhruv</dc:creator>
      <pubDate>Sun, 26 May 2019 13:56:47 +0000</pubDate>
      <link>https://dev.to/unography/recreating-paintings-with-generative-art-using-p5-js-1e46</link>
      <guid>https://dev.to/unography/recreating-paintings-with-generative-art-using-p5-js-1e46</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7amh3nhqzkjc9sws3kor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7amh3nhqzkjc9sws3kor.png" alt="Random Walk Van Gogh"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkqolvnmfpotu5iirpv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkqolvnmfpotu5iirpv0.png" alt="Random Walk Van Gogh"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foucko7ni09o85ytcjq4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foucko7ni09o85ytcjq4y.png" alt="Random Walk Van Gogh"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A bunch of random, squiggly lines being drawn to generate a portrait of Van Gogh.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The above method uses two concepts - &lt;strong&gt;Random Walk&lt;/strong&gt;, and &lt;strong&gt;Perlin Noise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine you are walking down an empty road, it's a holiday, and you have all the time in the world. Every 10 seconds, you flip a coin. Heads, you take a step forward. Tails, it's a step backward. This is essentially what a random walk is - a path defined by a series of random steps.&lt;/p&gt;

&lt;p&gt;Now instead of an empty road, suppose it's a maze, where you have options to take a step to your left and right, along with forward and backward directions. So now you take 2 coins and based on their flip you decide a step direction, e.g. if it is Head and Head, maybe you take 1 step forward, 1 step left, and so on.&lt;/p&gt;

&lt;p&gt;This is similar to what the algorithm above is doing. Lines are drawn between two points - starting from an initial point, &lt;code&gt;(x1, y1)&lt;/code&gt; the destination point &lt;code&gt;(x2, y2)&lt;/code&gt; is chosen based on some randomness. In the next iteration, the initial point now becomes the past &lt;code&gt;(x2, y2)&lt;/code&gt; and the whole thing repeats all over again.&lt;/p&gt;

&lt;p&gt;To get the colour, we take the rgb value of the destination point here &lt;code&gt;(x2, y2)&lt;/code&gt;. We could take the initial pixel value as well, but since the distance between the points are large, and a lot of times it starts from the background, taking the destination pixel value made more sense. Purely a personal preference.&lt;/p&gt;

&lt;p&gt;Now we come to the randomness part.&lt;/p&gt;

&lt;p&gt;Almost all programming languages and libraries have a &lt;em&gt;random()&lt;/em&gt; function. We could have used that to get a random direction and drawn lines accordingly, but the problem with it is, the result we get is just, too, random.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9hgby32vd18pxj5s2ze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9hgby32vd18pxj5s2ze.png" alt="Van Gogh with Random Noise"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2txe0wzhz4b2bh1uiwbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2txe0wzhz4b2bh1uiwbg.png" alt="Van Gogh with Random Noise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An interesting effect, but not quite what we want.&lt;/p&gt;

&lt;p&gt;We want our lines to be random, but also to have some kind of pattern to them, so the end result isn't quite as chaotic.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Perlin Noise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Invented by Ken Perlin, It's a way to get points in a random fashion, but, which also follow a certain pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrqfi0g4hjd6ewvb0656.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrqfi0g4hjd6ewvb0656.png" alt="Random Noise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is what random noise looks like - consecutive points fetched after calling a random function and then plotting them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw25hldn10demrngndk6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw25hldn10demrngndk6s.png" alt="Perlin Noise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is what Perlin Noise looks like - consecutive points fetched after calling 2D Perlin Noise function and then plotting them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The points in both the cases are random, yet in the second image they have a visual aesthetic to it.&lt;/p&gt;

&lt;p&gt;In p5.js, simply calling &lt;code&gt;noise()&lt;/code&gt; instead of &lt;code&gt;random()&lt;/code&gt; gives this type of pattern, which is what we used to get the semi-random destination points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85x8o0a6x88yotyrx46c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85x8o0a6x88yotyrx46c.gif" alt="Random Walk Portraits"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you're bored with just seeing Van Gogh - the code is deployed live here, where each time you refresh the page, you get a new, random painting !&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://unographymag.com/void" rel="noopener noreferrer"&gt;https://unographymag.com/void&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A few resources to check out!:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=l__fEY1xanY&amp;amp;" rel="noopener noreferrer"&gt;Daniel Shiffman on Random Walk&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Qf4dIN99e2w" rel="noopener noreferrer"&gt;Daniel Shiffman's introduction to Perlin Noise&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>p5js</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A few frequently asked (thought about) questions about Convolutions in Neural Networks</title>
      <dc:creator>Dhruv</dc:creator>
      <pubDate>Tue, 21 May 2019 19:55:35 +0000</pubDate>
      <link>https://dev.to/unography/a-few-frequently-asked-thought-about-questions-about-convolutions-in-neural-networks-3pih</link>
      <guid>https://dev.to/unography/a-few-frequently-asked-thought-about-questions-about-convolutions-in-neural-networks-3pih</guid>
      <description>&lt;h2&gt;
  
  
  What are convolutions?
&lt;/h2&gt;

&lt;p&gt;Before we answer this, let's understand one thing first. Computers are dumb creatures. They don't know what words mean, like cat or dog. They don't know what things look like, like a cat or a dog. All they understand are numbers (well... slightly not true, but for our case it works). &lt;/p&gt;

&lt;p&gt;Now let's introduce a few terms ~ &lt;strong&gt;&lt;em&gt;kernel&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;filters&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;channels&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Filters&lt;/em&gt; can be thought of as a collection of &lt;em&gt;kernels&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But what &lt;em&gt;are&lt;/em&gt; kernels?&lt;/p&gt;

&lt;p&gt;Imaging you're on the set of your favourite tv-show. We'll take Game of Thrones for now, but any show works. Kernels are each individual actor, writer, cinematographer, etc on that show.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H9fP3AXi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s86jdrdfoa2v8oqkai99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H9fP3AXi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s86jdrdfoa2v8oqkai99.png" alt="gotKernels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;kernels sitting across a table, trying to decide the course of the season&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And since computers don't understand anything other than numbers, kernels for us are just numbers. Each kernel is a matrix of numbers. Now if a Game of Thrones episode is analogous to a neural network trying to distinguish between a cat or a dog, kernels are the individual actors that helped it reach its decision.&lt;/p&gt;

&lt;p&gt;In case of Convolutional Neural Networks (CNN) kernels behave as &lt;em&gt;feature&lt;/em&gt; &lt;em&gt;extractors&lt;/em&gt;. The extract certain features from the data, and pass it along to the next layer, which ultimately helps in arriving at a decision.&lt;/p&gt;

&lt;p&gt;Thinking of kernels as feature extractors brings us to channels. &lt;em&gt;Channels&lt;/em&gt; can be thought of now as feature bags. A "bag" contains the same set of features. &lt;/p&gt;

&lt;p&gt;A colour image usually has three channels - Red, Green, and Blue (RGB image). The Red channel contains similar set of features about the image that describes the "redness" of it. Same for the Green and Blue channels.&lt;/p&gt;

&lt;p&gt;In case of Game of Thrones, channels can be thought of as a department - the sound department can be thought of as a channel, similarly the video department, marketing department can be the other channels.&lt;/p&gt;

&lt;p&gt;We now come to &lt;strong&gt;&lt;em&gt;convolutions&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZszfBzTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/36avjhix87i0ul7rv01l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZszfBzTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/36avjhix87i0ul7rv01l.gif" alt="2dConv"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;fig. 1: an example of 2D convolution of a 3x3x1 kernel on 5x5x1 data&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In convolution, we take a kernel of dimenstion (width, height, channel) e.g. 3x3x1 and slide it across our data, performing elementwise multiplication over the part of the input it is currently on, and summing up the results into get the output element.&lt;/p&gt;

&lt;p&gt;In the image above, a 3x3x1 kernel is convolving over 5x5x1 input data. This is also known as 2D Convolution &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The number of channels a kernel has needs to be the same as the number of channels in the input data. Now based on the number of kernels we use, the output data's channels get decided. e.g. if our input data is of size 7x71, our kernel must have 1 channel, like 3x3x1. Now if we use 32 such kernels, the output data's size will be something like 5x5x32 (it will have 32 channels) If we further want to convolve, we must use kernels with 32 channels, e.g. 3x3x32.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jy1vDatQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h56y1fdj8wlt2nmgzvfs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jy1vDatQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h56y1fdj8wlt2nmgzvfs.gif" alt="conv"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;fig. 3: convolution of 4 kernels of shape 3x3x3 on data of size 5x5x3 to get output of  shape 3x3x4&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why don't we use even shaped kernels like 2x2, 4x4, 6x6 ?
&lt;/h2&gt;

&lt;p&gt;When we have a kernel like 3x3 or 5x5, the kernel lies on top of a pixel, and it has a symmetrical view of the neighbouring pixels. There is a central element and a symmetry around this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bGSw-B70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/07ey341ickanro0mnj3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bGSw-B70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/07ey341ickanro0mnj3e.png" alt="2x2Kernel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;fig. 3: convolving with a 2x2 kernel has a non-symmetrical view of the pixels below it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We completely lose this symmetry if it's any even shaped kernel. The kernel doesn't know which pixel's local features it is extracting. If we do something like edge detection, there needs to be a central element, which has something to it's left and something to it's right - preferably with uniform similarity. If it's not there, it results in distortions for the output the kernel produces. Which is why we avoid using kernels like 2x2, 4x4, 6x6, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we usually use 3x3 kernels and not 1x1, 5x5, 7x7, etc?
&lt;/h2&gt;

&lt;p&gt;In a Convolutional Neural Network, we usually think of kernels as feature extractors. When we use a 1x1 kernel, the "view" of the kernel is very limited - it would just be the element right below the kernel. From fig.1. above, we see that when we use a 3x3 kernel, the "view" of the kernel when it is above a pixel is of 9 pixels below it. We are seeing more of the data, this helps us extract better features.&lt;/p&gt;

&lt;p&gt;If it's a 1x1 kernel, it behaves like an identity function, which is useless to us when extracting features.&lt;/p&gt;

&lt;p&gt;The next odd shaped kernel is 3x3 (we discussed why we don't use even shaped ones above).&lt;/p&gt;

&lt;p&gt;3x3 kernel behaves perfectly as a feature extractor. It has a central element and a symmetry around it. It covers enough area to have local knowledge useful for extracting features, so it works for us.&lt;/p&gt;

&lt;p&gt;5x5, 7x7 and others also have symmetry around pixels, but while convolving they have more parameters than when convolving with a 3x3 kernel, so the larger we go from 3x3, the less computationally effecient it becomes. The local area it covers is also larger than we want it to be, when extracting features. 3x3 gives us a good coverage of pixels.&lt;/p&gt;

&lt;p&gt;Another advantage with using 3x3 kernels is we can get the same affect of any odd shaped kernel with a 3x3 kernel. For example, we can use two 3x3 kernels to get the same effect as using a 5x5 kernel (with no padding and stride of 1).&lt;/p&gt;

&lt;p&gt;By affect, we mean receptive field, or the "view" we mentioned earlier. Using 2 3x3 kernels gives us the same global receptive field as using 1 5x5 kernel, and still using 3x3 is more computationally effecient in this case!&lt;/p&gt;

&lt;p&gt;Because of all these advantages, GPU's like those by NVIDIA have also optimized convolutions on 3x3 sized kernels. Many papers like the Resnet paper has 7x7 kernel in it's code, but while optimizing the performance of such networks, the 7x7 kernels get converted into 3 3x3 kernels.&lt;/p&gt;

&lt;p&gt;So we stick to using 3x3 kernels when we want to extract features.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: We do use 1x1 convolutions in our networks, but we don't use them for extracting features. They are typically used to increase/decrease the number of channels. We can use 3x3 for changing the number of channels, but it behave as normal convolution too, so changing the pixel values as well. 1x1, being an identity mapping, doesn't do the usual convolution, so it's an ideal kernel when we just want to change the number of channels.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>convolutions</category>
      <category>neuralnetworks</category>
    </item>
  </channel>
</rss>
