如何绘制长短期记忆图?

如何绘制长短期记忆图?

我是 TikZ 的新手,说实话,学习它有点困难。我已经能够绘制一些简单的形状,但我想绘制下面的图像,到目前为止,我的所有尝试都很糟糕,令人沮丧。我很难将文本变成形状,调整对象之间的相对位置,而且当我尝试添加图片的新部分时,东西似乎不断移动。有人能帮我画出下面的图片吗?
我发现以下内容非常有用(按升序排列):

  1. 如何开始?TikZ 的哪些功能有用?先画什么?

  2. 代码骨架

  3. TikZ 中的完整图像

在此处输入图片描述

答案1

开始吧:

首先,定义一些可用于不同图表元素的有用样式:中心单元(ct)、其他功能元素(ft)、过滤器(filter),...

ct/.style={circle, draw, inner sep=5pt, ultra thick, minimum width=10mm},
ft/.style={circle, draw, minimum width=8mm, inner sep=1pt},
filter/.style={circle, draw, minimum width=7mm, inner sep=1pt, 
      path picture={%
           \draw[thick, rounded corners] 
              (path picture bounding box.center)--++(65:2mm)--++(0:1mm);
           \draw[thick, rounded corners] 
              (path picture bounding box.center)--++(245:2mm)--++(180:1mm);
      }},
...

其次,将不同的元素放置在您想要的位置。使用positioning库,您可以将节点相对于其他节点放置。同时,您可以使用它label来标记所需的元素。

\node[ct, label={[mylabel]Cell}] (ct) {$c_t$};
\node[filter, right=of ct] (int1) {};
\node[prod, right=of int1] (x1) {$\times$}; 
...

第三,绘制节点之间的连接。在这种情况下,foreach循环可以节省一些输入。

\foreach \i/\j in {int2/x2, x2/ct, ct/int1, int1/x1,
            x1/ht, it/x2, ct/it, ct/ot, ot/x1, ft/x3}
    \draw[->] (\i)--(\j);

一些连接是单独绘制的。

第四,fit绘制一个节点来包含整个图表。

\node[fit=(int2) (it) (ot) (ft), draw, inner sep=0pt] (fit) {};

第五,完成外部箭头的绘制。

\draw[<-] (fit.west|-int2) coordinate (aux)--++(180:7mm) node[left]{$x_t$};
\draw[<-] ([yshift=1mm]aux)--++(135:7mm);
\draw[<-] ([yshift=-1mm]aux)--++(-135:7mm);
...

就这样。完整代码如下:

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, fit, arrows.meta}

\begin{document}
\begin{tikzpicture}[
    prod/.style={circle, draw, inner sep=0pt},
    ct/.style={circle, draw, inner sep=5pt, ultra thick, minimum width=10mm},
    ft/.style={circle, draw, minimum width=8mm, inner sep=1pt},
    filter/.style={circle, draw, minimum width=7mm, inner sep=1pt, path picture={\draw[thick, rounded corners] (path picture bounding box.center)--++(65:2mm)--++(0:1mm);
    \draw[thick, rounded corners] (path picture bounding box.center)--++(245:2mm)--++(180:1mm);}},
    mylabel/.style={font=\scriptsize\sffamily},
    >=LaTeX
    ]

\node[ct, label={[mylabel]Cell}] (ct) {$c_t$};
\node[filter, right=of ct] (int1) {};
\node[prod, right=of int1] (x1) {$\times$}; 
\node[right=of x1] (ht) {$h_t$};
\node[prod, left=of ct] (x2) {$\times$}; 
\node[filter, left=of x2] (int2) {};
\node[prod, below=5mm of ct] (x3) {$\times$}; 
\node[ft, below=5mm of x3, label={[mylabel]right:Forget Gate}] (ft) {$f_t$};
\node[ft, above=of x2, label={[mylabel]left:Input Gate}] (it) {$i_t$};
\node[ft, above=of x1, label={[mylabel]left:Output Gate}] (ot) {$o_t$};

\foreach \i/\j in {int2/x2, x2/ct, ct/int1, int1/x1,
            x1/ht, it/x2, ct/it, ct/ot, ot/x1, ft/x3}
    \draw[->] (\i)--(\j);

\draw[->] (ct) to[bend right=45] (ft);

\draw[->] (ct) to[bend right=30] (x3);
\draw[->] (x3) to[bend right=30] (ct);

\node[fit=(int2) (it) (ot) (ft), draw, inner sep=0pt] (fit) {};

\draw[<-] (fit.west|-int2) coordinate (aux)--++(180:7mm) node[left]{$x_t$};
\draw[<-] ([yshift=1mm]aux)--++(135:7mm);
\draw[<-] ([yshift=-1mm]aux)--++(-135:7mm);

\draw[<-] (fit.north-|it) coordinate (aux)--++(90:7mm) node[above]{$x_t$};
\draw[<-] ([xshift=1mm]aux)--++(45:7mm);
\draw[<-] ([xshift=-1mm]aux)--++(135:7mm);

\draw[<-] (fit.north-|ot) coordinate (aux)--++(90:7mm) node[above]{$x_t$};
\draw[<-] ([xshift=1mm]aux)--++(45:7mm);
\draw[<-] ([xshift=-1mm]aux)--++(135:7mm);

\draw[<-] (fit.south-|ft) coordinate (aux)--++(-90:7mm) node[below]{$x_t$};
\draw[<-] ([xshift=1mm]aux)--++(-45:7mm);
\draw[<-] ([xshift=-1mm]aux)--++(-135:7mm);
\end{tikzpicture}
\end{document}

结果如下:

在此处输入图片描述

相关内容