用于分布估计的掩蔽自动编码器 (MADE) 的 TikZ 图像

用于分布估计的掩蔽自动编码器 (MADE) 的 TikZ 图像

我正在尝试重新创建这个形象MADE 网络在 TikZ 中。

制成

这是我目前所拥有的。

tikz 制造

任何关于如何绘制掩码矩阵以及如何将 MADE 网络神经元内的数字合并到drawLayers宏中的建议都将不胜感激。(这些数字表示影响相关神经元的最大输入单元数量。)

\documentclass[tikz]{standalone}

\usetikzlibrary{positioning}

\newcommand\drawLayers[2]{
  % #1 (str): namespace
  % #2 (list[int]): number of nodes in each layer
  \foreach \neurons [count=\lyrIdx] in #2
    \foreach \n in {1,...,\neurons}
      \node[neuron] (#1-\lyrIdx-\n) at (1.5*\lyrIdx, \neurons/2-\n) {};
  }

\newcommand\denselyConnectNodes[2]{
  % #1 (str): namespace
  % #2 (list[int]): number of nodes in each layer
  \foreach \n [count=\lyrIdx, remember=\lyrIdx as \previdx, remember=\n as \prevn] in #2 {
    \foreach \y in {1,...,\n} {
      \ifnum \lyrIdx > 1
        \foreach \x in {1,...,\prevn}
          \draw (#1-\previdx-\x) -- (#1-\lyrIdx-\y);
      \fi
    }
  }
}

\newcommand\connectSomeNodes[2]{
  % #1 (str): namespace
  % #2 (list[list[list[int]]]): for each node in each layer, list all connected nodes in the next layer
  \foreach \layer [count=\lyrIdx, evaluate=\lyrIdx as \nextLyr using int(\lyrIdx+1)] in #2
    \foreach \neuron [count=\nIdx] in \layer
        \foreach \edge in \neuron
          \draw (#1-\lyrIdx-\nIdx) -- (#1-\nextLyr-\edge);
}

\begin{document}
\begin{tikzpicture}[
    shorten >=1pt, shorten <=1pt, ->,
    neuron/.style={circle, draw, minimum size=4ex, thick},
    legend/.style={font=\large\bfseries},
  ]

  % Fully-connected neural net
  \drawLayers{fcnn}{{3, 4, 4, 3}}
  \denselyConnectNodes{fcnn}{{3, 4, 4, 3}}

  \path (fcnn-1-1) -- (fcnn-2-1) node[midway, above=1ex] {$W_1$};
  \path (fcnn-2-1) -- (fcnn-3-1) node[midway, above=1ex] {$W_2$};
  \path (fcnn-3-1) -- (fcnn-4-1) node[midway, above=1ex] {$V$};


  % MADE net
  \begin{scope}[xshift=10cm]
    \drawLayers{made}{{3, 4, 4, 3}}
    \connectSomeNodes{made}{{
          {{}, {1,2,3,4}, {1,3,4}},
          {{2,3}, {1,2,3,4}, {2,3}, {2,3}},
          {{1,3}, {1}, {1}, {1,3}},
        }}
  \end{scope}

  % Input + output labels
  \foreach \label [count=\c] in {{$p(x_1|x_2,x_3)$}, $p(x_2)$, $p(x_3|x_2)$} {
      \node[left=0 of fcnn-1-\c] {$x_\c$};
      \node[right=0 of fcnn-4-\c] {$\hat x_\c$};
      \node[left=0 of made-1-\c] {$x_\c$};
      \node[right=0 of made-4-\c] {\label};
    }

  \node[legend, below=0.5 of fcnn-3-4] {autoencoder};
  \node[legend, below=0.5 of made-2-4] {MADE};
\end{tikzpicture}
\end{document}

答案1

回答我自己的问题,这是完整的图像:

tikz 制造

% TikZ-reproduction of fig. 1 from the paper MADE: Masked Autoencoder for Distribution Estimation (https://arxiv.org/abs/1502.03509).

\documentclass[tikz]{standalone}

\usepackage{xstring}

\usetikzlibrary{calc,positioning}

\newcommand\drawNodes[2]{
  % #1 (str): namespace
  % #2 (list[list[str]]): list of labels to print in the node of each neuron
  \foreach \neurons [count=\lyrIdx] in #2 {
    \StrCount{\neurons}{,}[\arrlength] % uses the xstring package
    \foreach \n [count=\nIdx] in \neurons
      \node[neuron] (#1-\lyrIdx-\nIdx) at (\arrlength/2-\nIdx, 1.5*\lyrIdx) {\n};
  }
}

\newcommand\denselyConnectNodes[2]{
  % #1 (str): namespace
  % #2 (list[int]): number of nodes in each layer
  \foreach \n [count=\lyrIdx, remember=\lyrIdx as \previdx, remember=\n as \prevn] in #2 {
    \foreach \y in {1,...,\n} {
      \ifnum \lyrIdx > 1
        \foreach \x in {1,...,\prevn}
          \draw[->] (#1-\previdx-\x) -- (#1-\lyrIdx-\y);
      \fi
    }
  }
}

\newcommand\connectSomeNodes[2]{
  % #1 (str): namespace
  % #2 (list[list[list[int]]]): for each node in each layer, list all connected nodes in the next layer
  \foreach \layer [count=\lyrIdx, evaluate=\lyrIdx as \nextLyr using int(\lyrIdx+1)] in #2
    \foreach \neuron [count=\nIdx] in \layer
        \foreach \edge in \neuron
          \draw[->] (#1-\lyrIdx-\nIdx) -- (#1-\nextLyr-\edge);
}

\begin{document}
\begin{tikzpicture}[
    shorten >=1pt, shorten <=1pt,
    neuron/.style={circle, draw, minimum size=4ex, thick},
    legend/.style={font=\large\bfseries},
  ]

  % Fully-connected neural net
  \drawNodes{fcnn}{{{,,}, {,,,}, {,,,}, {,,}}}
  \denselyConnectNodes{fcnn}{{3, 4, 4, 3}}

  \path (fcnn-1-1) -- (fcnn-2-1) node[midway, right=1ex] (W1) {$W_1$};
  \path (fcnn-2-1) -- (fcnn-3-1) node[midway, right=1ex] (W2) {$W_2$};
  \path (fcnn-3-1) -- (fcnn-4-1) node[midway, right=1ex] (V) {$V$};


  % MADE net
  \begin{scope}[xshift=93mm]
    \drawNodes{made}{{{3,1,2}, {2,1,2,2}, {1,2,2,1}, {3,1,2}}}
    \connectSomeNodes{made}{{
          {{}, {1,2,3,4}, {1,3,4}},
          {{2,3}, {1,2,3,4}, {2,3}, {2,3}},
          {{1,3}, {1}, {1}, {1,3}},
        }}
  \end{scope}

  % Input + output labels
  \foreach \idx in {1,2,3} {
      \node[below=0 of fcnn-1-\idx] {$x_\idx$};
      \node[above=0 of fcnn-4-\idx] {$\hat x_\idx$};
      \node[below=0 of made-1-\idx] {$x_\idx$};
    }

  % MADE output labels
  \node[xshift=2.5ex, above=0 of made-4-1] {$p(x_3|x_2)$};
  \node[above=0 of made-4-2] {$p(x_2)$};
  \node[xshift=-4ex, above=0 of made-4-3] {$p(x_1|x_2,x_3)$};

  % Bottom legend
  \node[legend, below=of fcnn-1-2] (encoder) {autoencoder};
  \node[legend, below=of made-1-2] (made) {MADE};
  \node[legend, right=27mm of encoder] (masks) {masks};
  \node[legend, yshift=-1pt] (masks) at ($(encoder)!0.55!(masks)$) {\texttimes};
  \node[legend, yshift=-1pt] (masks) at ($(masks)!0.65!(made)$) {$\longrightarrow$};

  % Mask matrices
  \begin{scope}[shift={(35mm,49mm)}, scale=0.4]
    \draw (0,0) grid (4,3);
    \node at (-1.8,1.5) {$M_V =$};
    \fill[black] (0,1) rectangle ++(4,1);
    \fill[black] (1,0) rectangle ++(2,1);

    \begin{scope}[yshift=-5cm]
      \draw (0,0) grid (4,4);
      \node at (-1.8,2) {$M_{W_2} =$};
      \fill[black] (0,0) rectangle ++(1,1);
      \fill[black] (0,3) rectangle ++(1,1);
      \fill[black] (2,0) rectangle ++(2,1);
      \fill[black] (2,3) rectangle ++(2,1);
    \end{scope}

    \begin{scope}[yshift=-10cm]
      \draw (0,0) grid (3,4);
      \node at (-1.8,2) {$M_{W_1} =$};
      \fill[black] (0,0) rectangle ++(1,4);
      \fill[black] (2,2) rectangle ++(1,1);
    \end{scope}

  \end{scope}

\end{tikzpicture}
\end{document}

答案2

我改编了代码金章洙的平面隔断。通过创建两个命令,其中一个命令称为mask从下到上逐行创建掩码。

截屏

\documentclass[]{article}
\usepackage{tikz}
\newcounter{x}
\newcounter{y}
\newcommand\square[3]{
  \fill[fill=#1, draw=black] (#2,#3) rectangle(#2+1,#3+1);
}
\newcommand\mask[1]{
 \setcounter{y}{-1}
  \foreach \a in {#1} {
        \addtocounter{y}{1}
        \setcounter{x}{-1}
        \foreach \b in \a {
            \addtocounter{x}{1}
            \ifnum \b>0
            \square{black}{\value{x}}{\value{y}}
             \else   
             \square{white}{\value{x}}{\value{y}}
             \fi
    }
  }
}
\begin{document}
\tikzset{x={(.5,0)},y={(0,.5)}}
    \begin{tikzpicture}
    \begin{scope}[local bounding box=figW1]
    \mask{{1,0,0},{1,0,0},{1,0,1},{1,0,0}}
    \node[anchor=west,font=\bf] at (figW1.east){$=M^{W^1}$};
    \end{scope}

\begin{scope}[yshift=3cm,local bounding box=figW2]
\mask{{1,0,1,1},{0,0,0,0},{0,0,0,0},{1,0,1,1}}
\node[anchor=west,font=\bf] at (figW2.east){$=M^{W^2}$};
\end{scope}

\begin{scope}[yshift=6cm,local bounding box=figV]
\mask{{0,1,1,0},{1,1,1,1},{0,0,0,0}}
\node[anchor=west,font=\bf] at (figV.east){$=M^{V}$};
\end{scope}

    \end{tikzpicture}
    

\end{document}

相关内容