From 86d2b8b48abe6c9d586cb226e8f428043cd4efd8 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 22 Feb 2018 16:20:59 +0100 Subject: [PATCH] Implement some visualisation for ReLU layers. --- src/LayerInfo.hpp | 1 - src/visualisations.cpp | 50 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/LayerInfo.hpp b/src/LayerInfo.hpp index 9f55886..2261300 100644 --- a/src/LayerInfo.hpp +++ b/src/LayerInfo.hpp @@ -16,7 +16,6 @@ namespace fmri Convolutional, ReLU, Pooling, - Output, InnerProduct, DropOut, Other diff --git a/src/visualisations.cpp b/src/visualisations.cpp index 06201d9..210268e 100644 --- a/src/visualisations.cpp +++ b/src/visualisations.cpp @@ -1,5 +1,5 @@ +#include #include -#include #include "visualisations.hpp" #include "DummyLayerVisualisation.hpp" #include "MultiImageVisualisation.hpp" @@ -41,6 +41,29 @@ static inline int getNodeNormalizer(const LayerData& layer) { } } +/** + * Deduplicate interaction entries. + * + * For duplicate interactions, the interaction strengths are summed. + * + * @param entries + * @return the deduplicated entries. + */ +static EntryList deduplicate(const EntryList& entries) +{ + map, float> combiner; + for (auto entry : entries) { + combiner[entry.second] += entry.first; + } + + EntryList result; + transform(combiner.begin(), combiner.end(), back_inserter(result), [](const auto& item) { + return make_pair(item.second, item.first); + }); + + return result; +} + fmri::LayerVisualisation *fmri::getVisualisationForLayer(const fmri::LayerData &layer) { switch (layer.shape().size()) { @@ -105,6 +128,29 @@ static Animation *getDropOutAnimation(const fmri::LayerData &prevState, } } + results = deduplicate(results); + + return new ActivityAnimation(results, prevPositions.data(), curPositions.data(), -10); +} + +static Animation *getReLUAnimation(const fmri::LayerData &prevState, + const fmri::LayerData &curState, + const vector &prevPositions, + const vector &curPositions) { + CHECK_EQ(curState.numEntries(), prevState.numEntries()) << "Layers should be of same size!"; + + const auto prevData = prevState.data(), curData = curState.data(); + const auto sourceNormalize = getNodeNormalizer(prevState); + const auto sinkNormalize = getNodeNormalizer(curState); + + EntryList results; + + for (auto i : Range(curState.numEntries())) { + results.emplace_back(curData[i] - prevData[i], make_pair(i / sourceNormalize, i / sinkNormalize)); + } + + results = deduplicate(results); + return new ActivityAnimation(results, prevPositions.data(), curPositions.data(), -10); } @@ -126,6 +172,8 @@ Animation * fmri::getActivityAnimation(const fmri::LayerData &prevState, const f case LayerInfo::Type::DropOut: return getDropOutAnimation(prevState, curState, prevPositions, curPositions); + case LayerInfo::Type::ReLU: + return getReLUAnimation(prevState, curState, prevPositions, curPositions); default: return nullptr;