// Copyright (C) 2016 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_DNn_UTILITIES_H_ #define DLIB_DNn_UTILITIES_H_ #include "core.h" #include "utilities_abstract.h" #include "../geometry.h" namespace dlib { // ---------------------------------------------------------------------------------------- inline double log1pexp(double x) { using std::exp; using namespace std; // Do this instead of using std::log1p because some compilers // error out otherwise (E.g. gcc 4.9 in cygwin) if (x <= -37) return exp(x); else if (-37 < x && x <= 18) return log1p(exp(x)); else if (18 < x && x <= 33.3) return x + exp(-x); else return x; } // ---------------------------------------------------------------------------------------- inline void randomize_parameters ( tensor& params, unsigned long num_inputs_and_outputs, dlib::rand& rnd ) { for (auto& val : params) { // Draw a random number to initialize the layer according to formula (16) // from Understanding the difficulty of training deep feedforward neural // networks by Xavier Glorot and Yoshua Bengio. val = 2*rnd.get_random_float()-1; val *= std::sqrt(6.0/(num_inputs_and_outputs)); } } // ---------------------------------------------------------------------------------------- namespace impl { class visitor_net_to_xml { public: visitor_net_to_xml(std::ostream& out_) : out(out_) {} template void operator()(size_t idx, const input_layer_type& l) { out << "\n"; to_xml(l,out); out << "\n"; } template void operator()(size_t idx, const add_loss_layer& l) { out << "\n"; to_xml(l.loss_details(),out); out << "\n"; } template void operator()(size_t idx, const add_layer& l) { out << "\n"; to_xml(l.layer_details(),out); out << "\n"; } template void operator()(size_t idx, const add_tag_layer& l) { out << "\n"; } template class T, typename U> void operator()(size_t idx, const add_skip_layer& l) { out << "\n"; } private: std::ostream& out; }; } template void net_to_xml ( const net_type& net, std::ostream& out ) { out << "\n"; visit_layers(net, impl::visitor_net_to_xml(out)); out << "\n"; } // ---------------------------------------------------------------------------------------- namespace impl { class visitor_net_map_input_to_output { public: visitor_net_map_input_to_output(point& p_) : p(p_) {} point& p; template void operator()(size_t idx, const layer_type& net) { p = net.layer_details().map_input_to_output(p); } }; class visitor_net_map_output_to_input { public: visitor_net_map_output_to_input(point& p_) : p(p_) {} point& p; template void operator()(size_t idx, const layer_type& net) { p = net.layer_details().map_output_to_input(p); } }; } template inline point input_tensor_to_output_tensor( const net_type& net, point p ) { impl::visitor_net_map_input_to_output temp(p); visit_layers_backwards_range<0,net_type::num_layers-1>(net, temp); return p; } template inline point output_tensor_to_input_tensor( const net_type& net, point p ) { impl::visitor_net_map_output_to_input temp(p); visit_layers_range<0,net_type::num_layers-1>(net, temp); return p; } // ---------------------------------------------------------------------------------------- } #endif // DLIB_DNn_UTILITIES_H_