<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.1">Jekyll</generator><link href="https://mdcramer.github.io/feed/perceptron-magic-blog.xml" rel="self" type="application/atom+xml" /><link href="https://mdcramer.github.io/" rel="alternate" type="text/html" /><updated>2026-04-27T11:57:27-07:00</updated><id>https://mdcramer.github.io/feed/perceptron-magic-blog.xml</id><title type="html">Hackin’ and Tinkerin’ | Perceptron-magic-blog</title><subtitle>A collection of blogs related to some of my work on GitHub and elsewhere</subtitle><author><name>Mark Cramer</name></author><entry><title type="html">The Perceptron Class</title><link href="https://mdcramer.github.io/perceptron-magic-blog/the-perceptron-class/" rel="alternate" type="text/html" title="The Perceptron Class" /><published>2019-01-05T00:00:00-08:00</published><updated>2021-12-24T00:00:00-08:00</updated><id>https://mdcramer.github.io/perceptron-magic-blog/the-perceptron-class</id><content type="html" xml:base="https://mdcramer.github.io/perceptron-magic-blog/the-perceptron-class/"><![CDATA[<h2 id="what-is-a-perceptron">What is a Perceptron?</h2>

<p>The node is the ‘atomic’ unit of a neural network and the <a href="https://en.wikipedia.org/wiki/Perceptron" title="Perceptron - Wikipedia">Perceptron</a> is the most basic form of node. Wikipedia describes it as an ‘algorithm,’ but you can also think of it as an ‘object’ that accepts some inputs and produces an output. Neural networks may then be constructed by stringing Perceptrons together and potentially stacking layers of them on top of each other. With enough of them, what they can end up doing is, often, nothing short of magic.</p>

<p>Walking through the diagram below, a Perceptron will accept any number (\(n\), for example) of inputs, \(x_0\) to \(x_n\), and product a single output, \(y\). These inputs are, of course, numbers, although they may be arbitrarily large or small and include fractions. Each input is then multiplied by a weight, \(w_0\) to \(w_n\). The summation of all the inputs multiplied by their weights is called the hypothesis:</p>

\[h(X) = x_0 w_0 + x_1w_1 + \cdots +x_nw_n\]

<p>The <em>hypothesis</em> is thus a single number which is then sent through an activation function. There are many types of activation functions (we’ll review some later), but the simplest is the “step”: if the hypothesis is positive or zero our output is 1, otherwise it is 0.</p>

<p><img src="/assets/images/perceptron-architecture.png" alt="" title="Perceptron Architecture" /></p>

<p>So what’s the point of this? We’ll dig into that, but at a high level what we’ve got is a linear classifier that simply checks to see if our hypothesis is either positive or negative. The key here, which we’ll explore through a process called “training,” is to determine the ‘right’ weights to make the Perceptron appropriately classify the inputs. That’s what makes the magic: finding the weights.</p>

<h2 id="the-perceptron-class">The Perceptron Class</h2>

<p>We’re going to use <a href="https://www.python.org/">Python</a> because it easy to learn, easy to use and has become, more or less, for reasons associated with data science-related libraries, the language of choice for people building neural networks. That being said, you could follow these exercises using most any <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented</a> programming language.</p>

<p>As mentioned in the <a href="/perceptron-magic-blog/motivation/">Motivation</a>, this is the thing that, for performance reasons, nobody ever does. To reiterate, we’re doing it to try to get insights into functioning of Perceptrons and neural networks.</p>

<p>Below is the first chuck of code we’ll need. We define the Perceptron call and set up the initialization function to accept the number of inputs. For the moment, there’s nothing else to define. Using the number of inputs we then create an equal number of weights to which we’ll assign random floating point numbers between -1 and +1.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">random</span> <span class="c1"># We'll need this to generate random numbers
</span>    
<span class="k">class</span> <span class="nc">Perceptron</span><span class="p">:</span> <span class="c1"># This begins the class definition
</span>        
    <span class="c1"># This runs whenever we instantiate
</span>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num_inputs</span><span class="p">):</span>
        <span class="c1"># Create an empty array for the weights
