cでxor その2
概要
cでxorやってみた。
サンプルコード
#include <stdio.h>
#include <math.h>
#define NPATTERNS 4
#define NHIDDEN 8
#define randomdef ((float) random() / (float) ((1 << 31) - 1))
double forward(double state[]);
void backprop(double push, double target);
void WeightChangesHO(double error);
void WeightChangesIH(double error);
void initWeights();
void initData();
double sigmoid(double x);
double tanh(double x);
void testAll();
void calcOverallError();
double trainInputs[4][2] = {
{0, 0},
{1, 0},
{0, 1},
{1, 1}
};
static double trainOutputs[] = {0, 1, 1, 0};
static int numEpochs = 200;
static int numInputs = 2;
static int numPatterns = NPATTERNS;
static double LR_IH = 0.7;
static double LR_HO = 0.07;
static double h[NHIDDEN];
static double wih[4][NHIDDEN];
static double who[NHIDDEN];
static int patNum;
static double error;
static double outPred;
static double RMSerror;
double forward(double state[])
{
int i,
j;
for (i = 0; i < NHIDDEN; i++)
{
h[i] = 0.0;
for (j = 0; j < numInputs; j++)
{
h[i] = h[i] + (state[j] * wih[j][i]);
}
h[i] = tanh(h[i]);
}
double push = 0.0,
sum = 0.0;
for (i = 0; i < NHIDDEN; i++)
{
sum += h[i] * who[i];
}
push = sum;
return push;
}
void backprop(double push, double target)
{
error = push - target;
WeightChangesHO(error);
WeightChangesIH(error);
}
void WeightChangesHO(double error)
{
int k;
for (k = 0; k < NHIDDEN; k++)
{
double weightChange = LR_HO * error * h[k];
who[k] = who[k] - weightChange;
if (who[k] < -5) who[k] = -5;
else if (who[k] > 5) who[k] = 5;
}
}
void WeightChangesIH(double error)
{
int i,
k;
for (i = 0; i < NHIDDEN; i++)
{
double gradient = (1 - (h[i]) * h[i]) * who[i] * error * LR_IH;
for (k = 0; k < numInputs; k++)
{
double weightChange = gradient * trainInputs[patNum][k];
wih[k][i] = wih[k][i] - weightChange;
}
}
}
double tanh(double x)
{
if (x > 20) return 1;
else if (x < -20) return -1;
else
{
double a = exp(x);
double b = exp(-x);
return (a - b) / (a + b);
}
}
double test(int patternNumber)
{
patNum = patternNumber;
return forward(trainInputs[patNum]);
}
void calcOverallError()
{
int i;
RMSerror = 0.0;
for (i = 0; i < numPatterns; i++)
{
patNum = i;
forward(trainInputs[patNum]);
RMSerror = RMSerror + (error * error);
}
RMSerror = RMSerror / numPatterns;
RMSerror = sqrt(RMSerror);
}
void printWeights()
{
int i,
j;
for (i = 0; i < 2; i ++)
{
for (j = 0; j < 4; j ++)
{
printf("%.4f ", wih[i][j]);
}
printf(" ok\n");
}
for (i = 0; i < 4; i ++)
{
printf("%.4f ", who[i]);
}
printf ("\n");
}
void testAll()
{
int i;
double push;
for (i = 0; i < numPatterns; i++)
{
push = test(i);
printf ("pat%d expected = %.1f neural model = %.2f\n", patNum + 1, trainOutputs[patNum], push);
}
}
static void train()
{
int i,
j;
double push;
for (j = 0; j <= numEpochs; j++)
{
for (i = 0; i < numPatterns; i++)
{
patNum = (int) ((randomdef * numPatterns) - 0.001);
push = forward(trainInputs[patNum]);
backprop(push, trainOutputs[patNum]);
}
calcOverallError();
if (j % 100 == 0)
{
printf ("epoch = %d loss = %.4f\n", j, RMSerror);
testAll();
}
}
}
void initWeights()
{
int i,
j;
for (j = 0; j < NHIDDEN; j++)
{
who[j] = (randomdef - 0.5) / 2;
for (i = 0; i < numInputs; i++)
{
wih[i][j] = (randomdef - 0.5) / 5;
}
}
}
void init()
{
initWeights();
}
int main()
{
init();
train();
return 0;
}
成果物
#include <stdio.h>
#include <math.h>
#define NPATTERNS 4
#define NHIDDEN 8
#define randomdef ((float) random() / (float) ((1 << 31) - 1))
double forward(double state[]);
void backprop(double push, double target);
void WeightChangesHO(double error);
void WeightChangesIH(double error);
void initWeights();
void initData();
double sigmoid(double x);
double tanh(double x);
void testAll();
void calcOverallError();
double trainInputs[4][2] = {
{0, 0},
{1, 0},
{0, 1},
{1, 1}
};
static double trainOutputs[] = {0, 1, 1, 0};
static int numEpochs = 200;
static int numInputs = 2;
static int numPatterns = NPATTERNS;
static double LR_IH = 0.7;
static double LR_HO = 0.07;
static double h[NHIDDEN];
static double wih[4][NHIDDEN];
static double who[NHIDDEN];
static int patNum;
static double error;
static double outPred;
static double RMSerror;
double forward(double state[])
{
int i,
j;
for (i = 0; i < NHIDDEN; i++)
{
h[i] = 0.0;
for (j = 0; j < numInputs; j++)
{
h[i] = h[i] + (state[j] * wih[j][i]);
}
h[i] = tanh(h[i]);
}
double push = 0.0,
sum = 0.0;
for (i = 0; i < NHIDDEN; i++)
{
sum += h[i] * who[i];
}
push = sum;
return push;
}
void backprop(double push, double target)
{
error = push - target;
WeightChangesHO(error);
WeightChangesIH(error);
}
void WeightChangesHO(double error)
{
int k;
for (k = 0; k < NHIDDEN; k++)
{
double weightChange = LR_HO * error * h[k];
who[k] = who[k] - weightChange;
if (who[k] < -5) who[k] = -5;
else if (who[k] > 5) who[k] = 5;
}
}
void WeightChangesIH(double error)
{
int i,
k;
for (i = 0; i < NHIDDEN; i++)
{
double gradient = (1 - (h[i]) * h[i]) * who[i] * error * LR_IH;
for (k = 0; k < numInputs; k++)
{
double weightChange = gradient * trainInputs[patNum][k];
wih[k][i] = wih[k][i] - weightChange;
}
}
}
double tanh(double x)
{
if (x > 20) return 1;
else if (x < -20) return -1;
else
{
double a = exp(x);
double b = exp(-x);
return (a - b) / (a + b);
}
}
double test(int patternNumber)
{
patNum = patternNumber;
return forward(trainInputs[patNum]);
}
void calcOverallError()
{
int i;
RMSerror = 0.0;
for (i = 0; i < numPatterns; i++)
{
patNum = i;
forward(trainInputs[patNum]);
RMSerror = RMSerror + (error * error);
}
RMSerror = RMSerror / numPatterns;
RMSerror = sqrt(RMSerror);
}
void printWeights()
{
int i,
j;
for (i = 0; i < 2; i ++)
{
for (j = 0; j < 4; j ++)
{
printf("%.4f ", wih[i][j]);
}
printf(" ok\n");
}
for (i = 0; i < 4; i ++)
{
printf("%.4f ", who[i]);
}
printf ("\n");
}
void testAll()
{
int i;
double push;
for (i = 0; i < numPatterns; i++)
{
push = test(i);
printf ("pat%d expected = %.1f neural model = %.2f\n", patNum + 1, trainOutputs[patNum], push);
}
}
static void train()
{
int i,
j;
double push;
for (j = 0; j <= numEpochs; j++)
{
for (i = 0; i < numPatterns; i++)
{
patNum = (int) ((randomdef * numPatterns) - 0.001);
push = forward(trainInputs[patNum]);
backprop(push, trainOutputs[patNum]);
}
calcOverallError();
if (j % 100 == 0)
{
printf ("epoch = %d loss = %.4f\n", j, RMSerror);
testAll();
}
}
}
void initWeights()
{
int i,
j;
for (j = 0; j < NHIDDEN; j++)
{
who[j] = (randomdef - 0.5) / 2;
for (i = 0; i < numInputs; i++)
{
wih[i][j] = (randomdef - 0.5) / 5;
}
}
}
void init()
{
initWeights();
}
int main()
{
init();
train();
return 0;
}
以上。
Author And Source
この問題について(cでxor その2), 我々は、より多くの情報をここで見つけました https://qiita.com/ohisama@github/items/e38e7b482e8c8b4dab03著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .