Tải bản đầy đủ (.doc) (58 trang)

Mạng thần kinh nhân tạo cho lớp phân màu sắc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (556.92 KB, 58 trang )

Chơng
12
mạng thần kinh nhân tạo cho phân lớp màu
sắc
12.1 Chỉ dẫn
Không nghi ngờ gì nữa, con ngời là cách tốt nhất để phân loại màu sắc. Tuy nhiên,
các ứng dụng đòi hỏi sự phân loại màu trực tuyến và sửa lại tín hiệu sắc màu một cách
có lựa chọn nh trong tín hiệu truyền hình màu, thay thế cho sự phân lớp của con ngời là
cần phải có. May mắn thay, một nhóm các kiểu phân loại đợc mô hình hoá theo kiểu trí
tuệ sinh vật (hệ thống thần kinh nhân tạo) đã đợc phát triển và nghiên cứu trong một
thời gian dài. Mục tiêu của các nghiên cứu này là đạt đợc tới mức giống nh con ngời.
Chúng ta cha đạt đợc mục tiêu này. Sự thách thức là chúng ta phải hiểu đợc bằng cách
nào mà một loạt các tác động thần kinh đem lại cho chúng ta khả năng nhìn, nghe, cảm
giác, chuyển động Mặc dù chúng ta đã có những hiểu biết đúng đắn cấu tạo của tổ
chức bộ não con ngời, chúng ta vẫn không hiểu một cách đầy đủ bằng cách nào mà con
ngời có thể có một loạt các chức năng nh vậy. Khả năng học hỏi và thích nghi của con
ngời vẫn còn là một điều bí ẩn. Một trích dẫn rất đáng quan tâm, "Tôi đã để lại các dấu
hiệu nh một bằng chứng về sự tồn tại của tôi, cái nào trong số các dấu hiệu này bạn
phản đối? Tôi đã tạo ra con ngời, tôi đã dạy [lập trình] cho họ có khả năng nhận biết "
(Kinh Coran, Suret Al-Rahman). Con ngời nhận ra họ có khả năng phát minh ra các
công cụ ngay từ khi họ mới đợc tạo ra. Phần lớn các sáng tạo của con ngời đều dựa trên
ham muốn tìm hiểu trong lĩnh vực vật lý. Bằng tất cả các khám phá, con ngời lại quay
trở về để tìm hiểu chính bản thân mình. Cùng với sự ra đời của phần mềm, tự động hoá,
phỏng sinh học ta đã có thể mô phỏng một số chức năng của con ngời qua các phần
cứng và phần mềm mô phỏng. Giống nh khi bắt đầu, hệ thống thần kinh nhân tạo vẫn
cha mô phỏng đợc dạng thức con ngời; tuy nhiên, các cấu trúc này có rất nhiều ứng
dụng hữu ích. Một trong những ứng dụng sẽ trình bày ở phần dới đây là phân lớp màu
sắc. Trong chơng này chúng ta sẽ xem xét một loạt các mô hình thần kinh nhân tạo,
cách thức nhận thức của chúng, và hiệu quả trong phân lớp màu.
12.2 Hệ thống thần kinh sinh vật
Mắt cảm nhận ánh sáng xung quanh chúng ta và chuyển chúng thành các xung điện,


sau đó đa về bộ nhớ qua các dây thần kinh. Tại phía sau của mắt, một lới dây thần kinh
từ giác mạc tạo thành các dây thần kinh cảm quang. Hai lới dây thần kinh cảm quang
gặp nhau tại một miền có tên là giao thoa thị giác (optic chiasm). Tại miền này hai dây
tạo thành một lới, và đợc chia làm hai vùng cảm quang đi tới bên trái và bên phải của
não. Tất cả các miền này mang tín hiệu từ hai mắt, và não tổng hợp đợc hình ảnh thực
255
sự. Vùng của não cho các đáp ứng của hình ảnh gọi là vỏ não thị giác (Hình 12.1). Nếu
mỗi vùng của não nhận đợc hai ảnh của vật thể, mỗi ảnh lấy từ một mắt với một góc
nhìn khác nhau nhỏ thì kết quả ta sẽ nhận đợc một hình ảnh ba chiều hay còn gọi là
hình ảnh nổi. Tại não, một số khổng lồ các liên lạc của các tế bào thần kinh tạo ra xử lý
thông tin.
Hình 12.1 Các đờng thị giác của bộ não.
Hình 12.2 là một sơ đồ đơn giản hoá của tế bào thần kinh. Nó bao gồm một tế bào
(soma) với dây thần kinh vào (dendrites) và dây thần kinh ra (axons). Các dây thần
kinh vào nhận các tín hiệu kích thích hoặc các tín hiệu kiềm chế. Các tín hiệu kích thích
làm tăng và các tín hiệu kiềm chế làm chậm khả năng phát tín hiệu của thần kinh. Các
dây thần kinh ra đa tín hiệu đến một tế bào khác. Thông tin đợc chuyển qua các hình
hành cuối khớp thần kinh (synaptic-end bulbs) và nhận bởi dây thần kinh vào thông
qua vùng chuyển tiếp. Hình hành cuối khớp thần kinh và vùng chuyển tiếp đợc chia ra
bằng một lỗ hở vào khoảng một phần triệu inch, và chuyển tiếp tín hiệu qua lỗ hổng này
bởi cơ chế hoá điện (hình 12.3). Phần cuối hành và miền chuyển tiếp đợc gọi là khớp
thần kinh (synapse). Tín hiệu đi trong dây thần kinh vào và dây thần kinh ra nh một
dòng điện. Có rất nhiều kiểu dây thần kinh trong não và một số lớn các tế bào trạng thái
và chức năng. Một số hạn chế các xung mà có khả năng làm quá tải mạch cảm biến.
Một số đa tin tức tổng hợp đến bề mặt não, một số khác nhận tín hiệu đa vào.
Các hành ở khớp thần kinh chứa các túi nhỏ bé gọi là các túi khớp thần kinh (hình
12.3). Mỗi túi chứa hàng ngàn các phân tử gọi là chuyển tiếp thần kinh
(neurotransmitter). Khi một tín hiệu thần kinh đến hành của khớp thần kinh, các túi hợp
nhất với màng, làm tràn các chất chứa bên trong vào các lỗ của khớp thần kinh. Các
chuyển tiếp thần kinh gắn chặt với các phần tử tiếp nhận ở tâm của tế bào; làm mở các

