Thứ Sáu, 23 tháng 3, 2012

Mạng nơron Phần 1 (sưu tầm ^^)

Mạng nơron nhân tạo

(trích blog http://thanhtra.nguyen.free.fr)


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.

Phần 2. Nơron và sự học tập


Sau đâ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.
Cá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.



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:

Kế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:

Trong đó f là hàm Heaviside:

f được gọi là threshold function hay transfer function của nơron, còn giá trị (-t) còn được gọi là bias hay offset của nơron.
Nếu chúng ta đưa thêm một input nữa vào, input thứ 0, có giá trị luôn luôn bằng 1 và weight luôn luôn bằng bias (-t) thì output của nơron còn có thể viết dưới dạng:

Lưu ý là chỉ số của tổng bây giờ bắt đầu từ 0 chứ không phải bằng 1 như trước nữa.
Nếu các bạn đã quen lập trình, thì các bạn chắc cũng nhận xét là chúng ta có thể dễ dàng viết một chương trình ngắn để mô phỏng hoạt động của nơron nhân tạo nói trên. Các bạn có kiến thức về điện tử cũng có thể tạo một mạch đơn giản để thực hiện một nơron nhân tạo.

Dạy nơron học như thế nào ?

Giả 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ố 0, 1 vào nơron.
Hãy bắt đầu bằng cách cho các weights những giá trị ngẫu nhiên, lúc này nơron chưa biết gì hết. Bây giờ hãy input chữ A. Nơron sẽ lấy tổng có trọng số của các inputs và so sánh kết quả với 0. Nếu kết quả dương thì output là 1, âm thì output là 0. Khả năng nơron đoán đúng là 50%, vì các weights đang có giá trị hoàn toàn ngẫu nhiên. Nếu nơron đoán đúng thì chúng ta không cần làm gì cả, nhưng khi nơron đoán sai (output bằng 0), thì chúng ta phải tăng các weights của các inputs đang hoạt động (các inputs khác không) lên, sao cho lần tới tổng có trọng số sẽ vượt quá threshold và tạo nên output là 1.
Ngượ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.




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 Window) 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õ:
clear net
Còn nếu muốn xóa tất cả các biến đang tồn tại trong bộ nhớ của MatLab, hãy dùng:
clear
Để xóa màn hình của Command Window bạn dùng:
clc
Khi bạn viết sai một câu lệnh và gõ Enter thì MatLab sẽ báo lỗi ngay. Tuy nhiên bạn không thể đưa con trỏ vào câu lệnh đó để sửa chữa đâu. Bạn phải nhấn nút mũi tên lên trê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:
answers = {0 1}
Để dạy cho Bi bộ ví dụ trên ta gõ như sau:
Bi = train(Bi,examples,answers);
Hàm train sẽ dùng bộ ví dụ examples và bộ lời giải answers để dạy cho Bi. Bi sẽ được dạy bộ ví dụ đó nhiều lần nếu cần thiết, cho tới chừng nào nó hết nhầm lẫn mới thôi. Trong MatLab mỗi vòng dạy qua tất cả các ví dụ được gọi là một epoch, còn sự nhầm lẫn của Bi được ước lượng bằng một đại lượng ký hiệu là MAE (Mean Average Error).
Bây giờ Bi đã học bài xong, ta hãy thử tài của nó xem sao. Trước hết hãy xem nó có thuộc bài hay không bằng cách bảo nó phân loại trở lại các số trong bộ ví dụ:
y = sim(Bi,examples)
Cuối cùng hãy thử tài suy đoán của Bi bằng cách bảo nó phân loại các số không nằm trong bài học:
tests = {-78 45 35.3 -24.6 pi 0}
y = sim(Bi,tests)
Các bạn sẽ thấy Bi phân loại được hết các số vừa rồi, chỉ trừ trường hợp số 0, nó cho rằng 0 là số âm ! Nhưng tôi không trách nó đâu, vì số 0 là một số đặc biệt.

Bi học lý luận

Chắc các bạn đều biết phép toán logic OR, chúng ta sẽ dạy cho Bi phép toán đó. Cho một cặp số nằm trong khoảng 0,1, kết quả của phép toán OR được cho trong bảng sau:

OR01
001
111

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:
clear
clc
Bi = newp([0 1;0 1],1);
examples = {[0;0] [0;1] [1;0] [1;1]}
answers = {0 1 1 1}
Bạn hãy dạy cho Bi bằng bộ ví dụ và bộ lời giải trên. Sau đó hãy ôn lại bài và thử tài suy đoán của Bi bằng cách làm nhiễu các inputs một chút như sau:
tests = {[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:

XOR01
001
110

Nếu cần bạn có thể tăng số vòng dạy (epochs) lên, để ấn định số epochs là 500 chẳng hạn bạn dùng dòng lệnh sau:
Bi.trainParam.epochs = 500;
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

Chủ Nhật, 11 tháng 3, 2012

Tìm hiểu công cụ Adaptive lookup table trong toolbox Simulink design optimization

 Đặt vấn đề:
 Đối với một hệ phi tuyến phức tạp nhất là với hệ tham số biến đổi theo thời gian, việc xác định quan hệ vào ra bằng hàm truyền là rất phức tạp ,do đó, việc thiết kế bộ điều khiển cũng  gặp rất nhiều khó khăn. Để khắc phục vấn đề đó, chúng ta có thể sử dụng các phương pháp như: Sử dụng đồ thị (Giống kĩ thuật nhiệt ấy, môn này nhiều anh em học lại mấy lần chắc chả xa lạ gì :D) và phương pháp tra bảng (Lookup table). Để dễ dàng trong quá trình thiết kế, MatLab đã cung cấp cho chúng ta một công cụ Adaptive nằm trong Toolbox Simulink Design Optimization.
Giải Quyết vấn đề:
Trước hết ta tìm hiểu về Lookup table
 1.Lookup table(Bảng tham chiếu): 
        Lookup table là một bảng lưu trữ dữ liệu ở dạng mảng đa chiều, nó cung cấp cho chúng ta một công cụ để thu thập các trạng thái động học của hệ thống.
        Đối với một hệ thống M đầu vào và N đầu ra thì có thể mô tả bằng N lookup table tạo bởi các mảng M chiều. Việc tạo các Lookup table có thể làm bằng cách thu thập dữ liệu vào ra của hệ thống.Ø    Mỗi tham số chỉ lấy 1 giá trị trong các giá trị trong tập giá trị gọi là  breakpoint( điểm ngắt)
        Mỗi giá trị đầu ra tương ứng với đầu vào tạo thành 1 phần tử trong bảng gọi là cell
        Tập các breakpoint tương ứng với bộ tham số đầu vào tạo thành 1 lưới M đầu vào.
Ưu điểm:
      Sau khi tạo đc bảng tham chiếu thì từ các giá trị đầu vào ta có thể sử dụng các mảng đa chiều tương ứng để xác định biến đầu ra mà ko cần thực hiện phép đo. Vì vậy bảng tham chiếu phù hợp để mô tả quan hệ vào ra của 1 hệ tĩnh.
Nhược điểm
Đối với mô hình tham số biến thiên thì hệ thống thay đổi liên tục do vậy với cùng một đầu vào có thể cho các diễn biến khác nhau tại các thời gian khác nhau.
   =>Vì vậy việc sử dụng bảng tham chiếu thông thường không hiệu quả
Giải pháp: Sử dụng Adaptive lookup table( Bảng tham chiếu thích nghi).
   Adaptive lookup table nhận các kết quả đo đầu vào và ra từ các cảm biến của hệ thống sau đó sử dụng để tự đổng tạo ra và liên tục cả thiện nội dung lookup table.đây chính là quá trình thích nghi
2.  Khối Adaptive lookup table trong Toolbox SDO:
 Simulink cung cấp thư viện  các khối sử dụng lookup table để xây dựng mô hình bao gồm 

 ·  Adaptive Lookup Table (1D Stair-Fit) —adaptive lookup table một chiều
·  Adaptive Lookup Table (2D Stair-Fit) —adaptive lookup table 2 chiều
·  Adaptive Lookup Table (nD Stair-Fit) —adaptive lookup table nhiều chiều


Bảng n chiều

* Các tham số cho khối Adaptive lookup table




-Table breakpoins (cell array): Bảng các điểm ngắt. Các điểm ngắt ứng với 1 đầu vào tạo thành một mảng (đơn điệu tăng). Tập các mảng ngắt đầu vào tạo thành 1 mảng cell
-Table data(initial) Bảng dữ liệu đầu ra ban đầu, các vector phải có chiều là N-1 với N là số điểm ngắt (tương ứng số đầu vào)
-Make initial table an input Lựa chọn bỏ qua bảng giá trị ban đầu  đồng thời tạo ra 1 cổng vào mới là Tin và dùng cổng này làm bảng dữ liệu.
-Table numbering data  Cách đánh số trong bảng, các vector phải có cùng kích thước giống như table data và mỗi giá trị là duy nhất.
-Adaptation method phương pháp thích nghi.
-Adaptation gain (0 to 1) lựa chọn 1 số từ 0-1 để điều chỉnh trọng số của dữ liệu trong quá trình thích nghi.
-Make adapted tabe an output  Lựa chọn thêm 1 cổng ra để xuất dữ liệu sau của bảng đã thích nghi.
-Add adaptation enable/disable/reset port: Thêm 1 cổng kích hoạt, vô hiệu hóa hay reset.
-Add cell lock enable/disable port Cổng kích hoạt hay vô hiệu hóa chức năng cell lock (chỉ cập nhật dữ liệu ở một số cell.
-Action for out-of-range input: tùy chọn hành động khi dữ liệu vượt quá số điểm ngắt. 
Ví dụ về khối
Mô hình dưới mô tả cách tạo ra 1 Adaptive lookup table và hoạt động của bảng.
Hệ thống trong ví dụ là hệ có 2 đầu vào do đó sử dụng bảng 2 chiều
Các dữ liệu thực nghiệm được lưu trữ trong khối Experiment Data sau đó qua khối 2 chiều tạo ra bảng thích nghi và hiển thị ở chân Tout. Giá trị hiển thị ở chân y, số cell đang cập nhật hiển thị ở chân N


VD2:


Trong ví dụ này, chúng ta sử dụng dữ liệu thực nghiêm được thu thập từ một động cơ trong đó
X – 10 điểm đo giá trị áp suất của động cơ trong khoảng [10,100]
Y-  36 điểm đo giá trị động cơ trong khoảng [0,7000]
Z- Ma trận10x36 chứa dữ liệu của công suất riêng động cơ 

















Kết luận 
    Adaptive Lookuptabe trong Matlab là một công cụ mạnh dùng để ước lượng tham số cho các hệ phi tuyến phức tạp. Sử dụng công cụ này giúp giảm thiểu thời gian tính toán đồng thời có biểu diễn một cách trực quan số liệu giúp thuận lợi cho việc thiết kế bộ điều khiển.



Chủ Nhật, 4 tháng 3, 2012