你好,我是一個絕對的初學者。
我使用了一些用於繪製神經網路的 tikz 模板並嘗試對其進行修改,以便我可以自動更改層數,但它會產生奇怪的錯誤。
我正在使用這些軟體包,不知道這是否重要
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[czech]{babel}
\usepackage[margin=2cm, a4paper]{geometry}
\usepackage[T1]{fontenc}
\usepackage{fontawesome}
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage{array}
\usepackage[protrusion,expansion]{microtype}
\usepackage{tikz}
\usepackage[nomessages]{fp}
我在單獨的 .sty 檔案中提出了以下巨集:
\newcommand{\mln}[3]{
\def\layersep{#1}
\def\inpneuroncount{#2}
\def\hidneuroncount{#3}
\FPeval{result}{clip((\hidneuroncount-\inpneuroncount)/2)}
\def\nodeoffset{yshift=\result cm}
\nodeoffset
\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=\layersep]
\tikzstyle{every pin edge}=[<-,shorten <=3pt]
\tikzstyle{neuron}=[circle,fill=black!25,minimum size=15pt,inner sep=0pt]
\tikzstyle{input neuron}=[neuron, fill=green!50];
\tikzstyle{output neuron}=[neuron, fill=red!50];
\tikzstyle{hidden neuron}=[neuron, fill=blue!50];
\tikzstyle{annot} = [text width=4em, text centered]
% Draw the input layer nodes
\foreach \name / \y in {1,...,\inpneuroncount}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
\node[input neuron, pin=left:Input \#\y] (I-\name) at (0,-\y) {};
% Draw the hidden layer nodes
\foreach \name / \y in {1,...,\hidneuroncount}
\path[\nodeoffset]
node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};
% Draw the output layer node
\node[output neuron,pin={[pin edge={->}]right:Output}, right of=H-1] (O) {};
% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,\inpneuroncount}
\foreach \dest in {1,...,\hidneuroncount}
\path (I-\source) edge (H-\dest);
% Connect every node in the hidden layer with the output layer
\foreach \source in {1,...,\hidneuroncount}
\path (H-\source) edge (O);
% Annotate the layers
\node[annot,above of=H-1, node distance=1cm] (hl) {Hidden layer};
\node[annot,left of=hl] {Input layer};
\node[annot,right of=hl] {Output layer};
\end{tikzpicture}
% End of code
}
我想做的就是讓隱藏層的 yshift 等於輸入神經元數量與隱藏層神經元數量差異的一半。我創建了一個變數 \nodeoffset,使用後,當您使用 \mln{2.5cm}{2}{3} 時,它會清楚地呈現文字“yshift=0.5cm”
當我嘗試在部分中使用它時
% Draw the hidden layer nodes
\foreach \name / \y in {1,...,\hidneuroncount}
\path[\nodeoffset]
它會產生類似“包 pgfkeys 錯誤:我不知道密鑰 '/tikz/yshift=0.5cm' 的錯誤,我將忽略它。也許你拼錯了它。”
如何正確取得那裡的參數?
答案1
您面臨著所謂的擴充問題。鈦kZ 並沒有完全展開宏\nodeoffset
。您可以透過替換來擴展它
\path[\nodeoffset] node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};
經過
\path[style/.expanded=\nodeoffset] node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};
完整範例:
\documentclass{article}
\usepackage{tikz}
\usepackage[nomessages]{fp}
\newcommand{\mln}[3]{
\def\layersep{#1}
\def\inpneuroncount{#2}
\def\hidneuroncount{#3}
\FPeval{result}{clip((\hidneuroncount-\inpneuroncount)/2)}
\def\nodeoffset{yshift=\result cm}
\nodeoffset
\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=\layersep]
\tikzstyle{every pin edge}=[<-,shorten <=3pt]
\tikzstyle{neuron}=[circle,fill=black!25,minimum size=15pt,inner sep=0pt]
\tikzstyle{input neuron}=[neuron, fill=green!50];
\tikzstyle{output neuron}=[neuron, fill=red!50];
\tikzstyle{hidden neuron}=[neuron, fill=blue!50];
\tikzstyle{annot} = [text width=4em, text centered]
% Draw the input layer nodes
\foreach \name / \y in {1,...,\inpneuroncount}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
\node[input neuron, pin=left:Input \#\y] (I-\name) at (0,-\y) {};
% Draw the hidden layer nodes
\foreach \name / \y in {1,...,\hidneuroncount}
\path[style/.expanded=\nodeoffset]
node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};
% Draw the output layer node
\node[output neuron,pin={[pin edge={->}]right:Output}, right of=H-1] (O) {};
% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,\inpneuroncount}
\foreach \dest in {1,...,\hidneuroncount}
\path (I-\source) edge (H-\dest);
% Connect every node in the hidden layer with the output layer
\foreach \source in {1,...,\hidneuroncount}
\path (H-\source) edge (O);
% Annotate the layers
\node[annot,above of=H-1, node distance=1cm] (hl) {Hidden layer};
\node[annot,left of=hl] {Input layer};
\node[annot,right of=hl] {Output layer};
\end{tikzpicture}
% End of code
}
\begin{document}
\mln{8em}{5}{4}
\end{document}
但是,我想建議一些修改/改進。
\tikzstyle
已棄用,請改用相應的\tikzset
語法(見下文)。- 你實際上不需要
fp
這裡。 - 使用
positioning
。 \def
開頭的 s 似乎沒有真正的目的。
還有很多事情可以改變,但這是部分修改的版本。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand{\mln}[3]{
\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=#1]
\tikzset{every pin edge/.style={<-,shorten <=3pt},
neuron/.style={circle,fill=black!25,minimum size=15pt,inner
sep=0pt},
input neuron/.style={neuron, fill=green!50},
output neuron/.style={neuron, fill=red!50},
hidden neuron/.style={neuron, fill=blue!50},
annot/.style={text width=4em, text centered},
my offset/.style={yshift={((#3-#2)/2)*1cm}}}
\begin{scope}[local bounding box=diag]
% Draw the input layer nodes
\foreach \name / \y in {1,...,#2}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
\node[input neuron, pin={[alias=auxI]left:Input \#\y}] (I-\name) at (0,-\y) {};
% Draw the hidden layer nodes
\foreach \name / \y in {1,...,#3}
{\path[my offset]
node[hidden neuron] (H-\name) at (#1,-\y cm) {};}
% Draw the output layer node
\node[output neuron,pin={[pin edge={->},alias=auxO]right:Output}, right=of H-1] (O) {};
% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,#2}
\foreach \dest in {1,...,#3}
\path (I-\source) edge (H-\dest);
% Connect every node in the hidden layer with the output layer
\foreach \source in {1,...,#3}
\path (H-\source) edge (O);
\end{scope}
% Annotate the layers
\path ([yshift=1ex]diag.north-|H-1.center) node[anchor=south,annot] (hl) {Hidden layer};
\path ([yshift=1ex]diag.north-|auxI.west) node[anchor=south west,annot] {Input layer};
\path ([yshift=1ex]diag.north-|auxO.east) node[anchor=south east,annot] {Output layer};
\end{tikzpicture}
% End of code
}
\begin{document}
\mln{8em}{5}{4}
\end{document}