</span>        <span class="bp">self</span><span class="p">.</span><span class="n">weights</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num_inputs</span><span class="p">):</span>
            <span class="c1"># Set each weight to a random number from -1 to +1
</span>            <span class="c1"># random.random() produces a floating point number in the range [0.0, 1.0)
</span>            <span class="bp">self</span><span class="p">.</span><span class="n">weights</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
        <span class="c1"># Print the weights to see what happened
</span>        <span class="k">print</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">weights</span><span class="p">)</span>
</code></pre></div></div>

<p>Now if you run <code class="language-plaintext highlighter-rouge">a = Perceptron(5)</code>, which creates a new Perceptron with 5 inputs, called <code class="language-plaintext highlighter-rouge">a</code>, you should get an output like <code class="language-plaintext highlighter-rouge">[0.12754034043801643, -0.20861593234059006, -0.37130273318835005, -0.10781144821380861, -0.5746109925723668]</code>, which is simply an array of 5 random numbers between -1 and +1. So the first step works.</p>

<p>Here is the next text.</p>

<p>Here is some more text.</p>]]></content><author><name>Mark Cramer</name></author><category term="Perceptron" /><summary type="html"><![CDATA[Provide description of a Perceptron and build the initial, basic Perceptron class.]]></summary></entry><entry><title type="html">Motivation</title><link href="https://mdcramer.github.io/perceptron-magic-blog/motivation/" rel="alternate" type="text/html" title="Motivation" /><published>2018-12-26T00:00:00-08:00</published><updated>2019-01-05T20:50:00-08:00</updated><id>https://mdcramer.github.io/perceptron-magic-blog/motivation</id><content type="html" xml:base="https://mdcramer.github.io/perceptron-magic-blog/motivation/"><![CDATA[<h2 id="why-build-neural-networks-using-a-perceptron-class">Why build neural networks using a Perceptron class?</h2>

<p>The obvious reason as to why neural networks are built using matrix math, as opposed to a Perceptron class using an object oriented language, is simple: performance. Even if you’re not using a GPU capable of massive parallel computations, the performance advantages of using matrices, to compute things like forward and backward propagation, are enormous. Having to go one neuron at a time while training, which is notoriously computationally intensive, could render the thing useless.</p>

<p>So why do it?</p>

<p>I’ve always felt that to fundamentally understanding something it helps to break it down into it’s smallest components and then look at how each one operates. In the case of a neural network, that’s the node, and the most fundamental form of a node is the <a href="https://en.wikipedia.org/wiki/Perceptron" title="Perceptron - Wikipedia">Perceptron</a>.</p>

<p>Naturally, this would eliminate the possibility of using a library, such as TensorFlow, but so much the better since the learning process is enhanced even further when building something from scratch. Finding examples of networks built using a Perceptron class was not easy, which is not surprising given the argument above, but I eventually stumbled across <a href="https://www.codementor.io/mcorr/an-introduction-to-python-machine-learning-with-perceptrons-k7pn85vfi">An Introduction to Python Machine Learning with Perceptrons</a> which offered some helpful guidance to get off the ground.</p>

<p>After a lot of fiddling around I got it to work, built a few simple networks to do some linear classification and simple logic functions and actually had a lot of fun along the way. While I didn’t find anything revolutionary, for anyone getting started with neural networks, or for those wanting to take a step back and look at things a different way, I’ll walk you through what I did.</p>

<h2 id="outline">Outline</h2>

<p>Roughly speaking, after building a simple Perceptron class and then expanding its capabilities as I move forward, here’s what I’ll present:</p>

<ol>
  <li>Single node point and line classifier</li>
  <li>Single node point and line classifier with bias</li>
  <li>Single node logical gates: AND &amp; OR</li>
  <li>Multi-node logical gate: XOR</li>
  <li>Multi-node point and parabola classifier</li>
</ol>]]></content><author><name>Mark Cramer</name></author><category term="Perceptron" /><category term="motivation" /><summary type="html"><![CDATA[Why build neural networks using a Perceptron class?]]></summary></entry></feed>