7 #define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message
8 #include <boost/property_tree/ptree.hpp>
9 #include <boost/property_tree/json_parser.hpp>
18 using namespace boost::property_tree;
27 Activation get_activation_function(
const std::string&);
33 void add_bidirectional_info(
LayerConfig&
lc,
const ptree::value_type&
pt);
36 std::map<std::string, double> get_defaults(
const ptree&
ptree);
45 boost::property_tree::read_json(
json,
pt);
48 for (
const auto&
v:
pt.get_child(
"inputs")) {
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>());
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 };
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"));
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;
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 +
"'");
174 v.second.get<std::string>(
"architecture"));
176 if (arch == Architecture::DENSE) {
178 }
else if (arch == Architecture::NORMALIZATION) {
180 }
else if (arch == Architecture::MAXOUT) {
181 add_maxout_info(
layer,
v);
182 }
else if (arch == Architecture::LSTM ||
183 arch == Architecture::GRU ||
184 arch == Architecture::HIGHWAY) {
185 add_component_info(
layer,
v);
186 }
else if (arch == Architecture::BIDIRECTIONAL) {
187 add_bidirectional_info(
layer,
v);
188 }
else if (arch == Architecture::EMBEDDING) {
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());
211 if (
cfg.function == Activation::ELU) {
221 if (
str ==
"sigmoid")
return Activation::SIGMOID;
222 if (
str ==
"rectified")
return Activation::RECTIFIED;
223 if (
str ==
"softmax")
return Activation::SOFTMAX;
224 if (
str ==
"tanh")
return Activation::TANH;
225 if (
str ==
"hard_sigmoid")
return Activation::HARD_SIGMOID;
226 if (
str ==
"elu")
return Activation::ELU;
227 if (
str ==
"leakyrelu")
return Activation::LEAKY_RELU;
228 if (
str ==
"swish")
return Activation::SWISH;
229 if (
str ==
"abs")
return Activation::ABS;
230 throw std::logic_error(
"activation function " +
str +
" not recognized");
237 if (
str ==
"dense")
return Architecture::DENSE;
238 if (
str ==
"normalization")
return Architecture::NORMALIZATION;
239 if (
str ==
"highway")
return Architecture::HIGHWAY;
240 if (
str ==
"maxout")
return Architecture::MAXOUT;
241 if (
str ==
"lstm")
return Architecture::LSTM;
242 if (
str ==
"gru")
return Architecture::GRU;
243 if (
str ==
"bidirectional")
return Architecture::BIDIRECTIONAL;
244 if (
str ==
"embedding")
return Architecture::EMBEDDING;
245 throw std::logic_error(
"architecture " +
str +
" not recognized");
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) {
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(sublayer);
285 const std::map<std::string, lwtDev::Component> component_map {
294 {
"carry", Component::CARRY}
299 for (
const auto&
comp:
v.second.get_child(
"components")) {
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"));
322 for(
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(forward_layer);
333 layer.sublayers.push_back(backward_layer);
334 layer.return_sequence =
v.second.get<
bool>(
"return_sequence");
335 layer.merge_mode =
v.second.get<std::string>(
"merge_mode");
336 layer.architecture = Architecture::BIDIRECTIONAL;
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(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;
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");