\documentclass[tikz,border=10pt]{standalone} \usepackage{tikz} \usetikzlibrary{positioning, shapes.geometric, fit, arrows, arrows.meta, backgrounds} % Define box styles \tikzset{ databox/.style={rectangle, align=center, draw=black, fill=blue!50, thick, rounded corners},%, inner sep=4}, procbox/.style={rectangle, align=center, draw=black, fill=orange!30, thick, rounded corners}, hyperbox/.style={rectangle, align=center, draw=black, fill=green!30, thick, rounded corners}, stepsbox/.style={rectangle, align=left, draw=black,fill=white, rounded corners, minimum width=6cm, minimum height=1.5cm, font=\small}, outputbox/.style={rectangle, align=center, draw=red!80, fill=red!20, rounded corners, minimum width=6cm, minimum height=1.5cm, font=\small}, hlabelbox/.style={rectangle, align=center, draw=black,fill=white, rounded corners, minimum width=6cm, minimum height=1.5cm, font=\small}, vlabelbox/.style={rectangle, align=center, draw=black,fill=white, rounded corners, minimum width=3cm, minimum height=1.8cm, font=\small}, arrow/.style={-{Latex[length=3mm]}}, arrowlabel/.style={fill=white,inner sep=2pt,midway} } \newcommand{\boxtitle}[1]{\textbf{#1}\\[.4em]} \pgfdeclarelayer{background} \pgfdeclarelayer{foreground} \pgfsetlayers{background,main,foreground} \begin{document} \begin{tikzpicture}[node distance=1cm and 2cm] \node (data) {Data}; \node[right=7 of data] (process) {Procedure}; \node[right=7 of process] (hyper) {Hyperparameters}; \begin{pgfonlayer}{foreground} \node[hlabelbox, below=of data] (unlabeled) {\boxtitle{Unlabeled Data} More normal than \\ anomalous samples required}; \node[hlabelbox, below=.1 of unlabeled] (labeled) {\boxtitle{Labeled Data} No requirement regarding ratio \\ +1 = normal, -1 = anomalous}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[databox, fit=(unlabeled) (labeled), label={[label distance = 1, name=traindatalabel]above:{\textbf{Training Data}}}] (traindata) {}; \end{pgfonlayer} %\draw[arrow] (latent.east) -- node{} (autoenc.west); \begin{pgfonlayer}{foreground} \node[stepsbox, below=of process] (pretrainproc) {Train Autoencoder for $E_A$ Epochs \\ with $L_A$ Learning Rate \\ No Labels Used}; \node[outputbox, below=.1 of pretrainproc] (pretrainout) {\boxtitle{Outputs} Encoder Network \\ $\mathbf{w}$: Network Weights}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[procbox, fit=(pretrainproc) (pretrainout), label={[label distance = 1, name=pretrainlab]above:{\textbf{Pre-Training of Autoencoder}}}] (pretrain) {}; \end{pgfonlayer} \begin{pgfonlayer}{foreground} \node[hlabelbox, below=of hyper] (autoencarch) {\boxtitle{Autoencoder Architecture} Choose based on data type \\ Latent Space Size}; \node[hlabelbox, below=.1 of autoencarch] (pretrainhyper) {\boxtitle{Hyperparameters} $E_A$: Number of Epochs \\ $L_A$: Learning Rate}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[hyperbox, fit=(autoencarch) (pretrainhyper), label={[label distance = 1, name=autoenclabel]above:{\textbf{Pre-Training Hyperparameters}}}] (pretrainhyp) {}; \end{pgfonlayer} \draw[arrow] (pretrainhyp.west) -- (pretrain.east); %\draw[arrow] (node cs:name=traindata,angle=10) -- node[arrowlabel]{data type} (node cs:name=autoenc,angle=177); % \draw[arrow] (node cs:name=autoenc,angle=196) |- (node cs:name=pretrain,angle=5); \begin{pgfonlayer}{foreground} \node[stepsbox, below=1.4 of pretrain] (calccproc) {1. Init Encoder with $\mathbf{w}$ \\ 2. Forward Pass on all data \\ 3. $\mathbf{c}$ = Mean Latent Representation}; \node[outputbox, below=.1 of calccproc] (calccout) {\boxtitle{Outputs} $\mathbf{c}$: Hypersphere Center}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[procbox, fit=(calccproc) (calccout), label={[label distance = 1, name=calcclab]above:{\textbf{Calculate Hypersphere Center}}}] (calcc) {}; \end{pgfonlayer} \draw[arrow] (pretrain.south) -- (calcclab.north); \draw[arrow] (traindata.east) -- (pretrain.west); \draw[arrow] (traindata.south) |- (calcc.west); %\draw[arrow] (node cs:name=traindata,angle=45) |- node[arrowlabel]{all training data, labels removed} (node cs:name=pretrain,angle=160); %\draw[arrow] (node cs:name=traindata,angle=-45) |- node[arrowlabel]{all training data, labels removed} (node cs:name=calcc,angle=200); \begin{pgfonlayer}{foreground} \node[stepsbox, below=1.4 of calcc] (maintrainproc) {Train Network for $E_M$ Epochs \\ with $L_M$ Learning Rate \\ Considers Labels}; \node[outputbox, below=.1 of maintrainproc] (maintrainout) {\boxtitle{Outputs} Encoder Network \\ $\mathbf{w}$: Network Weights \\ $\mathbf{c}$: Hypersphere Center}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[procbox, fit=(maintrainproc) (maintrainout), label={[label distance = 1, name=maintrainlab]above:{\textbf{Main Training}}}] (maintrain) {}; \end{pgfonlayer} \begin{pgfonlayer}{foreground} \node[hlabelbox, below=11.25 of hyper] (maintrainhyper) {$E_M$: Number of Epochs \\ $L_M$: Learning Rate \\ $\eta$: Strength Labeled/Unlabeled}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[hyperbox, fit=(maintrainhyper), label={[label distance = 1, name=autoenclabel]above:{\textbf{Main-Training Hyperparameters}}}] (maintrainhyp) {}; \end{pgfonlayer} %\draw[arrow] (pretrainoutput.south) -- (node cs:name=maintrain,angle=22); \draw[arrow] (calcc.south) -- (maintrainlab.north); \draw[arrow] (traindata.south) |- (maintrain.west); %\draw[arrow] (node cs:name=traindata,angle=-135) |- node[arrowlabel]{all training data, including labels} (maintrain.west); \draw[arrow] (maintrainhyp.west) -- (maintrain.east); \begin{pgfonlayer}{foreground} \node[stepsbox, below=1.4 of maintrain] (inferenceproc) {Forward Pass through Network = $\mathbf{p}$ \\ Calculate Geometric Distance $\mathbf{p} \rightarrow \mathbf{c}$ \\ Anomaly Score = Geometric Distance}; \node[outputbox, below=.1 of inferenceproc] (inferenceout) {\boxtitle{Outputs} Anomaly Score (Analog Value) \\ Higher for Anomalies}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[procbox, fit=(inferenceproc) (inferenceout), label={[label distance = 1, name=inferencelab]above:{\textbf{Inference}}}] (inference) {}; \end{pgfonlayer} \begin{pgfonlayer}{foreground} \node[hlabelbox, below=11.8 of traindata] (newdatasample) {\boxtitle{New Data Sample} Same data type as training data}; \end{pgfonlayer} \begin{pgfonlayer}{background} \node[databox, fit=(newdatasample), label={[label distance = 1] above:{\textbf{Unseen Data}}}] (newdata) {}; \end{pgfonlayer} \draw[arrow] (maintrain.south) -- (inferencelab.north); \draw[arrow] (newdata.east) -- (inference.west); \end{tikzpicture} \end{document}