Centrar múltiples salidas en la capa de salida del diagrama tikz de la red neuronal

Centrar múltiples salidas en la capa de salida del diagrama tikz de la red neuronal

Esta pregunta es la construcción de una solución publicada.aquí. El código que tengo a continuación debe optimizarse ya que la capa de salida no está centrada con el resto de la figura.

Me gustaría saber cómo centrar la capa de salida con el resto de la figura.

Además, quería saber cómo configurar la posición correcta de la capa de salida en lugar de codificarla de la forma en que la tenemos actualmente:

\node[output neuron, pin=right:Output \#\y] (O-\name) at (4*\layersep,-\y) {};

ingrese la descripción de la imagen aquí

Aquí está el código que tengo hasta ahora:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\pagestyle{empty}

\def\layersep{2.5cm}

\begin{tikzpicture}[
   shorten >=1pt,->,
   draw=black!50,
    node distance=\layersep,
    every pin edge/.style={<-,shorten <=1pt},
    neuron/.style={circle,fill=black!25,minimum size=17pt,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}
]

% Draw the input layer nodes
\foreach \name / \y in {1,...,8}
% 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) {};

% set number of hidden layers
\newcommand\Nhidden{3}

% Draw the hidden layer nodes
\foreach \N in {1,...,\Nhidden} {
   \foreach \y in {1,...,9} {
      \path[yshift=0.5cm]
          node[hidden neuron] (H\N-\y) at (\N*\layersep,-\y cm) {};
       }
\node[annot,above of=H\N-1, node distance=1cm] (hl\N) {Hidden layer \N};
}

% Draw the output layer node
\foreach \name / \y in {1,...,4}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
    \node[output neuron, pin=right:Output \#\y] (O-\name) at (4*\layersep,-\y) {};
    %  How to calculate the exact location of the output layers instead of hardcoding the value

% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,8}
    \foreach \dest in {1,...,9}
        \path (I-\source) edge (H1-\dest);

% connect all hidden stuff
\foreach [remember=\N as \lastN (initially 1)] \N in {2,...,\Nhidden}
   \foreach \source in {1,...,9}
       \foreach \dest in {1,...,9}
           \path (H\lastN-\source) edge (H\N-\dest);

% Connect every node in the hidden layer with the output layer
\foreach [remember=\N as \lastN (initially 3)] \N in {2,...,\Nhidden}
\foreach \source in {1,...,9}
    \foreach \dest in {1,...,4}
        \path (H\lastN-\source) edge (O-\dest);

% Annotate the layers

\node[annot,left of=hl1] {Input layer};
\node[annot,right of=hl\Nhidden] {Output layer};
\end{tikzpicture}
% End of code
\end{document} 

Respuesta1

Cambie las coordenadas de los nodos en la capa de salida de (4*\layersep,-\y)a (4*\layersep,-\y-2):

ingrese la descripción de la imagen aquí

MWE completo:

\documentclass[tikz, margin=3mm]{standalone}

\begin{document}
\def\layersep{2.5cm}

\begin{tikzpicture}[
   shorten >=1pt,->,
   draw=black!50,
    node distance=\layersep,
    every pin edge/.style={<-,shorten <=1pt},
    neuron/.style={circle,fill=black!25,minimum size=17pt,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}
]

% Draw the input layer nodes
\foreach \name / \y in {1,...,8}
% 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) {};

% set number of hidden layers
\newcommand\Nhidden{3}

% Draw the hidden layer nodes
\foreach \N in {1,...,\Nhidden} {
   \foreach \y in {1,...,9} {
      \path[yshift=0.5cm]
          node[hidden neuron] (H\N-\y) at (\N*\layersep,-\y cm) {};
       }
\node[annot,above of=H\N-1, node distance=1cm] (hl\N) {Hidden layer \N};
}

% Draw the output layer node
\foreach \name / \y in {1,...,4}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
    \node[output neuron, 
          pin=right:Output \#\y] (O-\name) 
          at (4*\layersep,-\y-2) {};  % <-----------
    %  How to calculate the exact location of the output layers instead of hardcoding the value

% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,8}
    \foreach \dest in {1,...,9}
        \path (I-\source) edge (H1-\dest);

% connect all hidden stuff
\foreach [remember=\N as \lastN (initially 1)] \N in {2,...,\Nhidden}
   \foreach \source in {1,...,9}
       \foreach \dest in {1,...,9}
           \path (H\lastN-\source) edge (H\N-\dest);

% Connect every node in the hidden layer with the output layer
\foreach [remember=\N as \lastN (initially 3)] \N in {2,...,\Nhidden}
\foreach \source in {1,...,9}
    \foreach \dest in {1,...,4}
        \path (H\lastN-\source) edge (O-\dest);

% Annotate the layers

\node[annot,left of=hl1] {Input layer};
\node[annot,right of=hl\Nhidden] {Output layer};
\end{tikzpicture}
\end{document}

Respuesta2

Es difícil darle una respuesta que no esté codificada, ya que todos los demás valores están codificados. Necesitas

at (4*\layersep,{-\y*1cm-(9-4-1)*0.5cm})

porque hay 9 nodos ocultos por capa, 4 nodos de salida, y luego hay un código rígido [yshift=0.5cm]en la construcción de las neuronas ocultas, por lo tanto, el adicional -1. El resultado es que si cambia el número de nodos de salida a 4otro valor, debe cambiar el 4de la fórmula anterior al mismo valor.

\documentclass{article}

\usepackage{tikz}
\begin{document}
\pagestyle{empty}

\def\layersep{2.5cm}

\begin{tikzpicture}[
   shorten >=1pt,->,
   draw=black!50,
    node distance=\layersep,
    every pin edge/.style={<-,shorten <=1pt},
    neuron/.style={circle,fill=black!25,minimum size=17pt,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}
]

% Draw the input layer nodes
\foreach \name / \y in {1,...,8}
% 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) {};

% set number of hidden layers
\newcommand\Nhidden{3}

% Draw the hidden layer nodes
\foreach \N in {1,...,\Nhidden} {
   \foreach \y in {1,...,9} {
      \path[yshift=0.5cm]
          node[hidden neuron] (H\N-\y) at (\N*\layersep,-\y*1cm) {};
       }
\node[annot,above of=H\N-1, node distance=1cm] (hl\N) {Hidden layer \N};
}

% Draw the output layer node
\foreach \name / \y in {1,...,4}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
    \node[output neuron, pin=right:Output \#\y] (O-\name) 
    at (4*\layersep,{-\y*1cm-(9-4-1)*0.5cm}) {};
    %  How to calculate the exact location of the output layers instead of hardcoding the value

% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,8}
    \foreach \dest in {1,...,9}
        \path (I-\source) edge (H1-\dest);

% connect all hidden stuff
\foreach [remember=\N as \lastN (initially 1)] \N in {2,...,\Nhidden}
   \foreach \source in {1,...,9}
       \foreach \dest in {1,...,9}
           \path (H\lastN-\source) edge (H\N-\dest);

% Connect every node in the hidden layer with the output layer
\foreach [remember=\N as \lastN (initially 3)] \N in {2,...,\Nhidden}
\foreach \source in {1,...,9}
    \foreach \dest in {1,...,4}
        \path (H\lastN-\source) edge (O-\dest);

% Annotate the layers

\node[annot,left of=hl1] {Input layer};
\node[annot,right of=hl\Nhidden] {Output layer};
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada