8 #ifndef LAYER_MANAGER_H_ 9 #define LAYER_MANAGER_H_ 16 template<
class Derived,
class Layer>
19 template<
class D,
class L>
31 template<
char C,
class Tensor, cache_key_type overr
ide=cache_key_type::inherit>
47 template<
class... Args>
51 template<
class T,
class l=Layer>
53 static_assert(T::tensor_dim == Layer::input_tensor_dim::value + 1,
54 "Invalid tensor_dim in forward_propagation");
55 BC_ASSERT(expression.get_shape() == this->get_batched_input_shape(),
56 "forward_propagation input must have the same shape as " 57 "get_batched_input_shape() of the current layer " 58 "(Invalid input dims) " 59 "\nLayer: " + Layer::classname() +
60 "\nExpected shape: " + this->get_batched_input_shape().to_string() +
61 "\nReceived Shape: " + expression.get_shape().inner_shape().to_string());
63 return forward_supply_outputs(
65 store_batched_inputs(expression));
70 static_assert(T::tensor_dim == output_tensor_dim::value + 1,
71 "Invalid tensor_dim in back_propagation");
72 BC_ASSERT(dy.get_shape() == this->get_batched_output_shape(),
73 "back_propagation input must have the same shape as " 74 "get_batched_output_shape() of the current layer " 75 "(Invalid input dims) " 76 "\nLayer: " + Layer::classname() +
77 "\nExpected shape: " + this->get_batched_input_shape().to_string() +
78 "\nReceived Shape: " + dy.get_shape().inner_shape().to_string());
80 return backward_supply_outputs(
83 maybe_cache_delta(dy));
89 static_assert(T::tensor_dim == input_tensor_dim::value + 1,
90 "Invalid tensor_dim in predict");
91 BC_ASSERT(expression.get_shape() == this->get_batched_input_shape(),
92 "predict<T> input must have the same shape as " 93 "get_batched_input_shape() of the current layer " 94 "(Invalid input dims) " 95 "\nLayer: " + Layer::classname() +
96 "\nExpected shape: " + this->get_batched_input_shape().to_string() +
97 "\nReceived Shape: " + expression.get_shape().inner_shape().to_string());
99 return predict_supply_outputs(
101 store_batched_inputs(expression));
107 static_assert(T::tensor_dim == input_tensor_dim::value,
108 "Invalid tensor_dim in single_predict");
109 BC_ASSERT(expression.get_shape() == this->get_input_shape(),
110 "single_predict<T> input must have the same shape as " 111 "get_input_shape() of the current layer " 112 "(Invalid input dims) " 113 "\nLayer: " + Layer::classname() +
114 "\nExpected shape: " + this->get_input_shape().to_string() +
115 "\nReceived Shape: " + expression.get_shape().inner_shape().to_string());
117 static_assert(T::tensor_dim ==
118 traits::input_tensor_dim::value,
119 "assert same dim as layer");
121 return single_predict_supply_outputs(
127 Layer::update_weights();
129 Layer::clear_bp_storage(m_cache);
135 Layer::save_from_cache(loader, m_cache);
141 Layer::load_to_cache(loader, m_cache);
145 Layer::copy_training_data_to_single_predict(m_cache, batch_index);
146 get_predict_inputs() = get_batched_inputs()[batch_index];
167 auto& get_batched_inputs()
const {
170 this->default_batched_input_tensor_factory());
173 auto& get_predict_inputs()
const {
176 this->default_input_tensor_factory());
180 auto& store_batched_inputs(
const X& x) {
185 return static_cast<Derived&
>(*this).next().layer();
191 auto forward_supply_outputs(std::false_type,
const X& inputs) {
192 return forward_supply_cache(
197 template<
class Input>
198 auto forward_supply_outputs(std::true_type,
const Input& inputs) {
199 auto& outputs = next_layer().get_batched_inputs();
200 return forward_supply_cache(
206 template<
class... Args>
207 auto forward_supply_cache(std::false_type,
const Args&... args) {
208 return Layer::forward_propagation(args...);
211 template<
class... Args>
212 auto forward_supply_cache(std::true_type,
const Args&... args) {
213 return Layer::forward_propagation(args..., m_cache);
219 auto predict_supply_outputs(std::false_type,
const X& inputs) {
223 template<
class Input>
224 auto predict_supply_outputs(std::true_type,
const Input& inputs) {
225 auto& outputs = next_layer().get_batched_inputs();
229 template<
class... Args>
230 auto predict_supply_cache(std::false_type, Args&&... args) {
234 template<
class... Args>
235 auto predict_supply_cache(std::true_type, Args&&... args) {
242 auto single_predict_supply_outputs(std::false_type,
const X& inputs) {
243 static_assert(X::tensor_dim == input_tensor_dim::value,
244 "Assert single-batch dim for Neural_Network.predict()");
248 template<
class Input>
249 auto single_predict_supply_outputs(std::true_type,
const Input& inputs) {
250 auto default_factory = [&]() {
254 using key_type =
typename std::decay_t<decltype(next_layer())>::input_key;
255 auto& outputs = next_layer().m_cache.load(
key_type(), default_factory);
259 template<
class... Args>
260 auto single_predict_supply_cache(std::false_type,
const Args&... args) {
264 template<
class... Args>
265 auto single_predict_supply_cache(std::true_type,
const Args&... args) {
271 template<
class X,
class... T>
272 auto backward_supply_outputs(std::false_type,
const X& x,
const T&... args) {
276 template<
class Input,
class Dy>
277 auto backward_supply_outputs(std::true_type,
const Input& inputs,
const Dy& delta) {
278 auto& outputs = next_layer().get_batched_inputs();
282 template<
class... Args>
283 auto backward_supply_cache(std::false_type,
const Args&... args) {
284 return Layer::back_propagation(args...);
287 template<
class... Args>
288 auto backward_supply_cache(std::true_type, Args&... args) {
289 return Layer::back_propagation(args..., m_cache);
293 auto&& maybe_cache_delta(
const T& dy) {
296 traits::greedy_evaluate_delta::value>;
298 return maybe_cache_delta_impl(should_greedy_eval(), dy);
302 auto& maybe_cache_delta_impl(std::true_type cache_delta,
const T& dy) {
307 const T& maybe_cache_delta_impl(std::false_type cache_delta,
const T& dy) {
bc::Tensor< input_tensor_dim::value, value_type, allocator_type > input_tensor_type
Definition: layer_manager.h:27
typename layer_traits< CurrentLayer >::output_tensor_dim output_tensor_dim
Definition: layer_manager.h:23
typename layer_traits< CurrentLayer >::allocator_type allocator_type
Definition: layer_manager.h:24
Layer_Manager(Args... args)
Definition: layer_manager.h:48
A Dictionary designed to store any type using the 'store' and 'load' functions.
Definition: layer_cache.h:46
Definition: layer_loader.h:19
bc::tensors::Tensor_Base< bc::tensors::exprs::Array< bc::Shape< dim >, ValueType, Allocator > > Tensor
Definition: tensors.h:39
auto forward_propagation(const T &expression)
Definition: layer_manager.h:52
bc::traits::conditional_detected_t< bc::traits::query_value_type, T, typename system_tag::default_floating_point_type > value_type
Definition: layer_traits.h:60
virtual void save(Layer_Loader &loader) const override
Definition: layer_manager.h:132
void save_variable(const T &tensor, string variable_name)
Definition: layer_loader.h:44
Definition: layer_cache.h:33
typename layer_traits< CurrentLayer >::value_type value_type
Definition: layer_manager.h:25
Definition: layer_traits.h:42
typename layer_traits< CurrentLayer >::input_tensor_dim input_tensor_dim
Definition: layer_manager.h:22
void copy_training_data_to_single_predict(int batch_index)
Definition: layer_manager.h:144
void zero_time_index()
Definition: layer_cache.h:187
bc::traits::conditional_detected_t< detail::query_forward_requires_outputs, T, std::false_type > forward_requires_outputs
Definition: layer_traits.h:80
void zero_time_index()
Definition: layer_manager.h:157
cache_key< bc::utility::Name< C >, Tensor, override > key_type
Definition: layer_manager.h:32
bc::traits::conditional_detected_t< bc::traits::query_allocator_type, T, bc::Allocator< value_type, system_tag > > allocator_type
Definition: layer_traits.h:65
Cache & get_cache()
Definition: layer_manager.h:153
auto back_propagation(const T &dy)
Definition: layer_manager.h:69
Definition: expression_template_traits.h:76
void increment_time_index()
Definition: layer_cache.h:185
void clear_bp_storage(key_type< K, V, cache_key_type::always_forward > key)
Definition: layer_cache.h:191
bc::traits::conditional_detected_t< detail::query_requires_extra_cache, T, std::false_type > requires_extra_cache
Definition: layer_traits.h:68
auto predict(const T &expression)
Definition: layer_manager.h:88
Definition: layer_manager.h:17
bc::traits::conditional_detected_t< detail::query_output_tensor_dim, T, input_tensor_dim > output_tensor_dim
Definition: layer_traits.h:74
auto single_predict(const T &expression)
Definition: layer_manager.h:106
void update_weights()
Definition: layer_manager.h:126
auto & store(key_type< K, V, cache_key_type::inherit > key, U &&expression)
Definition: layer_cache.h:104
static auto select_on_single_predict(T &layer, Args &&... args)
Definition: layer_traits.h:111
void load_variable(T &tensor, string variable_name)
Definition: layer_loader.h:50
auto & load(key_type< K, V, cache_key_type::inherit > key, int t_modifier=0) const
Definition: layer_cache.h:80
conditional_t< Bool, true_type, false_type > truth_type
Definition: type_traits.h:49
static auto select_on_predict(T &layer, Args &&... args)
Definition: layer_traits.h:102
#define BC_ASSERT(condition, message)
Definition: common.h:185
bc::traits::conditional_detected_t< detail::query_input_tensor_dim, T, bc::traits::Integer< 1 > > input_tensor_dim
Definition: layer_traits.h:71
void increment_time_index()
Definition: layer_manager.h:161
const Cache & get_cache() const
Definition: layer_manager.h:149
virtual void load(Layer_Loader &loader) override
Definition: layer_manager.h:138
bc::traits::conditional_detected_t< detail::query_backward_requires_outputs, T, std::false_type > backward_requires_outputs
Definition: layer_traits.h:89
The Evaluator determines if an expression needs to be greedily optimized.
Definition: algorithms.h:22