Implement a new layer data type.

Contrary to layerdata, this describes the layer itself rather than the
layer contents.
This commit is contained in:
2018-01-02 16:17:07 +01:00
parent 5c0dbcdaa4
commit 470399aabf
4 changed files with 116 additions and 13 deletions

33
src/LayerInfo.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include "LayerInfo.hpp"
using namespace std;
using namespace fmri;
LayerInfo::Type LayerInfo::typeByName(string_view name)
{
if (name == "Input") {
return Type::Input;
} else if (name == "Convolution") {
return Type::Convolutional;
} else if (name == "ReLU") {
return Type::ReLU;
} else if (name == "Pooling") {
return Type::Pooling;
} else {
LOG(INFO) << "Received unknown layer type: " << name << endl;
return Type::Other;
}
}
LayerInfo::LayerInfo(string_view name, string_view type,
const vector<boost::shared_ptr<caffe::Blob<DType>>> &parameters)
: parameters_(parameters), name_(name), type_(typeByName(type))
{
}
const std::string &LayerInfo::name() const
{
return name_;
}

35
src/LayerInfo.hpp Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include <string_view>
#include <caffe/blob.hpp>
#include <string>
#include "utils.hpp"
namespace fmri
{
class LayerInfo
{
public:
enum class Type
{
Input,
Convolutional,
ReLU,
Pooling,
Output,
Other
};
LayerInfo(std::string_view name, std::string_view type,
const std::vector<boost::shared_ptr<caffe::Blob<DType>>> &parameters);
const std::string& name() const;
static Type typeByName(std::string_view name);
private:
std::vector<boost::shared_ptr<caffe::Blob<DType>>> parameters_;
Type type_;
std::string name_;
};
}

View File

@@ -21,12 +21,18 @@ struct Simulator::Impl
cv::Size input_geometry;
optional<cv::Mat> means;
unsigned int num_channels;
map<string, LayerInfo> layerInfo_;
Impl(const string& model_file, const string& weights_file, const string& means_file);
vector<cv::Mat> getWrappedInputLayer();
cv::Mat preprocess(cv::Mat original) const;
vector<LayerData> simulate(const string &input_file);
const map<string, LayerInfo>& layerInfo() const;
void computeLayerInfo();
void loadMeans(const string &means_file);
};
// Create simple forwarding functions.
@@ -55,27 +61,33 @@ Simulator::Impl::Impl(const string& model_file, const string& weights_file, cons
net.Reshape();
if (!means_file.empty()) {
// Read in the means file
BlobProto proto;
ReadProtoFromBinaryFileOrDie(means_file, &proto);
loadMeans(means_file);
}
Blob<DType> mean_blob;
mean_blob.FromProto(proto);
computeLayerInfo();
}
CHECK_EQ(mean_blob.channels(), num_channels) << "Number of channels should match!" << endl;
void Simulator::Impl::loadMeans(const string &means_file)
{// Read in the means file
BlobProto proto;
ReadProtoFromBinaryFileOrDie(means_file, &proto);
vector<cv::Mat> channels;
float* data = mean_blob.mutable_cpu_data();
for (unsigned int i = 0; i < num_channels; ++i) {
Blob<DType> mean_blob;
mean_blob.FromProto(proto);
CHECK_EQ(mean_blob.channels(), num_channels) << "Number of channels should match!" << endl;
vector<cv::Mat> channels;
float* data = mean_blob.mutable_cpu_data();
for (unsigned int i = 0; i < this->num_channels; ++i) {
channels.emplace_back(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
data += mean_blob.height() * mean_blob.width();
}
cv::Mat mean;
cv::merge(channels, mean);
cv::Mat mean;
merge(channels, mean);
means = cv::Mat(input_geometry, mean.type(), cv::mean(mean));
}
this->means = cv::Mat(this->input_geometry, mean.type(), cv::mean(mean));
}
vector<LayerData> Simulator::Impl::simulate(const string& image_file)
@@ -177,7 +189,28 @@ cv::Mat Simulator::Impl::preprocess(cv::Mat original) const
}
const map<string, LayerInfo> &Simulator::Impl::layerInfo() const
{
return layerInfo_;
}
void Simulator::Impl::computeLayerInfo()
{
const auto& names = net.layer_names();
const auto& layers = net.layers();
for (auto i = 0u; i < names.size() && i < layers.size(); ++i) {
auto& layer = layers[i];
layerInfo_.emplace(names[i], LayerInfo(names[i], layer->type(), layer->blobs()));
}
}
Simulator::~Simulator()
{
// Empty but defined constructor.
}
const map<string, LayerInfo> & Simulator::layerInfo() const
{
return pImpl->layerInfo();
}

View File

@@ -4,6 +4,7 @@
#include <memory>
#include <vector>
#include "LayerData.hpp"
#include "LayerInfo.hpp"
namespace fmri {
using std::string;
@@ -15,6 +16,7 @@ namespace fmri {
~Simulator();
vector<LayerData> simulate(const string &input_file);
const std::map<std::string, LayerInfo>& layerInfo() const;
private:
struct Impl;