Computational Intelligence/Neural Networks

최소 평균 제곱법 (Least Mean Squares Method, Widrow-Hoff Learning) [두번째]

초인로크 2016. 6. 20. 12:54
반응형

최초작성일:2016.6.20


이전의 글에 이어서 프로그래밍 연습을 해 보는 것이니, 이전글을 참고 하고 싶은 분은 아래의 링크를 따라가 주길 바란다.

(이전글의 링크: 최소 평균 제곱법 (Least Mean Squares Method, Widrow-Hoff Learning) [첫번째])


위와같이 A와 B의 집단을 가로지르는 직선 y에 대한 함수가 있다고 가정할때 그 값을 구하기 위한 Adaline의 적용례 이다.


위의 그래프를 기준으로, 두가지 입력 A,B에 따라서 출력값이 달라져야 한다.

따라서, 선분 y의 학습에 따른 그룹을 분류하기 위해, A: 1, B: -1로 하여 두 그룹을 분리한다.


먼저 학습을 위한 뉴런을 디자인 하자면 아래와 같이 나타 낼 수 있다.


위의 뉴런구조에 대한 출력값의 계산식은 아래와 같다.


여기서 b는 바이어스 값으로, 그래프 상으로 비유하자면 y절편에 해당되는 값이다.

이 바이어스를 넣지 않으면, 원점을 지나는 그래프의 수식에 대한 학습밖에 진행되지 않는다.

위의 수식에 대해 A, B 그룹으로 분류하기 위한 기준을 아래의 그림에서 나타낸다.




여기서 학습가중치에 대한 y값을 시그마를 이용하여 간략하게 나타 낼 수 있는데,


이때는 위와같이 로 두어서 로 두는 방법도있다.


각 그룹에 대한 입력값은 C언어를 이용하여 아래와 같이 나타 낼 수 있다.


