![每层节点数可变的分层图](https://linux22.com/image/288435/%E6%AF%8F%E5%B1%82%E8%8A%82%E7%82%B9%E6%95%B0%E5%8F%AF%E5%8F%98%E7%9A%84%E5%88%86%E5%B1%82%E5%9B%BE.png)
我创建了一些 TikZ 代码来生成下面的图表(略有简化)。这是我第一次真正尝试 TikZ,到现在为止我花了大约 8 个小时才走到这一步。但我并不吝惜时间,花在学习上的时间是值得的。
它大致基于这是神经网络(多层感知器)的示例。
我希望每一层都有不同(可变)数量的节点,并且希望保持连接。
我目前的想法是拥有一个列表列表,然后{{1..3},{1..5},{1..7},{1..4},{1..3}}
我想我可以使用嵌套索引for-each
。但这有两个问题:我会丢失我的层号,我可以通过使用来解决这个问题count
。其次,更重要的是,我没有看到一个很好的方法来知道下一层有多大(以建立连接)。
\documentclass{article}
\usepackage{mathptmx}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}
\begin{document}
\def\layersep{3.5cm}
\def\topnum{5}
%\font\nullfont=cmr10
\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=\layersep]
\tikzstyle{neuron}=[circle,draw,fill=white!25,minimum size=25pt,inner sep=0pt]
\tikzstyle{bias neuron}=[neuron,dashed]
\foreach \y in {2,...,4}
\foreach \x in {1,...,5}
\path node[neuron] (L_\y_\x) at (\x cm,\y*\layersep) {$\sigma(\cdot)$};
%
\foreach \x in {1,...,5}
\path node[neuron] (L_1_\x) at (\x cm,1*\layersep) {$x_\x$};
\foreach \x in {1,...,5}
\path node[neuron] (L_5_\x) at (\x cm,5*\layersep) {$s_{m}(\cdot)$};
%Add Biases
\foreach \y in {1,...,4}
{
\path node[bias neuron] (B_\y) at (6 cm, 0.55*\layersep+\y*\layersep) {1};
\pgfmathtruncatemacro\nextlayer{\y+1}
\foreach \dest in {1,...,5}
\path (B_\y) edge[dashed] (L_\nextlayer_\dest.south);
}
% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \layer in {1,...,4}
\pgfmathtruncatemacro\nextlayer{\layer+1}
\foreach \source in {1,...,5}
\foreach \dest in {1,...,5}
\path (L_\layer_\source) edge (L_\nextlayer_\dest);
\end{tikzpicture}
\end{document}
答案1
这是我在试用 PGF/TikZ 3 中的新图形语法后得出的结论。我不确定这是否是您想要的。
\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{graphs,graphs.standard,graphdrawing,arrows}
\usegdlibrary{layered}
\begin{document}
\newcommand\sm{$s_{m}(\cdot)$}
\newcommand\sig{$\sigma(\cdot)$}
\begin{tikzpicture}
\tikzset{>=latex',
neuron/.style={circle,draw,fill=white!25,minimum size=25pt,inner sep=0pt},
bias neuron/.style={neuron,dashed}
}
\graph [allow inside edges=false, edges behind nodes] {
// [
layered layout, grow=up, sibling sep=1em, level distance=6em,
typeset=\sig, nodes={neuron}
] { %tail anchor=north, head anchor=south]
subgraph I_n [name=x, n=3, typeset=$x_\tikzgraphnodetext$] ->[complete bipartite]
subgraph I_n [name=B, n=5] ->[complete bipartite]
subgraph I_n [name=C, n=7] ->[complete bipartite]
subgraph I_n [name=D, n=4] ->[complete bipartite]
subgraph I_n [name=E, n=3, typeset=\sm]
},
{[typeset=1, nodes={bias neuron}, edges={dashed}]
Bone [x=8em,y=18em] -> subgraph I_n [name=B, n=5],
Cone [x=8em,y=26.5em]-> subgraph I_n [name=C, n=7],
Done [x=8em,y=36em] -> subgraph I_n [name=D, n=4],
Eone [x=8em,y=43.5em]-> subgraph I_n [name=E, n=3]
}
};
\end{tikzpicture}
\end{document}
显然,这可以通过多种方式改进(X节点按相反顺序重复我节点组、偏置神经元节点的手动放置、与神经元节点重叠的虚线)。
免责声明:我昨天升级了 PGF/TikZ 3,最近才开始了解它的新功能。不过,我确实想展示如何利用新的图形语法来避免编写 for 循环和计算节点位置。