C++ 单层多输出感知器的异常行为

一些背景信息:

我在C++中编写了一个单层多输出感知器类。它使用典型的WX + b判别函数,并允许用户定义激活函数。我已经相当彻底地测试了所有内容,一切似乎都按预期工作。我注意到代码中有一个小逻辑错误,当我尝试修复它时,网络的表现比之前差得多。错误如下:

我使用以下代码评估每个输出神经元的值:

output[i] =          activate_(std::inner_product(weights_[i].begin(), weights_[i].end(),                                       features.begin(), -1 * biases_[i]));

在这里,我将偏置输入视为固定的-1,但当我对每个偏置应用学习规则时,我将输入视为+1。

// 偏置可以被视为具有恒定特征值1的权重。biases_[i] = weight_update(1, error, learning_rate_, biases_[i]);

所以我尝试通过更改对weight_updated的调用来修复我的错误,使其与输出评估一致:

biases_[i] = weight_update(-1, error, learning_rate_, biases_[i]);

但这样做导致准确率下降了20%!过去几天我一直在试图找出代码中可能解释这种奇怪行为的其他逻辑错误,但一无所获。是否有比我更有知识的人能提供一些见解?我在下面提供了整个类供参考。提前感谢您。

#ifndef SINGLE_LAYER_PERCEPTRON_H#define SINGLE_LAYER_PERCEPTRON_H#include <cassert>#include <functional>#include <numeric>#include <vector>#include "functional.h"#include "random.h"namespace qp {namespace rf {namespace {template <typename Feature>double weight_update(const Feature& feature, const double error,                     const double learning_rate, const double current_weight) {  return current_weight + (learning_rate * error * feature);}template <typename T>using Matrix = std::vector<std::vector<T>>;}  // namespacetemplate <typename Feature, typename Label, typename ActivationFn>class SingleLayerPerceptron { public:  // 仅用于测试。  SingleLayerPerceptron(const Matrix<double>& weights,                        const std::vector<double>& biases, double learning_rate)      : weights_(weights),        biases_(biases),        n_inputs_(weights.front().size()),        n_outputs_(biases.size()),        learning_rate_(learning_rate) {}  // 用[-1, 1]范围内的随机权重和偏置初始化层。  SingleLayerPerceptron(std::size_t n_inputs, std::size_t n_outputs,                        double learning_rate)      : n_inputs_(n_inputs),        n_outputs_(n_outputs),        learning_rate_(learning_rate) {    weights_.resize(n_outputs_);    std::for_each(        weights_.begin(), weights_.end(), [this](std::vector<double>& wv) {          generate_back_n(wv, n_inputs_,                          std::bind(random_real_range<double>, -1, 1));        });    generate_back_n(biases_, n_outputs_,                    std::bind(random_real_range<double>, -1, 1));  }  std::vector<double> predict(const std::vector<Feature>& features) const {    std::vector<double> output(n_outputs_);    for (auto i = 0ul; i < n_outputs_; ++i) {      output[i] =          activate_(std::inner_product(weights_[i].begin(), weights_[i].end(),                                       features.begin(), -1 * biases_[i]));    }    return output;  }  void learn(const std::vector<Feature>& features,             const std::vector<double>& true_output) {    const auto actual_output = predict(features);    for (auto i = 0ul; i < n_outputs_; ++i) {      const auto error = true_output[i] - actual_output[i];      for (auto weight = 0ul; weight < n_inputs_; ++weight) {        weights_[i][weight] = weight_update(            features[weight], error, learning_rate_, weights_[i][weight]);      }      // 偏置可以被视为具有恒定特征值1的权重。      biases_[i] = weight_update(1, error, learning_rate_, biases_[i]);    }  } private:  Matrix<double> weights_;      // n_outputs x n_inputs  std::vector<double> biases_;  // 1 x n_outputs  std::size_t n_inputs_;  std::size_t n_outputs_;  ActivationFn activate_;  double learning_rate_;};struct StepActivation {  double operator()(const double x) const { return x > 0 ? 1 : -1; }};}  // namespace rf}  // namespace qp#endif /* SINGLE_LAYER_PERCEPTRON_H */

回答:

我最终解决了这个问题…

我的修复确实是正确的,准确率的损失只是由于拥有幸运(或不幸)的数据集所致。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注