Với kết quả kiểm tra độ chính xác nhận dạng như trên thì có thể thấy rằng việc áp dụng mô hình Markov ẩn trong nhận dạng tiếng Việt đã cho kết quả khá tốt. Tuy chưa thật sự hoàn hảo nhưng những kết quả thu được tương đối khả quan, từ đó có thể thấy rằng việc áp dụng mô hình Markov ẩn trong nhận dạng tiếng Việt là khá phù hợp, nếu đầu tư nghiên cứu nhiều hơn nữa phương pháp này sẽ còn đem lại hiệu quả cao hơn.
Trong chương trình khi chạy vẫn bị nhận dạng nhầm, nguyên nhân dẫn đến nhận dạng nhầm có thể là:
1. Dữ liệu huấn luyện chưa đầy đủ, số từ đem huấn luyện chưa nhiều, chưa thu được từ nhiều người, nhiều nơi
2. Một số thông số có ảnh hưởng đến độ chính xác nhận dạng như số trạng thái của mô hình, giá trị tối thiểu của bj(k), điều kiện hội tụ của mô hình có thể được lựa chọn chưa tối ưu.
Cả hai nguyên nhân trên muốn khắc phục được đều cần phải có thời gian, và cần phải bỏ công sức nghiên cứu nhiều hơn nữa.
Để chương trình có thể được ứng dụng rỗng rãi hơn cần phải cải tiến và mở rộng thêm. Với thiết kế đã được đưa ra thì hướng phát triển tiếp của tôi có thể là:
1. Tăng số lượng từ trong từ điển nhận dạng
2. Nhận dạng câu
3. Mở rộng ứng dụng của chương trình, không chỉ tích hợp với bộ Office của Microsoft mà có thể nhập dữ liệu vào bất cứ chương trình nào.
Do thời gian làm đồ án không có nhiều nên tôi chưa có điều kiện để tìm hiểu hết những hướng tiếp cận mới trong nhận dạng tiếng nói. Hy vọng rằng trong thời gian tới tôi, hoặc ai đó quan tâm đến lĩnh vực này có thể thực hiện được các mục đã đề ra.
100 trang |
Chia sẻ: oanh_nt | Lượt xem: 1358 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Đồ án Nhận dạng tiếng nói và ứng dụng tích hợp với các phần mềm máy tính, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
i độc lập với i (tức là chỉ phụ thuộc vào t) và có mục đích giữ cho giá trị at(i) sau khi lấy tỉ lệ không nằm ngoài khoảng cho phép của máy tính. Thủ tục lấy tỉ lệ này cũng được thực hiện tương tự cho các hệ số bt(i) (vì các hệ số này cũng có xu hướng tiến nhanh về 0), và ở cuối thủ tục ước lượng, các hệ số tỉ lệ này sẽ được loại bỏ một cách chính xác.
Để hiểu rõ quá trình thực hiện của thủ tục lấy tỉ lệ, chúng ta hãy xem lại công thức ước lượng các hệ số aij của ma trận chuyển trạng thái ở phương trình (4.54):
( 3.58)
Do :
Nên :
( 3.59)
Quá trình tính at(i) như sau. Ta dùng kí hiệu at(i) để chỉ giá trị khi chưa lấy tỉ lệ, để chỉ giá trị đã lấy tỉ lệ, để chỉ giá trị trung gian trước khi lấy tỉ lệ.
Ban đầu, với t=1, ta tính at(i) theo phương trình (3.19) đồng thời đặt và với
Với mỗi t (2£t£T), trước tiên ta tính theo công thức quy nạp ở phương trình (3.20) theo các giá trị đã lấy tỉ lệ trước đó, tức là :
( 3.60a)
Ta đặt hệ số tỉ lệ như sau :
(4.60b)
Và gán :
(4.60c)
khi đó hệ số được tính như sau :
( 3.61)
Bằng quy nạp ta có thể viết dưới dạng :
( 3.62)
Vì vậy sẽ được viết như sau :
( 3.63)
Tức là mỗi at(i) được lấy tỉ lệ theo hệ số là tổng tất cả các trạng thái của at(i).
Tiếp theo chúng ta sẽ tính các số hạng bt(i) theo công thức đệ quy của thủ tục Backward. Lưu ý rằng ta dùng cùng một hệ số tỉ lệ ở mỗi thời điểm t cho các giá trị b như đã dùng cho các giá trị a. Các giá trị bt(i) được lấy tỉ lệ có dạng :
( 3.64)
Theo các biến đã được lấy tỉ lệ, công thức ước lượng ở phương trình (3.61) trở thành :
( 3.65)
trong đó mỗi có thể được viết dưới dạng:
( 3.66)
v có dạng:
( 3.67)
Phương trình (3.56) sẽ trở thành:
( 3.68)
Ta nhận thấy CtDt+1 có dạng :
( 3.69)
Rõ ràng CT là độc lập với t nên CtDt+1 có thể được loại bỏ khỏi tử số và mẫu số của phương trình (3.59) và ta nhận được phương trình ước lượng aij chính xác.
Tương tự ta có thể áp dụng thủ tục lấy tỉ lệ cho các công thức ước lượng B.
( 3.70)
Ta lưu ý rằng thủ tục lấy tỉ lệ ở phương trình (3.63) không nhất thiết phải được áp dụng ở mỗi thời điểm t, mà có thể được áp dụng khi nào muốn hay khi cần thiết để tránh tràn số. Nếu không áp dụng việc lấy tỉ lệ tại thời điểm t thì ta cần đặt ct=1 ở thời điểm đó.
Do áp dụng thủ tục tính tỉ lệ nên thủ tục tính xác suất P(O|l) cũng phải thay đổi. Chúng ta không thể đơn giản chỉ lấy tổng các giá trị bởi vì các giá trị này đã được lấy tỉ lệ. Tuy nhiên, ta có thể sử dụng tính chất sau :
( 3.71)
nên ta có :
( 3.72)
Suy ra :
( 3.73)
hay là :
( 3.74)
Như vậy, ở đây ta sẽ tính log P chứ không tính P, bởi vì P có thể vượt quá phạm vi biểu diễn dữ liệu của máy tính.
Cuối cùng, ta lưu ý rằng với thuật toán Viterbi dạng logarit để xác định dãy trạng thái tối ưu thì không cần phải áp dụng thủ tục lấy tỉ lệ bởi vì nó không cần thiết.
Huấn luyện nhiều dãy quan sát
Trong phần trước chúng ta đã đề cập đến một loại mô hình Markov ẩn, đó là mô hình trái-phải (hay còn gọi là mô hình Bakis). Mô hình này có đặc điểm là dãy trạng thái tiến triển từ trạng thái 1 ở thời điểm t=1 đến trạng thái N ở thời điểm t=T. Chúng ta cũng đã xem xét các ràng buộc trên ma trận chuyển trạng thái và xác suất trạng thái ban đầu của mô hình trái-phải. Tuy nhiên điều khó khăn chính khi làm việc với mô hình trái-phải là vấn đề huấn luyện mô hình. Vì ta không thể chỉ dùng một dãy quan sát đơn để ước lượng các tham số cho nó. Đó là do bản chất tạm thời, ngắn ngủi của các trạng thái trong mô hình chỉ cho phép một số lượng nhỏ các quan sát ở mỗi trạng thái cho đến khi chuyển sang trạng thái kế tiếp. Vì vậy, để nhận được các ước lượng tham số đáng tin cậy ta phải dùng nhiều dãy quan sát để huấn luyện. Khi đó thủ tục huấn luyện lại sẽ được bổ sung như sau.
Giả sử ta có tập huấn luyện gồm K dãy quan sát:
O = [O(1), O(2), ....., O (K)]
Trong đó O(k) = (o1(k), o2(k), ...., oTk(k)) là dãy quan sát thứ k. Giả sử mỗi dãy quan sát là độc lập với nhau và mục tiêu của ta là hiệu chỉnh các tham số của mô hình để làm cực đại:
( 3.75)
Vì các công thức ước lượng dựa trên tần số xuất hiện của các biến cố khác nhau nên ta sẽ đưa các tần số xuất hiện riêng biệt cho một dãy quan sát vào công thức ước lượng. Các công thức đánh giá lại sẽ như sau:
( 3.76)
( 3.77)
Còn pi không cần ước lượng lại do p1=1, pi=0 "i¹1.
Nếu áp dụng các công thức lấy tỉ lệ ở phần sau, đồng thời chú ý rằng thì ta sẽ được các công thức ước lượng có lấy tỉ lệ đối với nhiều dãy quan sát như sau:
( 3.78)
( 3.79)
Khởi tạo các tham số của mô hình
Về mặt lý thuyết, các phương trình ước lượng của mô hình Markov ẩn tạo ra các tham số tương ứng với cực đại địa phương của hàm thích hợp nhất (likelihood). Vì vậy vấn đề quan trọng đặt ra là làm thế nào để chọn các ước lượng tham số ban đầu của mô hình để cực đại địa phương bằng hay xấp xỉ với cực đại toàn cục của hàm likelihood.
Về cơ bản, không có câu trả lời đơn giản và rõ ràng cho vấn đề này. Kinh nghiệm cho thấy rằng, với các tham số p và A, ta có thể khởi tạo một cách ngẫu nhiên hay khởi tạo các giá trị bằng nhau, miễn là thỏa mãn các ràng buộc thống kê, thì đều cho kết quả khá tốt trong hầu hết các trường hợp. Tuy nhiên, với tham số B, nếu các giá trị ban đầu được khởi tạo tốt thì quá trình ước lượng sẽ nhanh chóng hội tụ về điểm tới hạn.
Ta có thể sử dụng thuật toán phân đoạn k-trung bình để khởi tạo ma trận B như sau.
Ứng với mỗi chuỗi quan sát Ok=(o1ko2k...oTk) trong tập đa quan sát O= (O1,O2,....,Ok) ta sử dụng thuật toán Viterbi để tìm chuỗi trạng thái thích hợp nhất, dựa vào đó ta sẽ phân hoạch được các quan sát này thành N đoạn (N là số trạng thái của mô hình). Kết quả ta có N tập quan sát, mỗi tập tương ứng với một trạng thái của mô hình.
Với mỗi tập xác suất bj(k) được xác định như sau:
( 3.80)
Dữ liệu huấn luyện không đầy đủ
Tập quan sát huấn luyện là hữu hạn nên luôn tồn tại một số các sự kiện có xác suất thấp. Theo công thức ước lượng ở phương trình (3.43a) yêu cầu tính kỳ vọng số lần ở trạng thái j và quan sát vk. Nếu tập quan sát huấn luyện quá nhỏ không xảy ra sự kiện này (tức là qt=j và ot=vk) thì bj(k) trước và sau khi ước lượng vẫn bằng 0. Kết quả là mô hình sẽ tạo ra xác suất 0 cho những quan sát có qt=j và ot=vk. Như vậy bj(k)=0 là không đáng tin cậy do tập huấn luyện không đầy đủ.
Cách thứ nhất để giải quyết vấn đề này là tăng kích thước của tập quan sát huấn luyện, thông thường thì điều này là không thể thực hiện được. Cách thứ hai là giảm bớt kích thước của mô hình như giảm số trạng thái, giảm số kí hiệu quan sát ở mỗi trạng thái. Điều này có thể thực hiện được nhưng kết quả nhận dạng sẽ không cao. Hơn nữa, các tham số về số trạng thái và số kí kiệu quan sát thường có ý nghĩa vật lý nào đó nên trong nhiều trường hợp ta không nên thay đổi chúng. Cách giải quyết thứ ba và cũng là cách đơn giản nhất là đưa vào tham số mô hình các ràng buộc về ngưỡng để đảm bảo không có ước lượng tham số nào dưới một mức được đặt trước. Chẳng hạn ta có thể dùng ngưỡng như sau:
( 3.81)
Giá trị của thường thuộc vào khoảng là tốt nhất vì khi quá nhỏ thì lỗi nhận dạng sẽ tăng lên.
Tóm lại, chương này tập trung nói về lý thuyết mô hình Markov rời rạc và mô hình Markov ẩn. Các tham số của mô hình Markov ẩn và những vấn đề cần phải thực hiện khi cài đặt mô hình Markov ẩn trong ứng dụng nhận dạng tiếng nói.
TÍCH HỢP VỚI PHẦN MỀM MÁY TÍNH
GIỚI THIỆU
Khi công nghệ xử lý tiếng nói chưa được đưa vào ứng dụng một cách rộng rãi, việc trao đổi dữ liệu giữa nguời và máy chỉ thông qua một số phương tiện như: chuột, bàn phím, bút… với tốc độ thấp và dễ nhầm lẫn. Nhờ ứng dụng nhận dạng tiếng nói, con người có thể trao đổi dữ liệu với máy bằng ngôn ngữ tự nhiên giúp cho việc trao đổi dữ liệu hiệu quả và tự nhiên hơn…Trong phạm vi đồ án của mình tôi nghiên cứu ứng dụng tích hợp với bộ Microsoft Office XP để trao đổi dữ liệu với một số ứng dụng bằng giọng nói. Trên cơ sở đó xây dựng một phần mềm trao đổi dữ liệu với bảng tính Excel.
TRAO ĐỔI DỮ LIỆU VỚI OFFICE XP
Có hai cách để có thể trao đổi dữ liệu với Office XP đó là làm theo hướng Add-in và theo hướng Automation. Cả hai cách này chỉ khác nhau ở chỗ kết nối còn cách trao đổi dữ liệu của chúng với là giống nhau [10].
Kết nối theo hướng Add-in
Phân loại Add-in
Có hai loại Add-in thường gặp:
Add-ins ứng dụng đặc biệt chỉ sử dụng cho riêng một ứng dụng cụ thể
COM add-ins (Component Object Model): Là một thư viện liên kết động hoặc một file thực thi được sử dụng để tải ứng dụng Microsoft Office XP, MS Visual Basic, MS Visual C++. Có thể sử dụng cho bất kì ứng dụng nào có hỗ trợ kiểu add-in loại này.
Với COM Add-in có thể tạo một Add- in đơn bao gồm mã đặc tả để tạo một tài liệu trong Word, hoặc tạo một bảng tính trong Excel và một modul khác có mã được chia sẻ giữa các ứng dụng cho việc khôi phục và xử lý dữ liệu từ Access. Sau đó có thể đăng kí add-in sẵn dùng cho mỗi ứng dụng.
Bộ Office từ 2000 trở đi của Microsoft có hỗ trợ cả hai loại Add-in này. Các file Add-in phải được lưu trong một file theo quy định sau:
Add-ins
Phần mở rộng của file
Ứng dụng cho
Word Add-in
.dot,.wll,.wiz
Word
Excel Add-in
.xla,.xll
Excel
PowerPoint add-in
.ppa,.pwz
PowerPoint
Access add-in
.mda,.mde
Access
Com add-in
.dll,.exe
Cả bộ Office
Nếu Com add-in để dưới dạng .dll thì chương trình sẽ chạy trong cùng một tiến trình với ứng dụng còn nếu là .exe thì nó là một tiến trình độc lập ở bên ngoài.
Tạo, đăng kí và triển khai một COM Add-in
Một tiến trình tạo một COM Add-in có thể bị hủy trong 3 bước sau:
Tạo đối tượng DLL/EXE COM add-in mới
Cài đặt giao diện IDTExtensibility2
Thiết lập thêm cho Microsoft Window bản đăng kí bao gồm các thông tin chỉ ra kiểu ứng dụng có thể tổ chức COM add-in.
Mỗi add-in cho chương trình Office phải thực hiện giao diện IDTExtensibility2. Giao diện này được lưu ở trong file MSADDNDR.dll. Trong giao diện này có các hàm cần phải định nghĩa lại là:
OnConnection: Sự kiện này xuất hiện khi add-in được tải lên. Hàm này có bốn đối trong đó đối đầu tiên chính là con trỏ trỏ tới đối tượng Application của ứng dụng mà Add-in này đang được nó tải lên. Đây là một tham số hết sức quan trọng ta thường phải lưu lại tham số này để thực hiện các thao tác trao đổi dữ liệu tiếp theo.
OnDisconnection : Sự kiện này xuất hiện khi đối tượng Com add-in được giải phóng, ta thường sử dụng sự kiện này để viết các đoạn mã thực hiện các công việc dọn dẹp cần thiết.
OnStartupComplete: Sự kiện này xuất hiện khi ứng dụng đã thực hiện xong các bước khởi tạo của nó. Nếu một Add-in mà không được tạo để tải ngay từ khi ứng dụng khởi động thì sự kiện này sẽ không xuất hiện. Ngược lại sự kiện này xuất hiện sau sự kiện OnConnection.
OnBeginShutdown: Sự kiện này xuất hiện khi mà ứng dụng bắt đầu kết thúc. Nếu add-in mà chưa được tải thì sự kiện này không xuất hiện còn ngược lại sự kiện này xuất hiện trước sự kiện OnDisconnect. Nên
OnAddInsUpdate: Sự kiện này xuất hiện ở tất cả các add-in khi có một add-in nào đó được tải lên hoặc được giải phóng. Nếu một add-in mà phụ thuộc vào một add-in khác thì đặt mã kiểm tra trong hàm này là tốt nhất.
Kết nối theo hướng Automation
Theo cách này thì ứng dụng sẽ được nhúng vào trong chương trình và cần thực hiện kết nối vào ứng dụng này khi bắt đầu nhúng. Có hai cách kết nối là kết nối động và kết nối tĩnh.
Kết nối động
Theo cách này khi ta muốn kết nối với một chương trình nào đó ta cần tìm trong bảng các chương trình đang chạy ROT của hệ điều hành xem ứng dụng cần kết nối có đang chạy hay không. Nếu có thì lấy về con trỏ giao diện của đối tượng Applicaton của ứng dụng đó. Đoạn mã sau sẽ thực hiện kết nói vào ứng dụng Excel đang chạy trên máy của người sử dụng.
HRESULT hr;
CLSID clsid;
IDispatch* pDis;
IUnknown* pUnk;
CLSIDFromProgID(L"Excel.Application",&clsid);
hr = GetActiveObject(clsid,NULL,&pUnk);
ASSERT(!FAILED(hr));
hr = pUnk->QueryInterface(IID_IDispatch,(void**)&pDis);
ASSERT(!FAILED(hr));
pUnk->Release();
Kết nối tĩnh
Trong trường hợp này ứng dụng cần kết nối sẽ được khởi động từ chương trình của ta. Sau đây là câu lệnh khởi động Excel từ chương trình của ta:
Application oApp;
ASSERT(oApp.CreateDispatch("Excel.Application",oleExc));
//Cho hiện lên màn hình và trao quyền điều khiển cho người sử //dụng
oApp.put_Visible(TRUE);
oApp.put_UserControl(TRUE);
nếu mọi việc tiến hành thành công thì công việc kết nối đã hoàn thành và bước tiếp theo là tiến hành trao đổi dữ liệu.
MÔ HÌNH ĐỐI TƯỢNG CỦA EXCEL
Để phát triển các giải pháp sử dụng Microsoft Office Excel cần phải tương tác với các đối tượng của Excel để trao đổi dữ liệu với các bảng tính của Excel. Trước hết phải tìm hiểu mô hình đối tượng mô phỏng một cách trực tiếp giao diện người dùng. Ví dụ, đối tượng Application, Workbook, Worksheet, Range.
Excel cung cấp hàng trăm đối tượng mà bạn có thể tương tác, nhưng có thể tập trung vào một số đối tượng chính của ứng dụng.
Một số đối tượng cơ bản:
Application: Quản lý toàn bộ ứng dụng. Có được đối tượng này ta có thể thao tác hầu hết các chức năng trên Excel
Workbook: Đối tượng này quản lý một Workbook trong một ứng dụng. Nhiều Workbook được quản lý bởi tập hợp Workbooks.
Worksheet: Trong một Workbook có nhiều Worksheet đây là đối tượng mà ta thường phải thao tác với nó nhất khi trao đổi dữ liệu. Tập các Worksheet được quản lý bởi đối tượng Worksheets.
Range: Trong một sheet thì có nhiều ô một đối tượng Range quản lý một hoặc một số ô trong một sheet.
Như vậy trong chương trình cần xây dựng thì các đối tượng mà chúng ta cần phải quan tâm là Application, Workbooks, Workbook, Worksheét, Worksheet và Range.
Nguyên tắc để trao đổi dữ liệu với Excel là chúng ta cần phải có được đối tượng của lớp Range tham chiếu đến các ô mà chúng ta cần nhận hoặc ghi dữ liệu, sau đó sử dụng hàm get_Value hoặc put_Value tương ứng.
ĐỌC GHI DỮ LIỆU VÀO BẢNG TÍNH EXCEL
Ghi dữ liệu vào Excel
Ghi dữ liệu vào một mảng các ô từ ô A1 đến ô C8 của sheet1 trong Workbook1. Dữ liệu cần ghi được đặt trong đối tượng của lớp COleSafeArray - saRet
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
_Workbook objBook;
Workbooks objBooks;
Worksheets objSheets;
_Worksheet objSheet;
Range range;
objBooks = objApp.GetWorkbooks();
objBook = objBooks.get_Item(COleVariant((short)1));
objSheets = objBook.GetWorksheets();
objSheet = objSheets.GetItem(COleVariant((short)1));
range = objSheet.GetRange(COleVariant("A1"),COleVariant("C8"));
range.SetValue(COleVariant(saRet));
saRet.Detach();
Đọc dữ liệu vào Excel
Đọc dữ liệu từ các ô A1 đến ô C8 của Worksheet1 trong Workbook1 và lưu vào mảng
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); _Workbook objBook;
Workbooks objBooks;
Worksheets objSheets;
_Worksheet objSheet;
Range objRange;
VARIANT ret;
objBooks = objApp.GetWorkbooks();
objBook = objBooks.get_Item(ColeVariant((short)1));
objSheets = objBook.GetWorksheets();
objSheet = objSheets.GetItem(COleVariant((short)1));
objRange = objSheet.GetRange(COleVariant("A1"), COleVariant("C8"));
ret = objRange.GetValue();
COleSafeArray sa(ret);
Hai cách trên đều tương đương nhau, song nếu sử dụng làm theo kiểu Add-in thì khi tiến hành cài đặt ta phải viết thêm đoạn mã để tìm xem đường dẫn của ứng dụng mà chúng ta muốn tạo Add-in cho nó lằm ở đâu, công việc này không phải là một điều rễ dàng do vậy tôi chọn làm theo hướng Automation. Mặt khác làm ý tưởng của tôi là có thể làm để đọc dữ liệu vào bất cứ một chương trình nào (như làm bộ gõ) nên làm theo hướng Add-in là không hợp lý.
THIẾT KẾ CHƯƠNG TRÌNH
Với nội dung đồ án được giao thì có hai nhiệm vụ chính cần thực hiện là:
Xây dựng chương trình nhận dạng tiếng nói theo thời gian thực
Tích hợp với Excel.
Chương này đề cập chi tiết về việc thiết kế chương trình để thực hiện các nhiệm vụ được giao dựa trên các giải pháp đã lựa chọn. Sơ đồ khối của chương trình chính như sau:
Hình 51 Sơ đồ khối của chương trình chính
XÂY DỰNG CHƯƠNG TRÌNH NHẬN DẠNG TIẾNG NÓI
Trong chương trình nhận dạng tiếng nói theo thời gian thực thì quá trình nhận dạng được tiến hành ngay sau khi phát hiện thấy tín hiệu tiếng nói đã được lấy mẫu qua một thiết bị nào đó. Các bước cụ thể được trình bày dưới đây:
Thu âm
Trong thư viện của VC có hỗ trợ hai loại hàm để thu âm tiếng nói qua Card âm thanh là các hàm MCI và các hàm API. Ta hãy xem ưu nhược điểm của việc sử dụng các hàm này:
MCI: Có ưu điểm là người lập trình không phải xử lý một số công việc như cấp phát bộ nhớ, điều khiển bộ đệm… Song nhược điểm của nó là ta không truy cập được vào bộ đệm lưu tín hiệu thu được để tiến hành xử lý.
API: Có nhược điểm là người lập trình phải tự làm lấy một số công việc như cấp phát bộ nhớ, điều khiển bộ đệm… Nhưng có ưu điểm là ta có thể truy cập trực tiếp vào bộ đệm để lấy dữ liệu thu được tiến hành xử lý.
Như vậy để nhận dạng theo thời gian thực thì ta cần phải sử dụng các hàm API để tiến hành thu âm.
Đặc điểm thu âm bằng các hàm API là: Trình điều khiển thiết bị sẽ tiến hành lấy mẫu tín hiệu và lưu vào bộ đệm do ta cung cấp. Khi một bộ đệm nào đó đầy thì trình điều khiển thiết bị sẽ thông báo về để ta xử lý. Do ta tiến hành nhận dạng theo thời gian thực, mà việc nhận dạng lại mất một khoảng thời gian tương đối nên để thiết bị có thể hoạt động tốt thì ta phải sử dụng hài bộ đệm để thu. Khi một bộ đệm đầy thì ta lại thêm bộ đệm khác và tiến hành xử lý dữ liệu thu được. Mặt khác để không làm ảnh hưởng tới thao tác trên giao diện của người dùng thì tốt nhất là quá trình nhận dạng cua ta được tiến hành chạy nền ở bên dưới.
Sau đây là một số hàm và cấu trúc phục vụ cho việc thu âm.
Một số hàm sử dụng khi thu âm
WAVEFORMATEX
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} WAVEFORMATEX;
trong đó các tham số sau cần chú ý:
wFormatTag: Loại file cần thu tham số này để là WAVE_FORMAT_PCM.
nChannels: Số kênh thu thường là 1 hoặc 2
nSamplesPerSec: Tần số lấy mẫu
wBitsPerSample: Số bit dùng lượng tử hóa tín hiệu tiếng nói
các tham số còn lại tính dựa trên các tham số này
WAVEHDR
typedef struct {
LPSTR lpData;
DWORD dwBufferLength;
DWORD dwBytesRecorded;
DWORD_PTR dwUser;
DWORD dwFlags;
DWORD dwLoops;
struct wavehdr_tag * lpNext;
DWORD_PTR reserved;
} WAVEHDR;
trong đó:
lpData: Trỏ tới bộ đệm nhận dữ liệu
dwBufferLength: Kích thước của bộ đệm tính theo Byte
dwUser: Dữ liệu của người sử dụng tham số này thường được sử dụng khi ta nhận các Message bằng hàm Callback.
dwBytesRecorded: Số byte ghi được lưu trong bộ đệm. Có thể không bằng kích thước của bộ đệm mà ta cung cấp.
WAVEINOPEN:
MMRESULT waveInOpen(
LPHWAVEIN phwi,
UINT_PTR uDeviceID,
LPWAVEFORMATEX pwfx,
DWORD_PTR dwCallback,
DWORD_PTR dwCallbackInstance,
DWORD fdwOpen
);
hàm này dùng để mở một thiết bị thu âm có ID cho trong tham số uDeviceID, trong trường hợp không có ID của thiết bị thì có thể truyền vào giá trị WAVE_MAPPER thì trình điều khiển sẽ tự dò thiết bị để thu âm.
Nếu mở thành công hàm trả về giá trị MMSYSERR_NOERROR.
WAVEINPREPAREHEADER
MMRESULT waveInPrepareHeader(
HWAVEIN hwi,
LPWAVEHDR pwh,
UINT cbwh
);
hàm này dùng để báo cho thiết bị biết là sẽ có một bộ đệm được cấp cho nó. Các tham số về bộ đệm này được cho ở tham số pwh.
Nếu thành công hàm trả về giá trị MMSYSERR_NOERROR.
WAVEINADDBUFFER
MMRESULT waveInAddBuffer(
HWAVEIN hwi,
LPWAVEHDR pwh,
UINT cbwh
);
hàm này dùng để cấp bộ đệm(đã được chuẩn bị) cho trình thiết bị. Nếu hàm thành công thì giá trị trả về là MMSYSERR_NOERROR.
WAVEINSTART
MMRESULT waveInStart(
HWAVEIN hwi
);
bắt đầu lấy mẫu tín hiệu tiếng nói liên tục. Tín hiệu sau khi lấy mẫu sẽ lưu trong bộ đệm do ta cung cấp, nếu có nhiều bộ đệm thì nó sẽ lưu hết bộ đệm này đến bộ đệm khác, còn nếu không có bộ đệm nhận dữ liệu thì tín hiệu vẫn được lấy mẫu nhưng không lưu lại.
WAVEINSTOP
MMRESULT waveInStop(
HWAVEIN hwi
);
dừng thu âm, những bộ đệm đã được cấp phát mà chưa sử dụng thì vẫn được giữ lại nguyên còn bộ đệm đang thu sẽ được đánh dấu là đã dùng để trả về ứng dụng.
WAVEINCLOSE
MMRESULT waveInClose(
HWAVEIN hwi
);
Đóng thiết bị thu âm, tất cả bộ đệm sẽ được trả về cho ứng dụng, sau lệnh này tham số cho bởi hwi sẽ không còn hiệu lực để sử dụng nữa.
Giải thuật thu âm trong nhận dạng tiếng nói
Các thao tác xử lý và nhận dạng được tiến hành trong một luồng chạy nền ở bên dưới để không ảnh hưởng tới các thao tác trên giao diện của người sử dụng.
Do sử dụng hai bộ đệm để tiến hành thu âm nên có thể dữ liệu của một từ không nằm trên một bộ đệm mà nó lằm ở cả hai bộ đệm. Khi một bộ đệm đã được cấp cho thiết bị thì ta không can thiệp vào nó được cho đến khi thiết bị trả nó về cho ứng dụng, đồng thời quá trình nhận dạng chỉ được tiến hành khi mà cắt được một từ nào đó và thời gian để nhận dạng được một từ có thể khá lâu(nếu từ điển của ta lớn)… Để việc nhận dạng không ảnh hưởng gì tới các thao tác khác trong chương trình của tôi, tôi có sử dụng một bộ đệm vòng, khi đó dữ liệu từ bộ đệm thu âm sẽ được lưu sang bộ đệm vòng và dữ liệu xử lý sẽ được đọc từ bộ đệm vòng này ra. Vị trí đọc và ghi dữ liệu trên bộ đệm vòng được quản lý bởi hai con biến lưu chỉ số của phần tử đọc/ghi cuối cùng.
Để giảm việc viết mã cho nhiều kiểu nhận dạng khác nhau (nhận dạng từ file, nhận dạng từ bộ đệm…) tất cả dữ liệu của một từ sẽ được ghi xuống file và sẽ nhận dạng từ file đó khi từ được cắt ra. Dưới đây là sơ đồ giải thuật tiến hành thu âm trong giải thuật nhận dạng theo thời gian thực.
Modul xử lý đầu ra
Hình 52 Giải thuật thu âm trong luồng nhận dạng tiếng nói
Trong giải thuật trên có một chuyển mạch tương ứng với tình huống đã phát hiện hay chưa phát hiện thấy điểm đầu của tiếng nói (sẽ được trình bày chi tiết trong phần sau). Khi chưa phát hiện điểm đầu thì ta tiến hành tìm điểm đầu của tiếng nói, khi đã phát hiện điểm đầu thì bắt đầu tìm điểm cuối của tiếng nói. Trong giải thuật trên thì luồng thu âm chỉ trong (1) còn lại là luồng nhận dạng tiếng nói.
Phát hiện tiếng nói
Bước này hết sức quan trọng bởi kết quả phát hiện đúng hay sai sẽ ảnh hưởng tới hiệu năng của toàn hệ thống. Nhiệm vụ của bước này là phải tách được tín hiệu tiếng nói khỏi nhiễu hoặc nền.
Các tham số sử dụng
Trước khi tiến hành viết một giải thuật để phát hiện tiếng nói, chúng ta cần phải quyết định:
Sử dụng tham số nào
Ngưỡng cho tham số đó là bao nhiêu
Các tham số trên đều đã được cài đặt ở nhiều hệ thống nhận dạng, kinh nghiệm đã cho thấy các ưu nhược điểm của từng tham số:
Năng lượng ngắn hạn có ưu điểm là tính đơn giản, cho kết quả tốt trong những điều kiện thường. Nhược điểm của nó chỉ biểu hiện trong các môi trường có nhiễu lớn. Khi có nhiễu thì phương pháp phát hiện tiếng nói dựa trên năng lượng ngắn hạn cho kết quả không đáng tin cậy.
Tốc độ đi qua điểm không: Tham số này nếu sử dụng một mình thì kết quả của nó rất kém, vì vậy trong các hệ thống nhận dạng tiếng nói người ta thường hay sử dụng kết hợp nó với tham số năng lượng ngắn hạn của tiếng nói.
Lượng thông tin: Phát hiện tiếng nói dựa trên tham số này cho kết quả tốt hơn dựa trên tham số năng lượng trong các trường hợp nhiễu do các tiếng động lạ xung quanh, nháy môi… Nhưng nó lại cho kết quả rất kém trong trường hợp nhiễu là sóng âm thanh. Trong khi đó phương pháp dựa trên năng lượng của tín hiệu tiếng nói lại cho kết quả tốt đối với loại nhiễu này.
Mỗi một tham số đều có những ưu nhược điểm của mình, chúng cho kết quả tốt trong điều kiện này nhưng lại kém trong điều kiện khác. Chính vì vậy tùy vào điều kiện cụ thể mà sử dụng các tham số tương ứng. Trong chương trình của tôi do điều kiện thu âm không quá phức tạp nên tôi chọn phướng pháp sử dụng tham số năng lượng ngắn hạn để phát hiện tiếng nói sau đó dùng tham số tốc độ đi qua điểm không để tinh chỉnh lại kết quả.
Giải thuật phát hiện tiếng nói
Các giải thuật dùng để phát hiện tiếng nói hiện nay có rất nhiều và có nhiều giải thuật cho độ chính xác rất cao. Tuy nhiên như đã đề cập ở chương trước, những giải thuật phát hiện tiếng nói có độ chính xác cao thì thường là chạy chậm vì tính các tham số phưc tạp.
Vấn đề tồn tại trong tất cả các giải thuật phát hiện tiếng nói là làm sao để chọn ra ngưỡng cho các tham số để tách tín hiệu tiếng nói với các thành phần khác. Việc chọn ngưỡng này phụ thuộc rất nhiều vào kinh nghiệm làm trong lĩnh vực nhận dạng và đây là một điểm khó khăn đối với những người mới nghiên cứu. Để giải quyết vấn đề chọn ngưỡng cho các tham số, năm 1975 Lawrence Rabiner và Sambur đã đưa ra một giải thuật cho phép chọn ngưỡng cho các tham số một cách tự động. Giải thuật này dựa trên hai tham số là năng lượng ngắn hạn và tỉ lệ vượt quá điểm không, trong đó tham số chính là năng lượng ngắn hạn còn tỉ lệ vượt quá điểm không được sử dụng để điều chỉnh điểm đầu và điểm cuối sau khi đã tách bằng năng lượng. Sơ đồ khối của giải thuật này như sau:
Bắt đầu
Length =
SIL_LEN?
Y
Điều chỉnh kết quả
Tiếp tục?
N
Y
Kết thúc
N
Tìm điểm đầu
Phát hiện
điểm đầu?
Y
Tìm điểm cuối
Y
N
Tính ngưỡng
N
Phát hiện
điểm cuối?
Hình 53 Giải thuật phát hiện tiếng nói
Một số điểm cần lưu ý:
SIL_LEN có giá trị khoảng 100ms trong khoảng thời gian này các tham số thống kê của nhiễu và nền được tính toán để từ đó chọn ngưỡng cho việc tách tín hiệu tiếng nói. Trong khoảng thời gian này thì tốt nhất là không nên có tín hiệu tiếng nói. Nếu khi thu âm mà khoảng này bị cắt bỏ thì giải thuật này sẽ thất bại, ngưỡng do nó đưa ra sẽ không chuẩn xác.
Tính ngưỡng: Ngưỡng cho các tham số được tính dựa trên những tham số thống kê có được trong khoảng thời gian yên lặng mặc định ban đầu. Ngưỡng cho hai tham số được sử dụng trong giải thuật này tính như sau:
trong đó:
IZCT: Ngưỡng Zero crossing rate
: Trung bình Zero crossing rate
: Độ lệch chuẩn của Zero crossing rate
IFT: Ngưỡng do người sử dụng chọn, theo Rabiner ngưỡng là 2.5
ITL: Ngưỡng thấp của năng lượng
ITU: Ngưỡng cao của năng lượng
Phát hiện điểm đầu: Mỗi frame tín hiệu tiếng nói đầu vào sẽ được sử dụng để tính năng lượng ngắn hạn của tín hiệu. Năng lượng ngắn hạn này sau đó được đem so sánh với ngưỡng ITU, nếu năng lượng ngăn hạn của frame mà lớn hơn ITU thì frame này sẽ trở thành frame bắt đầu.
Phát hiện điểm cuối: Sau khi phát hiện được điểm đầu của tín hiệu tiếng nói thì công việc tiếp theo là đi tìm điểm kết thúc. Việc tìm điểm kết thúc này cũng dựa trên năng lượng ngắn hạn của frame. Trong giải thuật do Rabiner và Sambur đưa ra thì frame cuối là frame có năng lượng ngắn hạn nhỏ hơn ITL, nhưng khi cài đặt chương trình thì tôi thấy rằng nếu tìm frame có năng lượng nhỏ hơn ITL thì điểm cuối của tín hiệu sẽ bị sai đi rất nhiều. Bằng thực nghiệm tôi thấy rằng ngưỡng để coi đó là điểm cuối của tín hiệu tiếng nói cũng chính là ITU.
Hiệu chỉnh điểm đầu, điểm cuối: Sau hai bước trên thì đã xác định được điểm đầu và điểm cuối của tiếng nói, tuy nhiên, điểm đầu và điểm cuối này có sai lệch đôi chút so với điểm đầu và điểm cuối trên thực tế. Để tăng độ chính xác của giải thuật Rabiner và Sambur đã đưa ra thủ tục để điều chỉnh điểm đầu và điểm cuối như sau:
Điều chỉnh điểm đầu: Tìm ngược về phía trước của frame bătd đầu khoảng 250ms nếu có hiều hơn ba frame có Zero crossing rate vượt quá IZCT thì dịch điểm đầu về vị trí frame gần nó nhất có Zero crossing rate vượt quá IZCT nếu không thì điểm dầu được giữ nguyên.
Điều chỉnh điểm cuối: Tìm về phía sau điểm cuối khoảng 150ms, nếu phát hiện thất có nhiều hơn ba frame có Zero-crossing rate vượt quá IZCT thì dịch điểm cuối về vị trí frame gấn nó nhất có Zero-crossing rate vượt IZCT. Trên thực tế nếu nhận dạng theo thời gian thực thì ta chỉ có thể điều chỉnh được điểm đầu còn điểm cuối thì không thể điều chỉnh theo giải thật này được vì trong khoảng 150ms đó có thể có tính hiệu của một từ khác được nói vào.
Các bước trên sẽ được lặp đi lặp lại trên dữ liệu thu được cho đến khi nào ngừng thu âm.
Một điều cũng cần phải chú ý là khi cài đặt giải thuật này lúc thu âm không được sử dụng chức năng Bost của SoundCard, nếu sử dụng chức năng này thì tham số Zero crossing rate không có tác dụng nữa (Đây là qua thực nghiệm tôi thấy đặc điểm này). Cũng cần phải lưu ý thêm là cần phải có thêm ngưỡng để xác định dài, ngắn bao nhiêu là hợp lệ để nâng cao độ chính xác của giải thuật.
Trích chọn đặc trưng
Có hai phương pháp thường được sử dụng để phân tích các đặc trưng của tín hiệu tiếng nói là phân tích LPC và MFCC. Ưu, nhược điểm của từng phương pháp cũng đã được phân tích. Trong chương trình này tôi sử dụng phương pháp phân tích Cepstral thông qua mã hóa dự đoán tuyến tính. Sơ đồ khối của bộ phân tích và trích chọn cắc đặc trưng của tín hiệu tiếng nói sử dụng trong chương trình như sau:
Hình 54 Sơ đồ khối phân tích Cepstral thông qua mã hóa dự đoán tuyến tính
Chi tiết thực hiện từng bước như thế nào đã được đề cập ở chương 2 và chương năm. Dưới đây là giá trị của một số tham số quan trọng trong các modul trên (những giá trị này tôi rút ra được từ trong tài liệu tham khảo [6] và [7]).
Bộ lọc hiệu chỉnh: Hệ số a của bộ lọc có giá trị là 0.97
Phân khung: Hai tham số chủ yếu của nó là:
Độ dài của một frame tính theo mẫu N = 300
Số mẫu chồng lên nhau giữa hai frame kề nhau là M = 200
Lấy của sổ: Hàm của sổ được sử dụng trong chương trình là của sổ Hamming tính theo công thức sau:
, 0£ n £ N -1
Phân tích tự tương quan và phân tích LPC: Với hai modul này thì tham số cần phải lựa chọn duy nhất là bậc phân tích LPC. Theo Rabiner thì bậc phân tích LPC tối ưu phụ thuộc vào tần số mà ta lấy mẫu. Giá trị tối ưu theo các tần số lấy mẫu được tổng kết ở bảng sau:[1]
F
6.67KHz
8KHz
10KHz
P
8
10
10
Chuyển các hệ số LPC thành các hệ số Cepstral: Các hệ số Cepstral được tính dựa trên các hệ số LPC theo các công thức sau:
,
,
giá trị của tham số không quan trọng vì không cần sử dụng đến tham số c0. Số hệ số Cepstral tương ứng với các tần số lấy mẫu được cho trong bảng sau:[6]
F
6.67KHz
8KHz
10KHz
Q
12
12
12
Gắn trọng số cho các hệ số Cepstral: Các hệ số Cepstral được nhân với một hàm cửa sổ có dạng như sau:
1 £ m £ Q
Đạo hàm của các hệ số Cepstral theo thời gian: Đạo hàm của các hệ số Cepstral theo thời gian được tính theo công thức:
trong đó tham số có giá trị là 0.375, còn tham số K có giá trị là 3 [7]
Tạo codebook
Nhiệm vụ của Modul này là phải tạo ra Codebook để phục vụ cho lượng tử hóa dựa trên tập các Vector đặc trưng đầu vao. Giải thuật để xây dựng codebook như sau:
Tìm nhân ban đầu
Bắt đầu
Tách nhân
D’ = 0
Phân lớp vector
Tìm các nhân
Tính độ méo D’
D-D’<d
m< M
D’ = D
m= 2*m
Kết thúc
Y
N
N
m = 1
Y
Hình 55 Giải thuật tạo Codebook
Một số điểm cần chú ý:
Nhân ban đầu là nhân của tập Vector huấn luyện
Tách nhân: Mỗi một vector trong codebook hiện tại được tách làm hai, theo công thức:
trong chương trình này tôi sử dụng giá trị của là 0.4
Phân lớp vector: Các vector huấn luyện được phân về các nhóm. Nhóm mà một vector huấn luyện thuộc về là nhóm có chứa vector ở trong codebook hiện tại giống với nó nhất. Số nhóm sau khi phân chính là số vector có trong codebook hiện tại.
Tìm các nhân: Sau khi phân các vector huấn luyện thành các nhóm ta tiến hành tìm nhân của từng nhóm. Mỗi nhân này sẽ trở thành một vector trong codebook mới.
Độ méo D: Do sử dụng phân tích Cepstral thông qua LPC nên độ méo D thường được tính theo khoảng cách Cepstral theo công thức sau: (h chọn là L/2, L là số hệ số Cepstral)
chọn là 1% của D
Kích thước của codebook: Theo những nghiên cứu của Rabiner được trình bày trong cuốn [6] thì kích thước của codebook sẽ ảnh hưởng tới độ chính xác của kết quả nhận dạng. Nếu kích thước mà càng lớn thì độ chính xác càng cao nhưng tốc độ nhận dạng lại chậm đi. Còn nếu kích thước mà quá nhỏ thì sai số trong nhận dạng sẽ rất lớn. Vì vậy cần phải cân nhắc kích thước làm sao cho hơp lý nhất. Sau nhiều năm nghiên cứu thì Rabiner nhận thấy rằng nếu kích thước của codebook từ khoảng 32 vector trở nên thì sai số trong nhận dạng thay đổi không đáng kể khi thay đổi kích thước của codebook. Sau một thời gian thử nghiệm tôi chọn kích thước là 128. Kích thước này vừa đảm bảo được độ chính xác đồng thời tốc độ nhận dạng cũng chấp nhận được.
Lưu trữ codebook: Codebook sau khi tạo xong cần phải được lưu trữ để sử dụng về sau, cách lưu trữ đơn giản nhất là lưu xuống file, file này cần phải được tổ chức sao cho có thể lấy được các thông số như số vector trong codebook, kích thước của một vector... một cách dễ dàng nhất để thuận lợi khi cần lấy codebook nên. Trong chương trình của tôi toàn bộ dữ liệu về codebook được lưu xuống file nhị phân có phần mở rộng là cbf. Tổ chức của file này như sau:
Dòng đầu tiên lưu chữ ký nhận dạng file nó có giá trị là chuỗi “CBF”
Tiếp theo là một số nguyên lưu số vector có trong codebook
Tiếp đến là môt số nguyên lưu kích thước của một vector.
Phần còn lại lần lượt là dữ liệu của các vector có trong codebook. Trong chương trình của tôi thì mỗi một phần tử trong một vector là một số thực kiểu float.
Lượng tử hóa Vector
Ở bước này vector đầu vào được đem so sánh với tất cả các vector có trong codebook để xác định xem vector nào trong codebook giống với nó nhất. Kết quả trả về của bước này là chỉ số của vector trong codebook giống vector đầu vào nhất.
Sau đây là sơ đồ giải thuật lượng tử hóa với:
M: Kích thước của codebook dùng lượng tử hóa
P: Mảng các Vector trong codebook
V: Vector cần lượng tử hóa
index : Lưu kết quả lượng tử hóa.
Khởi tạo M,P,v
i =1, min = +¥;
index = i
d = d(P,v)
d < min?
index = i;
min = d;
i =M?
Kết thúc
Y
Y
N
N
i = i + 1
Bắt đầu
Hình 56 Giải thuật lượng tử hóa vector
khoảng cách giữa hai vector ở đây vẫn được tính theo công thức trong xây dựng codebook.
Huấn luyện mô hình
Để huấn luyện được mô hình cho mỗi từ trong từ điển thì có hai việc cần phải giải quyết đó là làm sao để tạo ra tập dữ liệu huấn luyện và sử dụng tập huấn luyện đó để tạo ra các mô hình.
Hình 57 Thuật toán huấn luyện mô hình
Tạo tập dữ liệu huấn luyện
Do tập dữ liệu huấn luyện này khá lớn nên nếu dùng theo cách thu từng từ một sau đó lưu từ này xuống file thì có một số vấn đề khó khăn là:
Tốn nhiều bộ nhớ để lưu trữ vì ngoài lưu trữ dữ liệu tiếng nói lại còn thêm cả các khoảng lặng.
Thời gian để thu được các mẫu dùng để huấn luyện sẽ rất lâu và công việc này rất buồn chán.
Khi huấn luyện ta phải sử dụng giải thuật phát hiện điểm đầu và điểm cuối của tín hiệu tiếng nói đối với từng file một, rất có thể là giải thuật phát hiện tiếng nói lại không cho kết quả đúng khi dùng để tách tín hiệu tiếng nói từ file (mà ta thì không thể dò từng file một vì mất nhiều thời gian). Từ đó, việc huấn luyện mô hình sẽ bị sai lệch nhiều.
Để khắc phục những khó khăn trên trong chương trình có thiết kế một modul để tạo ra các mẫu dùng cho huấn luyện. Hoạt động của modul này rất đơn giản: Ta tiến hành thu âm theo thời gian thực như khi nhận dạng nhưng ở đây không tiến hành nhận dạng mà chỉ sử dụng giải thuật phát hiện tiếng nói để tách tín hiệu tiếng nói với các thành phần khác, mỗi khi phát hiện được điểm đầu và điểm cuối của một từ thì tạo ra một file để lưu từ đó. Với cách này để thu được khoảng 100 mẫu cho một từ chỉ cần 15 phút.
Huấn luyện
Sau khi có được các mẫu dùng để huấn luyện, bước tiếp theo là cài đặt các thuật toán để huấn luyện mô hình. Sơ đồ khối của quá trình huấn luyện được cho trong hình 5.7. Muốn tiến hành huấn luyện thì cần phải xác định đước số trạng thái và kiểu mô hình sử dụng:
Số trạng thái của mô hình: Số trạng thái của mô hình là ẩn nhưng trong các ứng dụng nhận dạng tiếng nói thì số trạng thái này có thể xác định dựa trên một số điều kiện ràng buộc của ứng dụng. Theo những nghiên cứu của Rabiner đưa ra thì số trạng thái của các mô hình Markov trong các ứng dụng nhận dạng tiếng nói nằm trong khoảng từ 3-10 trạng thái là tốt nhất. Sau khi tiến hành thử nghiệm và thông qua tài liệu nghiên cứu tôi đã xác định được số trạng thái tối ưu cho ứng dụng của mình là 5 trạng thái.
Loại mô hình: Như đã đề cập trong chương 3 đối với các ứng dụng nhận dạng tiếng nói thì loại mô hình Markov phù hợp nhất là mô hình trái-phải, đồng thời bước nhảy =1 cũng được chọn là tối ưu nhất.
Khi đã lựa chọn được loại mô hình và số trạng thái thì công việc còn lại chỉ là cài đặt các thuật toán. Những công thức cho các bước ở trong giải thuật trên đều đã được đề cập trong chương 3 nên không nhắc lại ở đây.
Giải thuật huấn luyện dừng khi xác suất của mô hình với tập vector huấn luyện trước và sau khi ước lượng không chênh nhau một khoảng là d, giá trị của d trong chương trình là 1e-3.
Kết thúc quá trình huấn luyện ta thu được các mô hình cho các từ cần nhận dạng, để có thể sử dụng được sau này thì các tham số của mô hình cần phải được lưu trữ lại. Trong chương trình các mô hình được lưu xuống một file có phần mở rộng là hmf. Tổ chức của file này như sau
Dòng đầu tiên là chuỗi kí tự nhận dạng file “HMF”.
Tiếp theo là một số nguyên kiểu int lưu số mô hình có trong file
Các mô hình được lưu tuần tự với cấu trúc lưu trữ của từng mô hình như sau:
Một chuỗi kiểu CString lưu nhãn của mô hình trên một dòng
Một số nguyên kiểu int N lưu số trạng thái của mô hình
Một số nguyên kiểu int M lưu số giá trị cho một trạng thái (chính là kích thước của codebook dùng để lượng tử hóa).
Ma trận A có kích thước N x N được lưu tuần tự theo hàng với mỗi phần tử của ma trận là một số thực kiểu double.
Ma trận B có kích thước N x M được lưu tuần tự theo hàng, các phần tử của ma trận này có kiểu double.
Vector có N phần tử, các phần tử của vector có kiểu double.
Tính xác suất và quyết định
Dữ liệu của từ cần nhận dạng sau khi qua bộ phân tích và trích chọn đặc trưng sẽ cho ta một dãy các vector đặc trưng, sau khi đưa dãy các vector này qua bước lượng tử hóa ta thu được một chuỗi quan sát với các phần tử là kết quả lượng tử hóa của vector đầu vào tương ứng. Chuỗi quan sát này được dùng để nhận dạng từ ở đầu vào. Quá trình nhận dạng như sau:
Duyệt tất cả các mô hình có trong cơ sở dữ liệu, sử dụng giải thuật Viterbi để đánh giá xác suất của từng mô hình đối với chuỗi quan sát đầu vào, đem so sánh các xác suất này với nhau và chọn ra mô hình có xác suất lớn nhất. Khi đó nhãn của mô hình có xác suất lớn nhất đó chính là kết quả nhận dạng của từ đầu vào. Sơ đồ giải thuật nhận dạng một từ đầu vào như sau:
l,O, nModels
i =1, label = “”; max = -¥;
p = P(O|l)
p>max?
label = label(l);
max=p;
i=nModels?
Kết thúc
Y
Y
N
N
i = i + 1
Bắt đầu
Hình 58 Sơ đồ khối giải thuật nhận dạng
TÍCH HỢP VỚI EXCEL
Sau khi nhận dạng được từ thu được bước tiếp theo là xử lý kết quả nhận dạng. Trong ứng dụng này kết quả sẽ được hiện lên màn hình của chương trình hoặc tích hợp cùng Excel để trao đổi dữ liệu với Excel. Việc hiển thị kết quả nhận dạng lên màn hình đơn giản chỉ là vẽ chữ lên màn hình. Sau đây là thiết kế để trao đổi dữ liệu với Excel.
Kết quả nhận dạng S
Kiểm tra S:
S là lệnh:
Kiểm tra là lệnh gì.
Thực hiện hành động tương ứng với lệnh này.
S là dữ liệu thì ta cần thực hiện:
Tham chiếu đến ô đang Active của ứng dụng. Để tham chiếu đến ô này ta phải sử dụng hàm get_ActiveCell của đối tượng Application, kết quả trả về của hàm này là đối tượng của lớp Range.
Nhận về dữ liệu hiện thời của ô đang Active bằng hàm get_Value của đối tượng Range vừa lấy về được.
Kết hợp dữ liệu hiện thời của ô với S rồi lưu nó vào bộ đệm.
Sử dụng hàm put_Value của đối tượng Range tham chiếu đến ô đó để đưa dữ liệu vào Excel
Chú ý: Nếu dữ liệu nhận dạng được là dấu phảy phân tách phần thực và phần thập phân thì ta cần phải xử lý thêm, vì nếu là đưa dấu phảy này vào cuối dữ liệu mà không có số nào sau nó thì Excel luôn luôn loại bỏ dấu phảy này. Trong chương trình của tôi, tôi xử lý vấn đề này bằng cách lưu lại và khi có từ tiếp theo sẽ đưa dấu phảy vào.
XÂY DỰNG CHƯƠNG TRÌNH VÀ THỬ NGHIỆM
GIỚI THIỆU CHƯƠNG TRÌNH
Dựa trên những những phân tích trên tôi đã xây dựng một chương trình nhận dạng tiếng Việt dựa trên mô hình Markov ẩn có tên là ASR. Chương trình này được viết trên VC.NET vì vậy muốn chạy được nó thì cần phải có:
ASR.exe
MFC7D.dll
Framework của bộ MS Visual Studio.Net
Ngoài ra muốn chạy tích hợp với Excel thì trên máy cần phải cài chương trình Microsoft Excel (Tôi mới thử nghiệm trên Office XP). Đồng thời điều bắt buộc cần phải có nếu muốn nhận dạng trong thời gian thực là phải có thiết bị lấy mẫu âm thanh (SoundCard).
Giao diện chính của chương trình ứng dụng
Chương trình được viết với giao diện hai thứ tiếng là tiếng Anh và tiếng Việt. Giao diện của chương trình chính như sau:
Tín hiệu
Kết quả nhận dạng
Thông tin tạo codebook và huấn luyện mô hình.
1
2
3
Hình 61 Giao diện tiếng Anh
Hình 62 Giao diện tiếng Việt
Một số chức năng chính của chương trình
Xây dựng codebook dùng lượng tử hóa vector
Các chức năng về codebook nằm trong mục Codebook trên thanh menu của chương trình chính. Để tạo codebook mới chọn chức năng “Make”, khi đó có một hộp thoại yêu cầu nhập một số thông tin cần thiết để tạo codebook như sau:
Hình 63 Hộp thoại tạo codebook mới
Waves Path: Nhập đường dẫn đầy đủ của thư mục chứa các file wave (đã được cắt nhiễu và nền) dùng để tạo codebook.
Path: Nhập đường dẫn đầy đủ của file sẽ dùng để lưu dữ liệu của codebook mới sẽ được tạo ra. Có thể sử dụng nút “Select” để tìm vị trí lưu trên máy.
Size: Trong mục này chọn một giá trị có sẵn để chỉ định kích thước của codebook mới.
Sau khi nhập đầy đủ các thông tin cần thiết chọn “Make” nếu muốn tạo codebook còn chọn “Cancel” nếu thoát khỏi hộp thoại này mà không tạo codebook mới. Quá trình tạo codebook sẽ được thực hiện bởi một tiến trình nền ở bên dưới, các thông tin của tiến trình sẽ được hiển thị trong vùng (3).
Huấn luyện mô hình
Các chức năng về mô hình được đặt trong mục “Model” trên thanh menu. Để tạo tạo ra các mô hình mới hãy chọn mục “Train” trong mục Model. Khi đó một hộp thoại sẽ được hiện lên để yêu cầu nhập thông tin như sau:
Có thể nhập nhãn mới bằng cách nháy đúp vào hàng tương ứng
Hình 64 Hộp thoại huấn luyện mô hình
Waves path: Ở mục này bạn nhập hay chọn đường dẫn đầy đủ của thư mục lưu các file wave dùng để huấn luyện mô hình. Thư mục này phải có cấu trúc như đã nói ở phần trên.
Codeboook path: Nhập/chọn đường dẫn đầy đủ của file chứa codebook dùng cho lượng tử hóa để huấn luyện mô hình. File chứa codebook này phải có cấu hình như đã trình bày trong phần trên.
File name: Nhập/chọn đường dẫn đầy đủ của file sẽ lưu các thông số của các mô hình sẽ được tạo ra.
State number: Nhập số trạng thái của các mô hình sẽ được tạo ra. Số trạng thái này phải là một số nguyên dương.
Sau khi chọn thư mục chứa các file wave các thư mục con của nó sẽ hiện trong điều khiển danh sách ở bên dưới. Trong danh sách này thì cột bên trái là đường dẫn của thư mục còn cột bên phải là nhãn của mô hình sẽ được tạo ra dựa trên các file có trong thư mục tương ứng. Nhãn mặc định là tên của thư mục tuy nhiên nếu muốn sửa nhãn này bạn có thể nhấn đúp vào hàng tương ứng để nhập một nhãn mới.
Quá trình tạo các mô hình cũng được chạy bằng một luồng ở bên dưới. Một số thông tin về luồng hiển thị trong vùng (3) của giao diện chính.
Nhận dạng theo thời gian thực
Nhận dạng theo thời gian thực có thể thực hiện bằng cách vào mục “Record” trong menu “Audio” hoặc chọn vào biểu tượng trên thanh công cụ. Nếu mọi việc tiến hành thành công thì tiến trình nhận dạng sẽ được bắt đầu ngay sau đó, chỉ cần đọc từ cần nhận dạng và kết quả nhận dạng sẽ được hiển thị lên vùng (2) của giao hiện chính.
Chú ý: Nếu chưa chọn codebook hay mô hình dùng để nhận dạng thì khi cần phải sử dụng sẽ có thông báo yêu cầu nhập file chứa codebook và mô hình dùng để nhận dạng.
Tích hợp với MS Excel
Để chạy tích hợp với Excel ta chọn mục “Excel” trong menu “Application”. Nếu Excel chưa chạy trên máy thì chương trình sẽ khởi động Excel còn nếu Excel đang chạy thì chương trình sẽ thực hiện kết nối động vào ứng dụng Excel. Nếu mọi việc tiến hành thành công ta có thể nhập dữ liệu bằng lời nói vào Excel ngay sau đó. Khi nhập cần chú ý một số quy định là:
Trái
Phải
Lên
Xuống
Ghi
Mở
Chuyển sang ô bên trái của ô hiện tại
Chuyển tới ô bên phải của ô hiện tại
Chuyển lên ô phía trên ô hiện tại
Chuyển xuống ô bên dưới ô hiện tại
Lưu Workboook xuống file
Mở một file trên máy.
Để kết thúc tích hợp chương trình hãy nháy đúp chuột vào biểu tượng trên thanh Taskbar.
KẾT QUẢ THỬ NGHIỆM
Sau khi viết xong chương trình tôi có tiến hành kiểm tra độ tin cậy khi nhận dạng tiếng nói. Việc kiểm tra độ chính xác của chức năng nhận dạng của chương trình được tiến hành theo hai bước sau:
Thu âm các từ để kiểm tra. Trong quá trình thu âm có sử dụng giải thuật phát hiện tiếng nói để tách tín hiệu tiếng nói với các thành phần khác. Từ được cắt ra sẽ được lưu xuống file. Các phiên bản khác nhau của cùng một từ được lưu trong một thư mục.
Tiến hành nhận dạng lần lượt các file có trong thư mục.
Kiểm tra lần thứ nhất
Mic nhãn hiệu SHARP thông thường
Người tham gia kiểm tra :
Tên
Giới tính
Tuổi
Quê quán
Kí hiệu
Nguyễn Huyền Ngọc
Nữ
23
Vĩnh Phúc
N
Hoàng Thúy Hà
Nữ
25
Phú Thọ
H
Số lượng file đem huấn luyện:
Tên
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
N
30
30
30
30
30
30
30
30
30
30
30
30
30
30
H
30
30
30
30
30
30
30
30
30
30
30
30
30
30
Tên
Lên
Xuống
Trái
Phải
N
30
30
30
30
H
30
30
30
30
Kết quả nhận dạng:
KQ
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
Đúng
60
59
56
51
60
56
60
59
60
60
59
60
59
60
Tổng
60
60
60
60
60
60
60
60
60
60
60
60
60
60
KQ
Lên
Xuống
Trái
Phải
Tổng
Tỷ lệ
Đúng
59
60
60
59
1057
Tổng
60
60
60
60
1080
Kiểm tra lần thứ hai
Mic nhãn hiệu PHILIPS
Người tham gia kiểm tra :
Tên
Giới tính
Tuổi
Quê quán
Kí hiệu
Nguyễn Huyền Ngọc
Nữ
23
Vĩnh Phúc
N
Đỗ Tuấn Kiên
Nam
17
Hà Nội
K
Số lượng file đem huấn luyện:
Tên
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
N
40
40
40
40
40
40
40
40
40
40
40
40
40
40
K
11
11
11
11
11
11
11
11
11
11
11
11
11
11
Người
Lên
Xuống
Trái
Phải
N
40
40
40
40
K
11
11
11
11
Kết quả nhận dạng:
Số file cho một từ của Nguyễn Huyền Ngọc là 40
Số file cho một từ của Đỗ Tuấn Kiên là 10.
KQ
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
Đúng
50
50
49
49
45
46
50
49
49
49
50
50
50
49
Tổng
50
50
50
50
50
50
50
50
50
50
50
50
50
50
KQ
Lên
Xuống
Trái
Phải
Tổng
Tỷ lệ
Đúng
49
50
48
49
881
Tổng
50
50
50
50
900
Kiểm tra lần thứ ba
Míc thu: Nhãn hiệu SHARP
Người tham gia kiểm tra:
Tên
Giới tính
Tuổi
Quê quán
Kí hiệu
Nguyễn Huyền Ngọc
Nữ
23
Vĩnh Phúc
N
Trần Tất Thành
Nam
23
Nam Định
T
Số lượng file đem huấn luyện:
Tên
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
N
20
20
20
20
20
20
20
20
20
20
20
20
20
20
T
30
30
30
30
30
30
30
30
30
30
30
30
30
30
Người
Lên
Xuống
Trái
Phải
N
20
20
20
20
T
30
30
30
30
Kết quả kiểm tra:
Số file dùng kiểm tra cho một từ của Nguyễn Huyền Ngọc: 20
Số file dùng kiểm tra cho một từ của Trần Tất Thành: 30
KQ
0
1
2
3
4
5
6
7
8
9
10
.
Ghi
Mở
Đúng
50
50
49
49
45
46
50
49
49
49
50
50
50
49
Tổng
50
50
50
50
50
50
50
50
50
50
50
50
50
50
KQ
Lên
Xuống
Trái
Phải
Tổng
Tỷ lệ
Đúng
49
50
48
49
881
Tổng
50
50
50
50
900
Các kết quả kiểm tra trên tuy chưa thật đầy đủ trong mọi khía cạnh cần thiết nhưng cũng cho thấy được chương trình chạy tương đối ổn định mặc dù môi trường có thay đổi.
Những từ thường bị nhầm nhất trong các kiểm tra là 1 → 4, 2 → trái, 3 → 8.
KẾT LUẬN
Với kết quả kiểm tra độ chính xác nhận dạng như trên thì có thể thấy rằng việc áp dụng mô hình Markov ẩn trong nhận dạng tiếng Việt đã cho kết quả khá tốt. Tuy chưa thật sự hoàn hảo nhưng những kết quả thu được tương đối khả quan, từ đó có thể thấy rằng việc áp dụng mô hình Markov ẩn trong nhận dạng tiếng Việt là khá phù hợp, nếu đầu tư nghiên cứu nhiều hơn nữa phương pháp này sẽ còn đem lại hiệu quả cao hơn.
Trong chương trình khi chạy vẫn bị nhận dạng nhầm, nguyên nhân dẫn đến nhận dạng nhầm có thể là:
Dữ liệu huấn luyện chưa đầy đủ, số từ đem huấn luyện chưa nhiều, chưa thu được từ nhiều người, nhiều nơi…
Một số thông số có ảnh hưởng đến độ chính xác nhận dạng như số trạng thái của mô hình, giá trị tối thiểu của bj(k), điều kiện hội tụ của mô hình… có thể được lựa chọn chưa tối ưu.
Cả hai nguyên nhân trên muốn khắc phục được đều cần phải có thời gian, và cần phải bỏ công sức nghiên cứu nhiều hơn nữa.
Để chương trình có thể được ứng dụng rỗng rãi hơn cần phải cải tiến và mở rộng thêm. Với thiết kế đã được đưa ra thì hướng phát triển tiếp của tôi có thể là:
Tăng số lượng từ trong từ điển nhận dạng
Nhận dạng câu
Mở rộng ứng dụng của chương trình, không chỉ tích hợp với bộ Office của Microsoft mà có thể nhập dữ liệu vào bất cứ chương trình nào.
Do thời gian làm đồ án không có nhiều nên tôi chưa có điều kiện để tìm hiểu hết những hướng tiếp cận mới trong nhận dạng tiếng nói. Hy vọng rằng trong thời gian tới tôi, hoặc ai đó quan tâm đến lĩnh vực này có thể thực hiện được các mục đã đề ra.
TÀI LIỆU THAM KHẢO
Addison and Wesley, A programmer Guide to Sound , 1996.
Claudio Becchetti and lucio Prina Ricotti, Speech recognition Theory and C++ Implementation,1999.
Daniel Jurafsky and James H.Martin, Speech and Language Procesing, 2000.
H.P. Combrinck and E.C. Botha, On The Mel-scaled Cepstrum
(
Jia-lin Shen, Jeih-weih Hung, Lin-shan Lee. Robust Entropy-based Endpoint Detection for Speech Recognition in Noisy Environments.
(
Lawrence Rabiner, Biing-Hwang Juang, Fundamentals of Speech Recognition, 1996.
L.R. Rabiner, J.G.Wilpon, and F.K.Soong, Hight Performance Connected Digit Recognition, Using Hidden Markov Model.
( connected digit recogntion using hmm.pdf)
L.R. Rabiner and M.R. Sambur. An Algorithm for Determining the Endpoints for Isolated Utternances.
(
Nguyễn Thành Phúc, Một phương pháp nhận dạng lời Việt: Áp dụng phương pháp kết hợp mạng nơ-ron với mô hình Markov ẩn cho các hệ thống nhận dạng lời Việt, Luận án Tiến sĩ Kỹ thuật, Thư viện trường ĐHBK Hà Nội.
MSDN 2002.
Các file đính kèm theo tài liệu này:
- DAN208.doc