AI for Fun: Chơi Oản Tù Tì với AI

Chào mọi người, lại là mình, SuNT đến từ team AI VTI-VN!

Hà Nội, ngày giãn cách xã hội thứ 22, năm 2021!

Hà Nội và cả nước VN những ngày này đang oằn mình chống chọi với đại dịch COVID-19. Mọi công dân được chính quyền yêu cầu ở nhà, chỉ được phép ra đường trong những trường hợp đặc biệt ...

Đây có lẽ là lúc mà chúng ta có nhiều thời gian rảnh nhất. Bạn thường làm gì khi tự nhiên có nhiều thời gian rảnh như vậy? Xem phim, đọc sách, ngủ, ăn, chơi game, ...

Nói về chơi game, có một trò mà "nam nữ phụ ấu" đều biết. Không chỉ có ở VN, mà ở Nhật, ở Philippines, ỏ Trung Quốc, ở Ấn Độ ... đều có. Đó là trò chơi Oẳn Tù Tì. Người Nhật gọi là じゃんけんぽん, người Trung Quốc gọi là 剪刀 、 石頭 、 布, còn người Philippines gọi là jack en poy, ... Mình nhớ hồi còn đi học lớp tiếng kiểu do các cô giáo tình nguyện dạy bên Nhật, trong lớp có cả người VN, Philippine, Trung Quốc, Ấn Độ, ..., các thầy cô hay tổ chức chơi trò này. Ban đầu mình cứ nghĩ trò này xuất phát từ các nước Á châu, và chỉ những nước này mới chơi nó. Nhưng theo Wikipedia thì "Oẳn tù tì" ở Việt Nam là phát âm trại từ tiếng Anh: one, two, three (một, hai, ba) ở miền Nam trước 1975, có lẽ vì trò chơi này du nhập khi người Mỹ xuất hiện vào đầu thập niên 1960. Trò chơi tồn tại đến tận ngày nay với tên gọi "Oẳn tù tì". Khá ngạc nhiên đối với mình ...

Oẳn tù tì là trò chơi đơn giản, dễ chơi, nhanh chóng có kết quả nên hay được sử dụng để quyết định thắng thua mang tính may rủi, giống như trò tung đồng xu vậy.

Hôm nay, mình sẽ hướng dẫn mọi người tạo ra game Ỏăn tù tì để chơi với máy tính cho đỡ buồn chán trong những ngày giãn cách xã hội. Đặc biệt game này có sử dụng công nghệ AI nha mọi người! 😀

Cách thực hiện bao gồm các bước nhau sau:

  • Thu thập dữ liệu các cử chỉ tay tương ứng với: Kéo, Búa, Giấy.
  • Huấn luyện AI model để nhận diện các cử chỉ tay bên trên.
  • Cho máy tính sinh ra ngẫu nhiên một cử chỉ khi bạn đưa cử chỉ của bạn ra.
  • Quyết định người thắng dựa theo luật của game.

Chắc chắn rằng thông qua việc tạo game này, mọi người cũng sẽ học được khá nhiều kiến thức bổ ích!

Ok, bắt tay vào công việc thôi! Mình sẽ đưa luôn toàn bộ code vào trong bài để mọi người dễ theo dõi.

Bài viết được chia thành 2 phần:

  • Phần 1: Huấn luyện AI model để nhận diện các ký hiệu tay: Búa - rock, giấy - paper, kéo - scrissor, và không gì cả - nothing.
  • Phân 2: Tạo game.

1. Huấn luyện AI model

Đầu tiên, hãy import các thư viện sử dụng:

Một số biến, hàm dùng chung:

1.1 Thu thập dữ liệu

Dữ liệu ở đây bao gồm hình ảnh của 3 loại cử chỉ của tay (búa, giấy, kéo) và 1 loại không có gì (nothing). Mỗi loại có 100 hình ảnh. Mình test thử thì thấy 100 hình ảnh cho ta model nhận diện khá tốt rồi. Bạn có thể thử với số lượng khác.

Chúng ta sẽ thiết kế một giao diên đơn giản bằng OpenCV để thu thập dữ liệu này. Người chơi được yêu cầu giơ tay theo từng loại cử chỉ vào khu vực ROI có kích thước 224x224 (bằng kích thước input vào model) và nhấn các phím theo chỉ dẫn trên màn hình. Ảnh trong vùng ROI sẽ được lưu lại làm dữ liệu huấn luyện model.

Code thực hiện:

Khi thực thi code trên sẽ như sau:

Một số lưu ý:

  • Trong quá trình máy tính chụp ảnh các ký hiệu tay của bạn, cố gắng di chuyển tay lại gần, ra xa, sang trái, sang phải, xoay, ... nhưng không ra khỏi vùng ROI. Mục đích là để có thể thu được dữ liệu đa dạng hơn, giúp cho mô hình AI học tốt hơn.

  • Mặc dù chỉ có 3 ký hiệu tay nhưng chúng ta cần tạo thêm một lớp dữ liệu nữa, đó là nothing. Điều này là bởi vì khi chúng ta không chơi (đưa tay ra khỏi vùng ROI) thì mô hình AI vẫn sẽ cố gắng dự đoán ra một trong các lớp mà ta đã huấn luyện. Như thế thì máy tính sẽ tưởng là chúng ta đang chơi và sẽ xử lý sai logic mà ta mong muốn. Dữ liệu của lớp nothing này, lý tưởng nhất là tập các hình ảnh được chụp một cách ngẫu nhiên. Trong bài này, để cho đơn giản, mình chỉ lấy 100 ảnh tĩnh tại vị trí mình đang ngồi. Cách làm này có thể dẫn đến việc mô hình AI sẽ dự đoán sai khi chúng ta chơi ở một nơi khác. Mình sẽ đưa ra một số gợi ý để cải thiện độ chính xác của mô hình AI ở phần cuối bài này.

  • Hình ảnh chụp được từ camera sẽ không được lưu xuống ổ cứng máy tính mà vẫn giữ nguyên trong bộ nhớ RAM. Mình làm thế là để giảm thời gian đọc/ghi (I/O latency). Nếu bạn muốn chụp nhiều ảnh hơn, dung lượng RAM hạn chế, hoặc muốn sử dụng lại về sau thì nên xem xét lưu chúng vào HDD.

Vì không lưu vào HDD nên để chắc chắn là đã lấy được dữ liệu chính xác thì ta sẽ thử hiển thị ngẫu nhiên 8 ảnh của mỗi lớp:

1.2 Tiền xử lý dữ liệu

Ở bước này, chúng ta sẽ kết hợp tất cả hình ảnh vào một mảng, tất cả nhãn vào một mảng tương ứng. Sau đó tiến hành một số cac xử lý để phù hợp với yêu cầu của mô hình AI như: normalization, label encoder, ... Cuối cùng là chia dữ liệu thành các tập train và test.

1.3 Train AI model

Mình sẽ chọn một pre-trained model trong Keras để thực hiện fine-tune theo phương pháp Transfer Learning. Để cân bằng giữa tốc độ và độ chính xác, MobileNetV2 sẽ được sử dụng.

Download MobileNetV2 model và loại bỏ phần head của nó:

Thêm mới các lớp FC vào để tạo thành model hoàn chỉnh theo yêu cầu của chúng ta. Dropout và Global Average Pooling được thêm vào để hạn chế Overfitting. Số lượng node ở lớp đầu ra của model phải là 4 (= số lớp cần dự đoán).

Sử dụng thêm kỹ thụât Augmentation để hạn chế Overfitting:

Model sẽ được train với optimizer là Adam, loss function là categorical_crossentropy vì đây là bài toán phân loại nhiều lớp. Accuracy là metric mà chúng ta cần quan tâm.

Tiến hành train model với 15 epochs và batch_size 20.

Kết quả train:

Model rất nhanh đã hội tụ và đạt độ chính xác cao. Có lẽ vì dữ liệu của chúng ta khá đơn giản.

Lưu lại model để sử dụng về sau:

1.4 Kiểm tra hoạt động của AI model

Chúng ta thử test độ chính xác của model vừa huấn luyện trên camera video.

Load model lên:

Hàm dự đoán. Chú ý rằng mỗi frame của video cần phải được xử lý chính xác như lúc huấn luyện mô hình.

Đọc camera video và đưa vào model để dự đoán:

Mình tết quả như trong video sau:

OK, như vậy là chúng ta đã có được model AI để dự đoán ký hiệu tay của người chơi. Chúng ta sẽ chuyển qua xây dựng logic chơi game.

2. Tạo Game

Phần này thì chủ yếu là vận dụng kiến thức về xử lý ảnh và cách sử dụng thư viện OpenCV. Kết quả dự đoán của AI model đã được huấn luyện ở phần 1 sẽ là input cho game.

