将数组作为参数传递时,调节内存的最有效方法是什么?

Dom*_*rro 1 c++ arrays pointers instantiation neural-network

我学会了用 Python 编程,现在刚刚学习 C++,所以如果我使用的术语不是传统的(也没有comp. sci. 教育或背景),我深表歉意。

我正在尝试用 C++ 构建一个神经元。权重通常作为数组传递。在实例化神经元时,我需要传递一组权重。我一直试图让神经元对象只引用指针,这样我就不必复制,但我一直做错事。有人可以更改此代码,这样我就不会复制数组,然后解释您做了什么,为什么要这样做?

class Neuron {
    private:
        double bias;
        int num_weights;
        double weights[];
    public:
        Neuron(double*, int, double);
        double forward_prop(double[]);
};

Neuron::Neuron(double weights[], int num_weights, double bias) {
    this->num_weights = num_weights;
    this->bias = bias;
    // rotate through weights pointer and reassign to object attribute 'weights'
    for (int i=0;i<this->num_weights;i++) {
        this->weights[i] = weights[i];
    }
    // TODO: delete pointer

}

double Neuron::forward_prop(double values[]) {
    double output = this->bias;

    for (int i=0; i < this->num_weights; i++) {
        output += this->weights[i] * values[i];
    }
    return output;

}
Run Code Online (Sandbox Code Playgroud)

Pau*_*zie 5

这是您的类的重写,没有对象复制,并使用 C++ 标准库。下面的示例std::vector与移动语义一起使用以避免复制数据。代码示例之后的注释:

#include <vector>
#include <numeric>
#include <iostream>

class Neuron 
{
    private:
        std::vector<double> weights;  // We use a vector of doubles, not an array
        double bias; 

    public:
    
        Neuron(std::vector<double>&, double);
        double forward_prop(const std::vector<double>&);
};

Neuron::Neuron(std::vector<double>& weights_, double bias_) : weights(std::move(weights_)), bias(bias_) // The std::move avoids the copy
{}

double Neuron::forward_prop(const std::vector<double>& values) 
{
    // the std::inner_product function does what your code is doing now
    return std::inner_product(weights.begin(), weights.end(), values.begin(), bias);
}

int main()
{
    std::vector<double> myWeights {1,2,3,4};
    Neuron n(myWeights, 10);
    std::cout << n.forward_prop({5,6,7,8});
}
Run Code Online (Sandbox Code Playgroud)

输出:

80
Run Code Online (Sandbox Code Playgroud)

以下是关键点:

  1. std::vector是用来代替数组和指针。请注意,我们不再需要num_weights成员变量,因为向量已经通过调用 的size()成员函数知道它自己的大小std::vector

  2. Neuron构造函数中,std::move当我们将传入的向量分配给对象的成员时,我们会发出一个调用。这会调用内置于std::vector. 基本上,源向量使用的指针被“窃取”或移动到目标向量中,从而避免了复制。

请注意,完成此操作后将更改源向量。传入的向量实际上将变为空(请记住,它的内容已移出)。

  1. 最重要的是,我forward_prop使用std::inner_product实现了你。

  2. 附加项——在编写构造函数时注意成员初始化列表的用法。此外,对 的调用forward_prop利用了 的大括号初始化语法std::vector,这就是为什么当我们调用 时forward_prop,不需要显式声明std::vector<double>


请注意,真正的要点是从 C++11 开始,移动语义被正式引入到语言中。这允许以正式的方式进行移动(而不是复制)。

随着移动语义现在成为可能,添加了额外的功能(例如std::move,移动构造函数和移动赋值运算符,emplace_back某些 STL 容器类中的成员函数,std::unique_ptr可以工作而不是有些破损的std::auto_ptr,等等)。

在 C++11 之前,您必须使用指针“技巧”或希望编译器的优化器隐式移动(即使此类操作没有正式名称)。