3

I have the following TikZ code, which produces a Neural Network figure. However, I would like to have two sets of different output layers. The first one running from g_{1} to g_{J}, and the other running from s_{1} to s_{T}, both separated by three vertical dots. Could you suggest some modifications to my program? Thank you very much for your time.

Desired output

enter image description here


Current result

\documentclass[border=3pt,tikz]{standalone}
\usepackage{amsmath} % for aligned
%\usepackage{amssymb} % for \mathbb
\usepackage{tikz}
%\usepackage{etoolbox} % for \ifthen
\usepackage{listofitems} % for \readlist to create arrays
\usetikzlibrary{arrows.meta} % for arrow size
\usepackage[outline]{contour} % glow around text
\contourlength{1.4pt}

\tikzset{>=latex} % for LaTeX arrow head \usepackage{xcolor} \colorlet{myred}{red!80!black} \colorlet{myblue}{blue!80!black} \colorlet{mygreen}{green!60!black} \colorlet{myorange}{orange!70!red!60!black} \colorlet{mydarkred}{red!30!black} \colorlet{mydarkblue}{blue!40!black} \colorlet{mydarkgreen}{green!30!black} \tikzstyle{node}=[thick,circle,draw=myblue,minimum size=22,inner sep=0.5,outer sep=0.6] \tikzstyle{node in}=[node,green!20!black,draw=mygreen!30!black,fill=mygreen!25] \tikzstyle{node hidden}=[node,blue!20!black,draw=myblue!30!black,fill=myblue!20] \tikzstyle{node convol}=[node,orange!20!black,draw=myorange!30!black,fill=myorange!20] \tikzstyle{node out}=[node,red!20!black,draw=myred!30!black,fill=myred!20] \tikzstyle{connect}=[thick,mydarkblue] %,line cap=round \tikzstyle{connect arrow}=[-{Latex[length=4,width=3.5]},thick,mydarkblue,shorten <=0.5,shorten >=1] \tikzset{ % node styles, numbered for easy mapping with \nstyle node 1/.style={node in}, node 2/.style={node hidden}, node 3/.style={node out}, } \def\nstyle{int(\lay<\Nnodlen?min(2,\lay):3)} % map layer number onto 1, 2, or 3

\begin{document}

% NEURAL NETWORK with coefficients, shifted \begin{tikzpicture}[x=2.2cm,y=1.4cm] \message{^^JNeural network, shifted} \readlist\Nnod{4,5,3} % array of number of nodes per layer \readlist\Nstr{q,m,J} % array of string number of nodes per layer %\readlist\Cstr{\strut Z_{\index},w_{\index}^{(\prev)},g_{n,\index}^{}} \readlist\Cstr{\strut \boldsymbol{z }{\index},w{\index}^{(\prev)},\boldsymbol{g}_{\index}^{}} \def\yshift{0.5} % shift last node for dots

\message{^^J Layer} \foreachitem \N \in \Nnod{ % loop over layers \def\lay{\Ncnt} % alias of index of current layer \pgfmathsetmacro\prev{int(\Ncnt-1)} % number of previous layer \message{\lay,} \foreach \i [evaluate={\c=int(\i==\N); \y=\N/2-\i-\c*\yshift; \index=(\i<\N?int(\i):"\Nstr[\lay]"); \x=\lay; \n=\nstyle;}] in {1,...,\N}{ % loop over nodes % NODES \node[node \n] (N\lay-\i) at (\x,\y) {$\Cstr[\lay]$};

  % CONNECTIONS
  \ifnum\lay&gt;1 % connect to previous layer
    \foreach \j in {1,...,\Nnod[\prev]}{ % loop over nodes in previous layer
      \draw[connect,white,line width=1.2] (N\prev-\j) -- (N\lay-\i);
      \draw[connect] (N\prev-\j) -- (N\lay-\i);
      %\draw[connect] (N\prev-\j.0) -- (N\lay-\i.180); % connect to left
    }
  \fi % else: nothing to connect first layer

}
\path (N\lay-\N) --++ (0,1+\yshift) node[midway,scale=1.5] {$\vdots$};

} % LABELS \node[above=5,align=center,mygreen!60!black] at (N1-1.90) {input\[-0.2em]layer}; \node[above=1,align=center,myblue!60!black] at (N2-1.90) {hidden layer}; \node[above=10,align=center,myred!60!black] at (N\Nnodlen-1.90) {output\[-0.2em]layer}; \end{tikzpicture} \end{document}

enter image description here


1 Answers1

2

This example is made from scratch, so you'll probably want to change colors, line width, etc. I made a couple of styles just for this. I'm using the TikZ calc library for placing the \vdots (easier this way). The rest is just repeating each element with a \foreach loop

The code:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{calc} % for placing the \vdots

\tikzset {% styles my nodes/.style={circle,inner sep=0,minimum size=8mm}, input/.style={my nodes,draw=green!50!black,fill=green!20,text=green!50!black}, hidden/.style={my nodes,draw=violet,fill=violet!20,text=violet}, output/.style={my nodes,draw=red!60!black,fill=red!20,text=red!60!black}, my text/.style={text=#1,text width=1cm,align=center} }

\begin{document} \begin{tikzpicture} % grid %\draw[gray!30] (0,1) grid[step=0.5] (5,-9.5); % nodes, input layer \foreach\i in {1,2,3} \node[input] (z\i) at (0,-1.5\i) {$z_\i$}; \node[input] (z4) at (0,-7) {$z_q$}; % nodes, hideen layer \foreach\i in {1,2,3,4} \node[hidden] (w\i) at (2.5,0.75-1.5\i) {$w_\i^{(1)}$}; \node[hidden] (w5) at (2.5,-7.75) {$w_m^{(1)}$}; % nodes, output layer \foreach\i in {1,2} { \node[output] (g\i) at (5,2-1.5\i) {$g_\i$}; \node[output] (s\i) at (5,-4-1.5\i) {$s_\i$}; } \node[output] (g3) at (5,-3) {$g_J$}; \node[output] (s3) at (5,-9) {$s_T$}; % lines \foreach\i in {1,2,3,4,5} \foreach\j in {1,2,3,4} { \draw[violet,thick] (w\i) -- (z\j); \ifnum\j<4 \draw[violet,thick] (w\i) -- (g\j); \draw[violet,thick] (w\i) -- (s\j); \fi } % dots \foreach\i/\j in {z3/z4,w4/w5,g2/g3,g3/s1,s2/s3} \node at ($(\i)!0.5!(\j)$) {\strut$\vdots$}; % labels \node[my text=green!70!black] at (0,-0.5) {input layer}; \node[my text=violet!70!black] at (2.5,0.25) {hidden layer}; \node[my text=red!70!black] at (5,1.5) {output layer}; \end{tikzpicture} \end{document}

And the output:

enter image description here

Juan Castaño
  • 28,426