Skip to content
/ NomNaOCR Public

Leverage Deep Learning to digitize old Vietnamese handwritten for historical document archiving (Made with national pride in every single line of code): https://www.kaggle.com/datasets/quandang/nomnaocr

License

Notifications You must be signed in to change notification settings

ds4v/NomNaOCR

Repository files navigation

English | Tiếng Việt

Số hóa tài liệu lịch sử Việt Nam với Deep Learning

Demo.mp4

I. Tổng quan

1. Giới thiệu

Tiếng Việt diệu kì với ngữ âm cực kỳ phong phú cùng hệ thống chữ viết giàu mạnh nhất vùng Đông Á đã trải qua hành trình từ chữ Nho, chữ Hán cho đến chữ Nôm và cuối cùng là chữ Quốc Ngữ. Đi cùng với mỗi loại chữ ấy là những trang sử vẻ vang của dân tộc.

Sau khi kết thúc Nghìn năm Bắc thuộc, ông cha ta với ý thức tự chủ ngôn ngữ, đã sáng tạo ra chữ Nôm dựa trên cơ sở chữ Hán được đọc theo âm Hán-Việt. Và song song với chữ Hán, đây cũng là công cụ được dùng để ghi lại phần lớn lịch sử văn hoá của dân tộc trong khoảng 10 thế kỷ. Tuy nhiên, di sản này hiện tại có nguy cơ tiêu vong.

"Ngày nay, trên thế giới chưa có đến 100 người đọc được chữ Nôm. Một phần to tát
của lịch sử Việt Nam như thế nằm ngoài tầm tay của 80 triệu người nói tiếng Việt."

(Hội Bảo tồn di sản chữ Nôm Việt Nam – VNPF)

Để sử dụng nguồn tri thức khổng lồ này, chúng cần phải được số hóa và dịch sang Quốc Ngữ hiện đại. Do việc dịch thuật khó khăn và tốn nhiều thời gian cùng số lượng chuyên gia hạn chế nên các nổ lực này không thể thực hiện trong thời gian ngắn.

👉 Để có thể tăng tốc quá trình số hóa này, các kỹ thuật về OCR chính là chìa khóa giúp mọi công trình chính trong Hán-Nôm thành sẵn có trực tuyến.

2. Các công việc đã thực hiện

Mình cùng người đồng đội Nguyễn Đức Duy Anh đã thực hiện đề tài này trong gần 8 tháng dưới sự chỉ dẫn tận tình của TS. Đỗ Trọng Hợp (Khoa KH&KTTT - VNUHCM UIT) và đã thu được một số thành quả nhất định:

  • Xây dựng thành công bộ dữ liệu NomNaOCR:

    • Giải quyết 2 bài toán Text DetectionText Recognition cho các tài liệu lịch sử viết bằng Hán-Nôm.
    • Có kích thước lớn nhất Việt Nam hiện tại với tổng cộng 2953 Pages38318 Patches.
  • Xây dựng thành công Pipeline cho các tác vụ OCR trên văn bản Hán-Nôm bằng phương pháp Deep Learning.

  • Cài đặt và thử nghiệm các mô hình trên mức chuỗi (Sequence level). Điều này chẳng những giúp tiết kiệm được chi phí gán nhãn mà còn giúp giữ lại được ngữ nghĩa trong câu thay vì chỉ thực hiện cho từng ký tự riêng lẻ như đa phần các công trình trước. Các bạn có thể xem qua các project open-source này nếu cần triển khai theo mức kí tự (Character level):

👉 Mọi người có thể xem thêm bài viết của mình về OCR cũng như sơ lược các mô hình sử dụng trong project này hoặc có thể xem chi tiết hơn tại 2 file thesis_vi.pdfslide_vi.pptx.

II. Bộ dữ liệu NomNaOCR

Lưu ý: Các bạn nên sử dụng font NomNaTong để có thể đọc các nội dung Hán-Nôm 1 cách tốt nhất.

1. Quy trình thu thập dữ liệu

VNPF đã số hóa cho rất nhiều tác phẩm Hán-Nôm nổi tiếng có giá trị lịch sử cao. Để có thể sử dụng được khối tài nguyên vô giá trên, mình sử dụng Automa để tạo một luồng thu thập tự động gồm:

  • Các hình ảnh lẫn URL của chúng.
  • Các nội dung được phiên dịch gồm các ký tự Hán-Nôm kỹ thuật số và phần dịch Quốc Ngữ của chúng (nếu có).
Automa.mp4

a. Hướng dẫn thu thập

Khâu này mình lười viết code nên có làm hơi thủ công tí 😅.

  • Import file workflow.json vào Automa.
  • Chọn thẻ New tab và chọn Edit => nhập URL của các tác phẩm Hán-Nôm cần thu thập.
  • Edit trường To number của thẻ Loop Data để chỉ định số trang cần thu thập.
  • Edit CSS Selector của các thẻ:
    • Element exists: kiểm tra trang rỗng.
    • Blocks group: lấy URL hình ảnh và nội dung của trang hiện tại.
  • Bấm Execute để bắt đầu thu thập.
  • Chạy file automa2txt.py để parse file automa.json vừa có được sau khi thu thập thành 3 file:
    • url.txt: chứa các URL hình ảnh của tác phẩm.
    • nom.txt: chứa các text chữ Hán-Nôm.
    • modern.txt: chứa các phiên âm tương ứng với file nom.txt.

[*] Còn về phần download hình ảnh, mình chỉ đơn giản sử dụng tính năng Tải xuống hàng loạt của Internet Download Manager. Xem thêm video hướng dẫn tại đây.

b. Các tác phẩm đã thu thập

Tên tác phẩm Số lượng page
Lục Vân Tiên 104
Truyện Kiều bản 1866 100
Truyện Kiều bản 1871 136
Truyện Kiều bản 1872 163
ĐVSKTT Quyển Thủ 107
ĐVSKTT Ngoại kỷ toàn thư 178
ĐVSKTT Bản kỷ toàn thư 933
ĐVSKTT Bản kỷ thực lục 787
ĐVSKTT Bản kỷ tục biên 448
Tổng cộng 2956

[*] ĐVSKTT: Đại Việt Sử Ký Toàn Thư

2. Quy trình gán nhãn

Nhóm mình sử dụng PPOCRLabel thuộc hệ sinh thái của PaddleOCR để gán tự động các bounding box. Tool này mặc định sử dụng DBNet để phát hiện văn bản, đây cũng là mô hình nhóm mình sẽ thử nghiệm cho bài toán Text Detection. Ở đây, mình có phân tool này ra thành 2 bản:

  • annotators.zip: dành cho người gán nhãn, mình đã bỏ đi các chức năng không cần thiết như Auto annotation, ... để tránh việc nhấn tùm lum có thể gây sai sót khi gán nhãn cũng như để việc cài đặt dễ dàng và ít lỗi hơn.
  • composer.zip: dành cho người xây dựng guideline (Mình sẽ gọi là Composer) dùng để chạy Auto annotation, khá đầy đủ chức năng so với bản gốc. Mình có bỏ đi thao tác Auto recognition khi chạy Auto annotation và sử dụng nhãn cho text là TEMPORARY. Ngoài ra, mình cũng đã thực hiện xoay ảnh lại để khớp với đầu vào các mô hình Recognition khi chạy chức năng Export Recognition Result.

👉 Các Annotator sẽ thay thế nhãn TEMPORARY theo hướng dẫn trong các guideline dành cho thơ và cho văn xuôi. Cuối cùng là thực hiện map nhãn thật được thu thập từ VNPF.

Tuy nhiên, với các ảnh trong NomNaOCR thì PPOCRLabel đa phần sẽ phát hiện các vùng ảnh chứa văn bản theo chiều ngang nên mình đã thực hiện quay ảnh theo các góc 90 độ để phù hợp với bài toán:

  • Tùy vào từng tác phẩm mà Composer sẽ chọn xoay +90 hay -90 độ hoặc cả 2 hướng.
  • Chạy file rotated_generator.py để sinh các ảnh tương ứng.
  • Sau đó đưa ảnh vào PPOCRLabel để dự đoán các bounding box.
  • Khi dự đoán xong, chạy file unrotated_convertor.py để xoay dọc các bounding box lại.

Sau khâu triển khai thực tế, bộ dữ liệu NomNaOCR được xử lý và thu được 2953 Pages (đã bỏ đi 1 Page scan lỗi và 2 Page trống). Bằng cách gán nhãn bán thủ công, nhóm mình đã thu được thêm 38318 Patches. Tiếp theo, nhóm mình sử dụng công thức từ bộ dữ liệu IHR-NomDB để có được phân phối tương đồng giữa tập TrainValidate để chia dữ liệu Recognition 1 cách hiệu quả nhất. Phần Synthetic Nom String thuộc bộ dữ liệu này cũng được dùng để thực hiện Pretraining cho các mô hình Recognition.

Tập dữ liệu Số điểm dữ liệu Tỉ lệ ký tự giao nhau
Tập Train 30654 93.24%
Tập Validate 7664 64.41%

III. Triển khai mô hình

1. Quy trình huấn luyện

  • Với Detection, mình sử dụng PaddleOCR để huấn luyện với các file config tương ứng trong folder Text detection.
  • Với Recognition, trong quá trình PreTraining trên bộ Synthetic Nom String của IHR-NomDB, mình nhận thấy khi thực hiện Skip Connection (SC) cho feature map với 1 lớp X có cùng shape và nằm xa nó nhất sẽ cải thiện đáng kể hiệu suất mô hình. Vì vậy, mình có thử nghiệm 2 phương pháp Skip Connection cơ bản là AdditionConcatenation cho các mô hình khả thi nhất (tồn tại lớp X nói trên).

👉 Download weights của các mô hình tại đây.

2. Quy trình đánh giá

  • Metrics đánh giá Text DetectionEnd-to-End: sử dụng 1 phương pháp mới tên là CLEval giúp đánh giá hiệu quả cho cả 2 giai đoạn phát hiện và nhận dạng văn bản (End-to-End). Ngoài ra, phương pháp này cũng có thể đánh giá được cho riêng Text Detection nên tùy vào bài toán mà CLEval sẽ có sự khác nhau trong các thành phần tính toán của nó.

  • Metrics đánh giá cho riêng Text Recognition: sử dụng các phương pháp tương tự với các công trình trước đó bao gồm: Sequence Accuracy, Character AccuracyCharacter Error Rate (CER).

  • Ngoài ra, với Recognition mình chỉ giữ lại output của những notebook hay mô hình có kết quả tốt nhất trên tập Validate của NomNaOCR gồm:

👉 Xem thêm thesis_vi.pdfslide_vi.pptx để biết thêm thông tin chi tiết.

IV. Kết quả thực nghiệm

1. Text Detection

2. Text Recognition

a. Kết quả PreTraining

b. Kết quả Fine-tuning và ReTraining

3. End-to-End

V. Trân trọng cảm ơn

VI. TODO

  • Sử dụng Beam search hay xa hơn nữa là Language model để giải mã đầu ra (decode) cho Text Recognition, tham khảo từ các project của Harald Scheidl.

  • NomNaOCRpp: Thử nghiệm các mô hình hiện đại hơn hay các mô hình SOTA trên các bộ dữ liệu benchmark nổi tiếng như ICDAR 20132015.

  • NomNaSite: Xây dựng WebApp để ứng dụng các bài toán đã triển khai vào thực tế.

  • NomNaNMT: Phát triển 2 bài toán dịch máy sau.

    • Dịch các phiên âm Hán-Nôm sang chữ Quốc Ngữ: Đã được triển khai bởi HCMUS.
    • Từ phần Quốc Ngữ phía trên sẽ dịch tiếp ra Tiếng Việt (văn phong hiện tại).

  • Ghi nhận lại các lỗi trên VNPF vào 1 file. Trong quá trình làm dataset, nhóm mình có phát hiện 1 vài lỗi trong phần dịch của VNPF như 1 số phần dịch không khớp với Page hiện tại, chữ dịch sai so với hình, dịch thừa chữ hoặc thiếu chữ, .... Sau đây là 1 vài ví dụ:

    Miêu tả lỗi Tác phẩm Trang Vị trí trong ảnh Ghi chú
    Chữ 揆 trong từ điển không có nghĩa "cõi" Truyện Kiều bản 1866 1 Câu 1
    Chữ 別 khác trong hình Truyện Kiều bản 1866 9 Câu 22 Dị thể với chữ 别, đa phần các version từ 1902 về trước đều bị
    Chữ 𥪞 khác trong hình Truyện Kiều bản 1866 55 Câu 15
    Chữ 󰁳 khác trong hình Truyện Kiều bản 1866 55 Câu 15
    Có 21 câu > 20 trong ảnh Lục Vân Tiên 6 -
    Có 19 câu < 20 trong ảnh Lục Vân Tiên 7 -
    Chữ thứ 5 bị hiển thị [?] Lục Vân Tiên 7 Câu 10

VII. Tham khảo