tuyến tiếp nhận và cho phép các ion natri đi vào trong tâm tế bào và các ion kali đi ra.
256
Dòng của các ion kích thích các màng của tâm tế bào và tạo ra xung điện trong tế bào
trung tâm.
Hình 12.2 Sơ đồ đơn giản hoá của tế bào thần kinh.
Hình 12.3 Các khớp thần kinh.
Con ngời có vào khoảng xấp xỉ 10
11
tế bào thần kinh, ớc lợng có khả năng thực hiện
trên 100 tỷ phép tính một giây. Một siêu máy tính Cray X_MP, một loại máy tính
257
nhanh nhất hiện nay, có khả làm đợc 0.8 tỷ phép tính một giây. Con ngời nhanh hơn
100 lần bất kỳ một loại máy tính hiện đại nào, với u điểm hơn hẳn về kích thớc nhỏ gọn
và đòi hỏi ít hơn hẳn năng lợng. Một tính chất cũng cần phải nói tới là bộ não con ngời
đợc thiết kế để xử lý ba chiều. Trong khi đó, các mạch tích hợp thờng là hai chiều, và
với sự tiến bộ ngày nay việc thiết kế mạch tích hợp ba chiều vẫn cha đợc hoàn thiện
hoặc thậm chí cũng không gần đợc nh kiểu tích hợp ba chiều của bộ não con ngời.
12.3 Perceptron
Hình 12.4 giới thiệu cái mà ngời ta tin rằng đó là mô hình thuật toán học cho một tế
bào thần kinh đơn lẻ. Chú ý là có N đầu vào, cung cấp giá trị ngỡng , và cho kết quả
đi qua một hàm phi tuyến. Tín hiệu ra có thể là giá trị 1 kích thích cho một dây thần
kinh, hoặc là 0 (-1 cũng có thể đợc dùng). Hàm phi tuyến hay đợc dùng là hàm xichma
và hàm giới hạn (logic ngỡng).
Cấu trúc trong hình 12.4 gọi là perceptron, và là cơ sở cho một cách phân lớp tuyến
tính mà có thể chia ra làm hai lớp tách rời nhau nh trong hình 12.5. Tín hiệu ra từ
perceptron có thể viết dới dạng
y f= ( )

(12.1)
ở đây


= +
=


i i
i
N
x
0
1
(12.2)
Một sơ đồ xác định các trọng số {w
0
, w
1
, w
2
, , w
N
} và có hàm f() chia thành hai
lớp A và B phân biệt gọi là sơ đồ nhận thức. gọi là giá trị ngỡng, và thờng nằm trong
khoảng 0 đến 1.
Xuất phát từ sơ đồ nhận thức, chúng ta sẽ xem xét một perceptron chỉ có hai đầu vào:

= + +
0 0 1 1
x x
(12.3)
x

0
ký hiệu cho đặc điểm màu x của sơ đồ màu, x
1
là đặc điểm màu y. Nếu chúng ta muốn
perceptron phân biệt hai màu A và B, chúng ta sẽ chờ đầu ra cho giá trị 1 nếu (x
0
,x
1
)
thuộc về màu A, và 0 nếu đầu vào thuộc B. Theo các giả thiết trên chúng ta có thể viết:
nếu (x
0
, x
1
) A d
P
= 1
nếu (x
0
, x
1
) B d
P
= 0
ở đây ký hiệu p biểu thị cho một mẫu của (x
0
, x
1
) và d
P

biểu thị cho đáp ứng mong muốn
cho mẫu này. Nếu (w
0
, w
1
) đã biết thì đáp ứng ra thực sự y có thể tính từ biểu thức
(12.1). Sai số cho việc đọc mẫu này có thể cho bởi
E d y
p p p
=
1
2
2
( )
(12.4)
258
Hình 12.4 Các phần tử tính toán của một hệ thống thần kinh.
Hình 12.5 Một hàm phân chia đơn giản của một lớp.
259
Vấn đề cần giải quyết là tối thiểu hoá E
P
đối với w
0
và w
1
cho tất cả các mẫu lấy vào
(x
0
,x
1

)
P
. Biểu thức (12.1) cung cấp sự phân chia chính xác giữa hai lớp màu nh trong
hình (12.5). E
P
là hàm phi tuyến của các biến w
0
và w
1
và vì vậy các giản đồ phi tuyến
cần đợc sử dụng để tối thiểu hoá nó.
Nếu y cho bởi hàm xichma
y f
e
= =
+

