1

I'm working on a deep-learning project in which I've written some tests to evaluate net weights in a neural net. The code is looks like this for evaluate_net_weight:

/*! Compute the loss of the net as a function of the weight at index (i,j) in
 *  layer l. dx is added as an offset to the current value of the weight. */
//______________________________________________________________________________
template <typename Architecture>
auto evaluate_net_weight(TDeepNet<Architecture> &net, std::vector<typename Architecture::Matrix_t> & X,
                         const typename Architecture::Matrix_t &Y, const typename Architecture::Matrix_t &W, size_t l,
                         size_t k, size_t i, size_t j, typename Architecture::Scalar_t xvalue) ->
   typename Architecture::Scalar_t
{
    using Scalar_t = typename Architecture::Scalar_t;

    Scalar_t prev_value = net.GetLayerAt(l)->GetWeightsAt(k).operator()(i,j);
    net.GetLayerAt(l)->GetWeightsAt(k).operator()(i,j) = xvalue;
    Scalar_t res = net.Loss(X, Y, W, false, false);
    net.GetLayerAt(l)->GetWeightsAt(k).operator()(i,j) = prev_value;
    //std::cout << "compute loss for weight  " << xvalue << "  " << prev_value << " result " << res << std::endl;
    return res;
}

and the function is being called as follows:

// Testing input gate: input weights k = 0
    auto &Wi = layer->GetWeightsAt(0);
    auto &dWi = layer->GetWeightGradientsAt(0);
    for (size_t i = 0; i < (size_t) Wi.GetNrows(); ++i) {
        for (size_t j = 0; j < (size_t) Wi.GetNcols(); ++j) {
            auto f = [&lstm, &XArch, &Y, &weights, i, j](Scalar_t x) {
                return evaluate_net_weight(lstm, XArch, Y, weights, 0, 0, i, j, x);
            };
            ROOT::Math::Functor1D func(f);
            double dy = deriv.Derivative1(func, Wi(i,j), 1.E-5);
            Double_t dy_ref = dWi(i,j);

            // Compute relative error if dy != 0
            Double_t error;
            std::string errorType;
            if (std::fabs(dy_ref) > 1e-15) {
                error = std::fabs((dy - dy_ref) / dy_ref);
                errorType = "relative";
            } else {
                error = std::fabs(dy - dy_ref);
                errorType = "absolute";
            }

            if (debug) std::cout << "Input Gate: input weight gradients (" << i << "," << j << ") : (comp, ref) " << dy << ", " << dy_ref << std::endl;

            if (error >= maximum_error) {
                maximum_error = error;
                maxErrorType = errorType;
            }
        }
    }

The XArch is my inputs, Y is predictions, lstm refers to type of network. These are already been defined.

When I try to build program using cmake, I usually get this error:

/Users/harshitprasad/Desktop/gsoc-rnn/root/tmva/tmva/test/DNN/RNN/TestLSTMBackpropagation.h:385:24: error: 
      no matching function for call to 'evaluate_net_weight'
                return evaluate_net_weight(lstm, XArch, Y, weights, 0, 2, i, j, x);
                       ^~~~~~~~~~~~~~~~~~~
/Users/harshitprasad/Desktop/gsoc-rnn/root/tmva/tmva/test/DNN/RNN/TestLSTMBackpropagation.h:67:6: note: 
      candidate function [with Architecture = TMVA::DNN::TReference<double>] not viable: no known
      conversion from 'Scalar_t' (aka 'TMatrixT<double>') to 'typename TReference<double>::Scalar_t'
      (aka 'double') for 9th argument
auto evaluate_net_weight(TDeepNet<Architecture> &net, std::vector<typename Architecture::Matr...

I'm not able to figure it out, why this error is happening? It would be great if anyone can help me out with this issue. Thanks!

pseyfert
  • 3,263
  • 3
  • 21
  • 47
Harshit
  • 1,510
  • 19
  • 42
  • First of all, [templates needs to be defined in header files](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). Secondly, when asking about build errors, always include the *full* and *complete* copy-pasted (as text) error output, including any informational notes. Lastly, please always try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us (and use it to generate the errors you show us). – Some programmer dude Jul 07 '18 at 06:28
  • I've pasted the whole error with the note. I'll keep these points in my point and will follow them next time. – Harshit Jul 07 '18 at 06:32
  • 1
    Reading the full error message, the problem seem to be that you have different and conflicting definitions of the type `Scalar_t` in different scopes. The function expects `typename TReference::Scalar_t` (which is equal to `double`) but you pass an argument of type `Scalar_t` (presumably defined in the global scope?) which is equal to `TMatrixT`. – Some programmer dude Jul 07 '18 at 06:34
  • Hey, thanks a lot! I didn't noticed that. I was using `Scalar_t` variable as `Architecture_t::Matrix_t` because of which a matrix was being passed instead of scalar value. I really appreciated your help :) – Harshit Jul 07 '18 at 06:43

1 Answers1

0

You might have different and conflicting definitions of your custom type Scalar_t, in different scopes.

From the error message, we can see that the function expects a typename TReference<double>::Scalar_t (which is equivalent to double), but you actually pass an argument of type Scalar_t (which is defined somewhere in the global scope maybe), which is equivalent to TMatrixT<double>, which causes the error, as Some programmer dude mentioned.

gsamaras
  • 71,951
  • 46
  • 188
  • 305