gpt4 book ai didi

c - 训练神经网络进行函数逼近

转载 作者:行者123 更新时间:2023-12-04 11:29:42 24 4
gpt4 key购买 nike

我完全没有神经网络方面的经验,现在我只是在玩 FANN 库来学习它们。所以目标是训练网络逼近正弦函数。为此,我使用 3 层 NN 1 个输入、3 个隐藏神经元和 1 个输出神经元。代码是

const unsigned int num_input = 1;
const unsigned int num_output = 1;
const unsigned int num_layers = 3;
const unsigned int num_neurons_hidden = 3;

struct fann *ann;

ann = fann_create_standard(num_layers, num_input, num_neurons_hidden, num_output);

fann_set_activation_steepness_hidden(ann, 1);
fann_set_activation_steepness_output(ann, 1);

fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(ann, FANN_SIGMOID_SYMMETRIC);

fann_set_train_stop_function(ann, FANN_STOPFUNC_BIT);
fann_set_bit_fail_limit(ann, 0.01f);

fann_set_training_algorithm(ann, FANN_TRAIN_RPROP);

fann_randomize_weights(ann, 0, 1);

for(int i=0; i<2; ++i) {
for(float angle=0; angle<10; angle+=0.1) {
float sin_anle = sinf(angle);
fann_train(ann, &angle, &sin_anle);
}
}

int k = 0;
for(float angle=0; angle<10; angle+=0.1) {
float sin_anle = sinf(angle);
float *o = fann_run(ann, &angle);
printf("%d\t%f\t%f\t\n", k++, *o, sin_anle);
}

fann_destroy(ann);

但是我得到的结果与实正弦函数无关。我想我的网络设计存在一些基本错误。

最佳答案

您在此行中选择优化算法 Resilient Backpropagation (Rprop):

fann_set_training_algorithm(ann, FANN_TRAIN_RPROP);

Rprop是一种批量更新算法。这意味着您必须为每次更新提供整个训练集。 fann_train 的文档说

This training is always incremental training (see fann_train_enum), since only one pattern is presented.

因此,合适的优化选项是 FANN_TRAIN_INCREMENTAL。您必须使用以下方法之一进行批量学习:fann_train_on_datafann_train_on_filefann_train_epoch

我在更改您的代码时注意到的是:

  • 你的坡度太高了。我使用了默认值 (0.5)。
  • 您的训练周期太少。我用了大约 20,000。
  • 你的函数对于只有 3 个隐藏神经元来说太复杂了。这一点都不容易,因为它是一个周期函数。所以我把我逼近的正弦函数的取值范围改成了[0,3]这样就简单多了。
  • 位失败限制太难了。 :) 我将其设置为 0.02f
  • Rprop 不是一个很好的训练算法,他们应该实现像 Levenberg-Marquardt 这样的算法,速度要快得多。

我得到的解决方案并不完美,但至少是大致正确的:

0       0.060097        0.000000
1 0.119042 0.099833
2 0.188885 0.198669
3 0.269719 0.295520
4 0.360318 0.389418
5 0.457665 0.479426
6 0.556852 0.564642
7 0.651718 0.644218
8 0.736260 0.717356
9 0.806266 0.783327
10 0.860266 0.841471
11 0.899340 0.891207
12 0.926082 0.932039
...

我使用了这个修改后的代码:

#include <cstdio>
#include <cmath>
#include <fann.h>
#include <floatfann.h>

int main()
{
const unsigned int num_input = 1;
const unsigned int num_output = 1;
const unsigned int num_layers = 3;
const unsigned int num_neurons_hidden = 2;

const float angleRange = 3.0f;
const float angleStep = 0.1;
int instances = (int)(angleRange/angleStep);

struct fann *ann;

ann = fann_create_standard(num_layers, num_input, num_neurons_hidden, num_output);

fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(ann, FANN_SIGMOID_SYMMETRIC);

fann_set_train_stop_function(ann, FANN_STOPFUNC_BIT);
fann_set_bit_fail_limit(ann, 0.02f);

fann_set_training_algorithm(ann, FANN_TRAIN_INCREMENTAL);

fann_randomize_weights(ann, 0, 1);

fann_train_data *trainingSet;
trainingSet = fann_create_train(instances, 1, 1); // instances, input dimension, output dimension
float angle=0;
for(int instance=0; instance < instances; angle+=angleStep, instance++) {
trainingSet->input[instance][0] = angle;
trainingSet->output[instance][0] = sinf(angle);
}

fann_train_on_data(ann, trainingSet, 20000, 10, 1e-8f); // epochs, epochs between reports, desired error

int k = 0;
angle=0;
for(int instance=0; instance < instances; angle+=angleStep, instance++) {
float sin_angle = sinf(angle);
float *o = fann_run(ann, &angle);
printf("%d\t%f\t%f\t\n", k++, *o, sin_angle);
}

fann_destroy(ann);

return 0;
}

注意 fann_create_train 从 FANN 2.2.0 开始可用。

关于c - 训练神经网络进行函数逼近,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10588862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com