# TikZ: Diagram of a perceptron

I'm trying to create a TikZ based version of the following diagram (taken from here), but I don't know how to approach it.

It doesn't need to look exactly like the original, but the basic idea should be preserved. It would especially be great if the paths from X_n to the sum function were straight lines without a "bend" like in the original. That makes a matrix layout difficult to use.

The definition of the output function can be left away.

Could someone point me to an approach that will work in this case, or even create a tikz texample?

Update: I ended up combining the approaches by @m0nhawk and @Toscho and came up with this:

• Please add a minimal working example (MWE) that illustrates your problem. It's no fun to setup a file from scratch. When you post a compilable code, starting with \documentclass{...} and ending with \end{document} with your existing try-out (no matter how insufficient it is), everybody can jump in much easier. Mar 26 '13 at 8:30
• Approach it the same way you would draw it. Start with the input circles and place a few below each other. Then the wights, and connect them to the circles, etc... Make an attempt and ask a specific question about what part you are having difficulty with. Mar 26 '13 at 8:37
• @percusse The problem is that I don't know what approach/tikzlibrary/layout to use. Therefore a MWE would be just a "base skeleton" with the standalone documentclass. PeterGrill: Ok, I could split it up into different questions (e.g. how to align the inputs around the sum function). But maybe there's a layout or library well suited for this problem, that's why I'm asking. Mar 26 '13 at 8:41
• @DaniloBargen That skeleton would be more than enough :) Just spicing up with the required nodes and it would be good to go. You really don't need to go all the way, just to reduce the load on the potential answerers. Mar 26 '13 at 14:30
• @percusse ok, i'll do that next time :) Mar 26 '13 at 21:44

Here is the simple reconstruction. Issues:

• Left of equations, can easily be added with node.
• Make inputs and weights with \foreach.
• Increase the Activation function to be more like the original one.
• Improve TikZ styles.

Code:

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\tikzset{input/.style={basic,circle}}
\tikzset{weights/.style={basic,rectangle}}
\tikzset{functions/.style={basic,circle,fill=blue!10}}

\begin{document}
\begin{tikzpicture}
\node[functions] (center) {};
\node[below of=center,font=\scriptsize,text width=4em] {Activation function};
\draw[thick] (0.5em,0.5em) -- (0,0.5em) -- (0,-0.5em) -- (-0.5em,-0.5em);
\draw (0em,0.75em) -- (0em,-0.75em);
\draw (0.75em,0em) -- (-0.75em,0em);
\node[right of=center] (right) {};
\path[draw,->] (center) -- (right);
\node[functions,left=3em of center] (left) {$\sum$};
\path[draw,->] (left) -- (center);
\node[weights,left=3em of left] (2) {$w_2$} -- (2) node[input,left of=2] (l2) {$x_2$};
\path[draw,->] (l2) -- (2);
\path[draw,->] (2) -- (left);
\node[below of=2] (dots) {$\vdots$} -- (dots) node[left of=dots] (ldots) {$\vdots$};
\node[weights,below of=dots] (n) {$w_n$} -- (n) node[input,left of=n] (ln) {$x_n$};
\path[draw,->] (ln) -- (n);
\path[draw,->] (n) -- (left);
\node[weights,above of=2] (1) {$w_1$} -- (1) node[input,left of=1] (l1) {$x_1$};
\path[draw,->] (l1) -- (1);
\path[draw,->] (1) -- (left);
\node[weights,above of=1] (0) {$w_0$} -- (0) node[input,left of=0] (l0) {$1$};
\path[draw,->] (l0) -- (0);
\path[draw,->] (0) -- (left);
\node[below of=ln,font=\scriptsize] {inputs};
\node[below of=n,font=\scriptsize] {weights};
\end{tikzpicture}
\end{document}


Picture:

• +1 for reference have a look at Should \tikzset or \tikzstyle be used to define TikZ styles? Mar 26 '13 at 16:24
• @cmhughes: Never thought \tikzstyle is a "bad". Thanks! Mar 26 '13 at 17:40
• Thanks for this answer, very appreciated :) The lines between the inputs and the sum function are not straight, but it looks fine the way it is! Mar 26 '13 at 21:49

Here a shorter code without positioning, so you can scale the picture.

\documentclass[tikz]{article}
\usepackage{tikz}

\tikzset{basic/.style={draw,fill=blue!50!green!20,
\tikzset{input/.style={basic,circle}}
\tikzset{weights/.style={basic,rectangle,minimum width=2em}}
\tikzset{functions/.style={basic,circle,fill=blue!50!green!20}}
(0,-0.5em) --  (-0.5em,-0.5em)
(0em,0.75em) -- (0em,-0.75em)
(0.75em,0em) -- (-0.75em,0em);}

\begin{document}
\begin{tikzpicture}[scale=1.2]
\foreach \h [count=\hi ] in {$x_n$,$x_2$,$x_1$,$1$}{%
\node[input] (f\hi) at (0,\hi*2cm-5 cm) {\h};
}
\node[functions] (sum) at (4,0) {$\sum$};
\foreach \h [count=\hi ] in {$w_n$,$w_2$,$w_1$,$w_0$}{%
\path (f\hi) -- node[weights] (w\hi) {\h} (sum);
\draw[->] (f\hi) -- (w\hi);
\draw[->] (w\hi) -- (sum);
}
\node[functions] (step) at (7,0) {};
\begin{scope}[xshift=7cm,scale=.75]
\end{scope}
\draw[->] (sum) -- (step);
\draw[->] (step) -- ++(1,0);
% Labels
\node[above=1cm]  at (f4) {inputs};
\node[above=1cm] at (w4) {weights};
\end{tikzpicture}
\end{document}


With PSTricks but not completed...

\documentclass[preview,border=12pt]{standalone}
\usepackage{pst-node}
\usepackage{amsmath}
\psset
{
rowsep=4mm,
colsep=8mm,
mnodesize=10mm,
mnode=r,
}
\newcommand{\C}[1]{[mnode=circle,fillstyle=solid,fillcolor=blue!20]$#1$}
\newcommand{\R}[1]{[mnode=r]\psframebox[fillstyle=solid,fillcolor=blue!20]{\parbox{4mm}{\strut\centering$#1$}}}
\def\Symbol{%
\psset{unit=3mm}
\pspicture(-1,-1)(1,1)
\psset{linewidth=0.4pt}
\psline(-1,0)(1,0)
\psline(0,-1)(0,1)
\psline[linewidth=2\pslinewidth](-0.75,-0.5)(0,-0.5)(0,0.5)(0.75,0.5)
\endpspicture
}
\begin{document}
\offinterlineskip
\begin{psmatrix}
\C{1}           & \R{w_0}\\
\C{x_1}         & \R{w_1}\\
\C{x_2}         & \R{w_2}       & \C{\Sigma}    & [mnode=circle,fillstyle=solid,fillcolor=blue!20,name=symbol]\Symbol   &   [mnode=p]\\
\vdots          & \vdots\\
\C{x_n}         & \R{w_n}\\
\text{inputs}   & \text{weights}
\psset{arrows=->}
\ncline{1,1}{1,2}
\ncline{2,1}{2,2}
\ncline{3,1}{3,2}
\ncline{5,1}{5,2}
\ncdiagg{1,2}{3,3}
\ncdiagg{2,2}{3,3}
\ncdiagg{3,2}{3,3}
\ncdiagg{5,2}{3,3}
\ncline{3,3}{3,4}
\ncline{3,4}{3,5}
\end{psmatrix}
\end{document}

• Enough with PSTricks, already! Nah, just kidding... :) Good job! Mar 26 '13 at 19:05

If I understand you correctly, you want the nodes wn to lie on straight lines from the nodes xn to the node ∑. Then you can do

\usetikzlibrary{calc}
[…]
\node[…](w1) at ($(x1)!0.5!(sum)$) {$$w_n$$};
[…]


or

[…]
\path(x1)--node[…](w1){$$w_n$$}(sum);
[…]


I am aware this is an old post, but I'll share what I did in case in becomes useful for others. I liked @m0nhawk's design (with \vdots) and @Alain Matthes' code, so I combined them. I also changed the activation to ReLU, but the code step function is still avilable.

It should be noted that I broke the size "scalability" from @Alain Matthes' code. Instead I use \resizebox to resize the figure.

\documentclass[tikz]{article}
\usepackage{tikz}

\tikzset{basic/.style={draw,fill=none,
\tikzset{input/.style={basic,circle,minimum width=3.5em}}
\tikzset{weights/.style={basic,rectangle,minimum width=2em}}
\tikzset{functions/.style={basic,circle, minimum width=4em}}
(-1em,0em) -- (1em,0em);}
\newcommand{\relu}{\draw[line width=1.5pt] (-1em,0) -- (0,0)
(0,0) -- (0.75em,0.75em);}
\newcommand{\stepfunc}{\draw[line width=1.5pt] (0.65em,0.65em) -- (0,0.65em)
-- (0,-0.65em) -- (-0.65em,-0.65em);}

\begin{document}
\begin{tikzpicture}[scale=1.2]
% Draw input nodes
\foreach \h [count=\hi ] in {$x_2$,$x_1$,$x_0=1$}{%
\node[input] (f\hi) at (0,\hi*1.25cm-1.5 cm) {\h};
}
% Dot dot dot ... x_n
\node[below=0.62cm] (idots) at (f1) {\vdots};
\node[input, below=0.62cm] (last_input) at (idots) {$x_n$};
% Draw summation node
\node[functions] (sum) at (4,0) {\Huge$\sum$};
\node[below=0.69cm] at (sum) {$\sum_{i=0}^n w_ix_i$};
% Draw edges from input nodes to summation node
\foreach \h [count=\hi ] in {$w_2$,$w_1$,$w_0$}{%
\path (f\hi) -- node[weights] (w\hi) {\h} (sum);
\draw[->] (f\hi) -- (w\hi);
\draw[->] (w\hi) -- (sum);
}
% Dot dot dot ... w_n
\node[below=0.05cm] (wdots) at (w1) {\vdots};
\node[weights, below=0.45cm] (last_weight) at (wdots) {$w_n$};
% Add edges for last node and last weight etc
\path[draw,->] (last_input) -- (last_weight);
\path[draw,->] (last_weight) -- (sum);
% Draw node for activation function
\node[functions] (activation) at (7,0) {};
% Place activation function in its node
\begin{scope}[xshift=7cm,scale=1.25]
% flexible selection of activation function
\relu
% \stepfunc
\end{scope}
% Connect sum to relu
\draw[->] (sum) -- (activation);
\draw[->] (activation) -- ++(1,0);
% Labels
\node[above=1cm]  at (f3) {inputs};
\node[above=1cm] at (w3) {weights};
\node[above=1cm] at (activation) {activation function};
\end{tikzpicture}
\end{document}