<blockquote>
<p>Opening another pull request to discuss the implementation details sounds great.</p>
</blockquote>

<p>Then I would open one after I finished autoencoder(if no one open it yet)</p>

<blockquote>
<p>but instead just using the pre-existing SparseAutoencoder typedef</p>
</blockquote>

<p>I think this is a good idea and prefer to do it this way</p>

<p>By the way, this is the layers(example 1) I try to feed into the FNN, do you have any suggestions?</p>

<pre><code>const arma::mat trainData = arma::randu&lt;arma::mat&gt;(4,4);
const size_t visibleSize = trainData.n_rows;
const size_t hiddenSize = trainData.n_rows / 2;
const double range = sqrt(6) / sqrt(visibleSize + hiddenSize + 1);

LinearLayer&lt;RMSPROP, RandomInitialization&gt;
        hiddenLayer(visibleSize, hiddenSize, {-range, range});
BiasLayer&lt;RMSPROP, RandomInitialization&gt; hiddenBiasLayer(hiddenSize);
BaseLayer&lt;LogisticFunction&gt; hiddenBaseLayer;

LinearLayer&lt;RMSPROP, RandomInitialization&gt;
        outputLayer(hiddenSize, visibleSize, {-range, range});
BiasLayer&lt;RMSPROP, RandomInitialization&gt; outputBiasLayer(hiddenSize);
BaseLayer&lt;LogisticFunction&gt; outputBaseLayer;

auto network = std::tie(hiddenLayer, hiddenBiasLayer, hiddenBaseLayer,
                        outputLayer, outputBiasLayer, outputBaseLayer);
auto resultLayer = OneHotLayer();
FFN&lt;decltype(network), OneHotLayer, SparseErrorFunction&gt;
        ffn(network, resultLayer);
</code></pre>

<blockquote>
<p>We have to implement a new performance function to calculate the reconstruction error</p>
</blockquote>

<p>This one may need to change the implementation details of the ann module.</p>

<p>There are two problems need to be solved</p>

<p>1 : The performance function of ann cannot store the condition by current implementation<br>
2 : The performance function cannot access w1 and w2 of the network</p>

<pre><code>template&lt;typename DataType, typename ErrorType, typename... Tp&gt;
double OutputError(const DataType&amp; target,
                   ErrorType&amp; error,
                   const std::tuple&lt;Tp...&gt;&amp; t)
{
  // Calculate and store the output error.
  outputLayer.CalculateError(
      std::get&lt;sizeof...(Tp) - 1&gt;(t).OutputParameter(), target, error);

  // Masures the network's performance with the specified performance
  // function.
  return PerformanceFunction::Error(
      std::get&lt;sizeof...(Tp) - 1&gt;(t).OutputParameter(), target);
}
</code></pre>

<p>As you see, what I could get from the Error api is the target(in autoencoder, it is the original training data) and the activation of the output layer(please refer to example 1), but not the w1 and w2 of the hidden layer and the output layer.But we need them to calculate the weightDecay. Besides, I guess the users may want to setup the weight of KL divergence and weightDecay too.</p>

<p>If we could store the PerformanceFunction, this problem could be solved.Rather than calling static Error function, call it like </p>

<pre><code>performanceFunction.Error(std::get&lt;sizeof...(Tp) - 1&gt;(t).OutputParameter(), target);
</code></pre>

<p>change the constructor to</p>

<pre><code>FFN(const LayerTypes&amp; network, OutputLayerType&amp; outputLayer, 
      PerformanceFunction performanceFunction = CrossEntropyErrorFunction())
    : network(network), outputLayer(outputLayer), trainError(0),
performance(std::forward&lt;PerformanceFunction&gt;(performanceFunction))
  {
    // Nothing to do here.
  }
</code></pre>

<p>And call it like</p>

<pre><code>const double beta = 0.3; //weight of KL divergence
const double lambda = 0.001; //weight of weight decay
FFN&lt;decltype(network), OneHotLayer, SparseErrorFunction&gt;
ffn(network, resultLayer, 
    SparseErrorFunction(hiddenLayer.Weights(), outputLayer.Weights(), beta, lambda));
</code></pre>

<p>I think this should be more flexible. The other question is, do you have any plans to provide move constructor and move assignments for ann modules? Most of the class would not be needed to change anything if armadillo already implement it, maybe a better way is ask armadillo implement one, have no idea why they do not provide it.</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">&mdash;<br>Reply to this email directly or <a href="https://github.com/mlpack/mlpack/pull/451#issuecomment-162156786">view it on GitHub</a>.<img alt="" height="1" src="https://github.com/notifications/beacon/AJ4bFBk-81JHwMuGxpGcaOmtp64ypfQxks5pMoGlgaJpZM4GAqt4.gif" width="1" /></p>
<div itemscope itemtype="http://schema.org/EmailMessage">
<div itemprop="action" itemscope itemtype="http://schema.org/ViewAction">
  <link itemprop="url" href="https://github.com/mlpack/mlpack/pull/451#issuecomment-162156786"></link>
  <meta itemprop="name" content="View Pull Request"></meta>
</div>
<meta itemprop="description" content="View this Pull Request on GitHub"></meta>
</div>