Sự tải mẫu là quá trình đưa ảnh có độ phân giải cao được chuyển đổi về ảnh có
độ phân giải thấp hơn. Mỗi pixel trong ký tự (chữ ký) tải mẫu được ấn định cho một
mầu trung bình của vùng tương ứng trong ảnh có độ phân giải cao.
Kết quả ảnh tải mẫu sau đó được đưa tới tập huấn luyện hoặc tới quá trình nhớ
của mạng nơron Kohonen. Mạng nơron Kohonen được sử dụng trong ví dụ này có
số nơron đầu vào bằng số pixel của ký tự (hình ảnh) được tải mẫu, và số nơron đầu
ra bằng số ký tự mà ta tạo trong tập mẫu.
69 trang |
Chia sẻ: lylyngoc | Lượt xem: 3207 | Lượt tải: 2
Bạn đang xem trước 20 trang tài liệu Luận án Tìm hiểu về mạng nơron Kohonen (hay mạng nơron tự tổ chức – SOM), để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
u vào, chưa quan tâm khai thác các mối liên hệ có tính chất
cấu trúc trong lân cận của các vùng dữ liệu mẫu, hay toàn thể không gian. Nhưng
trong mạng nơron Kohonen đã quan tâm đến các yếu tố này.
Tự tổ chức trong mạng nơron là một trong những chủ đề cuốn hút trong
mạng nơron. Một mạng nơron như vậy có thể được luyện để tìm ra các quy luật và
các tương quan, các giá trị nhập vào và dự đoán các kết quả tiếp theo. Các nơron
của mạng thông qua quá trình luyện cạnh tranh để nhận ra một nhóm các đối tượng
đầu vào tương đương nhau. Mục đích chính của việc luyện trong mạng nơron
Kohonen là nhận dạng một nhóm các vector đầu vào cùng loại.
Trong phần tiếp theo, chúng ta có thể chỉ ra hình ảnh được lưu trữ và nhận
dạng với mạng nơron Kohonen. Việc thi hành mạng nơron Kohonen có thể được
thay thế bởi một thuật toán tương ứng mà dễ dàng thi hành, và luôn luôn được sử
dụng trong các ứng dụng của mạng nơron Kohonen. Chúng ta gọi thuật toán đó là
thuật toán mạng nơron tự tổ chức (Kohonen, 1988) hay ánh xạ tự tổ chức SOM. Ý
tưởng đáng chú ý của thuật toán này là ánh xạ các đặc trưng topo tự tổ chức nhằm
bảo toàn trật tự sắp xếp các mẫu trong không gian biểu diễn nhiều chiều sang một
- 33 -
không gian mới với các mảng nơron có số chiều nhỏ hơn, thường là hai chiều. Đây
là một phép chiếu phi tuyến đem lại một “ánh xạ đặc trưng” hai chiều, nó có thể
được sử dụng trong việc phát hiện và phân tích những đặc trưng trong không gian
đầu vào. Ta hiểu điều này như là bảo toàn cấu trúc các đặc trưng. Trong mạng
nơron Kohonen, các vector tín hiệu đầu vào gần nhau sẽ được ánh xạ sang các
nơron lân cận trong mạng.
Kỹ thuật SOM đã được áp dụng thành công trong một số lĩnh vực như nhận
dạng, phân cụm dữ liệu, dự đoán chuỗi và khai phá dữ liệu,... Mẫu được nhận dạng
có thể là ảnh, âm thanh hoặc văn bản,... Có thể xem SOM là một lớp điển hình,
nhưng rất đơn giản của các mạng nơron Kohonen.
2.2 Mạng nơron Kohonen
Mạng luyện không không có thầy hướng dẫn, là một kiểu luyện mà ở đó các
nơron tự xoay xở với các dữ liệu mẫu mà nó có được chứ không có “Ông thầy” gợi
ý cần luyện theo hướng nào.
Tự mình khám phá những quan hệ đang được quan tâm, ví dụ về các dạng
( patterns), các đặc trưng (features ) từ dữ liệu vào (input data) sau đó chuyển
thành cái ra (outputs). Như vậy thực chất : đó là các mạng tự tổ chức (hay mạng
nơron Kohonen) .
Định nghĩa: Mạng noron Kohonen là mạng có khả năng sử dụng những kinh
nghiệm của quá khứ để thích ứng với những biến đổi của môi trường (không dự
báo trước). Loại mạng này thuộc nhóm hệ học, thích nghi không cần có tín hiệu chỉ
đạo từ bên ngoài.
Trong phần này chúng ta sẽ trình bày một số quy trình luyện tham số của
luyện không có thày như sau:
Mô hình
Mạng có n nơron PEi , i=1,2,..., n.
Cái ra của chúng là
iy , i=1,...,n.
Có m tín hiệu vào {x1, x2,..., xm},wij là trọng số liên kết từ xj với PEi .
- 34 -
Gọi s(x), s(y) là hàm chuyển tín hiệu, giả thiết đó là hàm đơn điệu không
giảm liên tục như dạng hàm Sigmoid.
Phương thức biến đổi trọng số được gọi là luật luyện Hebb, quy tắc luyện
đơn giản theo dạng Hebb cho bởi phương trình :
)().(
)('
jjiiij
ij
ij xsyswdt
tdw
w (2.40)
Bây giờ ta xét một số trường hợp riêng:
- Quy tắc luyện cạnh tranh (Competitive Learning Rule – Grossberg 1969,
Rumelhart 1986)
))()((' ijjjiiij wxsysw (2.41)
ở đây 1( ) , 0
1 ii i c y
s y c
e
(2.42)
- Nếu dùng ( )j j js x x ta thu được :
Quy tắc luyện cạnh tranh tuyến tính (the Linear competitive learning rule)
))((' ijjiiij wxysw (2.43)
Trường hợp riêng quan trọng là quy tắc “ thắng lấy tất cả - the winner-take-all
learning rule “ của Kohonen , giải thích để hiểu qua bài toán phân cụm tập
mẫu 1 2, , ..., pX x x x thành n cụm , với n đã cho.
Kí hiệu
1 2, w ( w , w , ..., w )
m m
i i i imx R R , α là hệ số học.
Tại mỗi vòng lặp k, quy tắc luyện gồm 2 bước :
1/ Bước tìm cái khớp nhất (matching) – tìm nơron tạm gọi là nơron thắng (theo
nghĩa gần mẫu nhất), sử dụng công thức sau:
x
wx
yyy m
.
)...max( 1 , (2.44) (Phương pháp tính tích vô hướng).
2/ Tính toán sai số và điều chỉnh trọng số
Ký hiệu ej là sai số ở cột thứ j, wij là biểu diễn cho cột thứ j của ma trận trọng số w,
sai số này được tính theo công thức sau:
ej = ||x-wij|| (2.45)
- 35 -
Nếu tổng sai số chưa nằm dưới mức cho phép, ta điều chỉnh trọng số theo công
thức:
)(1 kiji
k
ij
k
ij wxww
với k =1,…,m (2.46)
Khi một mẫu được đưa tới một mạng Kohonen, những nơron được chọn là
nơron thắng (winner) (nơron thích hợp nhất theo nghĩa mà ta đặt ra). Nơron thắng
này là dữ liệu đầu ra từ mạng Kohonen. Thông thường, các nơron thắng này tương
ứng với các nhóm trong dữ liệu đưa vào mạng Kohonen.
Mạng Kohonen được huấn luyện trong một chế độ không có giám sát. Sử dụng
mạng Kohonen này, dữ liệu có thể được phân loại thành từng cụm. Chúng ta sẽ xem
xét mạng Kohonen qua quá trình huấn luyện.
2.2.1 Mạng nơron Kohonen nhận dạng
Ta sẽ xem việc huấn luyện mạng nơron Kohonen như thế nào để nhận dạng
đúng các mẫu mà ta mong muốn. Chúng ta bắt đầu bằng cách xem xét cấu trúc của
mạng nơron Kohonen.
2.2.2 Cấu trúc của mạng nơron Kohonen
Mạng nơron Kohonen chỉ bao gồm một lớp dữ liệu đầu vào và một lớp dữ
liệu đầu ra của các nơron và nó không chứa lớp ẩn.
Lớp dữ liệu đầu vào đối với mạng nơron Kohonen là các nơron đầu vào. Các
nơron đầu vào này tạo thành mẫu dữ liệu đầu vào của mạng. Đối với mạng nơron
Kohonen, ta nên chọn dữ liệu đầu vào chuẩn hóa trong khoảng giữa -1 và 1. Khi
thực thi mẫu dữ liệu đầu vào, mạng sẽ tạo ra các nơron đầu ra.
Lớp đầu ra của mạng nơron Kohonen rất khác với lớp đầu ra của mạng nơron
truyền thẳng. Đối với mạng truyền thẳng, nếu chúng ta có một mạng nơron với 5
nơron đầu ra, chúng sẽ có thể cho kết quả bao gồm 5 giá trị. Còn trong mạng nơron
Kohonen chỉ có một nơron đầu ra cho ra một giá trị. Giá trị duy nhất này có thể là
đúng hoặc sai. Dữ liệu đầu ra từ mạng nơron Kohonen thường là các chỉ số của
nơron (Ví dụ nơron số 5,…). Cấu trúc đặc trưng của mạng nơron Kohonen được chỉ
ra trong hình 2.1.
- 36 -
Hình 2.1: Một dạng mạng nơron Kohonen
Bây giờ, chúng ta xem xét mạng nơron Kohonen xử lý thông tin như thế nào.
Để kiểm tra quá trình này, chúng ta xem xét một ví dụ sau:
Ví dụ
Chúng ta sẽ xém xét một mạng nơron Kohonen đơn giản. Mạng này sẽ chỉ có
2 nơron đầu vào, và 2 nơron đầu ra. Dữ liệu đầu vào được cho là 2 nơron được chỉ
ra trong bảng 2.1 và các trọng số kết nối giữa các nơron trong bảng 2.2.
Bảng 2.1 Bảng 2.2
Sử dụng các giá trị này, chúng ta xem xét nơron có thể thắng và cung cấp dữ
liệu đầu ra. Chúng ta bắt đầu bằng cách chuẩn hóa dữ liệu đầu vào.
2.2.3 Chuẩn hóa dữ liệu đầu vào
Mạng nơron Kohonen đòi hỏi dữ liệu đầu vào phải được chuẩn hóa. Yêu cầu
của mạng nơron Kohonen là dữ liệu đầu vào của nó phải được phân hoạch trên miền
xác định giữa -1 và 1. Mỗi dữ liệu đầu vào nên sử dụng hoàn toàn miền xác định, vì
nếu các nơron đầu vào chỉ sử dụng các số giữa 0 và 1, thì thành quả của mạng nơron
sẽ không cao (bị tổn thất).
- 37 -
Để chuẩn hóa dữ liệu đầu vào, chúng ta sẽ tính toán độ dài vector (vector
length) của các dữ liệu đầu vào, hoặc vector đầu vào. Trong trường hợp này độ dài
vector sẽ là: (0.5 * 0.5) + (0.75 * 0.75) = 0.8125.
Vậy trường hợp trên sẽ có độ dài vector là 0.8125. Sử dụng độ dài này,
chúng ta có thể xác định được hệ số chuẩn hóa. Hệ số chuẩn hóa là số nghịch đảo
của căn bậc hai độ dài vector đầu vào. Trong trường hợp trên thì hệ số chuẩn hóa là:
Tính toán giá trị trên cho kết quả hệ số chuẩn hóa là 1.1094. Hệ số chuẩn hóa
này sẽ sử dụng cho bước tiếp theo, đó là tính toán đầu ra cho nơron.
2.2.4 Tính toán dữ liệu đầu ra của nơron
Để tính toán dữ liệu đầu ra, vector dữ liệu đầu vào và các trọng số kế nối
nơron đều phải được xem xét. Thứ nhất, tính tích vô hướng của hai vector vector
đầu vào và vector các trọng số liên kết. Để tính toán tích vô hướng giữa hai vector
này, ta thực hiện như sau.
Ta bắt đầu tính toán cho nơron thức nhất. Thuật toán Kohonen cho việc lấy
tích vô hướng hai vector của vector đầu vào và vector trọng số được tính như sau:
Phép tính toán trên "dot product" cho kết quả là 0.395. Tính toán này sẽ được
thực hiện cho nơron đầu ra đầu tiên, và nó sẽ được thực hiện như vậy đối với mỗi
nơron đầu ra tiếp theo.
Bây giờ, dữ liệu đầu ra này phải được chuẩn hóa bằng nhân kết quả của "dot
product" trên (0.395) với hệ số chuẩn hóa là 1.1094, và cho kết quả là 0.438213. Dữ
liệu đầu ra đã được tính toán và chuẩn hóa, nó được ánh xạ tới một số lưỡng cực?.
2.2.5 Ánh xạ lưỡng cực
Khi tạo bản đồ lưỡng cực, số 0 sẽ là -1, và các số còn lại là 1. Tức là tạo bản
đồ lưỡng cực từ [-1,1] tới [0,1].
- 38 -
Ví dụ, để biến đổi chuỗi 0101 về số lưỡng cực ta làm như sau:
Do dữ liệu đầu vào được chuẩn hóa trong khoảng [-1,1] nên ta phải thực hiện
chuẩn hóa tương tự đối với nơron đầu ra. Để lập được bản đồ, ta cộng thêm 1 vào
kết quả rồi lấy ½ kết quả đó. Theo kết quả trên có kết quả đầu ra là 0.438213, và kết
quả trong dữ liệu đầu ra cuối cùng là :
(0.438213+1)/2 = 0.7191065.
Giá trị 0.7191065 là dữ liệu đầu ra của nơron đầu tiên. Giá trị này sẽ được so
sánh với các dữ liệu đầu ra của nơron khác. Bằng cách so sánh các giá trị này,
chúng ta có thể xác định được nơron “ thắng”.
2.2.6 Chọn nơron thắng
Nếu chúng ta muốn xác định được một nơron đầu ra thắng, chúng ta phải
tính toán giá trị cho nơron đầu ra thứ hai. Bây giờ, chúng ta sẽ xem nhanh quá trình
tính toán cho nơron đầu ra thứ hai.
Nơron dữ liệu đầu ra thứ hai sẽ sử dụng hệ số chuẩn hóa giống như đã sử
dụng để tính toán cho nơron đầu ra đầu tiên. Theo trên ta có hệ số chuẩn hóa là
1.1094. Chúng ta áp dụng phương pháp tính tích vô hướng cho trọng số của nơron
đầu ra thứ hai và vector dữ liệu đầu vào, chúng ta sẽ nhận được một giá trị là :
|0.5 0.75|*|0.3 0.4| = (0.5*0.75)+(0.3*0.4) = 0.45.
Giá trị này được nhân với hệ số chuẩn hóa 1.1094, chúng ta nhận được kết
quả là 0.49923.
Bây giờ chúng ta đã có giá trị đầu ra cho mỗi nơron. Nơron đầu tiên có giá trị
đầu ra là 0.7191065 và nơron thứ hai có một giá trị đầu ra là 0.49923. Để chọn
nơron thắng, chúng ta chọn giá trị của dữ liệu đầu ra là lớn nhất. Trong trường hợp
này thì nơron thắng là nơron đầu ra đầu tiên với giá trị đầu ra là 0.7191065.
Như vậy ta đã xác định được giá trị đầu ra của mạng nơron Kohonen. Ta
thấy các trọng số giữa nơron đầu vào và nơron đầu ra xác định dữ liệu đầu ra. Trong
- 39 -
phần sau, chúng ta sẽ điều chỉnh các trọng số này để nó cung cấp dữ liệu đầu ra phù
hợp với cái mà ta mong muốn.
2.2.7 Quá trình học của mạng Kohonen
Toàn bộ quá trình huấn luyện cho một mạng nơron Kohonen cần phải lặp lại
qua vài công đoạn. Nếu sai số đã tính toán của mạng nơron Kohonen ở mức thấp
hơn mức có thể chấp nhận được thì sẽ hoàn tất quá trình huấn luyện. Để tính toán tỉ
lệ sai số cho mạng nơron Kohonen, ta sẽ điều chỉnh các trọng số cho mỗi công
đoạn.
Quá trình huấn luyện cho mạng nơron Kohonen là luyện cạnh tranh nên mỗi
tập huấn luyện sẽ có một nơron thắng. Nơron thắng này sẽ có trọng số được điều
chỉnh sao cho ngay lập tức nó sẽ tác động trở lại mạnh mẽ hơn trong dữ liệu đầu
vào ở lần tiếp theo. Sự khác nhau giữa các nơron thắng sẽ dẫn tới sự khác nhau giữa
các mẫu đầu vào tiếp theo.
Chúng ta xem xét toàn bộ quá trình liên quan đến việc huấn luyện mạng
nơron Kohonen. Các bước được tóm tắt trong hình 2.2.
Từ hình 2.2 ta thấy, mạng nơron Kohonen được huấn luyện bởi các công
đoạn tuần hoàn cho đến khi một trong hai vấn đề sau xảy ra:
- Nếu tính toán các sai số ở mức thấp hơn mức có thể chấp nhận được thì
nhiệm vụ của chu kỳ sẽ hoàn thành quá trình huấn luyện.
- Nếu tất cả các tỉ lệ sai số chỉ thay đổi bởi đa số cận biên, thì chu kỳ riêng
lẻ này sẽ bị loại bỏm và các trọng số lại được khởi tạo lại với các giá trị
ngẫu nhiên, đông thời một chu kỳ huấn luyện mới lại bắt đầu. Chu kỳ
huấn luyện này sẽ tiếp tục chu kỳ huấn luyện trước và nó sẽ phân tích các
công đoạn để đưa ra kết quả; hoặc là chu kỳ bị loại bỏ hoặc tạo ra một tập
các trọng số đó mà có mức sai số có thể chấp nhận được.
- 40 -
Hình 2.2: Sơ đồ khối biểu diễn huấn luyện mạng nơron Kohonen.
2.2.8 Tỉ lệ (tốc độ) học
Tham số học là một hằng và nó là một số nhỏ hơn 1, ở trên ký hiệu là α.
Dừng
Bắt đầu
Khởi tạo ngẫu nhiên ma trận trọng
số
Tính toán sai số
Kiểm tra sai số
xem có ở mức
chấp nhận được
không?
Thực hiện huấn luyện, điều
chỉnh trọng số dựa vào nơron
thắng
Tính toán lại tỉ lệ sai số, ghi
lại những giá trị đã được cải
thiện
Cải thiện tỉ lệ
sai số là tầm
thường?
Ma trận trọng số
này đã tốt nhất
chưa?
Nếu có ma trận
trọng số tốt hơn
của ma trận trọng
số tốt nhất?
Gán ma trận trọng số này thành
ma trận trọng số tốt nhất
Đã quá số chu
kỳ xác định?
Yes
No
Yes Yes
No
No
No
No
Yes
Yes
- 41 -
Thông thường, ta đặt cho tham số học một giá trị từ 0.4 đến 0.5, nếu tỉ lệ học
lớn thì quá trình huấn luyện nhanh hơn. Tuy nhiên, việc đặt cho tỉ lệ học một giá trị
quá lớn có thể sẽ làm cho mạng không bao giờ hội tụ. Điều này làm thay đổi các
vector trọng số sẽ quá lớn gây ảnh hưởng tới việc phân loại các mẫu nên ta chỉ cần
chọn tỉ lệ học vừa đủ, và sử dụng nó để điều chỉnh các trọng số của các nơron.
Trong phần tiếp theo, chúng ta sẽ xem các trọng số này được điều chỉnh sử dụng
tham số học như thế nào.
2.2.9 Điều chỉnh các trọng số (cập nhật trọng số)
Một công đoạn xuất hiện khi dữ liệu huấn luyện được đưa vào mạng nơron
Kohonen, và các trọng số được điều chỉnh dựa trên các kết quả của dữ liệu huấn
luyện. Sự điều chỉnh các trọng số sẽ làm cho mạng có thuận lợi hơn ngay sau khi nó
được đưa trở lại mạng. Ma trận trọng số cuối cùng được sử dụng sẽ là ma trận tốt
nhất được xác định từ mỗi chu kỳ. Bây giờ, chúng ta sẽ xem xét các trọng số này
được thay đổi như thế nào.
Phương pháp cho việc tính toán thay đổi các trọng số sử dụng phương trình
sau:
)(1 ttt wxww (2.48)
Biến x là vector huấn luyện được đưa vào mạng. Biến wt là trọng số của
nơron thắng, và biến wt+1 là trọng số mới, α là hệ số học.
2.2.10 Tính toán sai số
Khi mạng huấn luyện không giám sát bao giờ cũng có sai số, đó là sự khác
nhau giữa kết quả mong đợi và kết quả thực tế của mạng nơron. Sai số mà chúng ta
tính toán là những cái mà không đúng giữa kết quả mong đợi và kết quả thực tế.
ej = ||x-wj||
Mục đích của mạng nơron Kohonen là phân loại dữ liệu đầu vào vào trong
các tập khác nhau, cho nên sai số của mạng nơron Kohonen phải được đo lường. Sai
số này sẽ được tính toán trong quá trình huấn luyện mạng.
- 42 -
2.3. Thực thi mạng nơron Kohonen
Có vài lớp có thể được sử dụng cùng nhau để tạo ra một mạng nơron
Kohonen. Chương sau ta sẽ chỉ ra cách để xây dựng một ứng dụng dựa trên mạng
nơron Kohonen, đó là ứng dụng nhận dạng ký tự quang (cụ thể là nhận dạng chữ
viết tay). Các lớp được mô tả như sau:
· KohonenNetwork – Thực thi các phương thức thuộc về mạng nơron
Kohonen. Đây là nơi mà mạng nơron Kohonen được huấn luyện và lấy các
mẫu.
· Network – Chứa đựng các phương pháp không thuộc về mạng nơron
Kohonen. Các lớp này chứa các phương pháp để tính toán tích vô hướng, và
chiều dài vector.
· NeuralReportable – Một giao diện đơn giản cho phép mạng nơron
Kohonen trả về thông tin tiến bộ sau khi mạng nơron được huấn luyện.
· TrainingSet – Một tập huấn luyện chứa đối tượng, đó là có thể chứa các
mảng của các lần huấn luyện riêng lẻ. Tập huấn luyện có thể chứa cả các
phần tử dữ liệu đầu vào và dữ liệu đầu ra.
Các lớp này hoạt động cùng nhau để cung cấp các chức năng cho mạng
Kohonen. Trước tiên, ta xem việc thực thi mạng nơron truyền thẳng xem chúng hoạt
động như thế nào.
2.3.1 Thực thi mạng nơron truyền thẳng
Khi thực thi mạng nơron truyền thẳng, dữ liệu được truyền đến đối tượng
“synapse”. Phương thức run chạy một vòng lặp luôn luôn đợi mẫu dữ liệu mới và
sau đó chuyển chúng thành dữ liệu đầu ra, danh sách 2.1 chỉ ra phương thức run
hoạt động để nhớ mẫu của lớp Layer.
Danh sách 2.1: Phương thức Layer.run
public void run() {
while ( running ) {
int dimI = getRows();
int dimO = getDimension();
// Nhớ mẫu
- 43 -
inps = new double[dimI];
this.fireFwdGet();
if ( m_pattern != null ) {
forward(inps);
m_pattern.setArray(outs);
fireFwdPut(m_pattern);
}
if ( step != -1 )
// Kiểm tra nếu bước tiếp theo đang được học
m_learning = monitor.isLearningCicle(step);
else
// Dừng mạng
running = false;
//Nếu ((m_learning) && (m_batch != 1))
if ( (m_learning) && (running) )
{ // Học
gradientInps = new double[dimO];
fireRevGet();
backward(gradientInps);
m_pattern = new Pattern(gradientOuts);
m_pattern.setCount(step);
fireRevPut(m_pattern);
}
} // Kết thúc while (running = false)
myThread = null;
}
Phương thức fireFwdPut được gọi để truyền mẫu vào trong “synapse” đầu ra.
forward(inps);
m_pattern.setArray(outs);
fireFwdPut(m_pattern);
Khi các phương thức “forward” và “fireFwdPut” được gọi, có ba biến liên quan
đó là:
· Các trọng số kết nối
· Độ lệch trọng số
· Hàm ngưỡng
- 44 -
Phương thức đầu tiên được gọi là phương thức fireFwdGet. Công việc chính
của phương thức này là nhận mẫu từ “synapse” đầu vào, và đợi cho đến khi không
có mẫu nào được đưa vào.
Lớp dữ liệu đầu vào chỉ nhận các giá trị {0,1} của mẫu để nhớ. Sau đó, lớp
đầu vào sẽ áp dụng hàm ngưỡng, đưa chúng đến lớp tiếp theo. Chúng ta sử dụng
kiểu hàm sigmoid trong lớp dữ liệu đầu vào, thực thi hàm sigmoid qua lớp
SigmoidLayer. Danh sách 2.2 chỉ ra phương thức SigmoidLayer.forward().
Danh sách 2.2: Phương thức SigmoidLayer.forward
public void forward(double[] pattern)
{
int x;
double in;
int n = getRows();
try {
for ( x = 0; x < n; ++x ) {
in = pattern[x] + bias.value[x][0];
outs[x] = 1 / (1 + Math.exp(-in));
}
} catch ( Exception aioobe ) {
aioobe.printStackTrace();
}
}
Từ danh sách 2.2 ta thấy, phương thức SigmoidLayer.layer() áp dụng hàm
sigmoid cho mỗi nơron trong lớp này. Hàm sigmoid đã được đề cập ở trên.
Phương thức Layer.run đã xử lý dữ liệu đầu vào bằng cách sử dụng hàm
ngưỡng sigmoid, lớp này sẵn sàng đưa mẫu tới lớp kế tiếp. Khi mẫu được đưa vào
lớp tiếp theo, thì các trọng số thích hợp được cập nhật.
Bây giờ, phương thức Layer.run áp dụng hàm ngưỡng cho mỗi giá trị nơron,
lớp phải truyền mẫu lên trên synapse. Synapse này áp các trọng số kết nối và gửi
mẫu tới lớp tiếp theo, chúng được thể hiện ở phương thức fireFwdPut(). Phương
thức fireFwdPut được chỉ ra trong danh sách 2.3.
Danh sách 2.3: Phương thức Layer.fireFwdPut
protected void fireFwdPut(Pattern pattern) {
- 45 -
if ( aOutputPatternListener == null ) {
return;
};
int currentSize = aOutputPatternListener.size();
OutputPatternListener tempListener = null;
for ( int index = 0; index < currentSize; index++ ){
tempListener =
(OutputPatternListener)aOutputPatternListener.elementAt(index);
if ( tempListener != null ) {
tempListener.fwdPut((Pattern)pattern.clone());
};
};
}
Phương thức Layer.fireFwdPut chịu hai trách nhiệm. Thứ nhất, nó áp các
trọng số kết nối giữa các nơron ở lớp hiện thời cho các nơron ở lớp tiếp theo. Thứ
hai, nó chuyển mẫu này đến synapse. Phương thức này chuyển mẫu đến synapse
bằng cách gọi phương thức Synapse.fireFwdPut. Phương thức Synapse.fireFwdPut
được chỉ ra trong danh sách 2.4.
Danh sách 2.4: Phương thức Synapse.fireFwdPut
public synchronized void fwdPut(Pattern pattern) {
if ( isEnabled() ) {
count = pattern.getCount();
while ( items > 0 ) {
try {
wait();
} catch ( InterruptedException e ) {
//e.printStackTrace();
return;
}
}
m_pattern = pattern;
inps = (double[])pattern.getArray();
forward(inps);
++items;
notifyAll();
} }
- 46 -
Khi vòng lặp chờ hoàn thành synapse, nó sẽ xử lý dữ liệu đầu vào, và sau đó
truyền mẫu tới lớp tiếp theo. Việc xử lý chỉ là synapse sẽ thực hiện trên mẫu để áp
độ lệch. Theo các quy trình của phương thức Synapse.fwdPut, nó sẽ sao chép mẫu
mà nó đã truyền vào biến lớp m_pattern.
m_pattern = pattern;
Mảng mẫu sau đó được sao chép tới một mảng hai giá trị để xử lý.
inps = (double[])pattern.getArray();
Sau đó, mảng mẫu hai giá trị được truyền vào phương thức forward. Trong
tất cả các lớp, phương thức forward luôn luôn được sử dụng để áp độ lệch.
forward(inps);
Khi độ lệch đã được áp, mẫu được sẵn sàng được xử lý ở lớp tiếp
theo.
Có nhiều loại synapse được tạo để có thể xử lý độ lệch theo các cách khác
nhau. Bây giờ, chúng ta sẽ xem xét phương thức FullSynapse.forward áp dụng độ
lệch được chỉ ra trong danh sánh 2.5.
Danh sách 2.5: Phương thức FullSynapse.forward
public void forward(double[] pattern) {
int x;
double in;
int n = getRows();
try {
for ( x = 0; x < n; ++x ) {
in = pattern[x] + bias.value[x][0];
outs[x] = 1 / (1 + Math.exp(-in));
}
} catch ( Exception aioobe ) {
aioobe.printStackTrace();
}
}
Ta có thể thấy độ lệch được áp cho mỗi phần tử của mẫu, và mẫu sẽ được
thêm vào một độ lệch. Giá trị nghịch đảo của tổng này sẽ được trả về phương thức
calling để được truyền tới lớp tiếp theo. Các quá trình này sẽ được lặp lại cho mỗi
- 47 -
lớp của mạng nơron. Sau đây ta xem chúng sẽ thực thi lan truyền ngược trở lại như
thế nào.
2.3.2 Thực thi lan truyền ngược
Khi mạng nơron huấn luyện, nó được đưa vào với các tập huấn luyện. Sau
đó, kết quả thu được từ mạng nơron sẽ được so sánh với kết quả trước đó. Phần
được thêm vào để làm cho dữ liệu đầu ra hiện tại phù hợp với dữ liệu đầu ra trước
đó được gọi là sai số.
Có vài cách để giảm hàm sai số này về mức tối thiểu . Phổ biến nhất là sử
dụng phương thức giảm theo gradient. Thuật toán để ước lượng đạo hàm của hàm
sai số được biết đến như là thuật toán lan truyền ngược, đó là nó lan truyền các sai
số này ngược lại trong mạng.
Trong thực tế, phương thức lan truyền ngược hoạt động bằng cách; đầu tiên
nó chạy một chương trình nhận dạng đối với dữ liệu huấn luyện để thu được một ma
trận trọng số, và sau đó điều chỉnh các trọng số và độ lệch để cải thiện sai số.
Ở trên ta thấy rằng phương thức Layer.run được chỉ ra trong danh dách 5.1,
chịu trách nhiệm cung cấp dữ liệu huấn luyện cho mạng nơron. Nó sẽ được chạy đối
với từng tập huấn luyện, và dữ liệu huấn luyện sẽ được chạy lặp đi lặp lại cho đến
khi sai số của mạng nơron nằm trong mức cho phép.
Phương thức Synapse.revPut sẽ gọi phương thức Synapse.backward để điều
chỉnh các độ lệch cần thiết của nơron bất kỳ. Hoạt động của phương thức
Synapse.backward được chỉ ra trong danh sách 2.6.
Danh sách 2.6: Phương thức Synapse.backward
protected void backward(double[] pattern) {
int x;
int y;
double s, dw;
int m_rows = getInputDimension();
int m_cols = getOutputDimension();
// Điều chỉnh các trọng số
for ( x=0; x < m_rows; ++x ) {
double absv;
- 48 -
s = 0;
for ( y=0; y < m_cols; ++y ) {
s += pattern[y] * array.value[x][y];
if ( getMomentum() < 0 ) {
if ( pattern[y] < 0 )
absv = -pattern[y];
else
absv = pattern[y];
dw = getLearningRate() * pattern[y] * inps[x] + absv *
array.delta[x][y];
} else
dw = getLearningRate() * pattern[y] * inps[x] + getMomentum() *
array.delta[x][y];
array.value[x][y] += dw;
array.delta[x][y] = dw;
}
bouts[x] = s;
}
}
2.3.3 Các tập huấn luyện
Để huấn luyện mạng nơron Kohonen thì các tập huấn luyện phải được cung
cấp. Dữ liệu huấn luyện này sẽ được lưu trữ trong lớp TrainingSet, lớp này được
thiết kế để nó là một lớp chứa đựng dữ liệu. Lớp TrainingSet quản lý hai biến mảng
độ dài của đầu vào và đầu ra.
Trong lớp TrainingSet, nó lưu trữ các biến và cách sử dụng chúng được tóm
tắt như sau:
• inputCount - Số lượng các phần tử đầu vào sẽ có cho từng mẫu huấn luyện.
• outputCount - Số lượng các phần tử đầu ra sẽ có cho từng mẫu huấn luyện.
• input[][] - Các mẫu đầu vào huấn luyện.
• output[][] - Các mẫu đầu ra huấn luyện.
• trainingSetCount - Số lượng mẫu huấn luyện.
Do quá trình hoạt động của mạng nơron Kohonen là không có giám sát, chỉ
có các phần tử dữ liệu đầu vào được cung cấp, nên đối tượng TrainingSet được xây
- 49 -
dựng để huấn luyện cho ra dữ liệu đầu ra, nó sẽ được chuyển tới đối tượng
KohonenNetwork để huấn luyện trong lần tiếp theo.
2.3.4 Báo cáo tiến trình
Để chuẩn bị các tập huấn luyện và thu nhận tình trạng thông tin từ quá trình
huấn luyện, ta phải hiểu rõ các lớp mạng Kohonen hoạt động như thế nào. Chúng ta
sẽ bắt đầu bằng việc xem xét lớp mạng cơ sở.
2.3.4.1 Lớp mạng cơ sở
Bây giờ chúng ta sẽ xem xét lớp Network. Lớp này là lớp cơ sở cho lớp
KohonenNetwork, nó là lớp cuối cùng cung cấp cho mạng nơron Kohonen.
Việc tính toán chiều dài một vector là một phần quan trọng của mạng nơron
Kohonen. Lớp Network chứa một phương thức để tính toán độ dài vector của vector
đã cho, và nó được biểu diễn dưới dạng mảng. Phương thức này được chỉ ra trong
danh sách 2.7.
Danh sách 2.7: Tính độ dài của một vector (Network.java)
/**
* @Tham số v vector
* @Kết quả trả về độ dài vector.
*/
static double vectorLength( double v[] )
{
double rtn = 0.0 ;
for ( int i=0;i<v.length;i++ )
rtn += v[i] * v[i];
return rtn;
}
Một chức năng quan trong khác được cung cấp bởi lớp cơ sở Network là
chức năng tính toán tích vô hướng. Lớp Network của mạng Kohonen dùng phương
thức này để tính toán dữ liệu đầu ra của mạng nơron. Phương thức tính tích vô
hướng được chỉ ra trong danh sách 2.8.
Danh sách 2.8: Tính toán tích vô hướng (Network.java)
/**
- 50 -
* @Tham số vec1 là vector thứ nhất
* @Tham số vec2 là vector còn lại
* @Kết quả trả về là tích vô hướng.
*/
double dotProduct(double vec1[] , double vec2[] )
{
int k,v;
double rtn;
rtn = 0.0;
k = vec1.length;
v = 0;
while ( (k--)>0 ) {
rtn += vec1[v] * vec2[v];
v++;
}
return rtn;
}
Đầu tiên, các trọng số giữa nơron được khởi tạo với các giá trị ngẫu nhiên.
Sau đó các giá trị ngẫu nhiên này được huấn luyện để cho ra các kết quả tốt hơn.
Tại thời điểm bắt đầu của mỗi chu kỳ huấn luyện, các trọng số cũng được khởi tạo
với các giá trị ngẫu nhiên. Lớp Network cung cấp một phương thức để thực thi vấn
đề này. Danh sách 2.9 chỉ ra phương thức để sinh các trọng số ngẫu nhiên.
Danh sách 2.9: Khởi tạo các trọng số ngẫu nhiên (Network.java)
/**
* @Tham số weight là một ma trận trọng số.
*/
void randomizeWeights( double weight[][] )
{
double r ;
int temp = (int)(3.464101615 / (2. * Math.random() ));
for ( int y=0;y<weight.length;y++ ) {
for ( int x=0;x<weight[0].length;x++ ) {
r = (double) random.nextInt(Integer.MAX_VALUE) + (double)
random.nextInt(Integer.MAX_VALUE) -
(double) random.nextInt(Integer.MAX_VALUE) - (double)
random.nextInt(Integer.MAX_VALUE) ;
weight[y][x] = temp * r ;
- 51 -
}
}
}
}
2.3.4.2 Lớp KohonenNetwork
Chúng ta sẽ xem xét lớp KohonenNetwork. Lớp này là lớp thực thi mạng
nơron Kohonen. Lớp KohonenNetwork có một số tính chất được chỉ ra trong danh
sách 2.10.
Danh sách 2.10: Các tính chất của lớp KohonenNetwork
public class KohonenNetwork extends Network {
double outputWeights[][];
protected int learnMethod = 1;
protected double learnRate = 0.5;
protected double quitError = 0.1;
protected int retries = 10000;
protected double reduction = .99;
protected NeuralReportable owner;
public boolean halt = false;
protected TrainingSet train;
Các tính chất được mô tả như sau:
halt – Thiết lập này là xác thực hủy bỏ quá trình huấn luyện.
learnMethod – Tỷ lệ học, đặt bằng 1.
learnRate – Tỷ lệ học ban đầu.
outputWeights[][] – Các trọng số của các nơron đầu ra dựa trên đầu vào.
owner – Lớp owner, lớp này thực thi giao diện NeuralReportable.
quitError – Khi tỷ lệ sai số đạt đến mức nhỏ hơn 10% thì dừng huấn luyện.
reduction – Lượng giảm tỷ lệ học ban đầu (learnRate) bởi mỗi công đoạn.
retries - Tổng số chu kỳ cho phép, nó đặt một mức trần (a ceiling) số lượng
các chu kỳ huấn luyện có thể xảy ra.
train – Tập huấn luyện.
Để cho mạng nơron Kohonen hoạt động tốt, ta không chỉ chuẩn hóa vector
đầu vào, mà ta còn phải chuẩn hóa cả ma trận trọng số. Danh sách 2.13 chỉ ra một
- 52 -
phương thức để chuẩn hóa các dữ liệu đầu vào để đưa tới mạng nơron Kohonen, và
danh sách 2.14 chỉ ra sự chuẩn hóa ma trận trọng số.
Danh sách 2.13: Chuẩn hó dữ liệu đầu vào (KohonenNetwork.java)
/**
* @Tham số input là mẫu dữ liệu vào
* @Tham số normfac là nhân tố chuẩn hóa
* @Tham số synth là giá trị đầu vào cuối cùng
*/
void normalizeInput(
final double input[] ,
double normfac[] ,
double synth[]
)
{
double length, d ;
length = vectorLength ( input ) ;
// Điều chỉnh trong trường hợp độ dài quá nhỏ
if ( length < 1.E-30 )
length = 1.E-30 ;
normfac[0] = 1.0 / Math.sqrt ( length ) ;
synth[0] = 0.0 ;
}
Danh sách 2.14: Chuẩn hóa trọng số (KohonenNetwork.java)
/**
* @Tham số w là các trọng số đầu vào
*/
void normalizeWeight( double w[] )
{
int i ;
double len ;
len = vectorLength ( w ) ;
// Điều chỉnh trong trường hợp độ dài quá nhỏ
if ( len < 1.E-30 )
len = 1.E-30 ;
len = 1.0 / Math.sqrt ( len ) ;
for ( i=0 ; i<inputNeuronCount ; i++ )
- 53 -
w[i] *= len ;
w[inputNeuronCount] = 0;
}
Bây giờ ta kiểm tra phương thức thử mẫu, được sử dụng để đưa mẫu dữ liệu
đầu vào tới mạng nơron Kohonen. Phương pháp này được gọi là phương pháp thử
“trial”, được chỉ ra trong danh sách 2.15.
Danh sách 2.15: Thử mẫu vào (KohonenNetwork.java)
/**
* Phương thức này có thể được sử dụng khi đưa một mẫu tới mạng.
* Thường thường, nó hay dùng để gọi nơron thắng
* @Tham số input là mẫu vào.
*/
void trial ( double input[] )
{
int i ;
double normfac[]=new double[1], synth[]=new double[1], optr[];
normalizeInput(input,normfac,synth) ;
for ( i=0 ; i<outputNeuronCount; i++ ) {
optr = outputWeights[i];
output[i] = dotProduct( input , optr ) * normfac[0]
+ synth[0] * optr[inputNeuronCount] ;
// Tạo bản đồ lưỡng cực mới (từ -1,1 tới 0,1)
output[i] = 0.5 * (output[i] + 1.0) ;
// Tính toán làm tròn
if ( output[i] > 1.0 )
output[i] = 1.0 ;
if ( output[i] < 0.0 )
output[i] = 0.0 ;
}
}
Vậy quá trình tính toán giá trị cho mỗi nơron đầu ra được tính toán bằng cách
lấy tích vô hướng đã được chuẩn hóa của dữ liệu đầu vào và các trọng số. Do dữ
liệu đầu ra cuối cùng có thể lớn hơn 1 hoặc nhỏ hơn 0, ta phải đưa nó về khoảng
[0,1]. Để đưa dữ liệu đầu ra về khoảng [0,1] thì các kết quả nhỏ hơn 0 thì ta đưa nó
về 0, và các kết quả lớn hơn 1 được đưa về 1. Dữ liệu đầu ra cuối cùng của mỗi
nơron được lưu trữ trong mảng dữ liệu đầu ra.
- 54 -
Chúng ta chỉ quan tâm đến nơron thắng vì chúng được đưa lại vào mẫu để
huấn luyện. Danh sách 2.16 chỉ ra phương thức để đưa một mẫu dữ liệu đầu vào tới
mạng Kohonen, và thu nhận nơron thắng. Phương thức này chính là phương thức
dùng để phận loại mẫu trong mạng Kohonen.
Danh sách 2.16: Đưa ra một mẫu vào và thu nhận nơron thắng
/**
* @Tham số input là mẫu vào
* @Tham số normfac là nhân tố chuẩn hóa
* @Tham số synth là giả đầu vào cuối cùng – (synthetic last
input)
* @Kết quả trả về là số nơron thắng.
*/
public int winner(double input[] ,double normfac[] ,double
synth[])
{
int i, win=0;
double biggest, optr[];
normalizeInput( input , normfac , synth ) ; // Chuẩn hóa dữ
liệu đầu vào
biggest = -1.E30;
for ( i=0 ; i<outputNeuronCount; i++ ) {
optr = outputWeights[i];
output[i] = dotProduct (input , optr ) * normfac[0]
+ synth[0] * optr[inputNeuronCount] ;
// Tạo bản đồ lưỡng cực mới (từ -1,1 tới 0,1)
output[i] = 0.5 * (output[i] + 1.0) ;
if ( output[i] > biggest ) {
biggest = output[i] ;
win = i ;
}
// account for rounding
if ( output[i] > 1.0 )
output[i] = 1.0 ;
if ( output[i] < 0.0 )
output[i] = 0.0 ;
}
return win ; }
- 55 -
Phương thức này sẽ thường xuyên được sử dụng khi ta muốn đưa một mẫu
tới một mạng nơron để phân loại. Còn phương thức “thử” mà chúng ta vừa xem xét
ở trên chỉ được sử dụng trong khi huấn luyện mạng. Khi huấn luyện, chúng ta quan
tâm đến dữ liệu đầu ra hiện tại của mỗi nơron. Trái lại, khi phân loại mẫu thì chúng
ta chỉ quan tâm đến nơron thắng.
Phương thức winner lặp qua mỗi nơron đầu ra và tính toán dữ liệu đầu ra cho
mỗi nơron riêng biệt. Trong quá trình lặp này thì các chỉ số của nơron được lưu lại.
Chỉ số này là của nơron có giá trị đầu ra cao nhất. Nơron có chỉ số cao nhất được
gọi là nơron thắng. Nơron thắng này được trả về tập mẫu để tiếp tục tham gia vào
quá trình huấn luyện.
Bây giờ chúng ta bắt đầu xem xét quá trình huấn luyện. Phương thức
training được chỉ ra trong danh sách 2.17.
Danh sách 2.17: Huấn luyện mạng nơron (KohonenNetwork.java)
/**
* @exception java.lang.RuntimeException
*/
public void learn ()
throws RuntimeException
{
int i, key, tset,iter,n_retry,nwts;
int won[],winners ;
double work[],correc[][],rate,best_err,dptr[];
double bigerr[] = new double[1] ;
double bigcorr[] = new double[1];
KohonenNetwork bestnet; // Preserve best here
totalError = 1.0 ;
bestnet = new
KohonenNetwork(inputNeuronCount,outputNeuronCount,owner) ;
won = new int[outputNeuronCount];
correc = new double[outputNeuronCount][inputNeuronCount+1];
if ( learnMethod==0 )
work = new double[inputNeuronCount+1];
else
work = null ;
rate = learnRate;
initialize () ;
best_err = 1.e30 ;
// Vòng lặp chính:
n_retry = 0 ;
for ( iter=0 ; ; iter++ ) {
evaluateErrors ( rate , learnMethod , won , bigerr , correc , work
) ;
totalError = bigerr[0] ;
if ( totalError < best_err ) {
best_err = totalError ;
copyWeights ( bestnet , this ) ;
- 56 -
}
winners = 0 ;
for ( i=0;i<won.length;i++ )
if ( won[i]!=0 )
winners++;
if ( bigerr[0] < quitError )
break ;
if ( (winners < outputNeuronCount) &&
(winners < train.getTrainingSetCount()) ) {
forceWin ( won ) ;
continue ;
}
adjustWeights ( rate , learnMethod , won , bigcorr, correc ) ;
owner.update(n_retry,totalError,best_err);
if ( halt ) {
owner.update(n_retry,totalError,best_err);
break;
}
Thread.yield();
if ( bigcorr[0] < 1E-5 ) {
if ( ++n_retry > retries )
break ;
initialize () ;
iter = -1 ;
rate = learnRate ;
continue ;
}
if ( rate > 0.01 )
rate *= reduction ;
}
// Hoàn thành
copyWeights( this , bestnet ) ;
for ( i=0 ; i<outputNeuronCount ; i++ )
normalizeWeight ( outputWeights[i] ) ;
halt = true;
n_retry++;
owner.update(n_retry,totalError,best_err);
}
Phương thức training bắt đầu bằng việc khởi tạo các ma trận trọng số với các
giá trị ngẫu nhiên và điều chỉnh các giá trị trọng yếu khác. Khi khởi tạo xong, vòng
lặp chính đưa các mẫu huấn luyện tới mạng nơron và tính toán các sai số dựa trên
các kết quả thu được từ mạng nơron. Khi kết thúc vòng lặp chính, xác định được
nơron thắng, và nó sẽ tiếp tục huấn luyện để thúc đẩy hợp nhất các khả năng của nó
trong quá trình nhận dạng mẫu riêng biệt, đồng thời cho ra một ma trận trọng số tốt
hơn. Điều này được xác định bằng cách tính toán sự cải tiến sai số giữa công đoạn
hiện tại và công đoạn trước. Nếu sự cải tiến không đáng kể thì chu kỳ huấn luyện
này coi như hoàn thành, và lại bắt đầu một chu kỳ mới.
- 57 -
Vì chu kỳ huấn luyện cực nhanh nên chúng ta chỉ theo dõi chu kỳ có tỷ lệ sai
số tốt nhất. Khi chúng ta tìm thấy một ma trận trọng số có sai số nằm dưới mức sai
số cho phép, thì sự huấn luyện được hoàn thành. Ngược lại, thì chúng ta sẽ lấy ma
trận tốt nhất đã được xác định ở chu kỳ trước.
Bây giờ, chúng ta sẽ bắt đầu xem xét xem các sai số được ước lượng như thế
nào. Danh sách 2.18 chỉ ra ước lượng các sai số.
Danh sách 2.18: Ước lượng các sai số (KohonenNetwork.java)
/**
* Phương thức này dùng trong quá trình học. Nó dùng để ước lượng
các trọng số dựa vào tập huấn luyện.
* @Tham số rate là tỉ lệ học
* @Tham số learn_method là dùng phương thức method(0=additive,
1=subtractive)
* @Tham số won là quản lý số lần nơron thắng
* @Tham số bigerr là trả về sai số
* @Tham số correc là trả về mảng hiệu chỉnh
* @Tham số work là phạm vi hoạt động
* @exception java.lang.RuntimeException
*/
*/
void evaluateErrors (
double rate ,
int learn_method ,
int won[],
double bigerr[] ,
double correc[][] ,
double work[])
throws RuntimeException
{
int best, size,tset ;
double dptr[], normfac[] = new double[1];
double synth[]=new double[1], cptr[], wptr[], length, diff ;
// Hiệu chỉnh và đặt lại số lần thắng
for ( int y=0;y<correc.length;y++ ) {
for ( int x=0;x<correc[0].length;x++ ) {
correc[y][x]=0;
}
}
for ( int i=0;i<won.length;i++ )
won[i]=0;
bigerr[0] = 0.0 ;
// Lặp qua tất cả các tập huấn luyện để xác định giá trị hiệu chỉnh
for ( tset=0 ; tset<train.getTrainingSetCount(); tset++ ) {
dptr = train.getInputSet(tset);
best = winner ( dptr , normfac , synth ) ;
won[best]++;
wptr = outputWeights[best];
cptr = correc[best];
length = 0.0 ;
for ( int i=0 ; i<inputNeuronCo the unt ; i++ ) {
- 58 -
diff = dptr[i] * normfac[0] - wptr[i] ;
length += diff * diff ;
if ( learn_method!=0 )
cptr[i] += diff ;
else
work[i] = rate * dptr[i] * normfac[0] + wptr[i] ;
}
diff = synth[0] - wptr[inputNeuronCount] ;
length += diff * diff ;
if ( learn_method!=0 )
cptr[inputNeuronCount] += diff ;
else
work[inputNeuronCount] = rate * synth[0] +
wptr[inputNeuronCount] ;
if ( length > bigerr[0] )
bigerr[0] = length ;
if ( learn_method==0 ) {
normalizeWeight( work ) ;
for ( int i=0 ; i<=inputNeuronCount ; i++ )
cptr[i] += work[i] - wptr[i] ;
}
}
bigerr[0] = Math.sqrt ( bigerr[0] ) ;
}
Mạng được huấn luyện và tạo ra một mảng hiệu chỉnh chứa biến hiệu chỉnh
được tạo bởi phương thức adjustWeights.
Sau khi nhân tố hiệu chỉnh được tính toán, thì các trọng số phải được điều
chỉnh. Danh sách 2.19 chỉ ra việc điều chỉnh các trọng số.
Danh sách 2.19: Hiệu chỉnh các trọng số (KohonenNetwork.java)
/**
* Phương thức này được gọi vào cuối mỗi lần huấn luyện, và nó
điều chỉnh các trọng số dựa vào lần thử trước.
* @Tham số rate là tỉ lệ học
* @Tham số learn_method sử dụng phương pháp method(0=additive,
1=subtractive)
* @Tham số won quản lý số lần mỗi nơron thắng
* @Tham số bigcorr dùng để quản lý sai số
* @Tham số correc dùng để quản lý mảng hiệu chỉnh
*/
void adjustWeights (
double rate ,
int learn_method ,
int won[] ,
double bigcorr[],
double correc[][]
)
{
double corr, cptr[], wptr[], length, f ;
bigcorr[0] = 0.0 ;
for ( int i=0 ; i<outputNeuronCount ; i++ ) {
if ( won[i]==0 )
continue ;
wptr = outputWeights[i];
- 59 -
cptr = correc[i];
f = 1.0 / (double) won[i] ;
if ( learn_method!=0 )
f *= rate ;
length = 0.0 ;
for ( int j=0 ; j<=inputNeuronCount ; j++ ) {
corr = f * cptr[j] ;
wptr[j] += corr ;
length += corr * corr ;
}
if ( length > bigcorr[0] )
bigcorr[0] = length ;
}
// Tính toán nhân tố hiệu chỉnh
bigcorr[0] = Math.sqrt ( bigcorr[0] ) / rate ;
}
2.4 Kết luận
Trong chương này, chúng ta đã tìm hiểu về mạng nơron Kohonen. Mạng
nơron Kohonen khác với mạng lan truyền ngược ở vài điểm. Mạng nơron Kohonen
là luyện không giám sát. Điều này có nghĩa rằng, mạng nơron Kohonen được cho
dữ liệu đầu vào nhưng không biết trước được “cái ra”. Sau đó, trong khi huấn luyện
thì mạng nơron Kohonen bắt đầu vẽ lên bản đồ của mỗi nơron trong mẫu huấn
luyện, mẫu này bao gồm các nơron đầu ra.
Một mạng nơron Kohonen chỉ bao gồm hai lớp. Mạng được đưa vào một
mẫu dữ liệu đầu vào và coi đây là lớp dữ liệu vào. Mẫu dữ liệu đầu vào này phải
được chuẩn hóa thành các giá trị nằm trong khoảng [-1,1]. Dữ liệu đầu ra từ mạng
nơron này là nơron đầu ra thắng riêng lẻ. Các nơron đầu ra có thể được đưa lại vào
trong các nhóm, tương ứng với các nhóm mà mạng nơron Kohonen đã phân loại đối
với đầu vào.
Sự huấn luyện một mạng nơron Kohonen khác đáng kể so với thuật toán lan
truyền ngược đã được giới thiệu. Để huấn luyện một mạng nơron Kohonen, chúng
ta phải đưa vào cho nó các phần tử huấn luyện và xem nơron đầu ra là nơron thắng.
Để cho các nơron thắng thì các trọng số của nơron thắng này được sửa đổi sao cho
nó sẽ hoạt động cao hơn trên mẫu.
Cũng có trường hợp có thể có một hoặc vài nơron không bao giờ thắng. Như
vậy, sẽ có các nơron có trọng số chết được đưa đến mạng nơron. Điều này sẽ gây
- 60 -
cho mạng làm việc quá tải khi nhận dạng, và thường thất bại khi giá trị trên các
nơron đầu ra ngang nhau.
Trong chương tiếp theo chúng ta sẽ áp dụng mạng nơron Kohonen vào ứng
dụng thực tế, đó là ứng dụng nhận dạng ký tự quang (cụ thể là chữ viết tay bằng
chuột và chữ ký đưa và dưới dạng ảnh).
- 61 -
Chương 3. Nhận dạng ký tự quang sử dụng mạng nơron
Kohonen
Nhận dạng luôn là một phần quan trọng và thú vị trong các ứng dụng tin học
hiện nay. Nhận dạng chữ viết cũng như nhận dạng nói chung là dùng thuật toán để
tìm ra các đặc điểm riêng của từng cá thể trong quần thể mà chúng ta phải nhận
dạng. Đối với nhận dạng ký tự quang thì với mỗi dữ liệu nhập vào (có thể là ký tự
viết bằng chuột hay chữ ký được scan), ta sẽ phải tìm ra được đầu ra tương ứng với
nó.
Máy Scanner là một loại máy scan phẳng (Flatbed Scanner) dùng để scan
những tài liệu đơn lẻ như văn bản, hình ảnh, thẻ, CMND…
3.1 Giới thiệu chung
Trong chương trước, ta đã tìm hiểu về mạng nơron Kohonen. Ta đã biết rằng,
một mạng nơron Kohonen có thể được sử dụng để phân loại các mẫu vào trong các
nhóm khác nhau. Trong chương này, chúng ta sẽ xem xét kỹ hơn một ứng dụng
riêng biệt của mạng nơron Kohonen. Đó là, mạng nơron Kohonen sẽ được áp dụng
để nhận dạng ký tự quang, cụ thể là chữ viết tay bằng chuột hoặc chữ ký được scan.
Các chương trình nhận dạng quang cũng có khả năng đọc văn bản in. Văn
bản này có thể là văn bản được quét từ tài liệu, hoặc văn bản viết tay đó là vẽ bằng
thiết bị cầm tay,…
Trong chương này, chúng ta sẽ phát triển một ví dụ, đó là nó có thể được
huấn luyện để nhận dạng chữ viết tay của con người.
Trong đó:
Tiền xử lý: là quá trình chuẩn hóa dữ liệu đầu vào.
Trích chọn đặc trưng: là quá trình tìm ra các thông tin hữu ích và đặc trưng
nhất cho mẫu đầu vào để sử dụng trong quá trình nhận dạng.
- 62 -
Hình 3.1:Mô hình chung trong nhận dạng chữ viết.
Nhận dạng: là quá trình sử dụng một mô hình nhận dạng cụ thể và một thuật
toán cụ thể để trả lời mẫu đầu vào là ký tự nào.
Hậu xử lý: là quá trình xử lý kết quả cho phù hợp với từng ứng dụng cụ thể.
3.2 Huấn luyện mạng
Hình 3.2: Sơ đồ huấn luyện mạng
Trong đó:
Data: là tập dữ liệu ban đầu.
Training Set: là tập dữ liệu huấn luyện.
Test Set: là tập dữ liệu kiểm tra.
ANN: là mạng nơron cần huấn luyện.
- 63 -
Model: là mô hình tạo ra sau khi huấn luyện mạng với tập dữ liệu huấn
luyện.
Evaluator: là phần đánh giá chất lượng mô hình, thường lấy tỉ lệ phân loại
đúng trên tập kiểm tra làm tiêu chí đánh giá.
Huấn luyện mạng với tập dữ liệu huấn luyện, kiểm tra mô hình thu được trên tập
dữ liệu kiểm tra. Chừng nào sai số trên tập kiểm tra còn giảm xuống được thì ta tiếp
tục huấn luyện lại trên tập dữ liệu huấn luyện. Khi nào sai số trên tập kiểm tra
không giảm được nữa thì dừng.
3.3 Thử nghiệm sử dụng mạng nơron Kohonen để nhận dạng ký tự quang
Ứng dụng nhận dạng quang sẽ hiển thị một giao diện người-máy bằng đồ họa
đơn giản, đó là sẽ cho phép ta huấn luyện và sử dụng mạng nơron.
Như đã nói, chương trình này không trực tiếp đọc để nhận dạng các ký tự mà nó
phải được huấn luyện từ các ký tự được đưa vào bằng việc vẽ trực tiếp bằng chuột,
hoặc đưa vào dưới dạng ảnh được scan, trước khi nó có thể nhận dạng dữ liệu đầu
vào. Các file huấn luyện ký tự được lưu trữ trong quyển từ điển mẫu.
Dữ liệu ta đưa vào phải được tải mẫu trước khi chúng được nhận dạng. Ký tự
(ảnh) được tải mẫu bằng cách; đưa ký tự (ảnh) vào trong một lưới nhỏ 5x7 pixel.
Khi ta tải mẫu ký tự (ảnh), một khung hình chữ nhật được vẽ quanh ký tự (ảnh).
Khung này gọi là khung cắt xén. Mục đích của khung cắt xén là cắt ra khoảng trắng
không cần thiết cho ký tự (ảnh). Vì vậy, ta có thể vẽ ký tự (lấy ảnh) ở vị trí bất kỳ
trong khu vực vẽ, thì chương trình vẫn nhận dạng được ký tự (ảnh).
Theo cách phân chia trên thì mạng có 5x7=35 nơron đầu vào. Số nơron đầu ra
được chọn cho mạng nơron Kohonen được sử dụng trong chương trình này tương
ứng với số ký tự (ảnh) có trong tập mẫu. Nếu có 26 ký tự (ảnh) trong tập mẫu, thì sẽ
có 26 nơron đầu ra. Thử nghiệm chương trình với tập mẫu nhỏ (khoảng 150 mẫu)
thì độ chính xác khoảng 80%.
* Huấn luyện mạng nơron: Mỗi kết nối nơron được gán một trọng số. Để xác định
tổng số các kết nối, ta cần phải nhân số nơron đầu vào và số các nơron đầu ra. Nếu
- 64 -
một mạng nơron với 26 nơron đầu ra và 35 nơron đầu vào sẽ có kết quả là 910 trọng
số kết nối. Quá trình huấn luyện là quá trình điều chỉnh các trọng số để thu được ma
trận trọng số mà ta mong muốn.
Do đầu vào của mảng là 35 nơron nên các nơron này là nơron “thắng", nó
được lưu giữ với số nguyên "tốt nhất" đó chính là số 1. Hình minh họa phía dưới.
Hình 3.4: Biểu diễn ký tự e theo ma trận 5x7 pixcel.
Hình 3.5: Biểu diễn ký tự e theo ma trận 5x7 bởi các giá trị
Hình3.6: Biểu diễn ký tự e ở vector đầu vào
Ta bắt đầu khởi tạo ma trận trọng số bằng cách lựa chọn ngẫu nhiên. Sau khi
khởi tạo ma trận thì quá trình luyện sẽ bắt đầu. Ban đầu, ma trận trong số được đánh
giá để xác định xem những gì hiện tại của nó là sai số (lỗi) cấp. Sai số này được xác
định bởi việc huấn luyện đầu vào như thế nào (các ký tự mà ta tạo ra) để đưa ra các
nơron đầu ra. Nếu sai số tính toán ở mức dưới 10% thì quá trình đã hoàn thành.
Sau đây là một số kết quả thu được trong quá trình chạy thử nghiệm chương
trình.
- 65 -
a. Chọn vẽ trực tiếp, tải mẫu và gán ký tự cho mẫu (hình 3.7)
Hình 3.7 Vẽ và gán ký tự
Hình 3.8 Kết quả mạng nơron Kohonen nhận dạng ký tự e và ký tự c
f. Chọn ảnh, lấy chữ ký (hình 3.9)
Hình 3.9 Đưa chữ ký vào mạng và gán tên
- 66 -
Hình 3.10 Kết quả mạng nơron Kohonen nhận dạng chữ ký
3.4 Trường hợp ngoại lệ
Chương trình được trình bầy ở đây chỉ có khả năng trong nhận dạng các ký tự
riêng biệt.
Khi chạy chương trình, ta thấy có vấn đề xảy ra. Ví dụ như: chương trình khó có
thể xác định để phận biệt giữa chư “o” thường và chữ “O” hoa, hay chữ số 0 (số
không). Vậy ta thấy, giữa các ký tự này thì không thể vận dụng bằng mạng nơron
Kohonen.
3.5 Kết luận
Trong chương này, chỉ ra một ứng dụng thực tế của mạng nơron Kohonen. Tiêu
điểm của chương này là tạo ra một ứng dụng nhỏ đó là khả năng nhận dạng chữ viết
tay.
Các ký tự (chữ ký được scan) được người sử dụng đưa vào với độ phân giải cao.
Để biểu diễn được tới mạng nơron, ta giảm bớt độ phân giải này bằng cách sử dụng
kỹ thuật cắt xén và tải mẫu, ký tự (chữ ký) được chuyển sang một ảnh thứ hai với
độ phân giải thấp hơn nhiều.
Khi ảnh được đưa vào, nó phải được cắt xén để loại bỏ các khoảng trắng. Vì thế
nó không phụ thuộc vào vị trí và cỡ viết của ký tự (ảnh).
- 67 -
Sự tải mẫu là quá trình đưa ảnh có độ phân giải cao được chuyển đổi về ảnh có
độ phân giải thấp hơn. Mỗi pixel trong ký tự (chữ ký) tải mẫu được ấn định cho một
mầu trung bình của vùng tương ứng trong ảnh có độ phân giải cao.
Kết quả ảnh tải mẫu sau đó được đưa tới tập huấn luyện hoặc tới quá trình nhớ
của mạng nơron Kohonen. Mạng nơron Kohonen được sử dụng trong ví dụ này có
số nơron đầu vào bằng số pixel của ký tự (hình ảnh) được tải mẫu, và số nơron đầu
ra bằng số ký tự mà ta tạo trong tập mẫu.
- 68 -
KẾT LUẬN
Kiến thức đã tìm hiểu được
- Nắm được kiến thức cơ bản của mạng nơron nhân tạo và mạng nơron
Kohonen.
- Nắm đượcquy trình chung trong việc xây dựng hệ thống nhận dạng chữ viết.
- Sử dụng phương pháp tính tích vô hướng hai vector để tìm nơron thắng.
- Đưa ra phương pháp trích chọn đặc trưng cho nhận dạng ký tự quang (cụ thể
là chữ viết tay bằng chuột và chữ ký đưa và dưới dạng ảnh).
- Phát triển thành công phần mềm nhận dạng ký tự quang (cụ thể là chữ viết
tay bằng chuột và chữ ký đưa vào dưới dạng ảnh).
- Chương trình ứng dụng mới đang bước đầu thử nghiệm, và độ chính xác trên
tập mẫu (150 mẫu) khoảng 80%.
Hướng phát triển nghiên cứu
Luận văn có thể phát triển cho nhận dạng văn bản viết tay. Tuy nhiên để làm
được điều này phải là cả một quá trình tìm hiểu và nghiên cứu lâu dài. Do thời gian
có hạn nên luận văn mới chỉ trình bày ở mức độ đơn giản đó là nhận dạng chữ ký và
từng ký tự riêng biệt.
Tự đánh giá
Mặc dù em đã cố gắng để hoàn thiện đề tài, nhưng chắc chắn không thể tránh
được những thiếu sót, em rất mong nhận được sự chỉ bảo và giúp đỡ của các thầy cô
giáo, cùng với sự góp ý kiến của những ai quan tâm.
- 69 -
Tài tham khảo
1. Teuvo Kohonen,Self-Organizing Maps, Third Edition, Springer, Heidelberg,
2001
2. V. Rao and H. Rao, C++ Neural Networks and Fuzzy Logic, Second Edition,
MIS Press, NewYork, 1995
Các file đính kèm theo tài liệu này:
- luan_van_kohonen_7005.pdf