C 函数逼近的训练神经网络
我完全没有神经网络方面的经验,现在我只是在玩FANN library来学习它们。因此,目标是训练网络逼近正弦函数。为此,我使用了3层NN 1输入,3隐藏和1输出神经元。代码是C 函数逼近的训练神经网络,c,neural-network,fann,C,Neural Network,Fann,我完全没有神经网络方面的经验,现在我只是在玩FANN library来学习它们。因此,目标是训练网络逼近正弦函数。为此,我使用了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 *a
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);
const unsigned int num\u input=1;
const unsigned int num_output=1;
const unsigned int num_layers=3;
const unsigned int num_neurons_hidden=3;
结构范恩*安;
ann=fann\u创建标准(num\u层、num\u输入、num\u隐藏、num\u输出);
范数集、激活度、陡度、隐藏度(ann,1);
扇形集激活陡度输出(ann,1);
fann\u集合\u激活\u函数\u隐藏(ann,fann\u S形\u对称);
fann\u设置激活功能输出(ann,fann\u S形对称);
fann\u设置列车停止功能(ann,fann\u停止功能位);
风扇设置位失败极限(ann,0.01f);
fann_集训练算法(ann,fann_训练算法);
fann_随机化加权(ann,0,1);
对于(int i=0;i,您选择此行中的优化算法弹性反向传播(Rprop):
fann_set_training_algorithm(ann, FANN_TRAIN_RPROP);
是一种批更新算法。这意味着您必须为每次更新提供完整的训练集。的文档说明
此培训始终是增量培训(请参见fann_train_enum),因为只提供一种模式
因此,适当的优化选项是FANN\u TRAIN\u INCREMENTAL
。您必须使用以下方法之一进行批学习:FANN\u TRAIN\u on\u data
,FANN\u TRAIN\u on\u file
或FANN\u TRAIN\u epoch
当我更改您的代码时,我注意到:
- 您的陡度太高。我使用了默认值(0.5)
- 你的训练时间太少了。我用了大约20000个
- 你的函数对于只有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;
}
#包括
#包括
#包括
#包括
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;
常数浮动角度范围=3.0f;
常数浮动角度步长=0.1;
int实例=(int)(角度范围/角度步长);
结构范恩*安;
ann=fann\u创建标准(num\u层、num\u输入、num\u隐藏、num\u输出);
fann\u集合\u激活\u函数\u隐藏(ann,fann\u S形\u对称);
fann\u设置激活功能输出(ann,fann\u S形对称);
fann\u设置列车停止功能(ann,fann\u停止功能位);
风扇设置位失败极限(ann,0.02f);
fann\u集训练算法(ann,fann\u训练增量);
fann_随机化加权(ann,0,1);
fann\u列车数据*列车集;
trainingSet=fann\u create\u train(实例,1,1);//实例,输入维度,输出维度
浮动角度=0;
例如(int instance=0;instance输入[实例][0]=角度;
训练集->输出[实例][0]=sinf(角度);
}
fann_train_on_data(ann,trainingSet,20000,10,1e-8f);//年代,报告之间的年代,期望的错误
int k=0;
角度=0;
例如(int instance=0;instance
请注意,fann\u create\u train
从fann 2.2.0开始就可用。我目前找不到错误。但我不是一个风扇专家。您是否尝试过使用这些参数?优化算法(RPROP),隐藏单元数,训练时间。。。事实上,2个训练周期是不够的。我试图增加这个数字,但这并没有给我更好的结果。@alfa是的,我尝试了很多不同的参数。我认为问题在于只有一个输入和一个输出参数。你是对的。我马上就给你回信。