다중 퍼셉트론 (XOR 구현)작동이 안되요 ㅠㅠ

조회수 1281회
#include<math.h>
#include<stdio.h>
#include<stdlib.h>

int num_input = 2;
int num_hidden = 2;
int num_output = 1;
int num_train = 4;

double input[4][3];
double hidden[3] = { 0, 0, 1 };
double output[4][1] = { 0 };

double hidden_weight[2][3]; //[num_hidden][num_input +1] bias 때문에 +1
double output_weight[2][3]; //[num_output][num_hidden +1] bias 때문에 +1

void Train(int num_train, double learning_rate, double input[][3], double target_output[4]);
void Compute_Output(double input[][3], double hidden[], double output[][1], int num_train);

int main(void)
{
    int i,j;

    double learning_rate = 0.1;

    double target_output[4];

    input[0][0] = 0;    input[0][1] = 0;    input[0][2] = 1;
    input[1][0] = 1;    input[1][1] = 0;    input[1][2] = 1;
    input[2][0] = 0;    input[2][1] = 1;    input[2][2] = 1;
    input[3][0] = 1;    input[3][1] = 1;    input[3][2] = 1;

    target_output[0] = 0;
    target_output[1] = 1;
    target_output[2] = 1;
    target_output[3] = 0;

    Train(num_train, learning_rate, input, target_output);

    for(i=0; i<num_train; i++){
        printf("입력 : ");
        for(j=0; j<num_input; j++){
            printf("%lf ", input[i][j]);
        }

        printf("출력 : ");
        for(j=0; j<num_output; j++){
            printf("  %lf", output[i][j]);
        }
        printf("\n");
    }

    return 0;
}

void Train(int num_train, double learning_rate, double input[][3], double target_output[4])
{
    int i,j,k;

    int num_epoch = 0;
    int max_epoch = 10000;
    double error = 0;
    double net = 0;

    double hidden_derivative[2] = { 0 };
    double output_derivative[1] = { 0 };

    srand(0);
    for(i=0; i<num_hidden; i++){
        for(j=0; j<num_input +1; j++){
            hidden_weight[i][j] = 0.2 * rand() / RAND_MAX - 0.1;
        }
    }
    for(i=0; i<num_output; i++){
        for(j=0; j<num_hidden +1; j++){
            output_weight[i][j] = 0.2 * rand() / RAND_MAX - 0.1;
        }
    }

    do
    {
        net = 0;
        error = 0;

        for(i=0; i<num_train; i++){
            Compute_Output(input, hidden, output, i);

            // 출력층 가중치에 대한 학습
            for(j=0; j<num_output; j++){
                output_derivative[j] = learning_rate * (output[i][j] - target_output[i]) * (1 - output[i][j]) * output[i][j];
            }

            for(j=0; j<num_output; j++){
                for(k=0; k<num_hidden; k++){
                    output_weight[j][k] -= output_derivative[j] * hidden[k];
                }
                output_weight[j][num_hidden] -= output_derivative[j];
            }

            // 은닉층 가중치에 대한 학습
            for(j=0; j<num_hidden; j++){
                net = 0;

                for(k=0; k<num_output; k++){
                    net += output_derivative[k] * output_weight[k][j];
                }
                hidden_derivative[j] = net * (1 - hidden[j]) * hidden[j];
            }

            for(j=0; j<num_hidden; j++){
                for(k=0; k<num_input; k++){
                    hidden_weight[j][k] -= hidden_derivative[j] * input[i][k];
                }
                hidden_weight[j][num_input] -= hidden_derivative[j];
            }
            // 오차 계산
            for(j=0; j<num_output; j++){
                error += 0.5 * (output[i][j] - target_output[i]) * (output[i][j] - target_output[i]);
            }
        }
        if(num_epoch % 500 == 0){
            printf("반복횟수 : %d, 오차 : %lf\n", num_epoch, error);
        }
    }while(num_epoch++ < max_epoch);
}

void Compute_Output(double input[][3], double hidden[], double output[][1], int num_train)
{
    int i,j;
    double net = 0;

    for(i=0; i<num_hidden; i++){
        for(j=0; j<num_input; j++){
            net += input[num_train][j] * hidden_weight[i][j];
        }
        net += input[num_train][num_input] * hidden_weight[i][num_input];
        hidden[i] = 1 / (1 + exp(-net));

        net = 0;
    }
    for(i=0; i<num_output; i++){
        for(j=0; j<num_hidden; j++){
            net += hidden[j] * output_weight[i][j];
        }
        net += hidden[num_hidden] * output_weight[i][num_hidden];
        output[num_train][i] = 1 / (1 + exp(-net));

        net =0;
    }
}

다중 퍼셉트론을 이용하면 XOR이 실행 되어야하는데 AND랑 OR은 실행이 되는데 XOR만 안되네요.. 어디가 어떻게 잘못 된건지 전혀 모르겠네요 ㅠㅠ

  • (•́ ✖ •̀)
    알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)