如何从使用 TikZ 绘制的神经网络中的构建路径循环中排除某些元素

如何从使用 TikZ 绘制的神经网络中的构建路径循环中排除某些元素

我从中学到了一种制作神经网络(nn)的好方法这个答案

当我为我的个人 nn 编辑它时,如下所示:

\documentclass[article]{standalone}
\usepackage{tikz}
\usepackage{etoolbox} % for \ifnumcomp
\usepackage{listofitems} % for \readlist to create arrays    
\tikzset{>=latex} % for LaTeX arrow head
\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}
\definecolor{iceberg}{rgb}{0.44, 0.65, 0.82}
\definecolor{firebrick}{rgb}{0.7, 0.13, 0.13}
\definecolor{outerspace}{rgb}{0.25, 0.29, 0.3}
\definecolor{lemonchiffon}{rgb}{1.0, 0.98, 0.8}
\definecolor{flavescent}{rgb}{0.97, 0.91, 0.56}
\definecolor{floralwhite}{rgb}{1.0, 0.98, 0.94}
\definecolor{airforceblue}{rgb}{0.36, 0.54, 0.66}
\definecolor{electriclime}{rgb}{0.8, 1.0, 0.0}
\tikzstyle{node}=[thick,circle,draw=myblue,minimum size=22,inner sep=0.5,outer sep=0.6]
\tikzstyle{node in}=[node,myblue!30!black,draw=myblue!30!black,fill=floralwhite]
\tikzstyle{node hidden}=[node,blue!20!black,draw=myblue!5!black,fill=airforceblue!15]
\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=firebrick!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
\begin{tikzpicture}[x=2.2cm,y=1.4cm]
\message{^^JNeural network, shifted}
\readlist\Nnod{3,5,5,5,5,5,1} % array of number of nodes per layer
\readlist\Nstr{n,m,m,m,k} % array of string number of nodes per layer
\readlist\Cstr{\strut x,a^{(\prev)},a^{(\prev)},a^{(\prev)},y} % array of coefficient symbol per layer
\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]_{\index}$};
    % CONNECTIONS
    \ifnum\lay>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=0.8,align=center,myblue!50!black] at (N1-1.90) {Input\\[-0.2em]Layers};
    \node[above=0,align=center,airforceblue] at (N4-1.90) {Hidden Layers};
    \node[above=60,align=center,myred!60!black] at (N\Nnodlen-1.90) {Output\\[-0.2em]Layer};
    \end{tikzpicture}
\end{document}

如您所见,有三个垂直点($\vdots$),它们表示“输入层”、“隐藏层”和“输出层”之间的节点迭代。当我尝试仅删除(或取消)$\vdots$“输出层”时,所有点$\vdots$都消失了。所以我必须保留$\vdots$如下内容:

在此处输入图片描述

我的问题是:我怎样才能只保留$\vdots$输入层和隐藏层,而不保留输出层?或者如何设置任何单个层应$\vdots$相应地排除迭代符号?

提前谢谢您,我希望附图能帮助我解释我的问题。

答案1

概括\tikzCenterNodes可以重新创建\tikzMatrixNodes此图,而无需...代码中发生的一切。

此外,该graphs库还帮助绘制所有线条。

