16 delete non_blocking_thread_pool;
17 delete thread_pool_device;
37 case Type::Perceptron:
46 case Type::Probabilistic:
47 return "Probabilistic";
49 case Type::Convolutional:
50 return "Convolutional";
52 case Type::LongShortTermMemory:
53 return "LongShortTermMemory";
69void Layer::set_threads_number(
const int& new_threads_number)
71 if(non_blocking_thread_pool !=
nullptr)
delete this->non_blocking_thread_pool;
72 if(thread_pool_device !=
nullptr)
delete this->thread_pool_device;
74 non_blocking_thread_pool =
new NonBlockingThreadPool(new_threads_number);
75 thread_pool_device =
new ThreadPoolDevice(non_blocking_thread_pool, new_threads_number);
79void Layer::set_parameters_constant(
const type&)
83 buffer <<
"OpenNN Exception: Layer class.\n"
84 <<
"set_parameters_constant(const type&) method.\n"
85 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
87 throw logic_error(buffer.str());
91void Layer::set_parameters_random()
95 buffer <<
"OpenNN Exception: Layer class.\n"
96 <<
"set_parameters_random() method.\n"
97 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
99 throw logic_error(buffer.str());
103void Layer::set_parameters(
const Tensor<type, 1>&,
const Index&)
105 ostringstream buffer;
107 buffer <<
"OpenNN Exception: Layer class.\n"
108 <<
"set_parameters(const Tensor<type, 1>&) method.\n"
109 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
111 throw logic_error(buffer.str());
115Index Layer::get_parameters_number()
const
117 ostringstream buffer;
119 buffer <<
"OpenNN Exception: Layer class.\n"
120 <<
"get_parameters_number() method.\n"
121 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
123 throw logic_error(buffer.str());
127Tensor<type, 1> Layer::get_parameters()
const
129 ostringstream buffer;
131 buffer <<
"OpenNN Exception: Layer class.\n"
132 <<
"get_parameters() method.\n"
133 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
135 throw logic_error(buffer.str());
139Tensor<type, 2> Layer::calculate_outputs(
const Tensor<type, 2>&)
141 ostringstream buffer;
143 buffer <<
"OpenNN Exception: Layer class.\n"
144 <<
"calculate_outputs(const Tensor<type, 2>&) method.\n"
145 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
147 throw logic_error(buffer.str());
155 ostringstream buffer;
157 buffer <<
"OpenNN Exception: Layer class.\n"
158 <<
"get_inputs_number() const method.\n"
159 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
161 throw logic_error(buffer.str());
165Index Layer::get_neurons_number()
const
167 ostringstream buffer;
169 buffer <<
"OpenNN Exception: Layer class.\n"
170 <<
"get_neurons_number() const method.\n"
171 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
173 throw logic_error(buffer.str());
181 ostringstream buffer;
183 buffer <<
"OpenNN Exception: Layer class.\n"
184 <<
"get_synaptic_weight_number() const method.\n"
185 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
187 throw logic_error(buffer.str());
191void Layer::set_inputs_number(
const Index& )
193 ostringstream buffer;
195 buffer <<
"OpenNN Exception: Layer class.\n"
196 <<
"set_inputs_number(const Index& ) method.\n"
197 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
199 throw logic_error(buffer.str());
203void Layer::set_neurons_number(
const Index& )
205 ostringstream buffer;
207 buffer <<
"OpenNN Exception: Layer class.\n"
208 <<
"set_neurons_number(const Index& ) method.\n"
209 <<
"This method is not implemented in the layer type (" <<
get_type_string() <<
").\n";
211 throw logic_error(buffer.str());
215void Layer::hard_sigmoid(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
217 const Tensor<bool, 1> if_sentence = x < x.constant(type(-2.5));
218 const Tensor<bool, 1> elif_sentence = x > x.constant(type(2.5));
220 Tensor<type, 1> f1(x.dimension(0));
221 Tensor<type, 1> f2(x.dimension(0));
222 Tensor<type, 1> f3(x.dimension(0));
225 f2.setConstant(type(1));
226 f3 =
static_cast<type
>(0.2) * x +
static_cast<type
>(0.5);
228 y.device(*thread_pool_device) = if_sentence.select(f1,elif_sentence.select(f2,f3));
232void Layer::hyperbolic_tangent(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
234 y.device(*thread_pool_device) = x.tanh();
238void Layer::logistic(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
240 y.device(*thread_pool_device) = (type(1) + x.exp().inverse()).inverse();
244void Layer::linear(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
250void Layer::threshold(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
252 const Tensor<bool, 1> if_sentence = x >= x.constant(type(0));
254 Tensor<type, 1> ones(x.dimension(0));
255 ones.setConstant(type(1));
257 Tensor<type, 1> zeros(x.dimension(0));
258 zeros.setConstant(type(0));
260 y.device(*thread_pool_device) = if_sentence.select(ones, zeros);
264void Layer::symmetric_threshold(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
267 const Tensor<bool, 1> if_sentence = x > x.constant(type(0));
269 Tensor<type, 1> ones(x.dimension(0));
270 ones.setConstant(type(1));
272 y.device(*thread_pool_device) = if_sentence.select(ones, -ones);
276void Layer::rectified_linear(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
278 const Tensor<bool, 1> if_sentence = x < x.constant(type(0));
280 Tensor<type, 1> zeros(x.dimension(0));
282 zeros.setConstant(type(0));
284 y.device(*thread_pool_device) = if_sentence.select(zeros, x);
288void Layer::scaled_exponential_linear(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
291 const type lambda =
static_cast<type
>(1.0507);
293 const type alpha =
static_cast<type
>(1.67326);
295 const Tensor<bool, 1> if_sentence = x < x.constant(type(0));
297 Tensor<type, 1> f_1(x.dimension(0));
299 Tensor<type, 1> f_2(x.dimension(0));
301 f_1 = lambda*alpha*(x.exp()-
static_cast<type
>(1.0));
305 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
309void Layer::soft_plus(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
311 y.device(*thread_pool_device) = (x.constant(type(1)) + x.exp()).
log();
316void Layer::soft_sign(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
319 const Tensor<bool, 1> if_sentence = x < x.constant(type(0));
321 Tensor<type, 1> f_1(x.dimension(0));
323 Tensor<type, 1> f_2(x.dimension(0));
325 f_1 = x / (
static_cast<type
>(1) - x);
327 f_2 = x / (
static_cast<type
>(1) + x);
329 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
333void Layer::exponential_linear(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
335 const Tensor<bool, 1> if_sentence = x < x.constant(type(0));
337 const type alpha =
static_cast<type
>(1.0);
339 Tensor<type, 1> f_1(x.dimension(0));
341 Tensor<type, 1> f_2(x.dimension(0));
343 f_1.device(*thread_pool_device) = alpha*(x.exp() -
static_cast<type
>(1));
347 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
351void Layer::binary(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
353 const Tensor<bool, 1> if_sentence = x < x.constant(type(0.5));
355 Tensor<type, 1> f_1(x.dimension(0));
357 Tensor<type, 1> f_2(x.dimension(0));
359 f_1 = x.constant(type(
false));
361 f_2 = x.constant(type(
true));
363 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
367void Layer::competitive(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
371 const Index index = maximal_index(x);
377void Layer::softmax(
const Tensor<type, 1>& x, Tensor<type, 1>& y)
const
381 sum.device(*thread_pool_device) = x.exp().sum();
383 y.device(*thread_pool_device) = x.exp() / sum(0);
387void Layer::hard_sigmoid_derivatives(
const Tensor<type, 1>& combinations,
388 Tensor<type, 1>& activations,
389 Tensor<type, 1>& activations_derivatives)
const
393 const Tensor<bool, 1> if_sentence = combinations < combinations.constant(type(-2.5));
395 const Tensor<bool, 1> elif_sentence = combinations > combinations.constant(type(2.5));
397 const Tensor<bool, 1> if_sentence_2 = combinations < combinations.constant(type(-2.5)) || combinations > combinations.constant(type(2.5));
401 Tensor<type, 1> f1(combinations.dimension(0));
404 Tensor<type, 1> f2(combinations.dimension(0));
405 f2.setConstant(type(1));
407 Tensor<type, 1> f3(combinations.dimension(0));
408 f3 =
static_cast<type
>(0.2) * combinations +
static_cast<type
>(0.5);
410 Tensor<type, 1> f4(combinations.dimension(0));
411 f4.setConstant(type(0));
413 Tensor<type, 1> f5(combinations.dimension(0));
414 f5.setConstant(
static_cast<type
>(0.2));
418 activations.device(*thread_pool_device) = if_sentence.select(f1, elif_sentence.select(f2, f3));
422 activations_derivatives.device(*thread_pool_device) = if_sentence_2.select(f4, f5);
426void Layer::hyperbolic_tangent_derivatives(
const Tensor<type, 1>& combinations,
427 Tensor<type, 1>& activations,
428 Tensor<type, 1>& activations_derivatives)
const
432 activations.device(*thread_pool_device) = combinations.tanh();
436 activations_derivatives.device(*thread_pool_device) = type(1) - activations.square();
440void Layer::logistic_derivatives(
const Tensor<type, 1>& combinations,
441 Tensor<type, 1>& activations,
442 Tensor<type, 1>& activations_derivatives)
const
444 activations.device(*thread_pool_device) = (type(1) + combinations.exp().inverse()).inverse();
446 activations_derivatives.device(*thread_pool_device) = activations*(type(1) - activations);
450void Layer::linear_derivatives(
const Tensor<type, 1>& combinations,
451 Tensor<type, 1>& activations,
452 Tensor<type, 1>& activations_derivatives)
const
454 activations = combinations;
456 activations_derivatives.setConstant(type(1));
460void Layer::threshold_derivatives(
const Tensor<type, 1>& combinations,
461 Tensor<type, 1>& activations,
462 Tensor<type, 1>& activations_derivatives)
const
464 const Tensor<bool, 1> if_sentence = combinations > combinations.constant(type(0));
466 Tensor<type, 1> ones(combinations.dimension(0));
467 ones.setConstant(type(1));
469 Tensor<type, 1> zeros(combinations.dimension(0));
470 zeros.setConstant(type(0));
474 activations.device(*thread_pool_device) = if_sentence.select(ones, zeros);
478 activations_derivatives.setZero();
482void Layer::symmetric_threshold_derivatives(
const Tensor<type, 1>& combinations,
483 Tensor<type, 1>& activations,
484 Tensor<type, 1>& activations_derivatives)
const
486 const Tensor<bool, 1> if_sentence = combinations > combinations.constant(type(0));
488 Tensor<type, 1> ones(combinations.dimension(0));
490 ones.setConstant(type(1));
494 activations.device(*thread_pool_device) = if_sentence.select(ones, -ones);
498 activations_derivatives.setZero();
502void Layer::rectified_linear_derivatives(
const Tensor<type, 1>& combinations,
503 Tensor<type, 1>& activations,
504 Tensor<type, 1>& activations_derivatives)
const
506 const Tensor<bool, 1> if_sentence = combinations < combinations.constant(type(0));
508 Tensor<type, 1> zeros(combinations.dimension(0));
511 Tensor<type, 1> ones(combinations.dimension(0));
512 ones.setConstant(type(1));
516 activations.device(*thread_pool_device) = if_sentence.select(zeros, combinations);
520 activations_derivatives.device(*thread_pool_device) = if_sentence.select(zeros, ones);
524void Layer::scaled_exponential_linear_derivatives(
const Tensor<type, 1>& combinations,
525 Tensor<type, 1>& activations,
526 Tensor<type, 1>& activations_derivatives)
const
528 const type lambda =
static_cast<type
>(1.0507);
530 const type alpha =
static_cast<type
>(1.67326);
532 const Tensor<bool, 1> if_sentence = combinations < combinations.constant(type(0));
534 Tensor<type, 1> f_1(combinations.dimension(0));
536 Tensor<type, 1> f_2(combinations.dimension(0));
538 f_1 = lambda*alpha*(combinations.exp()-
static_cast<type
>(1.0));
540 f_2 = lambda*combinations;
544 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
548 f_1 = lambda*alpha*combinations.exp();
550 f_2 = combinations.constant(type(1))*lambda;
552 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
556void Layer::soft_plus_derivatives(
const Tensor<type, 1>& combinations,
557 Tensor<type, 1>& activations,
558 Tensor<type, 1>& activations_derivatives)
const
560 activations.device(*thread_pool_device) = (combinations.constant(type(1)) + combinations.exp()).
log();
562 activations_derivatives.device(*thread_pool_device) =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations.exp().inverse());
566void Layer::soft_sign_derivatives(
const Tensor<type, 1>& combinations,
567 Tensor<type, 1>& activations,
568 Tensor<type, 1>& activations_derivatives)
const
570 const Tensor<bool, 1> if_sentence = combinations < combinations.constant(type(0));
572 Tensor<type, 1> f_1(combinations.dimension(0));
574 Tensor<type, 1> f_2(combinations.dimension(0));
576 f_1 = combinations / (
static_cast<type
>(1) - combinations);
578 f_2 = combinations / (
static_cast<type
>(1) + combinations);
582 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
586 f_1 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) - combinations).
pow(type(2));
588 f_2 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations).
pow(type(2));
590 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
594void Layer::exponential_linear_derivatives(
const Tensor<type, 1>& combinations,
595 Tensor<type, 1>& activations,
596 Tensor<type, 1>& activations_derivatives)
const
599 const type alpha =
static_cast<type
>(1.0);
601 const Tensor<bool, 1> if_sentence = combinations < combinations.constant(type(0));
603 Tensor<type, 1> f_1(combinations.dimension(0));
605 Tensor<type, 1> f_2(combinations.dimension(0));
607 f_1 = alpha*(combinations.exp() -
static_cast<type
>(1));
613 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
617 f_1 = alpha * combinations.exp();
619 f_2 = combinations.constant(type(1));
621 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
627void Layer::hard_sigmoid(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
629 const Index n = x.size();
631 #pragma omp parallel for
633 for(Index i = 0; i < n; i++)
635 if(x(i) <
static_cast<type
>(-2.5))
639 else if(x(i) >
static_cast<type
>(2.5))
645 y(i) =
static_cast<type
>(0.2) * x(i) +
static_cast<type
>(0.5);
651void Layer::hyperbolic_tangent(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
653 y.device(*thread_pool_device) = x.tanh();
657void Layer::logistic(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
659 y.device(*thread_pool_device) = (type(1) + x.exp().inverse()).inverse();
663void Layer::linear(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
669void Layer::threshold(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
671 const Tensor<bool, 2> if_sentence = x >= x.constant(type(0));
673 Tensor<type, 2> ones(x.dimension(0), x.dimension(1));
674 ones.setConstant(type(1));
676 Tensor<type, 2> zeros(x.dimension(0), x.dimension(1));
677 zeros.setConstant(type(0));
679 y.device(*thread_pool_device) = if_sentence.select(ones, zeros);
683void Layer::symmetric_threshold(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
685 const Tensor<bool, 2> if_sentence = x > x.constant(type(0));
687 Tensor<type, 2> ones(x.dimension(0), x.dimension(1));
689 ones.setConstant(type(1));
691 y.device(*thread_pool_device) = if_sentence.select(ones, -ones);
695void Layer::rectified_linear(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
697 const Tensor<bool, 2> if_sentence = x < x.constant(type(0));
699 Tensor<type, 2> zeros(x.dimension(0), x.dimension(1));
701 zeros.setConstant(type(0));
703 y.device(*thread_pool_device) = if_sentence.select(zeros, x);
707void Layer::scaled_exponential_linear(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
709 const type lambda =
static_cast<type
>(1.0507);
711 const type alpha =
static_cast<type
>(1.67326);
713 const Tensor<bool, 2> if_sentence = x < x.constant(type(0));
715 Tensor<type, 2> f_1(x.dimension(0), x.dimension(1));
717 Tensor<type, 2> f_2(x.dimension(0), x.dimension(1));
719 f_1 = lambda*alpha*(x.exp() -
static_cast<type
>(1.0));
723 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
727void Layer::soft_plus(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
729 y.device(*thread_pool_device) = (x.constant(type(1)) + x.exp()).
log();
733void Layer::soft_sign(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
735 const Tensor<bool, 2> if_sentence = x < x.constant(type(0));
737 Tensor<type, 2> f_1(x.dimension(0), x.dimension(1));
739 Tensor<type, 2> f_2(x.dimension(0), x.dimension(1));
741 f_1 = x / (
static_cast<type
>(1) - x);
743 f_2 = x / (
static_cast<type
>(1) + x);
745 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
749void Layer::exponential_linear(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
751 const Tensor<bool, 2> if_sentence = x < x.constant(type(0));
753 const type alpha =
static_cast<type
>(1.0);
755 Tensor<type, 2> f_1(x.dimension(0), x.dimension(1));
757 Tensor<type, 2> f_2(x.dimension(0), x.dimension(1));
759 f_1 = alpha*(x.exp() -
static_cast<type
>(1));
763 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
767void Layer::binary(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
769 const Tensor<bool, 2> if_sentence = x < x.constant(type(0));
771 Tensor<type, 2> f_1(x.dimension(0), x.dimension(1));
773 Tensor<type, 2> f_2(x.dimension(0), x.dimension(1));
775 f_1 = x.constant(type(
false));
777 f_2 = x.constant(type(
true));
779 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
785void Layer::competitive(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
787 const Index samples_number = x.dimension(0);
789 Index maximum_index = 0;
793 for(Index i = 0; i < samples_number; i++)
795 maximum_index = maximal_index(x.chip(i, 1));
797 y(i, maximum_index) = type(1);
803void Layer::softmax(
const Tensor<type, 2>& x, Tensor<type, 2>& y)
const
805 const Index columns_number = x.dimension(1);
807 const Index rows_number = y.dimension(0);
811 y.device(*thread_pool_device) = x.exp();
813 Tensor<type, 1> sums(rows_number);
816 for (Index i = 0; i < rows_number; i++)
818 for (Index j = 0; j < columns_number; j++)
824 for (Index i = 0; i < rows_number; i++)
826 for (Index j = 0; j < columns_number; j++)
828 y(i, j) = y(i, j) / sums(i);
836void Layer::hard_sigmoid_derivatives(
const Tensor<type, 2>& combinations,
837 Tensor<type, 2>& activations,
838 Tensor<type, 2>& activations_derivatives)
const
842 const Tensor<bool, 2> if_sentence = combinations < combinations.constant(type(-2.5));
844 const Tensor<bool, 2> elif_sentence = combinations > combinations.constant(type(2.5));
846 const Tensor<bool, 2> if_sentence_2 = combinations < combinations.constant(type(-2.5)) || combinations > combinations.constant(type(2.5));
850 Tensor<type, 2> f1(combinations.dimension(0), combinations.dimension(1));
853 Tensor<type, 2> f2(combinations.dimension(0), combinations.dimension(1));
854 f2.setConstant(type(1));
856 Tensor<type, 2> f3(combinations.dimension(0), combinations.dimension(1));
857 f3 =
static_cast<type
>(0.2) * combinations +
static_cast<type
>(0.5);
859 Tensor<type, 2> f4(combinations.dimension(0), combinations.dimension(1));
860 f4.setConstant(type(0));
862 Tensor<type, 2> f5(combinations.dimension(0), combinations.dimension(1));
863 f5.setConstant(
static_cast<type
>(0.2));
867 activations.device(*thread_pool_device) = if_sentence.select(f1, elif_sentence.select(f2, f3));
871 activations_derivatives.device(*thread_pool_device) = if_sentence_2.select(f4, f5);
874void Layer::hyperbolic_tangent_derivatives(
const Tensor<type, 2>& combinations,
875 Tensor<type, 2>& activations,
876 Tensor<type, 2>& activations_derivatives)
const
880 activations.device(*thread_pool_device) = combinations.tanh();
884 activations_derivatives.device(*thread_pool_device) = type(1) - activations.square();
888void Layer::logistic_derivatives(
const Tensor<type, 2>& combinations,
889 Tensor<type, 2>& activations,
890 Tensor<type, 2>& activations_derivatives)
const
894 activations.device(*thread_pool_device) = (type(1) + combinations.exp().inverse()).inverse();
898 activations_derivatives.device(*thread_pool_device) = activations*(type(1) - activations);
902void Layer::linear_derivatives(
const Tensor<type, 2>& combinations,
903 Tensor<type, 2>& activations,
904 Tensor<type, 2>& activations_derivatives)
const
906 activations = combinations;
908 activations_derivatives.setConstant(type(1));
913void Layer::threshold_derivatives(
const Tensor<type, 2>& combinations,
914 Tensor<type, 2>& activations,
915 Tensor<type, 2>& activations_derivatives)
const
918 const Tensor<bool, 2> if_sentence = combinations > combinations.constant(type(0));
920 Tensor<type, 2> ones(combinations.dimension(0), combinations.dimension(1));
921 ones.setConstant(type(1));
923 Tensor<type, 2> zeros(combinations.dimension(0), combinations.dimension(1));
924 zeros.setConstant(type(0));
928 activations.device(*thread_pool_device) = if_sentence.select(ones, zeros);
932 activations_derivatives.setZero();
937void Layer::symmetric_threshold_derivatives(
const Tensor<type, 2>& combinations,
938 Tensor<type, 2>& activations,
939 Tensor<type, 2>& activations_derivatives)
const
942 const Tensor<bool, 2> if_sentence = combinations > combinations.constant(type(0));
944 Tensor<type, 2> ones(combinations.dimension(0), combinations.dimension(1));
946 ones.setConstant(type(1));
950 activations.device(*thread_pool_device) = if_sentence.select(ones, -ones);
954 activations_derivatives.setZero();
958void Layer::rectified_linear_derivatives(
const Tensor<type, 2>& combinations,
959 Tensor<type, 2>& activations,
960 Tensor<type, 2>& activations_derivatives)
const
962 const Tensor<bool, 2> if_sentence = combinations < combinations.constant(type(0));
964 Tensor<type, 2> zeros(combinations.dimension(0), combinations.dimension(1));
967 Tensor<type, 2> ones(combinations.dimension(0), combinations.dimension(1));
968 ones.setConstant(type(1));
972 activations.device(*thread_pool_device) = if_sentence.select(zeros, combinations);
976 activations_derivatives.device(*thread_pool_device) = if_sentence.select(zeros, ones);
980void Layer::scaled_exponential_linear_derivatives(
const Tensor<type, 2>& combinations,
981 Tensor<type, 2>& activations,
982 Tensor<type, 2>& activations_derivatives)
const
984 const type lambda =
static_cast<type
>(1.0507);
986 const type alpha =
static_cast<type
>(1.67326);
988 const Tensor<bool, 2> if_sentence = combinations < combinations.constant(type(0));
990 Tensor<type, 2> f_1(combinations.dimension(0), combinations.dimension(1));
992 Tensor<type, 2> f_2(combinations.dimension(0), combinations.dimension(1));
994 f_1 = lambda*alpha*(combinations.exp()-
static_cast<type
>(1.0));
996 f_2 = lambda*combinations;
1000 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1004 f_1 = lambda*alpha*combinations.exp();
1006 f_2 = combinations.constant(type(1))*lambda;
1008 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1013void Layer::soft_plus_derivatives(
const Tensor<type, 2>& combinations,
1014 Tensor<type, 2>& activations,
1015 Tensor<type, 2>& activations_derivatives)
const
1017 activations.device(*thread_pool_device)
1018 = (combinations.constant(type(1)) + combinations.exp()).
log();
1020 activations_derivatives.device(*thread_pool_device)
1021 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations.exp().inverse());
1025void Layer::soft_sign_derivatives(
const Tensor<type, 2>& combinations,
1026 Tensor<type, 2>& activations,
1027 Tensor<type, 2>& activations_derivatives)
const
1030 const Tensor<bool, 2> if_sentence = combinations < combinations.constant(type(0));
1032 Tensor<type, 2> f_1(combinations.dimension(0), combinations.dimension(1));
1034 Tensor<type, 2> f_2(combinations.dimension(0), combinations.dimension(1));
1036 f_1 = combinations / (
static_cast<type
>(1) - combinations);
1038 f_2 = combinations / (
static_cast<type
>(1) + combinations);
1042 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1046 f_1 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) - combinations).
pow(type(2));
1048 f_2 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations).
pow(type(2));
1050 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1054void Layer::exponential_linear_derivatives(
const Tensor<type, 2>& combinations,
1055 Tensor<type, 2>& activations,
1056 Tensor<type, 2>& activations_derivatives)
const
1058 const type alpha =
static_cast<type
>(1.0);
1060 const Tensor<bool, 2> if_sentence = combinations < combinations.constant(type(0));
1062 Tensor<type, 2> f_1(combinations.dimension(0), combinations.dimension(1));
1064 Tensor<type, 2> f_2(combinations.dimension(0), combinations.dimension(1));
1066 f_1 = alpha*(combinations.exp() -
static_cast<type
>(1));
1072 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1076 f_1 = alpha * combinations.exp();
1078 f_2 = combinations.constant(type(1));
1080 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1084void Layer::logistic_derivatives(
const Tensor<type, 2>& combinations,
1085 Tensor<type, 2>& activations,
1086 Tensor<type, 3>& activations_derivatives)
const
1090 activations.device(*thread_pool_device) = (type(1) + combinations.exp().inverse()).inverse();
1094 Tensor<type, 2> derivatives_2d(activations.dimension(0), activations.dimension(1));
1096 derivatives_2d.device(*thread_pool_device) = activations*(type(1) - activations);
1098 memcpy(activations_derivatives.data(), derivatives_2d.data(),
static_cast<size_t>(derivatives_2d.size())*
sizeof(type));
1102void Layer::softmax_derivatives(
const Tensor<type, 2>& combinations,
1103 Tensor<type, 2>& activations,
1104 Tensor<type, 3>& activations_derivatives)
const
1106 const Index dim = combinations.dimension(1);
1108 const Index matrix_number = activations.dimension(0);
1112 softmax(combinations, activations);
1130 type delta = type(0);
1133 for(Index row = 0; row < matrix_number; row++)
1135 for(Index i = 0; i < dim; i++)
1137 for(Index j = 0; j < dim; j++)
1139 (i == j) ? delta = type(1) : delta = type(0);
1143 activations_derivatives(index) = activations(row,j) * (delta - activations(row,i));
1181void Layer::linear(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1187void Layer::logistic(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1189 y.device(*thread_pool_device) = (type(1) + x.exp().inverse()).inverse();
1193void Layer::hyperbolic_tangent(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1195 y.device(*thread_pool_device) = x.tanh();
1199void Layer::threshold(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1201 const Tensor<bool, 4> if_sentence = (x >= x.constant(type(0)));
1203 Tensor<type, 4> ones(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1204 ones.setConstant(type(1));
1206 Tensor<type, 4> zeros(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1207 zeros.setConstant(type(0));
1209 y.device(*thread_pool_device) = if_sentence.select(ones, zeros);
1213void Layer::symmetric_threshold(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1215 const Tensor<bool, 4> if_sentence = x > x.constant(type(0));
1217 Tensor<type, 4> ones(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1219 ones.setConstant(type(1));
1221 y.device(*thread_pool_device) = if_sentence.select(ones, -ones);
1225void Layer::rectified_linear(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1227 const Tensor<bool, 4> if_sentence = x < x.constant(type(0));
1229 Tensor<type, 4> zeros(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1231 zeros.setConstant(type(0));
1233 y.device(*thread_pool_device) = if_sentence.select(zeros, x);
1237void Layer::scaled_exponential_linear(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1239 const type lambda =
static_cast<type
>(1.0507);
1241 const type alpha =
static_cast<type
>(1.67326);
1243 const Tensor<bool, 4> if_sentence = x < x.constant(type(0));
1245 Tensor<type, 4> f_1(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1247 Tensor<type, 4> f_2(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1249 f_1 = lambda*alpha*(x.exp() -
static_cast<type
>(1.0));
1253 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1257void Layer::soft_plus(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1259 y.device(*thread_pool_device) = (x.constant(type(1)) + x.exp()).
log();
1263void Layer::soft_sign(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1265 const Tensor<bool, 4> if_sentence = x < x.constant(type(0));
1267 Tensor<type, 4> f_1(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1269 Tensor<type, 4> f_2(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1271 f_1 = x / (
static_cast<type
>(1) - x);
1273 f_2 = x / (
static_cast<type
>(1) + x);
1275 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1281void Layer::hard_sigmoid(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1283 const Tensor<bool, 4> if_lower = x < x.constant(type(-2.5));
1284 const Tensor<bool, 4> if_greater = x > x.constant(type(2.5));
1285 const Tensor<bool, 4> if_middle = x < x.constant(type(-2.5)) && x > x.constant(type(2.5));
1287 Tensor<type, 4> f_lower(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1288 Tensor<type, 4> f_greater(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1289 Tensor<type, 4> f_middle(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1290 Tensor<type, 4> f_equal(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1292 f_lower = x.constant(type(0));
1293 f_greater = x.constant(type(1));
1294 f_middle =
static_cast<type
>(0.2) * x +
static_cast<type
>(0.5);
1297 y.device(*thread_pool_device) = if_lower.select(f_lower, f_equal);
1298 y.device(*thread_pool_device) = if_greater.select(f_greater, f_equal);
1299 y.device(*thread_pool_device) = if_middle.select(f_middle, f_equal);
1303void Layer::exponential_linear(
const Tensor<type, 4>& x, Tensor<type, 4>& y)
const
1306 const Tensor<bool, 4> if_sentence = x < x.constant(type(0));
1308 const type alpha =
static_cast<type
>(1.0);
1310 Tensor<type, 4> f_1(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1312 Tensor<type, 4> f_2(x.dimension(0), x.dimension(1), x.dimension(2), x.dimension(3));
1314 f_1 = alpha*(x.exp() -
static_cast<type
>(1));
1318 y.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1322void Layer::linear_derivatives(
const Tensor<type, 4>& combinations,
1323 Tensor<type, 4>& activations,
1324 Tensor<type, 4>& activations_derivatives)
const
1326 activations = combinations;
1328 activations_derivatives.setConstant(type(1));
1332void Layer::logistic_derivatives(
const Tensor<type, 4>& combinations,
1333 Tensor<type, 4>& activations,
1334 Tensor<type, 4>& activations_derivatives)
const
1338 activations.device(*thread_pool_device) = (type(1) + combinations.exp().inverse()).inverse();
1342 activations_derivatives.device(*thread_pool_device) = activations*(type(1) - activations);
1346void Layer::hyperbolic_tangent_derivatives(
const Tensor<type, 4>& combinations,
1347 Tensor<type, 4>& activations,
1348 Tensor<type, 4>& activations_derivatives)
const
1352 activations.device(*thread_pool_device) = combinations.tanh();
1356 activations_derivatives.device(*thread_pool_device) = type(1) - activations.square();
1360void Layer::threshold_derivatives(
const Tensor<type, 4>& combinations,
1361 Tensor<type, 4>& activations,
1362 Tensor<type, 4>& activations_derivatives)
const
1364 const Tensor<bool, 4> if_sentence = combinations > combinations.constant(type(0));
1366 Tensor<type, 4> ones(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1367 ones.setConstant(type(1));
1369 Tensor<type, 4> zeros(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1370 zeros.setConstant(type(0));
1374 activations.device(*thread_pool_device) = if_sentence.select(ones, zeros);
1378 activations_derivatives.setZero();
1382void Layer::symmetric_threshold_derivatives(
const Tensor<type, 4>& combinations,
1383 Tensor<type, 4>& activations,
1384 Tensor<type, 4>& activations_derivatives)
const
1386 const Tensor<bool, 4> if_sentence = combinations > combinations.constant(type(0));
1388 Tensor<type, 4> ones(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1390 ones.setConstant(type(1));
1394 activations.device(*thread_pool_device) = if_sentence.select(ones, -ones);
1398 activations_derivatives.setZero();
1402void Layer::rectified_linear_derivatives(
const Tensor<type, 4>& combinations,
1403 Tensor<type, 4>& activations,
1404 Tensor<type, 4>& activations_derivatives)
const
1407 const Tensor<bool, 4> if_sentence = combinations < combinations.constant(type(0));
1409 Tensor<type, 4> zeros(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1412 Tensor<type, 4> ones(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1413 ones.setConstant(type(1));
1417 activations.device(*thread_pool_device) = if_sentence.select(zeros, combinations);
1421 activations_derivatives.device(*thread_pool_device) = if_sentence.select(zeros, ones);
1425void Layer::scaled_exponential_linear_derivatives(
const Tensor<type, 4>& combinations,
1426 Tensor<type, 4>& activations,
1427 Tensor<type, 4>& activations_derivatives)
const
1430 const type lambda =
static_cast<type
>(1.0507);
1432 const type alpha =
static_cast<type
>(1.67326);
1434 const Tensor<bool, 4> if_sentence = combinations < combinations.constant(type(0));
1436 Tensor<type, 4> f_1(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1438 Tensor<type, 4> f_2(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1440 f_1 = lambda*alpha*(combinations.exp()-
static_cast<type
>(1.0));
1442 f_2 = lambda*combinations;
1446 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1450 f_1 = lambda*alpha*combinations.exp();
1452 f_2 = combinations.constant(type(1))*lambda;
1454 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1459void Layer::soft_plus_derivatives(
const Tensor<type, 4>& combinations,
1460 Tensor<type, 4>& activations,
1461 Tensor<type, 4>& activations_derivatives)
const
1466 activations.device(*thread_pool_device) = (combinations.constant(type(1)) + combinations.exp()).
log();
1470 activations_derivatives.device(*thread_pool_device) =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations.exp().inverse());
1475void Layer::soft_sign_derivatives(
const Tensor<type, 4>& combinations,
1476 Tensor<type, 4>& activations,
1477 Tensor<type, 4>& activations_derivatives)
const
1480 const Tensor<bool, 4> if_sentence = combinations < combinations.constant(type(0));
1482 Tensor<type, 4> f_1(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1484 Tensor<type, 4> f_2(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1486 f_1 = combinations / (
static_cast<type
>(1) - combinations);
1488 f_2 = combinations / (
static_cast<type
>(1) + combinations);
1492 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1496 f_1 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) - combinations).
pow(type(2));
1498 f_2 =
static_cast<type
>(1.0) / (
static_cast<type
>(1.0) + combinations).
pow(type(2));
1500 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1505void Layer::hard_sigmoid_derivatives(
const Tensor<type, 4>& combinations,
1506 Tensor<type, 4>& activations,
1507 Tensor<type, 4>& activations_derivatives)
const
1512 const Tensor<bool, 4> if_sentence = combinations < combinations.constant(type(-2.5));
1513 const Tensor<bool, 4> elif_sentence = combinations > combinations.constant(type(2.5));
1514 const Tensor<bool, 4> if_sentence_2 = combinations < combinations.constant(type(-2.5)) || combinations > combinations.constant(type(2.5));
1518 Tensor<type, 4> f1(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1521 Tensor<type, 4> f2(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1522 f2.setConstant(type(1));
1524 Tensor<type, 4> f3(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1525 f3 =
static_cast<type
>(0.2) * combinations +
static_cast<type
>(0.5);
1527 Tensor<type, 4> f4(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1528 f4.setConstant(type(0));
1530 Tensor<type, 4> f5(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1531 f5.setConstant(
static_cast<type
>(0.2));
1535 activations.device(*thread_pool_device) = if_sentence.select(f1, elif_sentence.select(f2, f3));
1539 activations_derivatives.device(*thread_pool_device) = if_sentence_2.select(f4, f5);
1543void Layer::exponential_linear_derivatives(
const Tensor<type, 4>& combinations,
1544 Tensor<type, 4>& activations,
1545 Tensor<type, 4>& activations_derivatives)
const
1548 const type alpha =
static_cast<type
>(1.0);
1550 const Tensor<bool, 4> if_sentence = combinations < combinations.constant(type(0));
1552 Tensor<type, 4> f_1(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1554 Tensor<type, 4> f_2(combinations.dimension(0), combinations.dimension(1), combinations.dimension(2), combinations.dimension(3));
1556 f_1 = alpha*(combinations.exp() -
static_cast<type
>(1));
1562 activations.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
1566 f_1 = alpha * combinations.exp();
1568 f_2 = combinations.constant(type(1));
1570 activations_derivatives.device(*thread_pool_device) = if_sentence.select(f_1, f_2);
Type
This enumeration represents the possible types of layers.
virtual Index get_synaptic_weights_number() const
Returns the number of layer's synaptic weights.
virtual Index get_inputs_number() const
Returns the number of inputs.
Type layer_type
Layer type.
string get_type_string() const
Takes the type of layer used by the model.