【发布时间】:2023-04-05 17:31:01
【问题描述】:
我目前正在做一个任务,需要我创建一个f(x) = x(1-x) 的神经网络。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define ITER 300000
#define L_RATE 0.5
#define N 11
#define I 1
#define J 4
#define K 1
#define SIGMOID(x) (1/(1+exp(-(x))))
所以我目前使用 4 个隐藏节点(J)和 0.5(L_RATE)的学习率,并计划将 11 个数据(N)作为训练的输入。
double error_v(double o, double t, double h)
{
return -(t-o)*o*(1-o)*h;
}
double error_w(double x, double h, double w, double t, double o)
{
return -x*h*(1-h)*w*(t-o)*o*(1-o);
}
这些将是每层权重的误差梯度。
int main(void)
{
double x[N][I];
double t[N][K];
double w[J][I+1];
double v[K][J+1];
double net_w[N][J];
double net_v[N][K];
double h[N][J];
double o[N][K];
for(int n=0; n<N; n++)
{
for(int i=0; i<I; i++)
{
x[n][i] = 0.1 * n;
t[n][i] = x[n][i] * (1 - x[n][i]);
}
}
//INITIALIZE WEIGHT
srand(time(NULL));
for(int j=0; j<J; j++)
{
for(int i=0; i<I+1; i++)
{
w[j][i] = (double)rand()/RAND_MAX*2.0-1.0;
printf("%.2f ", w[j][i]);
}
}
for(int k=0; k<K; k++)
{
for(int j=0; j<J+1; j++)
{
v[k][j] = (double)rand()/RAND_MAX*2.0-1.0;
printf("%.2f ", v[k][j]);
}
}
for(int iter=0; iter<ITER; iter++)
{
for(int n=0; n<N; n++)
{
//Initialize net zero
for(int j=0; j<J; j++)
{
net_w[n][j] = 0;
}
for(int k=0; k<K; k++)
{
net_v[n][k] = 0;
}
//Sum up net_w and produce h
for(int j=0; j<J; j++)
{
for(int i=0; i<I; i++)
{
net_w[n][j] += x[n][i] * w[j][i];
}
net_w[n][j] += 1 * w[j][I];
h[n][j] = SIGMOID(net_w[n][j]);
}
//Sum up net_v and produce o
for(int k=0; k<K; k++)
{
for(int j=0; j<J; j++)
{
net_v[n][k] += h[n][k] * v[k][j];
}
net_v[n][k] += 1 * v[k][J];
o[n][k] = SIGMOID(net_v[n][k]);
}
}
所以直到这里,我通过将输入(包括一个偏差)和权重(w)相乘来计算第一个净值,通过将第一个网络的“sigmoided”值(包括一个偏差)和权重相乘来计算第二个净值(五)。
for(int n=0; n<N; n++)
{
//error_v
for(int k=0; k<K; k++)
{
for(int j=0; j<J; j++)
{
v[k][j] -= L_RATE * error_v(o[n][k], t[n][k], h[n][j]);
}
v[k][J] -= L_RATE * error_v(o[n][k], t[n][k], 1);
}
}
for(int n=0; n<N; n++)
{
//error_w
for(int j=0; j<J; j++)
{
for(int i=0; i<I; i++)
{
for(int k=0; k<K; k++)
{
w[j][i] -= L_RATE * error_w(x[n][i], h[n][j], w[k][j], t[n][k], o[n][k]);
}
}
for(int k=0; k<K; k++)
{
w[j][I] -= L_RATE * error_w(1, h[n][j], w[k][j], t[n][k], o[n][k]);
}
}
}
}
但这就是问题所在。我通过将学习率和误差梯度乘以以下公式来纠正权重的误差。 我想我必须在第二层使用 3-for-loop,对于输入层、隐藏层、输出层和训练数据的每个数量,我必须使用 4-for-loop。
printf("INPUT\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", x[n][0]);
}
printf("\n");
printf("OUTPUT\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", o[n][0]);
}
printf("\n");
printf("EXPECTED\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", t[n][0]);
}
printf("\n");
return 0;
}
但是当我打印出经过训练的输出时,它并没有接近预期的数据,而是卡在了一个特定的值上。
我看到很多其他人都遇到过这类问题,他们的解决方案是给初始权重随机非零值或改变学习率或迭代次数。我已经这样做了很多次,但它似乎与我的问题不符。如果有人能告诉我我现在做错了什么,我将非常感激。
【问题讨论】:
标签: c machine-learning neural-network artificial-intelligence