1
2
3
4
5
6
7
8
9
10
11
void NomalInput(int k){
    if(k%2==0){
        x[k][1= 5.0 + normal_random_number() * 0.05;
        x[k][2= 1.0 + normal_random_number() * 0.05;
        x[k][3= 1.0;
    }else{
        x[k][1= 1.0 + normal_random_number() * 0.05;
        x[k][2= 5.0 + normal_random_number() * 0.05;
        x[k][3= -1.0;
    }
}
cs

2의 배수에 따라 (3,1)과 (1,3) 부근에 밀집하도록 점을 찍는다.

이 점들을 가로지르는 선분을 찾기 위해 뉴럴 네트워크의 학습을 이용한다.


가중치의 초기값을 0으로 초기화 하는 일이 없도록 해야 한다.

계산식이 곱셈으로 이루어 져 있기 때문에 0을 곱해버리면 학습이 진행되지 않는다.

따라서, 아래와 같이 가중치와 b값을 초기화 하였다.


1
2
3
4
5
6
void WeightsInit(){
    w[0][1= normal_random_number() * 0.001;
    w[0][2= normal_random_number() * 0.001;
    //바이어스 b
    b[0= normal_random_number() * 0.001;
}
cs

여기서는 위와같이 적당한 난수값을 이용하여서 초기 가중치를 적용하였다.


지난번에 설명을 했던 가중치를 갱신하기 위한 수식을 가져온다.


이것을 C언어로 프로그래밍 하면 아래와 같이 만들수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
void Adaline(int k){
    double mu=0.05;
    
    if(k%2==0){
        w[0][1+= mu*(1-y[k])*x[k][1];
        w[0][2+= mu*(1-y[k])*x[k][2];
        b[0+= mu* (1-y[k]);
    }else{
        w[0][1+= mu*(-1-y[k])*x[k][1];
        w[0][2+= mu*(-1-y[k])*x[k][2];
        b[0+= mu* (-1-y[k]);
    }
}
cs

우리가 구하고자 하는 값은 두 종류로 (Desire)값이 1 혹은 -1일때로 나뉠수 있다.

따라서 if문을 이용하여서 y값 보다 클 경우에는 1을 반대의 경우는 -1을 적용해 준다.

여기서 값은 학습이 진동하거나, 너무 세밀하게 진행되지 않도록 적당히 적용 할 필요가 있다.


이와같은 학습규칙을 실행하는 메인문을 구현하면 아래와 같이 나태 날 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
int main(int argc, const char * argv[]) {
 
    int k;
    srand((unsigned int)time(NULL));
    
    //입력부분
    for(i=0;i<100;i++){
        NomalInput(i);
    }
    
    WeightsInit();
        
    for(i=0;i<5000;i++){
        k=(int)(random_number()*100);
        y[k] = w[0][1]*x[k][1+ w[0][2]*x[k][2+ b[0];
        Adaline(k);
    }
    
    //출력부분
    printf("w[0][1]:%lf, \t w[0][2]:%lf, \t b[0]:%lf\n",w[0][1],w[0][2],b[0]);
    
    for (i=0;i<100;i++){
        y[i] = w[0][1]*x[i][1+ w[0][2]*x[i][2+ b[0];
    }
    
    printf("The group of +1\n");
    for(i=0;i<100;i++){
        if(y[i]>=0){
            printf("y[%d]:%lf\t",i,y[i]);
        }
    }
    
    printf("\nThe group of -1\n");
    for(i=0;i<100;i++){
        if(y[i]<0){
            printf("y[%d]:%lf\t",i,y[i]);
        }
    }
    printf("\n");
    
    return 0;
}
cs

위의 소스를 실행 한 결과는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
w[0][1]:0.247976,      w[0][2]:-0.257816,      b[0]:0.004910
The group of +1
y[0]:1.002532    y[2]:0.980550    y[4]:0.999439    y[6]:0.993767    y[8]:0.967772    
y[10]:1.002970    y[12]:0.959107    y[14]:0.988246    y[16]:0.999693    y[18]:0.954653    
y[20]:0.962063    y[22]:0.994093    y[24]:0.964085    y[26]:1.009830    y[28]:0.997437    
y[30]:0.970826    y[32]:0.979284    y[34]:0.999618    y[36]:0.968749    y[38]:0.988110    
y[40]:0.989170    y[42]:0.953714    y[44]:0.989208    y[46]:0.993478    y[48]:0.953484    
y[50]:0.996792    y[52]:0.959610    y[54]:0.979793    y[56]:1.018864    y[58]:0.941375    
y[60]:1.005707    y[62]:0.999593    y[64]:0.974662    y[66]:0.986495    y[68]:0.986200    
y[70]:0.983751    y[72]:0.992835    y[74]:0.967915    y[76]:0.982125    y[78]:0.982757    
y[80]:0.982970    y[82]:0.993718    y[84]:0.992167    y[86]:0.990641    y[88]:0.986043    
y[90]:0.988128    y[92]:0.965995    y[94]:0.974769    y[96]:1.003075    y[98]:0.976202    
The group of -1
y[1]:-1.018287    y[3]:-1.033705    y[5]:-1.048605    y[7]:-1.062589    y[9]:-1.026541    
y[11]:-1.030194    y[13]:-1.062776    y[15]:-1.018513    y[17]:-1.030166    y[19]:-1.025713    
y[21]:-1.006285    y[23]:-1.035965    y[25]:-1.048838    y[27]:-1.042318    y[29]:-1.038815    
y[31]:-1.043376    y[33]:-1.057584    y[35]:-1.034113    y[37]:-1.013286    y[39]:-1.045135    
y[41]:-1.042454    y[43]:-1.020391    y[45]:-1.053301    y[47]:-1.042524    y[49]:-1.052358    
y[51]:-1.057190    y[53]:-1.026822    y[55]:-1.050978    y[57]:-1.028512    y[59]:-0.985872    
y[61]:-1.044279    y[63]:-1.048507    y[65]:-1.036589    y[67]:-1.024148    y[69]:-1.024108    
y[71]:-1.037620    y[73]:-1.053545    y[75]:-0.999278    y[77]:-1.025617    y[79]:-1.032241    
y[81]:-1.031482    y[83]:-1.043788    y[85]:-1.030256    y[87]:-1.026200    y[89]:-1.049062    
y[91]:-1.020469    y[93]:-1.073367    y[95]:-1.071565    y[97]:-1.025625    y[99]:-1.010947    
Program ended with exit code: 0
cs

가중치 w를 학습 한 결과에 대한 값과, A, B에 대해 1, -1에 근접한 두 그룹으로 나뉘어진 것을 잘 알수있다.


여기에 작성하는 모든 포스팅 들은 스스로의 지식의 정리와, 지식의 공유 차원에서 정리한 것입니다.

학교의 레포트나 과제등은, 본인 스스로가 공부를 해서 직접 제출 하도록 합시다.

반응형