( )


1
1
và sau đó nếu lấy vi phân E
P
theo w
0
ta đợc:


E

d y y y x
p
p p p p p

0
= ( ) ( )1
0

và theo w
1
ta đợc :


E
d y y y x
p
p p p p p

1
= ( ) ( )1
1
Thuật toán rút ra giá trị của các trọng số theo các bớc sau:
1.Cho các trọng số (w
0
, w
1
) và các giá trị ngẫu nhiên nhỏ.
Tại bớc lặp thứ k:
2. Cho một giá trị đầu vào (x
0

, x
1
) và chọn giá trị đầu ra theo ý thích: 1 nếu thuộc về
một lớp màu và 0 nếu thuộc về lớp màu còn lại.
3. Tính tín hiệu ra thực sự y.
4. Tính

= ( ) ( )d y y y1
5. Tính các gradient
=






= E
E E
x





0 1
0
[ ] - x
1
6. Thay đổi các trọng số dùng biểu thức :
W W E

k k k( ) ( ) ( )+
=
1

ở đây W
k
= [ w
0
w
1
]
(k)
= các trọng số tại bớc lặp thứ k và

là một phân số dơng
nhỏ hơn 1.
260
7. Cho đầu vào giá trị mới hoặc nếu dữ liệu đã đợc đọc tất cả, đọc lại tập các giá trị
của dữ liệu. Quay lại bớc 2 và lặp lại cho đến khi hàm trọng số thoả mãn, cụ thể là

i
k
i
k
W
+

1 ( )
i= 0 ,1.
Hội tụ trong một số trờng hợp sẽ nhanh hơn nếu xung lợng (moment) đợc cộng thêm

vào và trọng số đợc làm giảm đi bởi:
W W E E E
k k k k k( ) ( ) ( ) ( ) ( )
(
+
= +
1 1

ở đây 0 < <1.
Thuật toán trên gọi là quy tắc "delta", đợc dùng rộng rãi trong tài liệu. Mặc dù thuật
toán trên có thể tính trọng số cho các lớp, nhng nó đòi hỏi một số rất lớn các phép lặp
để hội tụ. Việc chọn hai tham số và có vẻ nh là tuỳ ý. Để cho bạn có thể kiểm tra
thuật toán quy tắc delta chúng tôi cho ở dới đây một chơng trình C thiết kế cho một
perceptron với hai đầu vào.
Chơng trình 12.1 PERECEPT.C Perceptron học nhận thức bằng quy tắc
denlta
/*Program 12.1 "PERECEPT.C". Perceptron learning using the delta
rule. */
/************************************
* Developed by M.A.Sid_Ahmed. *
* ver. I.O. 1992. *
* @ 1994 *
*************************************/
/* Teaching a single pereptrjon using
the delta rule. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <io.h>

#include <custom.h>
#define eta 0.8
#define alpha 0.2
void main()
{
unsigned int d[200];
unsigned int N,ind,iter,i;
float w[2],x[2],x1[200],x2[200],net,E;
float dEp[2],sum,y,theta,dEp_old[2],delta;
FILE *fptr;
char file_name[14];
clrscr();
261
N=0;
iter=0;
gotoxy(1,1);
printf("Enter file name containing data >");
scanf("%s", file_name);
fptr=fopen(file_name,"r");
if(fptr==NULL)
{
printf("file %s does not exist.",file_name);
exit(1);
}
while((fscanf(fptr,"%f %f %d ",&x1[N], &x2[N],&d[N])!=EOF))
N++;
fclose(fptr);
srand(1);
w[0]=(float)rand()/32768.00;
srand(2);

w[1]=(float)rand()/32768.00;
theta=0.1;
i=0;
sum=0.0;
ind=1;
gotoxy(1,10);
printf("Press ESC to exit before convergence.");
while(ind)
{
x[0]=x1[i];
x[1]=x2[i];
gotoxy(1,3);
printf("Iteration # %5d ",iter);
net=w[0]*x[0]+w[1]*x[1]+theta;
if(net>=20) E=0.0;
else E=exp(-(double)net);
y=1.0/(1.0+E);
delta=(d[i]-y)*y*(1.0-y);
dEp[0]=x[0]*delta;
dEp[1]=x[1]*delta;
if(i==0)
{
w[0]+=eta*dEp[0];
w[1]+=eta*dEp[1];
dEp_old[0]=dEp[0];
dEp_old[1]=dEp[1];
}
else
{
w[0]+=eta*dEp[0]+alpha*(dEp[0]-dEp_old[0]);

w[1]+=eta*dEp[1]+alpha*(dEp[1]-dEp_old[1]);
dEp_old[0]=dEp[0];
dEp_old[1]=dEp[1];
262
}
sum+=fabs((double)(d[i]-y));
i++;
if(i>=N)
{
gotoxy(1,6);
printf(" Square error= %f",sum);
i=0; sum=0;
iter++;
}
if(d[i]==1)
gotoxy(1,4);
else
gotoxy(1,5);
printf("%d %f", d[i],y);
if((i==N)&&(sum<=1.0e-1))
{
gotoxy(1,7);
printf("\n w[0]=%f W[1]=%f",w[0], w[1]);
exit(1);
}
if(kbhit()!=0)
{
gotoxy(1,7);
if(getch()==27)
{

printf("\n w[0]=%f w[1]=%f",w[0],w[1]);
exit(1);
}
}
}
}
Trên đĩa đi kèm đã có sẵn file dữ liệu có tên là "TINT.DAT" rút ra từ sơ đồ màu.
Dùng = 0.8 và = 0.2, phải mất gần 200 lần lặp để làm cho sai số giảm từ 28
xuống 9,55. Sau 15,000 phép lặp sai số đã giảm xuống nhỏ hơn 1 và tiếp tục giảm
xuống. Thay

= 0.2 và = 0.8 sự hội tụ sẽ chậm hơn. Trớc khi chúng ta nghiên cứu
một phơng pháp tốt hơn cho tính toán giá trị cảm nhận, chúng tôi sẽ cung cấp cho bạn
công cụ thu nhập dữ liệu.
12.4 Thu nhập dữ liệu cho các lớp màu sắc
Chơng trình cho ở dới đây chỉ làm việc trên vỉ mạch ATI PIB đã đợc đề cập đến
trong chơng 11. Bạn có thể sửa đổi làm cho nó tơng thích với các phần cứng thông
dụng; các sửa đổi này không có gì là khó khăn lắm. Chơng trình này có sử dụng chuột.
Nếu bạn có vỉ mạch ATI PIB , đầu tiên bạn cần nạp một ảnh trên màn hình PIB. Chạy
chơng trình và con trỏ sẽ xuất hiện trên màn hình. Dùng chuột, thay thế con trỏ trên sắc
màu mà bạn muốn tách ra (một perceptron đơn thì sẽ không thể tách ra đợc một sắc
màu; chúng ta sẽ đề cập đến việc tách các sắc màu ở phần cuối chơng này). Lấy rất
263
nhiều các giá trị từ một loạt các điểm trên miền đã lựa chọn sắc màu bằng cách nhắp
đơn nút trái chuột. Chú ý là màn hình VGA sẽ hiện lên biểu đồ màu và cờng độ màu tại
nơi mà bạn trỏ tới. Nơi mà bạn kích vào sẽ đánh dấu bằng một dấu thập màu đỏ trên
biểu đồ màu vẽ trên màn hình VGA (xem hình 12.6) và lu nó vào một mảng. Nếu bạn
muốn dời dấu thập đi chỗ khác trong trờng hợp các điểm nhập vào lớn hơn một, thì
nhắp nút trái chuột nhiều lần. Hành động này sẽ làm dời đi rất nhiều điểm tuỳ theo bạn
chọn (bắt đầu từ điểm cuối cùng) từ biểu đồ màu và lu trong mảng. Khi bạn ấn ESC, con

trỏ sẽ xuất hiện trên màn hình VGA. Đa con trỏ vào sơ đồ màu vẽ trên màn hình VGA,
bằng cách kích lại nút trái chuột ta sẽ thu đợc dữ liệu cho một lớp màu khác. Nhắp nút
trái chuột, nh trớc đây, sẽ làm dịch chuyển đến đầu vào cuối cùng. Chú ý rằng một dấu
thập màu xanh sẽ xuất hiện bất cứ khi nào bạn nhắp trái chuột, và sẽ bị dời đi khi bạn
nhắp phải chuột. Nhấn ESC để thoát. Bạn sẽ đợc hỏi tên file cho chứa dữ liệu. Dữ liệu
đợc lu trữ bao gồm 3 số: số đầu tiên biểu diễn cho x, số thứ hai biểu diễn cho y, và số
cuối cùng xác định lớp. Giá trị lớp này đợc gán bằng 1 trong trờng hợp lựa chọn sắc
màu và 0 trong các trờng hợp còn lại. Dữ liệu đợc cho dới dạng "%f%f%d". Kết quả ta
thu đợc là một cung màu trên biểu đồ màu đợc tách ra từ phần còn lại của phổ màu.
Hình 12.6 Thu thập dữ liệu cho phân lớp màu sắc.
Chơng trình 12.2 COLORRDM.C . Ch ơng trình thu thập dữ liệu; Đợc dùng
với PIB.
/************************************
* Developed by M.A.Sid_Ahmed. *
* ver. 1.0, 1992. *
* @ 1994
*************************************/
/* Program to read color from PIB screen. It also classifies
color according to colors in Chromaticity diagram. Use
264
mouse left button to enter x.y coordinates and right
button to erase as many previous entries as you wish.
The cursor will initially point to the PIB screen,
use the mouse to enter the tone you wish to classify
as one color set. Press ESC to exit from PIB screen.
The cursor mouse will appear on VGA screen. Use mouse
to point at points in the Chromaticity diagram that do
not belong to the set of colors you wish to classify.
Use left button to enter a point, right button to erase
previous entry or entries. Press ESC again to exit and

store data. */
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include <io.h>
#include <custom.h>
#define white (circ<0)
#define green (l[0]&&l[6])
#define yellow ((!l[0])&&l[1])
#define skin_tone ((!l[1])&&l[2])
#define red ((!l[2])&&l[3])
#define magenta ((!l[3])&&l[4])
#define blue ((!l[4]&&(!l[53))
#define cyan (l[5]&&(!l[6]))
#define ESC 0x1B
#define LBUTTON 0x01
#define RBUTTON 0x02
void make_cursor(int,int);
void find_color(int,int);
void move_cursor(int,int);
void get_video_mode(int *,int *);
void set_video_mode(int);
void mouse_cursor_on(void);
void mouse_cursor_off(void);
void read_mouse(int *, int *, int *);
void draw_line(int,int,int,int,int);
void draw_circle(int,int,int,int);
void set_pixel(int,int,int);
void mouse_vrange(int,int);

void mouse_hrange(int,int);
void set_mouse(int,int);
void CIE(void);
void draw_cross(float,float,int);
int kount=-1;
float xold[200],yold[200];
int set[200];
void main()
265
{
int mode,page,row,col,button,ind,i;
float x,y;
char ch,file_name[14];
FILE *fptr;
clrscr();
InitPIB();
SetScreen(0);
SetInDispMode();
get_video_mode(&mode,&page);
set_video_mode(0x12);
CIE();
for(i=0;i<100;i++)
read_mouse(&row,&col,&button);
row=100;
col=200;
set_mouse(row,col);
read_mouse(&row, &col, &button);
gotoxy(1,18);
make_cursor(col, row);
find_color(col, row);

move_cursor (col, row);
mouse_vrange(5,480);
mouse_hrange( 5,640);
mouse_cursor_on();
ind=1;
while(ind)
{
for(i=0;i<100;i++)
read_mouse(&row,&col,&button);
gotoxy(1,19);
printf("row_%d, col_%d",row,col);
if(button==LBUTTON)
{
delay(150);
x=((float)col-200.0)/400.0;
y=(400.0-(float)row)/250.0;
gotoxy(1,15);
printf("x=%f y=%f ",x,y);
draw_cross(x,y,GREEN);
if(kount<200) kount++;
else
{
gotoxy(1,4);
printf("Max. total number data points should not exceed 200.\n");
}
xold[kount]=x; yold[kount]=y;
set[kount]=0;
gotoxy(1,3);
printf("x=%f y=%f set=%2d total number of points=%4d",
xold[kount],yold[kount],set[kount],kount);

266
}
else if(button==RBUTTON)
{
delay(150);
draw_cross(xold[kount],yold[kount],BLACK);
if(kount>-1) kount ;
gotoxy(1,3);
printf("x=%f y=%f set=%2d total number of points=%4d",
xold[kount],yold[kount],set[kount],kount);
}
if(kbhit()!=0)
{
if(getch()==ESC)
ind=0;
}
}
gotoxy(1,5);
printf("Do you wish to save data? (y or n) >");
while(((ch=getch())!='y')&&(ch!='n'));
switch(ch)
{
case 'y':
printf("\n Enter file name >");
scanf("%s",file_name);
ind=access(file_name,0);
while(!ind)
{
printf("File exists. Wish to overwrite? (y or n) >");
while(((ch=getch())!='y')&&(ch!='n'));

switch(ch)
{
case 'y':
ind=1;
break;
case 'n':
gotoxy(1,6);
printf("\n Enter file name > ");
scanf("%s",file_name);
ind=access(file_name,0);
}
}
fptr=fopen(file_name,"w");
for(i=0;i<kount;i++)
fprintf(fptr,"%f %f %d ", xold[i],yold[i],set[i]);
break;
case 'n':
break;
}
fclose(fptr);
set_video_mode(mode);
}
267
/* Routine to draw cursor on PIB screen. */
void make_cursor(x,y)
int x,y;
{
int i,j;
unsigned value=0xffff;
for(i=x-5;i<x+6;i++)

PutPixel(&value,i,y,1);
for(j=y-5;j<y+6;j++)
PutPixel(&value,x,j,1);
}
#define sqr(x) ((x)*(x))
/* Routine to read and classify colors from PIB screen. */
void find_color(x1,y1)
{
unsigned int color,R,G,B;
float X,Y,Z,D,x,y;
int row,col,button;
float m[]={3.3600, 1.260274, 0.663317, -1.029762,
-61.75, 0.384, -0.875};
float c[]={-0.785880, -0.086671, 0.112116, 0.675911,
20.89575, 0.205128, 0.624375};
float r=0.01;
float lt,circ;
int l[7], i;
GetPixel(&color,x1,y1);
B=(0x001F & color);
G=(0x03E0 & color)>>5;
R=(0x7C00 & color)>>10;
gotoxy(1,1);
printf(" blue= %5u, oreen=%5u, red=%5u ",B,G,R);
if(R+G+B)
{
X=2.769*R+1.7518*G+1.1300*B;
Y=R+4.5907*G+0.0601*B;
Z=0.0565*G+5.5943*B;
D=X+Y+Z ;

x=X/D; y=Y/D;
circ=sqr(x-0.333)+sqr(y-0.333)-sqr(r);
for(i=0;i<7;i++)
{
lt=m[i]*x+c[i]-y;
if(lt<0.0) l[i]=1;
else l[i]=0;
}
gotoxy(1,2);
printf("Color is:");
268
if(white)
{
gotoxy(11,2);
printf("white. ");
}
else if(green)
{
gotoxy(11,2);
printf("green. ");
}
else if(yellow)
{
gotoxy(11,2);
printf("yellow. ");
}
else if(skin_tone)
{
gotoxy(11,2);
printf("Skin tone.");

}
else if(red)
{
gotoxy(11,2);
printf("red. ");
}
else if(magenta)
{
gotoxy(11,2);
printf("magenta. ");
}
else if(blue)
{
gotoxy(11,2);
printf("blue. ");
}
else if(cyan)
{
gotoxy(11,2);
printf("cyan. ");
}
for(i=0;i<100;i++)
read_mouse(&row,&col,&button);
if(button==LBUTTON)
{
delay(150);
if(kount<200) kount++;
else
{
gotoxy(1,4);

printf("Max. total number data points should not exceed 200.\n");
}
269
draw_cross(x,y,RED);
xold[kount]=x; yold[kount]=y;
set[kount]=(char)1;
gotoxy(1,3);
printf("x=%f y=%f set=%2d total number of points=%4d",
xold[kount],yold[kount],set[kount],kount);
}
else if(button==RBUTTON)
{
delay(150);
gotoxy(1,3);
printf("x=%f y=%f set=%2d total number of points=%4d",
xold[kount],yold[kount],set[kount],kount);
draw_cross(xold[kount],yold[kount],BLACK);
if(kount>-1) kount ;
}
}
else
{
gotoxy(11,2);
printf("black. ");
}
}
/* Routine to translate mouse movements to PIB screen. */
void move_cursor(x,y)
int x,y;
{

int ind,row,col,button;
char ch;
mouse_vrange(5,250);
mouse_hrange(5,500);
ind=1;
while (ind)
{
make_cursor(x,y);
read_mouse(&row,&col,&button);
x=col; y=row;
make_cursor(x,y);
find_color(x,y);
if(kbhit()!=0)
{
ch=getch();
if(ch==ESC)
{
make_cursor(x,y);
ind=0;
}
}
}
}
270
/* Routine to obtain video mode and active page. */
void get_video_mode(int *display_mode,int *active_page)
{
union REGS reg;
reg.h.ah=0x0F;
int86(0x10,&reg,&reg);

*display_mode=reg.h.al;
*active_page=reg.h.bh;
}
/* Routine to change to one of the VGA/EGA modes. */
void set_video_mode( int set_mode)
{
union REGS reg;
reg.h.ah=0x00;
reg.h.al=set_mode;
int86(0x10,&reg,&reg);
}
/* Routine to draw a straight line of any standard color to join two
end points (xl,yl) and (x2,y2) using Bresenham's algorithm. */
void draw_line(x1,y1,x2,y2,color)
{
int dx,dy,x,y,x_end,y_end,p,const1,const2,ind;
/* Bresenham's line algorithm. */
dx=abs(x1-x2);
dy=abs(y1-y2);
if((dx==0)&&(dy==0))
{
set_pixel(x1,y1,color);
return;
}
else if(dy==0)
{
if(x1>x2)
{
x_end=x1;
x=x2 ;

}
else
{
x_end=x2;
x=x1;
}
while(x<=x_end)
{
set_pixel(x,y1,color);
x++;
}
271
return;
}
else if(dx==0)
{
if(y1>y2)
{
y_end=y1;
y=y2;
}
else
y_end=y2 ;
y=y1;
}
while(y<=y_end)
{
set_pixel(x1,y,color);
y++;
}

return;
}
else
{
if(dy<=dx)
{
if(x1>x2)
{
x_end=x1;
y_end=y1;
x=x2; y=y2;
}
else
{
x=x1; y=y1;
x_end=x2;
y_end=y2;
}
if(y_end>y) ind=1;
else ind=0;
p=2*dy-dx;
const1=2*dy;
const2=2*(dy-dx);
set_pixel(x,y,color);
while((x < x_end))
{
x++;
if(p<0) p+=const1;
else
{

if(ind) y++;
else y ;
p+=const2;
}
272
set_pixel(x,y,color);
}
set_pixel(x,y,color);
}
else
{
if(y1>y2)
{
x_end=x1;
y_end=y1;
x=x2; y=y2;
}
else
{
x_end=x2;
y_end=y2;
x=x1; y=y1;
}
if(x_end>x) ind=1;
else ind=0;
p=2*dx-dy ;
const1=2*dx;
const2=2*(dx-dy);
set_pixel(x,y,color);
while((y < y_end))

{
y++;
if(p<0) p+=const1;
else
{
if(ind) x++:
else x ;
p+=const2;
}
set_pixel(x,y,color);
}
set_pixel(x,y,color);
}
}
}
/* Routine to draw a circle of any color given the radius,
land cent re. It uses Bresenham's algorithm for circle drawing . */
void draw_circle(int x_centre, int y_centre,
int radius,int color)
{
int p,x,y;
x=0;
y=radius;
p=3-2*radius;
while(x<y)
273
{
set_pixel(x_centre+x,y_centre+y,color);
set_pixel(x_centre-x,y_centre+y,color);
set_pixel(x_centre+x,y_centre-y,color);

set_pixel(x_centre-x,y_centre-y,color);
set_pixel(x_centre+y,y_centre+x,color);
set_pixel(x_centre-y,y_centre+x,color);
set_pixel(x_centre+y,y_centre-x,color);
set_pixel(x_centre-y,y_centre-x,color);
if(p<0)
p+=4*x+6;
else
{
p+=4*(x-y)+10;
y ;
}
x++;
}
if (x==y)
{
set_pixel(x_centre+x,y_centre+y,color);
set_pixel(x_centre-x,y_centre+y,color);
set_pixel(x_centre+x,y_centre-y,color);
set_pixel(x_centre-x,y_centre-y,color);
set_pixel(x_centre+y,y_centre+x,color);
set_pixel(x_centre-y,y_centre+x,color);
set_pixel(x_centre+y,y_centre-x,color);
set_pixel(x_centre-y,y_centre-x,color);
}
}
/* Routine to set a pixel on the VGA screen
to any of the standard colors.*/
void set_pixel(int x,int y, int color)
{

union REGS reg;
reg.h.ah=0x0c;
reg.h.al=color;
reg.h.bh=0;
reg.x.cx=x;
reg.x.dx=y:
int86(0x10,&reg,&reg);
}
/* Routine to turn on cursor mouse on the VGA screen. */
void mouse_cursor_on(void)
{
union REGS reg;
reg.x.ax=0x01;
int86(0x33,&reg,&reg);
274
}
/* Routine to turn off cursor mouse on the VGA screen.*/
void mouse_cursor_off(void)
{
union REGS reg;
reg.x.ax=0x02;
int86(0x33,&reg,&reg);
}
/* Routine to read mouse row and column location.
It also provides mouse button status.*/
void read_mouse( int *row, int *col, int *button )
{
union REGS reg:
reg.x.ax=0x03;
int86(0x33,&reg,&reg);

*button=reg.x.bx;
*col=reg.x.cx;
*row=reg.x.dx;
}
/* Routine to set vertical range for mouse. */
void mouse_vrange(int min, int max)
{
union REGS reg;
reg.x.ax=0x08;
reg.x.cx=min;
reg.x.dx=max;
int86(0x33,&reg,&reg);
}
/* Routine to set horizontal range for mouse. */
void mouse_hrange(int min, int max)
{
union REGS reg;
reg.x.ax=0x07;
reg.x.cx=min;
reg.x.dx=max;
int86(0x33,&reg,&reg);
}
/* Routine to move mouse cursor to a specified location. */
void set_mouse(int row, int col)
275
{
union REGS reg;
reg.x.ax=0x04;
reg.x.cx=col;
reg.x.dx=row;

int86(0x33,&reg,&reg);
}
/* Routine to draw the chromaticity diagram on the VGA screen. */
#define xxp(x) (int)((x)*400.0+200.0)
#define yyp(y) (int)(400.0-(y)*250.0)
float xx[]={ 0.7347, 0.2757, 0.1661 };
float yy[]={ 0.2653, 0.7147, 0.0094 };
struct coord
{
float xc;
float yc;
};
struct coord p[7]={ { 0.408, 0.585 }, {0.479, 0.517}, {0.532,
0.465},{ 0.501, 0.160 }, {0.337, 0.086},
{0.208, 0.285}, {0.229, 0.424 }};
struct coord w={0.333, 0.333};
void CIE(void)
{
float x1,Y1,x2,y2;
int i,radius;
x1=xxp(xx[0]); y1=yyp(yy[0]);
x2=xxp(xx[1]); y2=yyp(yy[1]);
draw_line(x1,y1,x2,y2,LIGHTGRAY);
x1=x2; y1=y2;
x2=xxp(xx[2]); y2=yyp(yy[2]);
draw_line(x1,y1,x2,y2,LIGHTGRAY);
x1=x2; y1=y2;
x2=xxp(xx[0]); y2=yyp(yy[0]);
draw_line(x1,y1.x2,y2,LIGHTGRAY);
x1=xxp(w.xc); y1=yyp(w.xc);

for(i=0;i<7;i++)
{
x2=xxp(p[i].xc); y2=yyp(p[i].yc);
draw_line(x1,y1,x2,y2,LIGHTGRAY);
}
radius=(int)((xxp(((float)(w.xc)+0.01))-x1)+0.5);
draw_circle(x1,y1,radius,LIGHTGRAY);
}
276
/* Routine to draw a cross on the VGA screen. */
void draw_cross( float x. float y, int color)
{
int xx,yy;
xx=xxp(x); yy=yyp(y);
draw_line(xx-2,yy-2,xx+2,yy+2,color);
draw_line(xx-2,yy+2,xx+2,yy-2,color);
}
12.5 Dạy nhận biết bằng phơng pháp tối thiểu hoá hàm sai lệch tổng
Quy tắc delta nh chúng ta đã chứng kiến, là sơ đồ lặp hội tụ rất chậm. Sự lựa chọn
giá trị của và quyết định tốc tốc độ hội tụ. Phép hội tụ này chậm, đòi hỏi hàng trăm
phép lặp, và để giải quyết hết các vấn đề thì số phép lặp lên đến hàng nghìn. Một
perceptron có hai đầu vào và vì vậy có hai trọng số có thể thay đổi đợc, phần tử mà tự
nó có thể chia đợc hai lớp màu riêng biệt nhau, đòi hỏi một số lợng phép tính nh trong
trờng hợp phân chia lớp màu trong file "TINT.DAT". Nếu tất cả các phép tính này cần
thoả mãn cho một bài toán đơn giản nh vậy, thì bạn tởng tợng điều gì sẽ xảy ra nếu
chúng ta dùng phơng pháp này để dạy cho một cấu trúc thần kinh đa chức năng. Vấn đề
cấp thiết đặt ra là phải tìm cách để đảm bảo sự hội tụ xảy ra với tốc độ nhanh hơn.
Yêu cầu thực tế bây giờ là phải tối thiểu hoá, và đòi hỏi cho sự tối thiểu hoá này là
hàm sai lệch tổng:


E d y
i i
i
M
=
=


1
2
2
0
1
( )
(12.5)
ở đây d
i
là đáp ứng ra mong muốn cho các mẫu X
i
= [ x
0
, x
1
, , x
N-1
], và y
i
là đáp ứng ra
thực sự cho cùng các mẫu đầu vào này. Nếu y
i

là một hàm phi tuyến của trọng số có thể
thay đổi đợc : W = [ w
0
, w
1
, , w
N
], vấn đề trở thành bài toán tối thiểu hoá một hàm phi
tuyến. Vì vậy, chúng ta sẽ tìm kiếm các phơng pháp từ phạm vi phi tuyến đã đợc chứng
minh để có kết quả trong việc giải quyết các vấn dề tơng tự.
12.5.1 Phơng pháp tìm kiếm bất biến
277
Một phơng pháp hay dùng nhất để rút ra giá trị nhỏ nhất của một hàm đơn biến là
phơng pháp tỷ lệ vàng (Golden Section). Phơng pháp này dựa trên một giản đồ loại trừ
miền, và giả thiết rằng hàm chỉ có một giá trị nhỏ nhất trong một miền xác định trớc.
Hàm nh thế gọi là hàm đơn điệu. Giản đồ loại trừ miền trong trờng hợp tổng quát có thể
giải thích bằng biểu đồ nh trong hình 12.7.
Hình 12.7 Sơ đồ loại trừ miền.
Trong hình 12.7, nếu hai điểm đợc chọn trong miền giữa w
0
và w
1
, và nếu y
2
> y
1
thì
rõ ràng giá trị cực tiểu nằm giữa w
1
và a