有一种方法parse可以循环遍历所有隐藏层,但我想不出一个干净的方法。在这里,我将手动添加节点,但使用循环\foreach跳过\vdots节点。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{ext.positioning-plus,graphs}
\tikzset{
  node matrix/.style={row sep=y_node_dist, column sep=x_node_dist,
    every outer matrix/.append style={/pgf/inner sep=+0pt, /pgf/outer sep=+0pt, draw=none, fill=none, shape=rectangle}},
  node matrix/node/.style={node contents=,anchor=center,
    name/.expanded={\tikzmatrixname_\ifnum\pgfmatrixcurrentrow=1 \the\pgfmatrixcurrentcolumn\else\the\pgfmatrixcurrentrow\fi},
    {nm \ifnum\pgfmatrixcurrentrow=1 \the\pgfmatrixcurrentcolumn\else\the\pgfmatrixcurrentrow\fi}/.try},
  node matrix/place 1st node/.code args={#1,#2}{\node[node matrix/node,#1];},
  node matrix/place other nodes/.style args={#1,#2}{/tikz/node matrix/place oth node/.list={#2}},
  vertical   node matrix/.style={/tikz/node matrix/place oth node/.code={\pgfmatrixendrow  \node[node matrix/node,##1];}},
  horizontal node matrix/.style={/tikz/node matrix/place oth node/.code={\pgfmatrixnextcell\node[node matrix/node,##1];}}}
\newcommand*\tikzMatrixNodes[2][1]{%
  \matrix[every node matrix/.try,node matrix,#1]{
    \tikzset{node matrix/place 1st node={#2},node matrix/place other nodes={#2}}\\};}
\begin{document}
\begin{tikzpicture}[
  node distance=5mm and 10mm,
  layers/.style={circle, thick, draw, minimum size=+5mm},
  input/.style ={layers, fill=yellow!30},
  hidden/.style={layers, fill=blue!30},
  output/.style={layers, fill=red!30},
  every node matrix/.style={vertical node matrix},
  second to last/.style={
    nm #1/.style={node contents=\vdots, text height=2ex, fill=none, draw=none, minimum size=+0pt,inner sep=+0pt, shape=rectangle},
    row #1/.append style={row sep=.5*y_node_dist}, row \inteval{#1-1}/.append style={row sep=.5*y_node_dist}},
]

\tikzMatrixNodes[name=hidden0, nodes=input, second to last=3]{,,,}
\foreach \hidden[count=\lastHidden from 0] in {1,...,5}{% chains?
  \tikzMatrixNodes[
    right=of hidden\lastHidden, name=hidden\hidden,
    nodes=hidden, second to last=5]{,,,,,}}
\node[right=of hidden5, output](output){};

\path[thick, blue] graph[use existing nodes]{
  {\foreach \x in {1,2,4}{hidden0_\x}}
    -- [complete bipartite] {\foreach \x in {1,...,4,6}{hidden1_\x}}
    -- [complete bipartite] {\foreach \x in {1,...,4,6}{hidden2_\x}}
    -- [complete bipartite] {\foreach \x in {1,...,4,6}{hidden3_\x}}
    -- [complete bipartite] {\foreach \x in {1,...,4,6}{hidden4_\x}}
    -- [complete bipartite] {\foreach \x in {1,...,4,6}{hidden5_\x}}
    -- {output};
};

\path[nodes={align=center}]
  (hidden3_1.north)     node[above,blue!70] (hl) {Hidden Layers} % could've been a label
  (hidden0_1|-hl.south) node[above,blue]         {Input\\Layers}
  (output|-hl.south)    node[above,red]          {Output\\Layers};
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

我还没有尝试去理解代码——它一点也不简单。我只是注意到它使用了\ifnum\lay ... \fi——所以你可以这样做:

\documentclass[tikz, border=1cm]{standalone}
\usepackage{etoolbox} % for \ifnumcomp
\usepackage{listofitems} % for \readlist to create arrays    
\tikzset{>=latex} % for LaTeX arrow head
\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}
\definecolor{iceberg}{rgb}{0.44, 0.65, 0.82}
\definecolor{firebrick}{rgb}{0.7, 0.13, 0.13}
\definecolor{outerspace}{rgb}{0.25, 0.29, 0.3}
\definecolor{lemonchiffon}{rgb}{1.0, 0.98, 0.8}
\definecolor{flavescent}{rgb}{0.97, 0.91, 0.56}
\definecolor{floralwhite}{rgb}{1.0, 0.98, 0.94}
\definecolor{airforceblue}{rgb}{0.36, 0.54, 0.66}
\definecolor{electriclime}{rgb}{0.8, 1.0, 0.0}
\tikzstyle{node}=[thick,circle,draw=myblue,minimum size=22,inner sep=0.5,outer sep=0.6]
\tikzstyle{node in}=[node,myblue!30!black,draw=myblue!30!black,fill=floralwhite]
\tikzstyle{node hidden}=[node,blue!20!black,draw=myblue!5!black,fill=airforceblue!15]
\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=firebrick!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
\begin{tikzpicture}[x=2.2cm,y=1.4cm]
\message{^^JNeural network, shifted}
\readlist\Nnod{3,5,5,5,5,5,1} % array of number of nodes per layer
\readlist\Nstr{n,m,m,m,k} % array of string number of nodes per layer
\readlist\Cstr{\strut x,a^{(\prev)},a^{(\prev)},a^{(\prev)},y} % array of coefficient symbol per layer
\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]_{\index}$};
    % CONNECTIONS
    \ifnum\lay>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
    }
      \ifnum\lay<7 \path (N\lay-\N) --++ (0,1+\yshift) node[midway,scale=1.5] {$\vdots$}; \fi
    }
    % LABELS
    \node[above=0.8,align=center,myblue!50!black] at (N1-1.90) {Input\\[-0.2em]Layers};
    \node[above=0,align=center,airforceblue] at (N4-1.90) {Hidden Layers};
    \node[above=60,align=center,myred!60!black] at (N\Nnodlen-1.90) {Output\\[-0.2em]Layer};
    \end{tikzpicture}
\end{document}

神经网络

相关内容