Commit 87b182b5 authored by Davis King's avatar Davis King

merged

parents 24698f87 92073c20
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "tensor.h" #include "tensor.h"
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <sstream>
#include <type_traits> #include <type_traits>
#include "../statistics.h" #include "../statistics.h"
#include "../rand.h" #include "../rand.h"
...@@ -1542,23 +1543,29 @@ namespace dlib ...@@ -1542,23 +1543,29 @@ namespace dlib
resizable_tensor gradient_input; resizable_tensor gradient_input;
}; };
}
// TODO, remove? struct layer_test_results
inline void print_tensor( {
const tensor& a layer_test_results() : was_good(true) {}
) explicit layer_test_results(const std::string& l) : log(l),was_good(false) {}
{
auto data = a.host(); std::string log;
for (size_t i = 0; i < a.size(); ++i) bool was_good;
std::cout << data[i] << " ";
std::cout << std::endl; operator bool() const { return was_good; }
} };
inline std::ostream& operator<< (std::ostream& out, const layer_test_results& item)
{
out << item.log;
return out;
} }
template < template <
typename layer_details_type typename layer_details_type
> >
void test_layer ( layer_test_results test_layer (
layer_details_type l layer_details_type l
) )
{ {
...@@ -1577,12 +1584,13 @@ namespace dlib ...@@ -1577,12 +1584,13 @@ namespace dlib
resizable_tensor input_grad; resizable_tensor input_grad;
input_grad.copy_size(output); input_grad.copy_size(output);
std::cout << "output.num_samples(): "<< output.num_samples() << std::endl;
fill_with_gassuan_random_numbers(input_grad, rnd); fill_with_gassuan_random_numbers(input_grad, rnd);
std::ostringstream sout;
// The f() we are computing gradients of is this thing. It's value at the current // The f() we are computing gradients of is this thing. It's value at the current
// parameter and data values is: // parameter and data values is:
std::cout << "f(data,params): " << dot(output, input_grad) << std::endl; //sout << "f(data,params): " << dot(output, input_grad) << std::endl;
// We are going to save a copy of the subnetwork.get_gradient_input() data before we do // We are going to save a copy of the subnetwork.get_gradient_input() data before we do
// backpropagation since the backward() function is supposed to *add* to the // backpropagation since the backward() function is supposed to *add* to the
...@@ -1604,7 +1612,6 @@ namespace dlib ...@@ -1604,7 +1612,6 @@ namespace dlib
params_grad = random_noise; params_grad = random_noise;
l.backward(output, input_grad, subnetwork, params_grad); l.backward(output, input_grad, subnetwork, params_grad);
running_stats<double> rs_param, rs_data;
// ================================================================== // ==================================================================
// first validate the way the parameter gradients are computed // first validate the way the parameter gradients are computed
...@@ -1629,12 +1636,12 @@ namespace dlib ...@@ -1629,12 +1636,12 @@ namespace dlib
if (std::abs(relative_error) > 0.01) if (std::abs(relative_error) > 0.01)
{ {
using namespace std; using namespace std;
cout << "PARAM ERROR: "<< relative_error << endl; sout << "Gradient error in parameter #" << i <<". Relative error: "<< relative_error << endl;
cout << " reference_derivative: " << reference_derivative << endl; sout << "expected derivative: " << reference_derivative << endl;
cout << " output_derivative: " << output_derivative << endl; sout << "output derivative: " << output_derivative << endl;
return layer_test_results(sout.str());
} }
rs_param.add(std::abs(relative_error));
} }
// ================================================================== // ==================================================================
...@@ -1658,26 +1665,14 @@ namespace dlib ...@@ -1658,26 +1665,14 @@ namespace dlib
if (std::abs(relative_error) > 0.01) if (std::abs(relative_error) > 0.01)
{ {
using namespace std; using namespace std;
cout << "DATA ERROR: "<< relative_error << endl; sout << "Gradient error in data variable #" << i <<". Relative error: "<< relative_error << endl;
cout << " reference_derivative: " << reference_derivative << endl; sout << "expected derivative: " << reference_derivative << endl;
cout << " output_derivative: " << output_derivative << endl; sout << "output derivative: " << output_derivative << endl;
return layer_test_results(sout.str());
} }
rs_data.add(std::abs(relative_error));
} }
using namespace std; return layer_test_results();
if (rs_param.current_n() > 1)
{
cout << "rs_param.mean(): " << rs_param.mean() << endl;
cout << "rs_param.stddev(): " << rs_param.stddev() << endl;
cout << "rs_param.max(): " << rs_param.max() << endl;
}
if (rs_data.current_n() > 1)
{
cout << "rs_data.mean(): " << rs_data.mean() << endl;
cout << "rs_data.stddev(): " << rs_data.stddev() << endl;
cout << "rs_data.max(): " << rs_data.max() << endl;
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -965,10 +965,24 @@ namespace dlib ...@@ -965,10 +965,24 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
struct layer_test_results
{
std::string log;
bool was_good;
operator bool() const { return was_good; }
};
inline std::ostream& operator<< (std::ostream& out, const layer_test_results& item)
{
out << item.log;
return out;
}
template < template <
typename layer_details_type typename layer_details_type
> >
void test_layer ( layer_test_results test_layer (
layer_details_type l layer_details_type l
); );
/*! /*!
...@@ -976,6 +990,10 @@ namespace dlib ...@@ -976,6 +990,10 @@ namespace dlib
- Checks if l correctly implements the EXAMPLE_LAYER_ interface defined in - Checks if l correctly implements the EXAMPLE_LAYER_ interface defined in
layers_abstract.h. Importantly, it computes numerical approximations to the layers_abstract.h. Importantly, it computes numerical approximations to the
gradients and compares them to the outputs of the layer. gradients and compares them to the outputs of the layer.
- The results of the testing are returned. In particular, if the returned object
is RESULT then we will have:
- RESULT.was_good == false if and only if the layer failed the testing.
- RESULT.log == a string describing why the testing failed if was_good==false.
- Note that this function is only capable of checking layers that take - Note that this function is only capable of checking layers that take
arbitrary subnetworks as input. So if you have designed a layer that expects arbitrary subnetworks as input. So if you have designed a layer that expects
only a certain restricted type of subnetwork then you might get a compile or only a certain restricted type of subnetwork then you might get a compile or
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment