Luận án Tìm hiểu về mạng nơron Kohonen (hay mạng nơron tự tổ chức – SOM)

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.

pdf69 trang | Chia sẻ: lylyngoc | Ngày: 03/12/2013 | Lượt xem: 2690 | Lượt tải: 2download
Bạn đang xem nội dung 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), để tải tài liệu về máy 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:

  • pdfluan_van_kohonen_7005.pdf
Luận văn liên quan