Ngày nay không ai có thể phủ nhận vai trò cực kỳ quan trọng của máy tính trongnghiên cứu khoa học kỹ thuật cũng như trong đời sống. Máy tính đã làm được nhữngđiều kỳ diệu và giải được những vấn đề tưởng chừng nan giải. Càng ngày càng cónhiều người tự hỏi, liệu máy tính đã thông minh hơn con người hay chưa? Chúng tôisẽ không trả lời câu hỏi ấy. Thay vào đó, chúng tôi sẽ nêu ra những khác biệt chủ yếugiữa cách làm việc của máy tính và bộ óc con người.Một máy tính, dù có mạnh đến đâu chăng nữa, đều phải làm việc theo một chươngtrình chính xác đã được hoạch định trước bởi các chuyên gia. Bài toán càng phức tạpthì việc lập trình càng công phu. Trong khi đó con người làm việc bằng cách học tậpvà rèn luyện. Trong khi làm việc con người có khả năng liên tưởng, kết nối sự việcnày với sự việc khác, và quan trọng hơn hết, họ có thể sáng tạo.Do có khả năng liên tưởng, con người có thể dễ dàng làm nhiều điều mà việc lập trìnhcho máy tính đòi hỏi rất nhiều công sức. Chẳng hạn như việc nhận dạng hay trò chơi ôchữ. Một em bé có thể tự học hỏi để nhận dạng và phân loại đồ vật chung quanh mình,biết được cái gì là thức ăn, cái gì là đồ chơi. Một người bình thường cũng có thể đoánđược vài chữ trong một ô chữ. Nhưng thật khó mà dạy cho máy tính làm được nhữngviệc ấy. Bạn hãy thử thiết kế một máy tính có khả năng làm như thế Từ lâu các nhà khoa học đã nhận thấy những ưu điểm ấy của bộ óc con người và tìmcách bắt chước để thực hiện những máy tính có khả năng học tập, nhận dạng và phânloại. Các mạng nơron nhân tạo (Artificial Neural Network, ANN) đã ra đời từ nhữngnỗ lực đó. ANN là một lãnh vực nghiên cứu rộng lớn và chỉ mới phát triển mạnhkhoảng 15 năm gần đây thôi. Tuy có nhiều kết quả khích lệ, nhưng ANN hãy còn xamới đạt được sự hoàn chỉnh như bộ óc con người
Trang 1Mạng nơron nhân tạo Phần 1 Con người và máy tính
Ngày nay không ai có thể phủ nhận vai trò cực kỳ quan trọng của máy tính trong
nghiên cứu khoa học kỹ thuật cũng như trong đời sống Máy tính đã làm được những
điều kỳ diệu và giải được những vấn đề tưởng chừng nan giải Càng ngày càng có
nhiều người tự hỏi, liệu máy tính đã thông minh hơn con người hay chưa? Chúng tôi
sẽ không trả lời câu hỏi ấy Thay vào đó, chúng tôi sẽ nêu ra những khác biệt chủ yếu
giữa cách làm việc của máy tính và bộ óc con người
Một máy tính, dù có mạnh đến đâu chăng nữa, đều phải làm việc theo một chương
trình chính xác đã được hoạch định trước bởi các chuyên gia Bài toán càng phức tạp
thì việc lập trình càng công phu Trong khi đó con người làm việc bằng cách học tập
và rèn luyện Trong khi làm việc con người có khả năng liên tưởng, kết nối sự việc
này với sự việc khác, và quan trọng hơn hết, họ có thể sáng tạo
Do có khả năng liên tưởng, con người có thể dễ dàng làm nhiều điều mà việc lập trình
cho máy tính đòi hỏi rất nhiều công sức Chẳng hạn như việc nhận dạng hay trò chơi ô
chữ Một em bé có thể tự học hỏi để nhận dạng và phân loại đồ vật chung quanh mình,
biết được cái gì là thức ăn, cái gì là đồ chơi Một người bình thường cũng có thể đoán
được vài chữ trong một ô chữ Nhưng thật khó mà dạy cho máy tính làm được những
việc ấy Bạn hãy thử thiết kế một máy tính có khả năng làm như thế !
Từ lâu các nhà khoa học đã nhận thấy những ưu điểm ấy của bộ óc con người và tìm
cách bắt chước để thực hiện những máy tính có khả năng học tập, nhận dạng và phân
loại Các mạng nơron nhân tạo (Artificial Neural Network, ANN) đã ra đời từ những
nỗ lực đó ANN là một lãnh vực nghiên cứu rộng lớn và chỉ mới phát triển mạnh
khoảng 15 năm gần đây thôi Tuy có nhiều kết quả khích lệ, nhưng ANN hãy còn xa
mới đạt được sự hoàn chỉnh như bộ óc con người
Mạng nơron nhân tạo Phần 2 Nơron và sự học tập
Trang 2Sau đây là những thành phần chính trong cấu trúc của một nơron:
Soma là thân của nơron
Các dendrites là các dây mảnh, dài, gắn liền với soma, chúng truyền dữ liệu (dưới dạng xung điện thế) đến cho soma xử lý Bên trong soma các dữ liệu đó được tổng hợp lại Có thể xem gần đúng sự tổng hợp ấy như là một phép lấy tổng tất cả các dữ liệu mà nơron nhận được
Một loại dây dẫn tín hiệu khác cũng gắn với soma là các axon Khác với
dendrites, axons có khả năng phát các xung điện thế, chúng là các dây dẫn tín hiệu từ nơron đi các nơi khác Chỉ khi nào điện thế trong soma vượt quá một giá trị ngưỡng nào đó (threshold) thì axon mới phát một xung điện thế, còn nếu không thì nó ở trạng thái nghỉ
Axon nối với các dendrites của các nơron khác thông qua những mối nối đặc biệt gọi là synapse Khi điện thế của synapse tăng lên do các xung phát ra từ axon thì synapse sẽ nhả ra một số chất hoá học (neurotransmitters); các chất này mở "cửa" trên dendrites để cho các ions truyền qua Chính dòng ions này làm thay đổi điện thế trên dendrites, tạo ra các xung dữ liệu lan truyền tới các nơron khác
Có thể tóm tắt hoạt động của một nơron như sau: nơron lấy tổng tất cả các điện thế vào mà nó nhận được, và phát ra một xung điện thế nếu tổng ấy lớn hơn một ngưỡng nào đó Các nơron nối với nhau ở các synapses Synapse được gọi là mạnh khi nó cho phép truyền dẫn dễ dàng tín hiệu qua các nơron khác Ngược lại, một synapse yếu sẽ truyền dẫn tín hiệu rất khó khăn
Trang 3Các synapses đóng vai trò rất quan trọng trong sự học tập Khi chúng ta học tập thì
hoạt động của các synapses được tăng cường, tạo nên nhiều liên kết mạnh giữa các
nơron Có thể nói rằng người nào học càng giỏi thì càng có nhiều synapses và các
synapses ấy càng mạnh mẽ, hay nói cách khác, thì liên kết giữa các nơron càng nhiều,
càng nhạy bén Hãy nhớ kỹ nguyên tắc này, vì chúng ta sẽ dùng nó trong việc học tập
của các ANNs
Mạng nơron nhân tạo Phần 3 Mô hình nơron
Mô hình McCulloch-Pitts (1943)
Sau đây là mô hình của một nơron nhân tạo:
Nơron này sẽ hoạt động như sau: giả sử có N inputs, nơron sẽ có N weights (trọng số)
tương ứng với N đường truyền inputs Nơron sẽ lấy tổng cótrọng số của tất cả các
inputs Nói như thế có nghĩa là nơron sẽ lấy input thứ nhất, nhân với weight trên
đường input thứ nhất, lấy input thứ hai nhân với weight của đường input thứ hai v.v ,
rồi lấy tổng của tất cả các kết quả thu được Đường truyền nào có weight càng lớn thì
tín hiệu truyền qua đó càng lớn, như vậy có thể xem weight là đại lượng tương đương
với synapse trong nơron sinh học Có thể viết kết quả lấy tổng của nơron như sau:
Trang 4Kết quả này sẽ được so sánh với threshold t của nơron, nếu nó lớn hơn t thì nơron cho output là 1, còn nếu nhỏ hơn thì output là 0 Ngoài ra ta cũng có thể trừ tổng nói trên cho t, rồi so sánh kết quả thu được với 0, nếu kết quả là dương thì nơron cho ouput bằng 1, nếu kết quả âm thì output là 0 Dưới dạng toán học ta có thể viết output của nơron như sau:
Dạy nơron học như thế nào ?
Trang 5Giả sử chúng ta muốn dạy nơron phân biệt chữ A và B Khi đưa input là A chúng ta muốn nơron cho output là 1, còn khi input là B thì nơron phải cho output bằng 0
Hình ảnh của hai chữ A và B có thể phân tích thành nhiều ô nhỏ như sau:
Các bạn cũng thấy là trong ví dụ trên mỗi chữ gồm 5x10=50 ô, mỗi ô có thể có chứa dấu x hay không chứa gì cả Chúng ta có thể mã hóa một ô có chứa dấu x bằng số 1,
và một ô trống bằng số 0 Như vậy mỗi chữ được mã hóa bằng một dãy 50 số 1 và 0 Nói cách khác, với mỗi chữ ta phải dùng 50 đường truyền để đưa 50 inputs là các số
Trang 6Ngược lại, khi đưa chữ B vào và nơron đoán sai (output bằng 1), thì ta phải giảm các
weights của các inputs đang hoạt động xuống, sao cho lần tới tổng có trọng số sẽ nhỏ
hơn threshold và buộc nơron phải cho output bằng 0
Như vậy, khi dạy chữ B thành công rồi thì nơron có quên đi chữ đã học trước đó là A
không ? Không, vì khi input là các chữ khác nhau thì nhóm các đường inputs đang
hoạt động cũng khác nhau hoặc là không hoàn toàn trùng nhau Nhớ là chúng ta chỉ
biến đổi weights của các inputs đang hoạt động thôi Chúng ta chỉ việc lập đi lập lại
quá trình dạy như trên cho tới khi nơron học thuộc bài mới thôi
Phương pháp dạy vừa rồi được gọi là Hebbian Learning, vì nó được Donald Hebb đề
nghị năm 1949 Phương pháp dạy bằng cách biến đổi weights của các đường truyền
này có làm bạn liên tưởng tới sự tăng cường các synapses trong bộ óc con người
không ? Lưu ý là ta cũng có thể lập trình để thực hiện Hebbian Learning trên máy tính
một cách dễ dàng
Mạng nơron nhân tạo Phần 4 Perceptron
Trong phần này, chúng ta sẽ áp dụng ngay những kiến thức vừa rồi cho một mạng
nơron đơn giản là Perceptron, do Frank Rosenblatt đề nghị năm 1962 Perceptron là
một mạng chỉ có một lớp nơron (lớp này có thể có một hay nhiều nơron), có cấu trúc
như sau:
Tạo ra một Perceptron
Như đã nhận xét trong phần 3, chúng ta có thể lập trình để mô phỏng nơron nhân tạo
và việc dạy học cho nơron Trong MatLab ta có thể thực hiện điều đó tương đối dễ
dàng Trước hết hãy mở MatLab Trong cửa sổ chính của MatLab (MatLab Command
Trang 7Window) bạn chỉ cần gõ dòng lệnh sau đây để tạo một Perceptron tên là net, có một nơron, và nhận input là một số có giá trị trong khoảng từ -1 đến 1:
net = newp([-1 1],1)
Trong MatLab [-1 1] là một ma trận một hàng và hai cột, có hai yếu tố là -1 và 1 Nếu muốn tạo một Perceptron có một nơron, nhận input là một cặp số, số thứ nhất có giá trị trong khoảng -1,1, và số thứ hai có giá trị trong khoảng 0,1, ta viết:
net = newp([-1 1;0 1],1)
Trong cách viết ma trận dấu ";" được dùng để tách các hàng, [-1 1;0 1] là một ma trận
có hai hàng và hai cột, hàng thứ nhất chứa min, max của thành phần input thứ nhất, hàng thứ hai chứa min, max của thành phần input thứ hai:
-1 1
0 1
Sau khi bạn kết thúc dòng lệnh và gõ Enter, MatLab sẽ tạo ra Perceptron, gán nó cho biến net và biểu thị các tính chất và biến số của mạng net Tạm thời chúng ta không quan tâm tới các tính chất và biến số đó Để MatLab không biểu thị chúng ra, ta chỉ cần thêm dấu ";" vào cuối dòng lệnh Ví dụ, dòng lệnh sau đây sẽ tạo ra một
perceptron có hai nơron, nhận input là một bộ ba số, mỗi số có min, max trong khoảng
từ -10 đến 10, mà không biểu thị kết quả:
net = newp([-10 10;-10 10;-10 10],2);
Ngoài ra bạn có thể dùng ";" ở sau bất kỳ dòng lệnh nào trong MatLab để MatLab không biểu thị kết quả của dòng lệnh ấy ra Trước khi tiếp tục các bạn hãy xóa biến net ra khỏi bộ nhớ, muốn thế hãy gõ:
Trang 8trên bàn phím để MatLab hiển thị lần lượt các câu lệnh đã gõ trước đó Khi tới câu lệnh cần sửa đổi thì bạn ngừng lại để sửa
Cho Perceptron hoạt động
Bây giờ trong MatLab Command Window các bạn hãy tạo một Perceptron có một nơron, nhận input là một số thay đổi trong khoảng từ -100 tới 100, và đặt tên cho nó là Bi:
Bi = newp([-100 100],1);
Perceptron Bi đang có các weights ngẫu nhiên, nó chưa có một kiến thức nào đặc biệt
cả Hãy đưa một số nào đó trong khoảng -100, 100, số 97 chẳng hạn, và xem nó cho output là gì:
y = sim(Bi,97)
Trong dòng lệnh vừa rồi, các bạn vừa bảo Bi nhận diện con số 97 bằng lệnh
sim(Bi,97), gán output của Bi cho biến số y, và biểu thị y ra màn hình Hãy thử bảo Bi nhận diện một số inputs khác xem sao
Dạy Bi phân biệt các số âm, dương
Bây giờ chúng ta hãy dạy Bi phân biệt các số âm, dương trong khoảng -100, 100 Muốn thế trước hết ta chọn một bộ các số âm, dương làm ví dụ để dạy, chẳng hạn như
bộ gồm hai số -2 và 65 sau đây:
examples = {-2 65}
Chúng ta muốn khi đưa một số âm thì Bi phải trả lời là 0, còn khi đưa một số dương thì nó phải trả lời là 1 Vì vậy ta cũng phải soạn một bộ lời giải tương ứng để dạy cho
Bi Trong trường hợp này bộ lời giải sẽ gồm hai số 0 và 1, lời giải 0 tương ứng với ví
dụ -2 và lời giải 1 tương ứng với ví dụ 65:
Trang 9lẫn của Bi được ước lượng bằng một đại lượng ký hiệu là MAE (Mean Average
Bộ ví dụ sẽ gồm 4 cặp số, mỗi cặp được cho dưới dạng một ma trận hai hàng, một cột
Do đó trước hết Bi phải được trang bị để có thể đọc các inputs gồm 2 số Ngoài ra, bộ lời giải sẽ gồm 4 số 0,1 tương ứng với từng trường hợp trong bộ ví dụ Ta gõ lần lượt các dòng lệnh sau:
Trang 10tests = {[0.01;0] [0;0.96] [1;0.01] [0.95;0.96]}
Một bài học lý luận khác
Bi giỏi quá phải không các bạn ? Các bạn hãy thử dạy Bi phép toán logic XOR
(Exclusive OR) xem sao Sau đây là bảng giá trị của XOR:
Nếu bạn đã quen với cách lập trình định hướng đối tượng (object-oriented) thì có lẽ
cách viết như trên rất quen thuộc với bạn Bi là một Perceptron, các thông số dạy học
trainParam là một thuộc tính của Bi, vì vậy để xem xét các thông số ấy ta viết:
Bi.trainParam
Số các vòng dạy epochs lại là một yếu tố trong các thông số dạy học trainParam, vì
thế để biết giá trị của epochs ta dùng dấu "." thêm một lần nữa:
Bi.trainParam.epochs
Các bạn hãy xem câu trả lời của bài tập này ở phần kế tiếp
Mạng nơron nhân tạo Phần 5 Mạng Feedforward
Thật ra mạng Perceptron không thể học được bài toán XOR, hạn chế ấy là do chính
cấu trúc của mạng Vì thế năm 1986 Rumelhart và McClelland đã cải tiến Perceptron
thành mạng Perceptron nhiều lớp (MultiLayer Perceptron, MLP), hay còn gọi là mạng
Feedforward
Trang 11Mạng Feedforward là một mạng gồm một hay nhiều lớp nơron, trong đó các dây dẫn tín hiệu chỉ truyền theo một chiều từ input qua các lớp, cho đến output Sau đây là một
ví dụ gồm hai lớp, mỗi lớp có hai nơron:
Lưu ý là lớp input không được coi là một lớp của mạng Ngoài ra mạng Feedforward cũng khác Perceptron ở chỗ là nó không dùng hàm Heaviside làm transfer function nữa, thay vào đó là các hàm sigmoid (tansig hay logsig) Sau đây là dạng của hàm tansig (tanh(x/2)):
Tạo ra một mạng Feedforward
Để tạo một mạng Feedforward tên là net, nhận input là các cặp số trong khoảng 0,1,
có hai lớp, mỗi lớp có một nơron, ta gõ dòng lệnh sau:
net = newff([0 1;0 1],[1 1]);
Ma trận thứ nhất trong hai arguments của newff cũng giống như trong trường hợp Perceptron, là ma trận chứa các giá trị min,max của hai thành phần input Còn ma trận thứ hai, [1 1], thì chứa số nơron trong mỗi lớp; ở đây ma trận có hai cột vì mạng có hai lớp, cà hai yếu tố của ma trận đều bằng 1, vì mỗi lớp chỉ có chứa một nơron thôi Sau đây là cấu trúc của net:
Trang 12Ngoài những tính chất xác định bởi các arguments trong lệnh newff, thì các tính chất còn lại của mạng đều được cho trước một cách mặc nhiên (default properties) Nhưng chúng ta cũng có thể thay đổi các tính chất ấy khi cần thiết Transfer function mặc nhiên của tất cả các lớp đều có dạng tansig, để dùng logsig cho lớp thứ nhất và tansig cho lớp thứ hai ta dùng:
net = newff([0 1;0 1],[1 1],{'logsig' 'tansig'});
Nếu dùng logsig làm transfer function cho cả hai lớp ta viết:
net = newff([0 1;0 1],[1 1],{'logsig' 'logsig'});
Phương pháp dạy học mặc nhiên của một mạng Feedforward là trainlm, ngoài ra còn
có trainbfg và trainrp Tuỳ theo nội dung bài học, các phương pháp sau có thể hiệu quả hơn Để dùng trainbfg hay trainrp làm phương pháp giảng dạy ta thêm một
argument thứ tư vào dòng lệnh vừa rồi:
net = newff([0 1;0 1],[1 1],{'logsig' 'logsig'},'trainbfg');
net = newff([0 1;0 1],[1 1],{'logsig' 'logsig'},'trainrp');
Thay đổi tính chất của mạng
Transfer function và phương pháp dạy học là hai thuộc tính duy nhất có thể thay đổi bằng cách thêm argument vào hàm newff Để thay đổi các thuộc tính còn lại ta phải viết lệnh gán trực tiếp, tương tự như khi thay đổi số epochs dạy của Perceptron vậy Trong nhóm các thông số dạy học, ngoài epochs ra còn có các thông số thông dụng sau:
goal: là sai số mà ta muốn mạng đạt được khi học tập, goal có giá trị mặc nhiên
là 0
min_grad: là gradient nhỏ nhất của sai số khi học tập, min_grad có giá trị mặc nhiên là 1e-6
Trang 13Để đổi goal và min_grad của mạng thành 1e-12 ta dùng:
net.trainParam.goal = 1e-12;
net.trainParam.min_grad = 1e-12;
Ngoài ra còn có hai thuộc tính quan trọng khác là inputConnect và layerConnect;
inputConnect quy định các đường truyền từ input tới các lớp, còn layerConnect quy
định các đường truyền giữa các lớp của mạng Cả hai thuộc tính này đều là các ma
trận
Trong trường hợp này inputConnect là một ma trận hai hàng một cột, [1;0], mỗi hàng
ứng với một lớp Yếu tố thứ nhất bằng 1, có nghĩa là input được nối trực tiếp với lớp
thứ nhất, yếu tố thứ hai bằng 0, có nghĩa là input không được nối trực tiếp với lớp thứ
hai Để cả hai lớp của net đều được nối trực tiếp với input ta viết dòng lệnh sau:
net.inputConnect = [1;1];
Còn layerConnect là một ma trận có hai hàng hai cột, [0 0;1 0] (nếu số lớp nơron là n
thì đây là một ma trận nxn) Yếu tố (i,j) của ma trận này, ký hiệu là layerConnect(i,j)
chỉ lấy một trong hai giá trị là 0 hay 1; layerConnect(i,j) bằng:
0 khi không có đường truyền từ lớp j tới lớp i;
1 khi có đường truyền từ lớp j tới lớp i
Bài tập: Phép toán XOR
Các bạn hãy thiết kế một mạng Feedforward có thể học phép toán XOR Nhớ là không
cần dùng quá 3 lớp nơron, vì Kolmogorov đã chứng minh rằng một mạng 3 lớp đã có
thể thực hiện được bất kỳ bài toán phân loại nào Rất tiếc là Kolmogorov không thể
cho chúng ta biết mỗi lớp phải có bao nhiêu nơron Đây là một chỉ dẫn: hãy đi từ đơn
giản tới phức tạp, đừng bắt tay vào xây dựng ngay những mạng có nhiều nơron, hãy
bắt đầu từ 1 hay 2 lớp, mỗi lớp có 1 hay 2 nơron; ngoài ra hãy chú ý tới liên kết giữa
input và các lớp trong mạng
Mạng nơron nhân tạo Phần 5 Mạng Feedforward (tiếp theo)
Bài tập: Nhận dạng chữ số