jasu's blog
블로그 메뉴글
Multipayer Perceptron(EBP 알고리즘 구현 프로그램)
프 로그램 구현 과정에서 처음에는 5 by 5픽셀로 설정을 하여 패턴을 입력한 결과 숫자들이 서로 비슷한 픽셀 안에서 학습을 하기 때문에 학습율이 저조한 편이었습니다. 그래서 픽셀의 수를 7 by 7로 하여 구현해 보았습니다. 앞의 5 by 5 픽셀에 비해서는 좀더 나은 학습율을 보였지만 이것 마저도 학습율은 만족스럽지 못했습니다. 그래서 다음에는 픽셀의 수를 7 by 8로 가로 세로의 픽셀수를 다르게 하여 총 입력 노드수를 56개로 패턴을 결정하고 노이즈 패턴을 입력한 결과 앞의 픽셀보다는 나은 결과치를 얻을 수 있었습니다.
이 과정에서 한가지 알수 있던 것은 10개의 패턴들이 1로 세팅된 수가 많으면 많은 수록 학습율은 떨어졌으며 0인 부분 즉 패턴에서 색깔이 칠해지지 않은 부분이 많은 10개의 패턴의 학습율은 크게 향상되는 것을 알수 있었습니다.
그리고 에타의 값과 초기의 가중치값의 변경에서도 학습율이 변동되는 사실을 입증할 수 있었습니다.
프로그램 설명
EBP 알고리즘으로 구현한 제 프로그램은 패턴의 픽셀 수(가로, 세로)와 히든 노드의 수,에타값, 웨이트을 프로그램 구동 중에 수정할 수 있도록 하였으며 10개의 패턴의 픽셀을 마우스로 클릭하여 임의의 패턴들을 만들어 노이즈패턴을 입력 결과를 확인할수 있도록 하였습니다.
프로그램 버그, 및 문제점
1.)이 프로그램의 입력 노드는 총 56개인대 반하여 패턴의 수가 10개이기 때문에 입력노드의 15% 벗어나는 패턴들을 학습하였기 때문에 학습율이 보다 작은 패턴으로 학습하는 것보다는 저조할 수 있습니다.
2.> 프로그램의 패턴의 픽셀 수를 프로그램 구동중에 수정할 수 있도록 하였으나 자바 언어에서는 배열의 값을 초기 세팅할 때 초기 선언 부분에서만 가능하여 7 by 8의 배열 범위를 넘는 필셀의 수를 입력하였을 경우에는 ArrayIndexOutOfBoundsException에러를 냅니다. 그래서 초기 배열의 값을 넣을 때 뒤에 20개의 공간을 추가하여 사용자가 7 by 8이상의(가로*세로 20이하) 픽셀을 입력하였을 경우에도 프로그램에 에러가 나오지 않도록 보완하였습니다.
3.> EBP 알고리즘의 학습의 끝을 모든 가중치가 0에 가깝거나 가중치의 차이가 거의 없을 때까지 반복 학습을 해야하는데 반하여 제 프로그램의 학습의 끝은 카운트로 설정을 하였습니다. 픽셀의 수를 고정했을 경우에는 차이의 최소 값을 셋팅할 수 있지만 사용자가 임의로 픽셀의 수를 셋팅하게 만들었기 때문에 그 기준에 문제점이 있었습니다.
* 대학교시절 인공지능 수업을 들으면서 실습 과제로 제작했던 EBP 알고리즘 프로그램.
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 import javax.swing.border.*;
5 import javax.swing.JOptionPane;
6
7 public class EBP extends JFrame{
8 EBP ebp;
9 JPanel Up,Down; //메인 프래임에서 위와 아래로 패널을 나눔
10 JPanel Type_BackGround[];
11 JPanel Type[]; //타입별 패널을 3개로 나눔
12 JPanel Type_Field[][]; //타입1, 타입2, 타입3에 대한 필드들의 패널
13 JPanel Input_Data[],Output_Data[];
14 JPanel Down_Left,Down_Right,Left,Right;
15 JPanel Space[];
16 JPanel p[],p2[];
17 JButton Processing_Button;
18 JTextField pixel_text1;
19 JTextField pixel_text2;
20
21 JTextField hidden_text;
22 JTextField Eta_text;
23 JTextField Wait_text;
24
25 Color color;
26 double Type_Array[][]=
{{0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,
27 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,1,1,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
28 {0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
29 {0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
30 {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
31 {0,0,1,1,1,1,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
32 {0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
33 {0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
34 {0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
35
36 double Input_Data_Integer[];
37 int pixel_x,pixel_y;
38 double Output_Data_Integer[];
39
40 double input_to_hidden_wait[][];
41 double hidden_to_output_wait[][];
42
43 double input_to_hidden[];
44 double hidden_to_output[]=new double[10];
45
46 double output_error[]=new double[10];
47 double hidden_error[];
48 double wait;
49
50 double eta;
51
52 int input_node_count,hidden_node_count;
53 double output[][]={{1,0,0,0,0,0,0,0,0,0},
54 {0,1,0,0,0,0,0,0,0,0},
55 {0,0,1,0,0,0,0,0,0,0},
56 {0,0,0,1,0,0,0,0,0,0},
57 {0,0,0,0,1,0,0,0,0,0},
58 {0,0,0,0,0,1,0,0,0,0},
59 {0,0,0,0,0,0,1,0,0,0},
60 {0,0,0,0,0,0,0,1,0,0},
61 {0,0,0,0,0,0,0,0,1,0},
62 {0,0,0,0,0,0,0,0,0,1}};
63 BevelBorder bevelborder;
64 EtchedBorder etchedborder;
65
66 public EBP(int pixel_x,int pixel_y,int hidden_node_count,Double eta,Double wait){
67 super("EBP Application");
68 Container c=getContentPane();
69
70 color=new Color(0,0,255);
71
72 this.input_node_count=pixel_x*pixel_y;
73 this.hidden_node_count=hidden_node_count;
74 this.eta=eta.doubleValue();
75 this.wait=wait.doubleValue();
76
77
78
79 input_to_hidden_wait=new double[hidden_node_count][input_node_count];
80 hidden_to_output_wait=new double[10][hidden_node_count];
81
82 input_to_hidden=new double[hidden_node_count];
83 hidden_error=new double[hidden_node_count];
84
85
86
87 Output_Data_Integer=new double[input_node_count];
88
89 bevelborder=new BevelBorder(BevelBorder.RAISED);
90 etchedborder=new EtchedBorder(EtchedBorder.RAISED);
91 Input_Data_Integer=new double[input_node_count];
92
93 for(int j=0j<input_node_count;j++){
94 Input_Data_Integer[j]=0
95 }
96 if(pixel_x!=7||pixel_y!=8){
97 this.Type_Array=new double[10][input_node_count];
98 for(int i=0i<10i++)
99 for(int j=0j<input_node_count;j++){
100 Type_Array[i][j]=0
101 }
102
103 }
104 Processing_Button=new JButton("Processing");
105 Processing_Button.addActionListener(new actionhandler_button());
106
107
108 JLabel Input_Title=new JLabel("INPUT");
109 JLabel Output_Title=new JLabel("OUTPUT");
110
111 Input_Title.setBorder(bevelborder);
112 Input_Title.setBackground(new Color(64,94,153));
113 Output_Title.setBorder(bevelborder);
114 Output_Title.setBackground(new Color(64,94,153));
115 Type=new JPanel[10];
116 for(int i=0i<10i++){
117 Type[i]=new JPanel();
118 Type[i].setBorder(bevelborder);
119 Type[i].setLayout(new GridLayout(pixel_x,pixel_y));
120 }
121
122 Down_Left=new JPanel();
123 Down_Left.setBorder(bevelborder);
124
125 Down_Left.setLayout(new BorderLayout());
126 JPanel Down_Center=new JPanel();
127 Down_Center.setLayout(new GridLayout(5,1));
128
129 Space=new JPanel[5];
130 for(int i=0i<5i++){
131 Space[i]=new JPanel();
132 Space[i].setBackground(new Color(95,107,122));
133 Down_Center.add(Space[i]);
134 }
135 Space[2].setBorder(bevelborder);
136 Space[2].setLayout(new BorderLayout());
137 Space[2].add(Processing_Button,BorderLayout.CENTER);
138
139 p=new JPanel[16];
140 p2=new JPanel[16];
141 for(int i=0i<16i++){
142 p[i]=new JPanel();
143 p2[i]=new JPanel();
144 p[i].setBackground(color);
145 p2[i].setBackground(color);
146 Space[1].add(p[i]);
147 Space[4].add(p2[i]);
148 }
149
150 Down_Center.setBorder(bevelborder);
151 Down_Right=new JPanel();
152 Down_Right.setBorder(bevelborder);
153 Down_Right.setLayout(new BorderLayout());
154
155 Left=new JPanel();
156 Left.setLayout(new GridLayout(pixel_x,pixel_y));
157 Right=new JPanel();
158 Right.setLayout(new GridLayout(pixel_x,pixel_y));
159 Type_Field=new JPanel[10][input_node_count];
160 for(int i=0i<10i++)
161 for(int j=0j<input_node_count;j++){
162 Type_Field[i][j]=new JPanel();
163 Type_Field[i][j].setBorder(etchedborder);
164 Type_Field[i][j].addMouseListener(new mousehandler1());
165 Type[i].add(Type_Field[i][j]);
166 }
167 Setting();
168 Type_BackGround=new JPanel[10];
169 for(int i=0i<10i++){
170 Type_BackGround[i]=new JPanel();
171 Type_BackGround[i].setLayout(new BorderLayout());
172 Type_BackGround[i].setBorder(etchedborder);
173 Type_BackGround[i].setBackground(new Color(212,208,200));
174 }
175
176 Up=new JPanel();
177 Up.setBorder(bevelborder);
178 Up.setLayout(new GridLayout(2,5));
179
180 for(int i=0i<10i++){
181 Type_BackGround[i].add(Type[i]);
182 Up.add(Type_BackGround[i]);
183 }
184 Down=new JPanel();
185 Down.setBorder(bevelborder);
186 Down.setLayout(new GridLayout(1,3));
187
188 Input_Data=new JPanel[input_node_count];
189 for(int i=0i<input_node_count;i++){
190 Input_Data[i]=new JPanel();
191 Input_Data[i].setBorder(etchedborder);
192 Input_Data[i].addMouseListener(new mousehandler_Input());
193 Left.add(Input_Data[i]);
194
195 }
196 Output_Data=new JPanel[input_node_count];
197 for(int i=0i<input_node_count;i++){
198 Output_Data[i]=new JPanel();
199 Output_Data[i].setBorder(etchedborder);
200 Right.add(Output_Data[i]);
201
202 }
203 Down_Left.add(Input_Title,BorderLayout.NORTH);
204 Down_Left.add(Left,BorderLayout.CENTER);
205 Down_Right.add(Output_Title,BorderLayout.NORTH);
206 Down_Right.add(Right,BorderLayout.CENTER);
207
208 //setting screen
209 JPanel right_setting_screen=new JPanel();
210 right_setting_screen.setLayout(new GridLayout(3,1));
211 right_setting_screen.setBorder(bevelborder);
212 JPanel setting[]=new JPanel[3];
213 for(int i=0i<3i++){
214 setting[i]=new JPanel();
215 setting[i].setBorder(etchedborder);
216 right_setting_screen.add(setting[i]);
217 }
218 setting[1].setLayout(new GridLayout(5,1));
219 JPanel Temp_panel[]=new JPanel[5];
220 for(int i=0i<5i++){
221 Temp_panel[i]=new JPanel();
222 setting[1].add(Temp_panel[i]);
223 }
224 Label pixel=new Label("Pixel ");
225 Label pixel_X=new Label(" X");
226 Label hidden=new Label("Hid ");
227 Label Eta=new Label("Eta ");
228 Label Wait=new Label("Wait ");
229 Label setting_title=new Label(" [SETTING SPACE]");
230
231 pixel_text1=new JTextField(3);
232 pixel_text2=new JTextField(3);
233
234 hidden_text=new JTextField(6);
235 Eta_text=new JTextField(6);
236 Wait_text=new JTextField(6);
237
238
239 Temp_panel[0].add(setting_title);
240 Temp_panel[0].setBorder(bevelborder);
241 Temp_panel[1].add(pixel);
242 Temp_panel[1].add(pixel_text1);
243 Temp_panel[1].add(pixel_X);
244 Temp_panel[1].add(pixel_text2);
245
246 Temp_panel[2].add(hidden);
247 Temp_panel[2].add(hidden_text);
248
249 Temp_panel[3].add(Eta);
250 Temp_panel[3].add(Eta_text);
251
252 Temp_panel[4].add(Wait);
253 Temp_panel[4].add(Wait_text);
254
255 pixel_text1.setText(String.valueOf(pixel_x));
256 pixel_text2.setText(String.valueOf(pixel_y));
257 hidden_text.setText(String.valueOf(hidden_node_count));
258 Eta_text.setText(String.valueOf(eta));
259 Wait_text.setText(String.valueOf(wait));
260
261 JButton clear_button=new JButton("CLEAR");
262 JButton setting_button=new JButton("SETTING");
263 clear_button.addActionListener(new actionhandler_button());
264 setting_button.addActionListener(new actionhandler_button());
265
266 setting[2].add(clear_button);
267 setting[2].add(setting_button);
268
269 Down.add(Down_Left);
270 Down.add(Down_Center);
271 Down.add(Down_Right);
272
273 Panel main=new Panel();
274 main.setLayout(new GridLayout(2,1));
275 c.setLayout(new BorderLayout());
276 main.add(Up);
277 main.add(Down);
278 c.add(main,BorderLayout.CENTER);
279 c.add(right_setting_screen,BorderLayout.EAST);
280
281
282
283 setBounds(100,60,100,145);
284 setSize(860,640);
285 show();
286 }
287 public void Processing_Method(){
288 System.out.println("Processing");
289
290 for(int j=0j<hidden_node_count;j++)
291 for(int i=0i<input_node_count;i++)
292 input_to_hidden_wait[j][i]=wait;
293 for(int j=0j<10j++)
294 for(int i=0i<hidden_node_count;i++)
295 hidden_to_output_wait[j][i]=wait;
296 double tt[]=new double[10];
297 int count=0
298 do{
299 count++;
300 for(int i=0i<10i++){ //패턴 10개 반복문
301
302 // 1 Level start
303 double temp1=0.0
304 for(int j=0j<hidden_node_count;j++){
305
306 for(int k=0k<input_node_count;k++)
307 temp1+=((double)Type_Array[i][k]*input_to_hidden_wait[j][k]);
308 input_to_hidden[j]=Sigm(temp1);
309 }
310 // 1 Level end
311 // 2 Level start
312
313 for(int j=0j<10j++){
314 double temp2=0.0
315 for(int k=0k<hidden_node_count;k++)
316 temp2+=(input_to_hidden[k]*hidden_to_output_wait[j][k]);
317 hidden_to_output[j]=Sigm(temp2);
318 }
319 // 2 Level end
320 // 3 Level start
321 for(int k=0k<10k++){
322 output_error[k]=hidden_to_output[k]*(1-hidden_to_output[k])*(output[i][k]-hidden_to_output[k]);
323 }
324 // 3 Level end
325 // 4 Level start
326
327 for(int j=0j<hidden_node_count;j++){
328 double temp=0
329 for(int k=0k<10k++)
330 temp+=output_error[k]*hidden_to_output_wait[k][j];
331 hidden_error[j]=input_to_hidden[j]*(1-input_to_hidden[j])*temp;
332 }
333 // 4 Level end
334 // 1 Level start of Step 4
335 for(int j=0j<10j++)
336 for(int k=0k<hidden_node_count;k++) {
337 hidden_to_output_wait[j][k]=hidden_to_output_wait[j][k]+(eta*output_error[j]*input_to_hidden[k]);
338
339 }
340 // 1 Level end
341 // 2 Level start
342 for(int k=0k<hidden_node_count;k++){
343 for(int j=0j<input_node_count;j++){
344 input_to_hidden_wait[k][j]=input_to_hidden_wait[k][j]+(eta*hidden_error[k]*(double)Type_Array[i][j]);
345 }
346 }
347 }
348
349 }while(count<=16000);
350 input_output_processing();
351
352 }
353 public void input_output_processing(){
354
355 // 1 Level start
356 double temp1=0
357 for(int j=0j<hidden_node_count;j++){
358
359 for(int k=0k<input_node_count;k++)
360 temp1+=((double)Input_Data_Integer[k]*input_to_hidden_wait[j][k]);
361 input_to_hidden[j]=Sigm(temp1);
362 }
363 // 1 Level end
364 // 2 Level start
365 for(int j=0j<10j++){
366 double temp=0
367 for(int k=0k<hidden_node_count;k++)
368 temp+=(input_to_hidden[k]*hidden_to_output_wait[j][k]);
369 hidden_to_output[j]=Sigm(temp);
370 }
371 double temp=hidden_to_output[0];
372 int count_type=0
373 for(int i=1i<10i++){
374
375 if(temp<=hidden_to_output[i]){
376 temp=hidden_to_output[i];
377 count_type=i;
378 }
379
380 }
381 for(int i=0i<input_node_count;i++){
382 Output_Data_Integer[i]=Type_Array[count_type][i];
383 }
384 Output_Data_Interface();
385 }
386 public double Sigm(double Temp){
387 return 1/(1+Math.exp(-Temp));
388 }
389 public void Output_Data_Interface(){
390 for(int i=0i<input_node_count;i++){
391 if(Output_Data_Integer[i]==1)
392 Output_Data[i].setBackground(color);
393 else
394 Output_Data[i].setBackground(new Color(204,204,204));
395 }
396
397 }
398
399 public class mousehandler1 extends MouseAdapter{
400
401 public void mousePressed(MouseEvent me){
402 JPanel pp=(JPanel)me.getSource();
403 for(int i=0i<10i++){
404
405 for(int j=0j<input_node_count;j++){
406 if(pp.equals(Type_Field[i][j])){
407 if(Type_Array[i][j]==0){
408 Type_Field[i][j].setBackground(color);
409 Type_Array[i][j]=1
410 }else{
411 Type_Field[i][j].setBackground(new Color(204,204,204));
412 Type_Array[i][j]=0
413 }
414
415 break
416 }
417 }
418 }
419 }
420 }
421 public void Setting(){
422
423 for(int i=0i<10i++){
424 for(int j=0j<input_node_count;j++){
425 if(Type_Array[i][j]==0){
426 Type_Field[i][j].setBackground(new Color(204,204,204));
427 }else{
428 Type_Field[i][j].setBackground(color);
429 }
430 }
431 }
432 }
433
434 public class mousehandler_Input extends MouseAdapter{
435
436 public void mousePressed(MouseEvent me){
437 JPanel pp=(JPanel)me.getSource();
438 for(int i=0i<input_node_count;i++){
439 if(pp.equals(Input_Data[i])){
440
441 if(Input_Data_Integer[i]==0){
442 Input_Data[i].setBackground(color);
443 Input_Data_Integer[i]=1
444
445 }else{
446 Input_Data[i].setBackground(new Color(204,204,204));
447 Input_Data_Integer[i]=0
448
449 }
450 break
451 }
452
453 }
454 for(int i=0i<input_node_count;i++){
455 Output_Data_Integer[i]=Input_Data_Integer[i];
456 }
457
458 }
459 }
460 final class actionhandler_button implements ActionListener{
461
462 public void actionPerformed(ActionEvent ae){
463 JButton bb=(JButton)ae.getSource();
464
465 if(bb.getLabel()=="Processing"){
466 Processing_Method();
467 }
468 if(bb.getLabel()=="CLEAR"){
469 pixel_text1.setText("");
470 pixel_text2.setText("");
471 hidden_text.setText("");
472 Eta_text.setText("");
473 Wait_text.setText("");
474 }
475 if(bb.getLabel()=="SETTING"){
476 dispose();
477 System.gc();
478
479 Double d1,d2
480 d1=new Double(Eta_text.getText());
481 d2=new Double(Wait_text.getText());
482
483 ebp=new EBP(Integer.parseInt(pixel_text1.getText()),Integer.parseInt(pixel_text2.getText()),
484 Integer.parseInt(hidden_text.getText()),d1,d2);
485 ebp.setBounds(100,60,100,145);
486 ebp.setSize(860,640);
487 ebp.show();
488
489
490 }
491 }
492 }
493 public static void main(String args[]){
494 EBP EBPApp =new EBP(7,8,8,new Double(0.3),new Double(0.5));
495 EBPApp.addWindowListener(
496 new WindowAdapter(){
497 public void windowClosing(WindowEvent e){
498 System.exit(0);
499 }
500 }
501 );
502 }
503 }