首页 > 解决方案 > FANN:使用从多个文件读取的数据训练 ANN 时的内存泄漏

问题描述

我有以下循环:

for (int i = 1; i <= epochs; ++i) {
    for (std::vector<std::filesystem::path>::iterator it = batchFiles.begin(); it != batchFiles.end(); ++it) {
        struct fann_train_data *data = fann_read_train_from_file(it->string().c_str());
        fann_shuffle_train_data(data);
        float error = fann_train_epoch(ann, data);
    }
}

ann是网络。
batchFiles是一个std::vector<std::filesystem::path>

此代码遍历文件夹中的所有训练数据文件,并每次使用它来训练 ANN,次数由epochs变量确定。

以下行导致内存泄漏:

struct fann_train_data *data = fann_read_train_from_file(it->string().c_str());

问题是我必须不断地在训练文件之间切换,因为我没有足够的内存来一次加载它们,否则我只会加载一次训练数据。

为什么会这样?我该如何解决这个问题?

标签: c++memory-leaksneural-networkfann

解决方案


在 C++ 中,当管理它的对象超出范围时,会自动释放内存。(假设类被正确编写。)这就是所谓的RAII

但 FANN 提供的是 C API,而不是 C++ API。在 C 中,您需要在完成后手动释放内存。通过扩展,当 C 库为您创建一个对象时,它通常需要您在完成该对象时告诉它。该库没有一个很好的方法来自行确定何时应该释放对象的资源。

惯例是,只要 C API 为您提供类似的函数struct foo* create_foo(),您就应该寻找相应的函数,例如void free_foo(struct foo* f). 它是对称的。

在您的情况下,正如 PaulMcKenzie 最初指出的那样,您需要void fann_destroy_train_data(struct fann_train_data * train_data). 从文档中,强调我的:

销毁训练数据并正确释放所有相关数据。 请务必在使用完训练数据后调用此函数。


推荐阅读