2
. Vì vậy, miền [a
2
, w
2
] có thể loại trừ khỏi vùng
tìm kiếm. Nếu hai điểm khác đợc lựa chọn trong miền nhỏ hơn và phép xử lý đợc lặp
lại, miền tìm kiếm sẽ bị co hẹp lại. Cuối cùng, giá trị nhỏ nhất đợc thu hẹp nằm trong
một vùng rất nhỏ. Một câu hỏi đặt ra: Bằng cách nào chúng ta chọn đợc các điểm nằm
bên trong này? Một câu hỏi khó hơn nữa sẽ là: Có điều kiện gì cho việc tìm kiếm một
dãy các điểm này để giá trị nhỏ nhất thu hẹp trong một vùng có độ rộng 2

sau một số
xác định các bớc? Câu trả lời cho vấn đề này đã đợc Kiefer tìm ra vào năm 1953. Cách
tìm kiếm lần lợt đợc biết dới tên tìm kiếm Fibonacci. Phép tìm kiếm này dựa trên dãy số
nguyên do Fibonacci đa ra vào thế kỉ 13. Một phơng pháp tìm kiếm không đòi hỏi toàn
bộ dãy số nguyên Fibonacci đợc đa ra dới tên là tìm kiếm tỷ lệ vàng (Golden Section).
Chứng minh của phơng pháp này vẫn cha đợc trình bày trong cuốn sách này; nhng bởi
vì nó đơn giản và tôi đoán chắc là bạn muốn tìm hiểu, nên tôi sẽ trình bày với bạn phần
chứng minh:
Chúng ta sẽ giả sử rằng việc tìm kiếm cho tìm kiếm Fibonacci sẽ tiến hành trên miền
chuẩn hoá [0, 1]. Dãy số nguyên Fibonacci đợc định nghĩa bằng các biểu thức:
F
0
= F
1
= 1 (12.6)
278
F
n

= F
n-1
+ F
n-2
n = 2,3,
Nếu N các giá trị hàm đợc dùng để tính

, nếu chúng ta đã bắt đầu lùi từ phía sau kết
quả và chuyển dịch về phía trớc tới đầu miền trong khi mở rộng miền trong tất cả các b-
ớc giới thiệu dới đây
Hình 12.8 Tìm kiếm Fibonacci.
L
N
= 2 = F
2

L
N-1
= 3 = F
3
(12.7)
L
N-2
= 5 = F
4

.
.
.
L

2
= F
N

L
1
= F
N+1

ở đây L
i
là khoảng cách trong lần lặp thứ i, và F
k
, k = 2, 3, , N+1 là các số Fibonacci.
Nếu khoảng cách đầu tiên là [0,1] thì biểu thức cuối cùng của (12.7) có thể viết thành

=
+
1
1
F
N

hoặc
279

×