PlotNeuralNet的Latex解析与定制

本文参考了demonlord1997糯米鸡呀呀呀呀等人的博文,在此表示感谢!

基本构件

构件类型

基本构件类型和顺序是:

  1. \pic, 表示添加层
  2. 指定层的位置: \pic[shift ={(x, y, z)}] at (x, y, z), 表示:第1个坐标是指相对于第2个坐标的偏移量
  3. 添加具体类型的层,其中,**Box={…}**表示单个层, **RightBandedBox={…}**表示多个层,**Ball={…}**表示层间相加符号\bigoplus
  4. 添加层间连线,\draw [connection] (层的位置,如vonv1-east,或坐标(x,y,z)) – node { 箭头形状,如\midarrow} (cr2-west)
  5. 自定义层间连线路径,**\path (p4-east) – (cr5-west) coordinate[pos=0.25] (between4_5) **

层的类型

网络中层包括:layer, block 和 unit。

在绘制网络层时,要在指定层的类型

其中,layer是单个网络层,对应的配置文件是layers文件夹下的Box.sty,在绘图时,所用的命令是:

1
2
3
4
5
6
7
8
9
10
{Box                ={
name =...,
caption = ...,
xlabel = ...,
ylabel = ...,
fill = ...,
opacity = ...,
height = ...,width= ...,depth= ...,
}
}

其中,以下语句是绘图时常用的,其中,\subimport{…/layers/}{init},表示layer文件夹下的init文件,因此,这一句的具体写法要结合当前tex文件所在位置。**\def\ReLUColor{rgb:red,1;black,0.3}**是自定义的ReLU层的颜色,可以根据需要自己调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
\documentclass[border=15pt, multi, tikz]{standalone}
\usepackage{import}
\subimport{../layers/}{init}
\usetikzlibrary{positioning}
\usetikzlibrary{3d} %for including external image

\def\ReLUColor{rgb:red,1;black,0.3}

\begin{document}
\begin{tikzpicture}
\tikzstyle{connection}=[ultra thick,every node/.style={sloped,allow upside down},draw=\edgecolor,opacity=0.7]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 这部分添加绘图命令
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{tikzpicture}
\end{document}

可以看到,图中标签“深度”的位置没有居中,需要自行设置,具体设置方法见下文自定义配置。

单个layer

单个layer要在shift后指定Box,可以通过fill指定填充的颜色,height=..,width=...,depth=...指定图片的高、宽和深。

  • [shift ={(0,0,0)}] at (0,0,0)表示第1个坐标是指相对于第2个坐标的偏移量。

  • name =score16,% 表示该层的名称

  • caption= 标题, %表示该层的标题

  • xlabel ={{ "宽度: 显示的是s\_filer的值", }}, 无论是中文还是英文,只能显示第1个位置的字符;同时,要在s后加转义符\:s\_filer。xlabel的值是数组形式,即(x,y,z,…),在Box中只显示第1个值,即x。如果是在"RightBandedBox",则可以显示多个值。

  • ylabel ={{高度 }}, 加不加引号,似无影响;这里可以显示多个字符;ylabel在神经网络架构中一般不显示

  • zlabel = 深度, : 显示的是n_filer的值, 加不加{},似无影响;这里可以显示多个字符

  • opacity表示透明度

“”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
\documentclass[border=15pt, multi, tikz]{standalone}
\usepackage[UTF8]{ctex} %显示中文
\usepackage{import}
\subimport{../layers/}{init}
\usetikzlibrary{positioning}
\usetikzlibrary{3d} %for including external image

\def\ReLUColor{rgb:red,1;black,0.3}

\begin{document}
\begin{tikzpicture}
\tikzstyle{connection}=[ultra thick,every node/.style={sloped,allow upside down},draw=\edgecolor,opacity=0.7]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Draw Layer Blocks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% one layer for a conv or BN or ReLU layer, etc
\pic[shift ={(5,0,0)}] at (0,0,0) % 第1个坐标是指相对于第2个坐标的偏移量
{
Box ={
name =conv,% 表示该层的名称
caption= 标题, %表示该层的标题
xlabel ={{ "宽度: 显示的是s\_filer的值", }}, % 无论是中文还是英文,只能显示第1个位置的字符;同时,要在s后加转义符\
ylabel ={{高度 }}, % 加不加引号,似无影响;这里可以显示多个字符;ylabel在神经网络架构中一般不显示
zlabel = 深度: 显示的是n\_filer的值, % 加不加{},似无影响;这里可以显示多个字符
fill =\ReLUColor,
opacity = 0.2,
height=64,width=30,depth=45
}
};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{tikzpicture}
\end{document}

效果如图所示:

layer

layer组合

多个layer的组合,有2种方法实现。

  1. 在shift后使用RightBandedBox,此外,layer的名称和层数,是通过xlabelwidth进行设定。例如:xlabel={{"32","64", "128"}}, ···,width={2,2,4}。xlabel和width的值是数组形式,即(x,y,z,…),数组内的数值个数决定了有多少个层。
  2. 通过多个Box,使多个单层layer成为layers的组合。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
\pic[shift={(5,0,0)}] at (0,0,0) 
{RightBandedBox={
name=cr1,
caption=使用RightBandedBox,
xlabel={{"1","2", "3"}},
% zlabel=layer_blocks,
fill=\ConvColor,
bandfill=\ConvReluColor,%
opacity = 0.2,
height=40,width={1,1,1},depth=40}
};

