7#define BOOST_BIND_GLOBAL_PLACEHOLDERS
8#include <boost/property_tree/ptree.hpp>
9#include <boost/property_tree/json_parser.hpp>
18 using namespace boost::property_tree;
21 Input get_input(
const ptree::value_type& pt);
23 NodeConfig get_node(
const ptree::value_type& pt);
27 Activation get_activation_function(
const std::string&);
30 void add_dense_info(
LayerConfig& lc,
const ptree::value_type& pt);
31 void add_maxout_info(
LayerConfig& lc,
const ptree::value_type& pt);
32 void add_component_info(
LayerConfig& lc,
const ptree::value_type& pt);
33 void add_bidirectional_info(
LayerConfig& lc,
const ptree::value_type& pt);
34 void add_embedding_info(
LayerConfig& lc,
const ptree::value_type& pt);
36 std::map<std::string, double> get_defaults(
const ptree&
ptree);
44 boost::property_tree::ptree pt;
45 boost::property_tree::read_json(
json, pt);
48 for (
const auto& v: pt.get_child(
"inputs")) {
49 cfg.inputs.push_back(get_input(v));
51 for (
const auto& v: pt.get_child(
"layers")) {
52 cfg.layers.push_back(get_layer(v));
54 for (
const auto& v: pt.get_child(
"outputs"))
56 assert(v.first.empty());
57 cfg.outputs.push_back(v.second.data());
59 cfg.defaults = get_defaults(pt);
60 const std::string mname =
"miscellaneous";
61 if (pt.count(mname)) {
62 for (
const auto& misc: pt.get_child(mname)) {
63 cfg.miscellaneous.emplace(
64 misc.first, misc.second.get_value<std::string>());
72 boost::property_tree::ptree pt;
73 boost::property_tree::read_json(
json, pt);
76 for (
const auto& v: pt.get_child(
"inputs")) {
77 cfg.inputs.push_back(get_input_node(v));
79 for (
const auto& v: pt.get_child(
"input_sequences")) {
80 cfg.input_sequences.push_back(get_input_node(v));
82 for (
const auto& v: pt.get_child(
"nodes")) {
83 cfg.nodes.push_back(get_node(v));
85 for (
const auto& v: pt.get_child(
"layers")) {
86 cfg.layers.push_back(get_layer(v));
88 for (
const auto& v: pt.get_child(
"outputs")) {
89 cfg.outputs.emplace(v.first, get_output_node(v));
99 std::string
name =
v.second.get<std::string>(
"name");
100 auto offset =
v.second.get<
double>(
"offset");
101 auto scale =
v.second.get<
double>(
"scale");
107 cfg.name =
v.second.get<std::string>(
"name");
108 for (
const auto& var:
v.second.get_child(
"variables")) {
110 if (
var.second.count(
"default")) {
111 std::string
name =
var.second.get<std::string>(
"name");
112 cfg.defaults.emplace(name,
var.second.get<
double>(
"default"));
118 const std::set<NodeConfig::Type> layerless_nodes {
119 NodeConfig::Type::CONCATENATE, NodeConfig::Type::SUM };
120 NodeConfig get_node(
const ptree::value_type& v) {
123 for (
const auto& source:
v.second.get_child(
"sources")) {
124 int source_number =
source.second.get_value<
int>();
125 if (source_number < 0) {
126 throw std::logic_error(
"node source number must be positive");
128 cfg.sources.push_back(source_number);
131 cfg.type = get_node_type(
v.second.get<std::string>(
"type"));
133 if (
cfg.type == Type::INPUT ||
cfg.type == Type::INPUT_SEQUENCE) {
134 cfg.index =
v.second.get<
int>(
"size");
135 }
else if (
cfg.type == Type::FEED_FORWARD ||
cfg.type == Type::SEQUENCE ||
136 cfg.type == Type::TIME_DISTRIBUTED) {
137 cfg.index =
v.second.get<
int>(
"layer_index");
138 }
else if (layerless_nodes.count(
cfg.type)){
141 throw std::logic_error(
"unknown node type");
148 for (
const auto& lab:
v.second.get_child(
"labels")) {
149 cfg.labels.push_back(lab.second.get_value<std::string>());
151 int idx =
v.second.get<
int>(
"node_index");
152 if (idx < 0)
throw std::logic_error(
"output node index is negative");
159 if (
type ==
"feed_forward")
return Type::FEED_FORWARD;
160 if (
type ==
"sequence")
return Type::SEQUENCE;
161 if (
type ==
"input")
return Type::INPUT;
162 if (
type ==
"input_sequence")
return Type::INPUT_SEQUENCE;
163 if (
type ==
"concatenate")
return Type::CONCATENATE;
164 if (
type ==
"time_distributed")
return Type::TIME_DISTRIBUTED;
165 if (
type ==
"sum")
return Type::SUM;
166 throw std::logic_error(
"no node type '" +
type +
"'");
169 LayerConfig get_layer(
const ptree::value_type& v) {
174 v.second.get<std::string>(
"architecture"));
177 add_dense_info(layer, v);
179 add_dense_info(layer, v);
181 add_maxout_info(layer, v);
185 add_component_info(layer, v);
187 add_bidirectional_info(layer, v);
189 add_embedding_info(layer, v);
191 throw std::logic_error(
"architecture not implemented");
193 layer.architecture = arch;
202 cfg.function = get_activation_function(
203 v.get<std::string>(
"function"));
204 cfg.alpha =
v.get<
double>(
"alpha");
206 cfg.function = get_activation_function(
v.data());
230 throw std::logic_error(
"activation function " +
str +
" not recognized");
245 throw std::logic_error(
"architecture " +
str +
" not recognized");
254 void add_dense_info(
LayerConfig& layer,
const ptree::value_type& v) {
255 for (
const auto& wt:
v.second.get_child(
"weights")) {
256 layer.weights.push_back(wt.second.get_value<
double>());
258 for (
const auto& bs:
v.second.get_child(
"bias")) {
259 layer.bias.push_back(bs.second.get_value<
double>());
262 if (
v.second.count(
"U") != 0) {
263 for (
const auto& wt:
v.second.get_child(
"U") ) {
264 layer.U.push_back(wt.second.get_value<
double>());
268 if (
v.second.count(
"activation") != 0) {
274 void add_maxout_info(
LayerConfig& layer,
const ptree::value_type& v) {
276 for (
const auto& sub:
v.second.get_child(
"sublayers")) {
278 set_defaults(sublayer);
279 add_dense_info(sublayer, sub);
280 layer.sublayers.push_back(std::move(sublayer));
285 const std::map<std::string, lwtDev::Component> component_map {
297 void add_component_info(
LayerConfig& layer,
const ptree::value_type& v) {
299 for (
const auto& comp:
v.second.get_child(
"components")) {
302 add_dense_info(cfg, comp);
303 layer.components[component_map.at(
comp.first)] = std::move(cfg);
306 layer.go_backwards =
false;
307 if (
v.second.count(
"return_sequence") != 0)
308 layer.return_sequence =
v.second.get<
bool>(
"return_sequence");
309 if (
v.second.count(
"go_backwards") != 0)
310 layer.go_backwards =
v.second.get<
bool>(
"go_backwards");
311 if (
v.second.count(
"inner_activation") != 0) {
313 v.second.get_child(
"inner_activation"));
317 void add_bidirectional_info(
LayerConfig& layer,
const ptree::value_type& v) {
322 for(
const auto& val:
v.second){
323 if(
val.first ==
"forward_layer"){
324 add_component_info(forward_layer, val);
325 forward_layer.
architecture = get_architecture(
val.second.get<std::string>(
"architecture"));
327 if(
val.first ==
"backward_layer"){
328 add_component_info(backward_layer, val);
329 backward_layer.
architecture = get_architecture(
val.second.get<std::string>(
"architecture"));
332 layer.sublayers.push_back(std::move(forward_layer));
333 layer.sublayers.push_back(std::move(backward_layer));
334 layer.return_sequence =
v.second.get<
bool>(
"return_sequence");
335 layer.merge_mode =
v.second.get<std::string>(
"merge_mode");
339 void add_embedding_info(
LayerConfig& layer,
const ptree::value_type& v) {
341 for (
const auto& sub:
v.second.get_child(
"sublayers")) {
343 for (
const auto& wt: sub.second.get_child(
"weights")) {
344 emb.
weights.push_back(wt.second.get_value<
double>());
346 emb.
index = sub.second.get<
int>(
"index");
347 emb.
n_out = sub.second.get<
int>(
"n_out");
348 layer.embedding.push_back(std::move(emb));
352 std::map<std::string, double> get_defaults(
const ptree& pt) {
353 const std::string
dname =
"defaults";
354 std::map<std::string, double>
defaults;
357 if (
pt.count(dname)) {
358 for (
const auto& def:
pt.get_child(dname)) {
359 defaults.emplace(def.first, def.second.get_value <
double>());
362 const std::string dkey =
"default";
363 for (
const auto& v:
pt.get_child(
"inputs")) {
364 if (
v.second.count(dkey)) {
365 std::string
key =
v.second.get<std::string>(
"name");
366 defaults.emplace(key,
v.second.get<
double>(dkey));
boost::property_tree::ptree ptree
Input get_input(const nlohmann::json &v)
OutputNodeConfig get_output_node(const nlohmann::json &v)
InputNodeConfig get_input_node(const nlohmann::json &v)
GraphConfig parse_json_graph(std::istream &json)
JSONConfig parse_json(std::istream &json)
std::function< double(double)> get_activation(lwtDev::ActivationConfig act)
std::vector< double > weights
Architecture architecture