对机器学习有点好奇,我已经开始阅读一些与该主题相关的入门教程。因此,几天前我发现了一个非常简单的神经网络示例,使用带有numpy
库的Python实现,为了实践目的,我决定使用C ++实现相同的算法,尽可能减少外部库。 / p>
然后,我首先编写了一个能够处理矩阵定义/声明和相关数学运算的简单类,如加法,乘法等。我雄辩地将该类命名为Matrix
。
这是它的头文件:
template <typename T>
class Matrix {
public:
Matrix(int numRows, int numColumns);
~Matrix();
int getRows();
int getColumns();
T readValue(int row, int column);
void writeValue(int row, int column, T value);
Matrix<T> operator+(Matrix<T> other);
Matrix<T> operator-(Matrix<T> other);
Matrix<T> operator*(T scalar);
Matrix<T> operator*(Matrix<T> other);
Matrix<T> entrywiseProduct(Matrix<T> other);
Matrix<T> transpose();
void print();
private:
const int rows;
const int columns;
T** matrix;
};
如您所见,为了分配正确的内存大小,我决定让类构造函数需要两个不同的参数,即行数和列数。
无论如何,在这个简要解释的类的定义之后,我开始编写网络实现的主类。特别是,这个更抽象的类将主要使用Matrix
类进行大多数操作。这是标题:
#include "Matrix.h"
template <typename T>
class Neuron {
public:
Neuron(int matrixRows, int matrixColumns);
~Neuron();
Matrix<T> estimate(Matrix<T> inputMatrix);
void train(Matrix<T> inputMatrix, Matrix<T> outputMatrix, int iterations);
private:
Matrix<T> weights;
};
尽管它不够优雅,但这个类构造函数还需要两个与矩阵相关的输入参数:这是因为它们将用于在类中正确实例化加权系数存储的矩阵。
这就是问题:在Neuron
类初始化之后,应该明确地实例化所提到的矩阵。据我所知,这种操作需要使用一个指针,该指针将被new
函数引用 - 在这种情况下 - 用于动态实例化Matrix
类。但是,另一方面,我已经决定使用矩阵的操作总是返回一个新矩阵,而不是指向矩阵的指针,正如您在第一个类头中看到的那样。
所以,我将问你:是否有可能在Neuron
构造函数中定义一个矩阵并将其用作类变量,如前一个头文件中所定义的那样?通过这种方式,我可以在对weights
命名矩阵进行操作时覆盖相同的变量
如果是,我该怎么做?
答案 0 :(得分:4)
是;像应该初始化任何其他类成员一样初始化矩阵:在构造函数的member initialisation list中。
Neuron::Neuron(int matrixRows, int matrixColumns)
: weights(matrixRows, matrixColumns)
{}
执行此操作时:
T::T()
{
member = firstValue;
}
这不是初始化,而是分配。如果成员的类型没有默认构造函数,那么当你说这是不够的时,你是正确的,因为如果你不自己初始化一个成员,编译器会尝试为你初始化它,并且它不能提供它没有的参数知道关于。如果由于某种原因无法正确初始化您的成员(例如,需要首先收集信息),则智能指针/动态分配是一种常见的解决方法。
顺便说一句,T**
建议你创建一个指针数组。 Don't do that;它非常低效且过于复杂。只需创建一个宽度为×高度T
的数组,并相应地映射索引(i = y×width + x; x = i%width; y = i / width)。