% conv+bn+relu
\pic[shift ={ (10,0,0)}] at (0,0,0)
{
Box ={
name =conv1,%
xlabel ={{1}},
fill =\ConvColor,%
height =40,width=1,depth=40}
};
\pic[shift ={ (0,0,0)}] at (conv1-east)
{
Box ={
name =bn1,%
caption =layer叠加,
xlabel ={{2}},
fill =\BnColor,%
opacity =0.5,
height =40,width=1,depth=40}
};
\pic[shift ={(0,0,0)}] at (bn1-east)
{
Box ={
name =relu1,%
xlabel ={{3}},
fill =\ReLUColor,
opacity =0.5,
height =40,width=1,depth=40,
}
};

效果如图所示:

layers

残差结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
\documentclass[border=15pt, multi, tikz]{standalone}
\usepackage{import}
\subimport{../../layers/}{init}
\usetikzlibrary{positioning}
\usetikzlibrary{3d} %for including external image

\def\ConvColor{rgb:yellow,5;red,2.5;white,5}
\def\ConvReluColor{rgb:yellow,5;red,5;white,5}
\def\ConvBnReluColor{rgb:yellow,5;red,5;white,2.5}
\def\PoolColor{rgb:red,1;black,0.3}
\def\DcnvColor{rgb:blue,5;green,2.5;white,5}
\def\SoftmaxColor{rgb:magenta,5;black,7}
\def\SumColor{rgb:blue,5;green,15}

\begin{document}
\begin{tikzpicture}
\tikzstyle{connection}=[ultra thick,every node/.style={sloped,allow upside down},draw=\edgecolor,opacity=0.7]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Draw Layer Blocks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% conv1_1,conv1_2,%pool1
\pic[shift={(0,0,0)}] at (0,0,0) {RightBandedBox={name=cr1,caption=conv1,%
xlabel={{"64","\ 64"}},zlabel=I,fill=\ConvColor,bandfill=\ConvBnReluColor,%
height=40,width={2,2},depth=40}};
\pic[shift={(0,0,0)}] at (cr1-east) {Box={name=p1,%
fill=\PoolColor,opacity=0.5,height=35,width=1,depth=35}};

\pic[shift={(3,0,0)}] at (p1-east) {Ball={name=elt1,%
fill=\SumColor,opacity=0.6,%
radius=2.5,logo=$+$}};


%% score16
\pic[shift={(0,-4,0)}] at (elt1-west) {Box={name=score16,%
fill=\PoolColor,%
opacity=0,height=0.01,width=0.01,depth=0.01}};
%% draw connections
%\draw [connection] (p1-east) -- node {\midarrow} (p1-east -| elt1-west) -- node {\midarrow} (elt1-west);
\draw [connection] (p1-east) -- node {\midarrow} (elt1-west);
\path (p1-east) -- (elt1-south) coordinate[pos=0.25] (between4_5) ;
\draw [connection] (between4_5) -- node {\midarrow} (score16-west-|between4_5) -- node {\midarrow} (score16-west);
\draw [connection] (score16-east) -- node {\midarrow} (score16-east -| elt1-south) -- node {\midarrow} (elt1-south);
\draw [connection] (p1-east) -- node {\midarrow} (elt1-west);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{tikzpicture}
\end{document}

残差结构

PlotNeuralNet的个性化定制

PlotNeuralNet默认将图形的深度,也就是n_fliter的数据标注在角上,如下图所示,没有居中,因此,需要对它进行修改

自定义方法:修改layers文件夹下的Box.sty和RightBandedBox.sty文件。

zlabel

Box.sty

将depthlabel设置中的pos=0改为pos=0.5,将captionlabel中的文本宽度由text width=15改为text width=40,这是因为默认宽度有些小,长文本显示不全。

\coordinate (a1) at (0 , \y/2 , \z/2);
\coordinate (b1) at (0 ,-\y/2 , \z/2);
\tikzstyle{depthlabel}=[pos=0,text width=14*\z,text centered,sloped]
\tikzstyle{depthlabel}=[pos=0.5,text width=14*\z,text centered,sloped]

\tikzstyle{captionlabel}=[text width=15*\LastEastx/\scale,text centered]
\tikzstyle{captionlabel}=[text width=40*\LastEastx/\scale,text centered]

\path (\LastEastx/2,-\y/2,+\z/2) + (0,-25pt) coordinate (cap)
edge ["\textcolor{black}{ \bf \caption}"',captionlabel](cap) ; %Block caption/pic object label

RightBandedBox.sty

RightBandedBox.sty的修改与Box.sty的修改类似。pos=0改为pos=0.5,text width=15改为text width=40

\coordinate (a1) at (0 , \y/2 , \z/2);
\coordinate (b1) at (0 ,-\y/2 , \z/2);
\tikzstyle{depthlabel}=[pos=0,text width=14*\z,text centered,sloped]
\tikzstyle{depthlabel}=[pos=0.5,text width=14*\z,text centered,sloped]

\path (c) edge ["\small\zlabels"',depthlabel](f); %depth label'\path (b1) edge ["\ylabel",midway] (a1); %height label’

\tikzstyle{captionlabel}=[text width=15*\LastEastx/\scale,text centered]
`\tikzstyle{captionlabel}=[text width=40*\LastEastx/\scale,text centered]’

\path (\LastEastx/2,-\y/2,+\z/2) + (0,-25pt) coordinate (cap)'edge ["\textcolor{black}{ \bf \caption}"’,captionlabel] (cap); %Block caption/pic object label’

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2017-2024 善良的右行
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信