参考にしたページに訓練データや結果や詳しいことが載っています.URL:http://blog.livedoor.jp/rtabaladi_58/ar ... 58901.html
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
//ディスプレイに仕切りを表示する関数
void partition(void)
{
int i;
for(i=0; i<20; i++){
printf("*");
}
printf("\n");
}
double sigmoid_1(int N, int l, double alpha, double *omega, double *dt[])
{
int i;
double s = 0;
for(i=0; i<=N; i++){
s += omega[i]*dt[l][i];
}
return 1/(1 + exp(-alpha*s));
}
double sigmoid_2(int N, int l, double alpha, double theta, double *omega, double *dt[])
{
int i;
double s = 0;
for(i=0; i<N; i++){
s += omega[i + 1]*dt[l][i];
}
return 1/(1 + exp(-alpha*(s - theta)));
}
int neuron_learning(int N, int num, double alpha, double epsilon, double omega[], double *dt[])
{
int i, k, count;
int count_MAX = pow(10, 6);
double grad, d_sigm;
double *initial_omega;
double convergence_value = pow(10, -6);
initial_omega = (double *)malloc(sizeof(double)*N);
srand((unsigned)time(NULL));
for(i=0; i<N+1; i++){
omega[i] = (((double)rand() / ((double)RAND_MAX + 1))*2.0 - 1.0)*0.01;
}
for(i=0; i<N+1; i++){
printf("初期重み\nω[%i] = %f\n", i, omega[i]);
}
for(i=0; i<=N; i++){
count = 0;
do{
for(k=0; k<num; k++){
d_sigm = alpha* sigmoid_1(N, k, alpha, omega, dt)*(1 - sigmoid_1(N, k, alpha, omega, dt));
grad = -2*(dt[k][N + 1] - sigmoid_1(N, k, alpha, omega, dt))*d_sigm*dt[k][i];
omega[i] -= epsilon*grad;
count ++;
}
if(count>count_MAX)break;
}while(fabs(grad) >= convergence_value);
}
return 0;
}
int use_of_neurons(int N, int num, double alpha, double omega[], double *dt_in[], double dt_out[])
{
int i, k;
for(i=0; i<num; i++){
dt_out[i] = sigmoid_2(N, i, alpha, -omega[0], omega, dt_in);
}
for(i=0; i<num; i++){
printf("y_%d = %f\n", i+1, dt_out[i]);
}
return 0;
}
int main(void)
{
int i, k, num, choice;
double eps;
double **data_set, **input, *output;
int N;//ニューロンの入力数
int check = 1;//ニューロンの学習を行ったか判定
double alpha;//シグモイド関数のゲイン
double *omega;//重み係数
do{
partition();
printf("[1] ニューロンの学習\n[2] 学習したニューロンの使用\n[0] 戻る\n");
partition();
printf("機能を選択してください : ");
scanf("%d", &choice);
partition();
switch (choice) {
case 1:
printf("学習率 ε を決定してください.\nε = ");
scanf("%lf", &eps);
partition();
printf("シグモイド関数のゲイン α を決定してください.\nα = ");
scanf("%lf", &alpha);
partition();
printf("入力数 N を決定してください.\nN = ");
scanf("%d", &N);
partition();
printf("訓練データの数を入力してください.:");
scanf("%d", &num);
partition();
omega = (double *)malloc(sizeof(double)*(N + 1));
data_set = (double **)malloc(sizeof(double *)*num);
for (i=0;i<num;i++) {
data_set[i] = (double *)malloc(sizeof(double)*(N + 2));
}
printf("訓練用データセットを決定してください.\n");
for(i=0; i<num; i++){
printf("%d つ目\n", i + 1);
data_set[i][0] = 1;
for(k=1; k<=N; k++){
printf("x_%d = ", k);
scanf("%lf", &data_set[i][k]);
}
printf(" y = ");
scanf("%lf", &data_set[i][N+1]);
printf("\n");
}
neuron_learning(N, num, alpha, eps, omega, data_set);
check = 0;
for(i=0; i<N+1; i++){
printf("重み\nω[%i] = %f\n", i, omega[i]);
}
for (i=0;i<num;i++) free(data_set[i]);
free(data_set);
break;
case 2:
if(check == 0){
printf("入力データの数を入力してください");
scanf("%d", &num);
partition();
input = (double **)malloc(sizeof(double *)*num);
for (i=0;i<num;i++) {
input[i] = (double *)malloc(sizeof(double)*N);
}
output = (double *)malloc(sizeof(double )*num);
printf("入力データセットを決定してください.\n");
for(i=0; i<num; i++){
printf("%d つ目\n", i+1);
for(k=0; k<N; k++){
printf("x_%d = ", k+1);
scanf("%lf", &input[i][k]);
}
}
use_of_neurons(N, num, alpha, omega, input, output);
for (i=0;i<num;i++) free(input[i]);
free(input);
}
else if(check == 1){
printf("ニューロンの学習を行ってください\n");
}
else{
printf("想定されていない動作が発生しました.\n");
}
break;
case 0:
break;
default:
printf("Unexpected characters were entered.\n");
}
partition();
}while(choice != 0);
free(omega);
return 0;
}