Luật chơi của game sẽ đơn giản như sau:

  • Áp dụng luật chơi chuẩn của game Oẳn tù tì: Kéo thắng Giấy, Búa thắng Kéo, ...
  • Mgười và máy tính sẽ chơi với nhau 10 lần, mỗi lần thắng được cộng 1 điểm, hòa thì không có điểm.
  • Sau 10 lần chơi, số điểm của bên nào lớn hơn thì người đó thắng cả game.

Mỗi lần người chơi đưa ra một ký hiệu tay thì máy tính cũng sẽ lựa chọn ngẫu nhiên một ký hiệu tay để chơi cùng.

Về phần dự đoán của AI model, để tăng độ chính xác thì kết quả dự đoán cuối cùng sẽ được căn cứ theo kết quả của 5 lần dự đoán liên tiếp. Trong 5 lần đó, nhãn nào chiếm đa số sẽ là nhãn được chọn.

Import các thư viện cần sử dụng:

Khai báo các biến toàn cục sử dụng trong toàn bộ chương trình:

Các hàm tạo UI thì vẫn như phần 1:

Tiếp theo là load AI model đã huấn luyện lên để chuẩn bị sử dụng:

Hàm tạo đoán từ AI model. Hàm này có khác một chút so với hàm cùng tên ở phần 1, vì chúng ta cần nhiều giá trị trả về hơn để phục vụ việc tính toán logic game.

Hàm tìm người chiến thắng trong mỗi lần chơi. Đây chính xác là hàm mô tả luật chơi kinh điển của game Oẳn tù tì:

Hàm quyết định người chơi chiến thắng cuối cùng và trả về hình ảnh tương ứng để hiển thị lên giao diện:

Hàm hiển thị hình ảnh hand sign của máy tính mỗi lần chơi.

Hàm hiển thị ảnh của người chiến thắng lên giao diện:

Hàm tính điểm mỗi lần chơi:

Hàm cập nhật thông tin điểm, hướng dẫn chơi game lên giao diện:

Hàm chơi game:

Cuối cùng là vòng lặp main, đọc frame từ camera video và gọi các hàm khác để tạo thành game đầy đủ chức năng:

Đây là video mình chơi thử:

Khá thú vị phải không các bạn? 😀

3. Hướng cải tiến và phát triển tiếp theo

3.1 Cải tiến AI model

Đây là hạn chế lớn nhất cần giải quyết nếu muốn phát triển sâu hơn game này. Vì dữ liệu được thu thập trong một không gian cố định nên khả năng bị overfitting là rất lớn (bạn có thể mang thử ra một địa điể khá để kiểm tra). Cách cải tiến thì rất đơn giản nhưng cũng mất rất nhiều thời gian, đó là tập hơn thêm thật nhiều ảnh của cả 4 nhãn ở các địa điểm, môi trường, không gian, thời gian, ... khác nhau,c àng đa dạng càng tốt. Sau đó huấn luyện lại model AI trên dữ liệu đó.

3.2 Cải tiến giao diện người chơi

Vì bài này mình chủ yếu minh họa cách sử dụng mô hình AI và kỹ thuật xử lý ảnh nên không chú trọng vào giao diện. Nếu muốn phát triển sâu hơn, thu hút nhiều người chơi hơn thì chắc chắn phần UI/UX phải được cải tiến theo hướng đơn giản, đẹp mắt, dễ sử dụng. Chi tiết về các kỹ thuật tạo UX/UI mình xin phép không bàn sâu thêm trong bài này.

3.3 Đưa game lên các thiết bị mobile

Nếu bạn muốn kiếm tiền bằng game này (có khả năng lắm chứ), có thể nghĩ đến việc triển khai nó lên điện thoại, máy tính bảng để thu hút nhiều người chơi. Cách làm chắc cũng đơn giản thôi vì các framework Tensorflow và Keras đều hỗ trợ việc porting AI model của nó lên các thiết bị đầu cuối cho cả 2 hệ điều hành là Android và iOS.

4. Kết luận

Vậy là chúng ta đã hoàn thành việc xây dựng game Oẳn tù tì với AI và Computer Vision. Mình nghĩ là có khá nhiều kiến thức thú vị mà bạn đã học được thông qua bài này. Cảm ơn các bạn đã theo dõi!

Toàn bộ code của bài này, các bạn có thể tham khảo tại đây.

5. Tham khảo

[1] SuNT, "AI for Fun: Chơi Oản Tù Tì với AII", Available online: https://tiensu.github.io/blog/102_playing-rock-paper-scissors-with-ai/ (Accessed on 10 Aug 2021).

Leave a Reply