Làm quen với CoreML trong iOS 11

Tại hội nghị WWDC 2017 đang diễn ra, Apple đã ra mắt một bộ kit mới, hỗ trợ cho việc tích hợp học máy (Machine Learning – ML), đó chính là CoreML. Bản thân mình cũng đang chân ướt chân ráo vào ML được một thời gian ngắn, nên mình quyết định viết blog này nhằm mục đích chia sẻ và giới thiệu những gì mình biết, mình hiểu, và hi vọng sẽ cung cấp được cho các bạn cái nhìn sơ khai nhất về ML và CoreML trong iOS.

Trước khi đi vào vấn đề chính, mình sẽ chia sẻ qua một chút kiến thức ở dạng vỡ lòng nhất của ML, nhằm tạo mindset cho các bạn về vấn đề mà chúng ta sẽ tìm hiểu trong bài viết này. ML thật sự là một lĩnh vực rất lớn, để nói về nó thì không thể chỉ vỏn vẹn trong một vài bài viết được, hơn nữa, người viết cũng thừa nhận bản thân không đủ kiến thức để chia sẻ toàn bộ ML cho các bạn. Dựa trên tinh thần chia sẻ và học tập, nếu các bạn có thắc mắc hay câu hỏi gì, hãy để lại comment và mình sẽ hồi đáp.

Phần I: ML trong tầm tay.

  1. Nghĩ khác đi:

Ví dụ thực tiễn về AI và ML hiện tại không thiếu, các hệ thống nhận dạng khuôn mặt, vật thể, giọng nói,… hay các hệ thống tự đưa ra quyết định như xe tự hành, Alpha Go,… ML xuất hiện khắp mọi với tốc độ chóng mặt và độ chuẩn xác cực kỳ cao. Chúng ta hẳn sẽ tự hỏi, điều gì đã đem đến sức mạnh cho ML, và nó có gì khác so với những gì chúng ta từng biết hay không?

Ta lấy ví dụ đơn giản với hệ thống nhận dạng vật thể thông qua ảnh, bạn đưa vào một bức ảnh, chẳng hạn là con mèo, bạn muốn nó trả cho bạn kết quả “đó là ảnh của con mèo”, theo bạn, nó sẽ làm thế nào ?

Đây là bài toán filter thông thường trong lập trình, việc của chúng chỉ là for loop để duyệt, rồi tìm ra bức ảnh giống hoặc gần giống nhất với cái ảnh ta nhét vào, rồi xài mấy thuật toán tối ưu như là sắp xếp trước (sort) filter sau hoặc xài multithreading để duyệt cho nhanh, so easy. Thế nhưng bạn ơi, nếu dữ liệu của bạn lên đến hàng trăm nghìn, rồi hàng triệu thậm chí hàng trăm triệu thì sao? Đó mới chỉ là 1 đầu vào, đến khi họ muốn nhét thêm nhiều đầu vào (ở ví dụ này là nhét thêm ảnh mèo, ảnh gấu) thì sao??

Hồi chưa biết, mình cũng từng nghĩ như thế, và mình cũng băn khoăn là nếu như vậy thì làm sao mà AI nó đưa kết quả nhanh được như vậy. Không, suy nghĩ đó là SAI HOÀN TOÀN, hãy bỏ nó đi, clear your mind.

Cùng nghĩ về cụm từ “Học Máy” (Machine Learning) – nghĩa là ta cho cái máy nó học. Vậy cái máy thì nó học gì? Đúng, chính là học các dữ liệu mà bạn cung cấp. Nhưng cái chúng ta đang khúc mắc ở đây chính là động từ “HỌC”, với một cái máy tính, học ở đây là làm gì? Nhìn lại vấn đề, bài toán thực sự của chúng ta là chuyển một tập ảnh vật thể xác định, sang một tập các kết quả phán quyết (con mèo, con gà, con gấu, … ). Đây chính là bài toán ánh xạ trong toán học:

330px-codomain2-svg <figcaption class="wp-caption-text">(nguồn: wikipedia)</figcaption></figure>

ánh xạ là việc 1 đại lượng trong tập X, cho ra 1 kết quả nằm trong tập Y, dựa trên công thức tính toán của hàm f. Bạn có thấy nó quen quen không? Đúng, nó chính là ML mà chúng ta đang nói đến đấy. Ở đây X là tập các ảnh vật thể, còn Y là các nhãn phân loại con vật (mèo, gà, chó,..) mà mình nói ở trên. Đầu vào của chúng ta là một bức ảnh (tức là nằm trong tập “ảnh” – X), và đầu ra là kết quả phán định ảnh này là ảnh con mèo (tập Y) . Vậy ML làm gì? Thực ra việc của ML là tìm ra mối liên hệ ánh xạ giữa X và Y, hay nói cách khác, việc “học” ở đây chính là tìm ra hàm f, dựa trên X và Y.

Vậy, việc tìm ra hàm f có ý nghĩa gì?

2. Sự khác biệt:

Như đã nói ở trên, hàm f chính là công thức, là chìa khóa để chúng ta có thể ánh xạ qua lại giữa đầu vào và đầu ra. Khác với cách giải bằng phương pháp lọc (filter) ban đầu, giờ đây mỗi khi chúng ta có đầu vào (một bức ảnh), đưa nó qua hàm f để tính, và nhận kết quả đầu ra. Việc tính toán này rất nhanh, vì lúc này chúng ta chỉ áp dụng công thức toán học, so với việc phải dò trong tập dữ liệu ban đầu.

Tuy nhiên, việc tìm ra hàm f này cực kỳ phức tạp, trên thực tế, chúng ta không tìm hàm f, mà thay vào đó chúng ta cố gắng tìm một hàm h nào đó, sao cho nó gần giống với hàm f nhất có thể, cái gần giống ở đây chính là việc cho ra kết quả dựa trên đầu vào, phải gần nhau:

screen-shot-2016-07-23-at-7-05-47-am <figcaption class="wp-caption-text">(nguồn: septeni-technology)</figcaption></figure>

Việc học máy của chúng ta cuối cùng có thể quy về việc tìm cho ra hàm h, bước suy đoán tìm ra hàm này dựa trên dữ liệu đầu vào, được gọi là bước huấn luyện dữ liệu (training data), và hàm h thu được, chính là mô hình dữ liệu (model). Cơ sở suy luận để tìm ra hàm h này cần nhiều kiến thức về toán học cao cấp: giải tích, đại số tuyến tính, xác suất thống kê,… Chi tiết cụ thể mình sẽ không trình bày lần này, vì nó rất rộng và trong bài viết này, các bạn cũng không cần dùng đến mức sâu như vậy. Quay trở lại với hàm h, vì đây là hàm suy diễn gần đúng, cho nên so với hàm mong muốn (là hàm f) sẽ có sai số nhất định, do đó sinh ra khái niệm confidence (độ tin tưởng) nhằm chỉ xác suất tiên đoán nó là kết quả đúng là bao nhiêu. Ngoài ra, ML còn bị ảnh hưởng bởi dữ liệu đầu vào, hiển nhiên nếu ta cho ít dữ liệu, thì việc suy đoán sẽ khó, hoặc suy đoán hàm h không chuẩn. Bên cạnh đó, trước khi đưa vào suy đoán, ML còn phải tách đầu vào thành các đặc trưng khác nhau (feature) để giảm thiểu khối lượng tính toán và tăng cường độ chính xác cho kết quả ( ví dụ như tách đặc trưng của con mèo so với con chó, con gà,…).

–> Tổng kết: Bạn cần nhớ gì qua phần này ?

  • Công việc của ML là tìm kiếm hàm H gần giống với hàm ánh xạ chuẩn giữa 2 tập đầu vào và đầu ra.
  • Training data là bước sử dụng dữ liệu đầu vào để tìm hàm H.
  • Model là hàm H thu được, và đó chính là kết quả của học máy.
  • Confidence: xác suất chính xác của kết quả phán định bởi model.

 

Phần II: Làm quen với CoreML.

Huấn luyện dữ liệu là một công đoạn không hề đơn giản, với chi phí tính toán và thời gian lớn, điều này phụ thuộc vào các bước toán học và số lượng cũng như độ phức tạp của tập đầu vào. Mình đã thử tự tay training 1 tập 20.000 bức ảnh (dạng bit) và công đoạn này ngốn ~ 30 phút. Tuy rằng hiện nay một số framework hỗ trợ việc training data ngay trên mobile, tiêu biểu nhất là TensorFlow (viết bằng Objective-C++ và C), nhưng cũng chỉ giải quyết một số bài toàn nhỏ.

–> Training data trên mobile là việc làm không khuyến khích và không đem lại nhiều ý nghĩa. Người dùng có thể sẵn lòng bỏ ra 1 khoảng thời gian không nhỏ chỉ để đợi cái ứng dụng của chúng ta training data không?

Trở về với công việc chính của chúng ta – những người lập trình viên iOS, vậy chúng ta kỳ vọng điều gì ở ML ? Đúng, chúng ta không huấn luyện dữ liệu, thay vào đó chúng ta ứng dụng kết quả của chúng, chính là Model (hay hàm H ở trên). Và tại WWDC2017, Apple đã giúp chúng ta điều này bằng việc cung cấp CoreML.

  1. CoreML là gì (What is CoreML):

Trên trang chủ của mình, Apple chỉ viết ngắn gọn thế này:

Integrate machine learning models into your app.

CoreML giúp tích hợp model vào trong ứng dụng của bạn. Tích hợp như thế nào ? Hồi sau sẽ rõ.

CoreML còn hỗ trợ một số native framework khác của Apple, như là Vision (cho việc phân tích ảnh), Foundation (cho việc xử lý nhận dạng âm thanh và ngữ nghĩa),…

2. Sử dụng CoreML như thế nào: (how to use it)

Vì bản chất của CoreML là tích hợp model đã được huấn luyện vào trong ứng dụng

–> Bước đầu tiên: phải có Model. Vậy model này lấy ở đâu?

CoreML hiện tại chỉ nhận đúng một định dạng là .mlmodel, do đó, nếu chúng ta muốn sử dụng model bên ngoài, chúng ta cần phải convert nó sang định dạng này. Apple có hỗ trợ  sẵn CoreMLTools để làm việc này. Trong phạm vi và mục tiêu của một bài làm quen, chúng ta sẽ không cần thao tác phức tạp đến vậy, chúng ta chỉ cần sử dụng những mlmodel có sẵn, do Apple chính Apple đưa ra, các bạn có thể tải chúng về tại đây.

Screen Shot 2017-06-12 at 10.16.58 AM.png

Ở đây mình dùng model tên là VGG16.

–> Bước thứ 2: Tích hợp model vào trong project và xcode.

Đầu tiên, các bạn kéo thả file vừa download vào trong thư mục:

1.gif

Tiếp đến: các bạn kéo thả nó vào trong project tại xcode và lựa chọn target cho nó là project của bạn. Lưu ý bước này rất quan trọng, vì nếu bạn không lựa chọn target cho nó, thì đồng nghĩa nó không được add vào project và bundle lúc đóng gói của project, vì vậy bạn không thể dùng được nó.

2

3

Giờ thì hãy chọn file VGG16.mlmodel của các bạn trên XCode, và cùng tìm hiểu:

Screen Shot 2017-06-12 at 10.38.15 AM.png

  • Mục 1 là thông tin về mlmodel, không có gì quan trọng.
  • Mục 2 là Model Class. Khi các bạn import file mlmodel vào Xcode, Xcode sẽ tự động sinh ra cho bạn cái Model Class này, đây chính sức mạnh then chốt của CoreML – từ model, bạn có class.
  • Mục 3 là detail input và output, như trong hình: model của chúng ta nhận đầu vào là 1 ảnh có dạng Image,<BGR,224,224>, và output gồm 2 giá trị là classLabelProbs và classLabel.

Dưới đây là class mà Xcode sinh sẵn từ model cho chúng ta:

Screen Shot 2017-06-12 at 1.42.00 PM.png

Screen Shot 2017-06-12 at 1.42.29 PM.png

3. Ví dụ về sử dụng CoreML:

Ý tưởng bài toán: chọn ảnh trong Gallery –> dùng CoreML để tiên đoán xem ảnh đó mô tả cái gì?.

a) Thiết kế UI:

Screen Shot 2017-06-12 at 1.16.56 PM.png

Mình có 1 cái ảnh, để thể hiện ảnh mình chọn, 1 cái label để thể hiện kết quả có được khi kiểm tra với ML, 1 nút “Add” để show màn hình chọn ảnh trong bộ sưu tập của máy. Đối với các bạn test trên simulator, các bạn nên kéo thêm ảnh bên ngoài vào trong, thay vì 4 ảnh mặc định.

4.gif

b) Nào mình cùng code:

Đầu tiên các bạn cần thực hiện phần việc click vào button để show lên màn hình chọn ảnh:

Screen Shot 2017-06-12 at 1.23.54 PM.png

Chú ý, vì model của chúng ta đã được Xcode chuyển thành class, cho nên chúng ta có thể sử dụng nó như một class bình thường, ví dụ tạo instance cho nó, ở đây mình gán cho nó vào 1 biến:

Screen Shot 2017-06-12 at 1.25.31 PM.png

Nhìn lại model của chúng ta, khi được convert theo XCode, đầu vào lúc này nhận vào 1 image có dạng PixelBuffer –> chúng ta cần phải convert ảnh cũng chúng ta sang dạng này. Mình tạo 1 class Utils để đảm nhận 2 việc resizeImage và convert nó sang PixelBuffer:

Screen Shot 2017-06-12 at 2.15.40 PM.png

Ok, chúng ta đã xong 90% công việc rồi, giờ quay lại với ViewController, phần việc còn lại của chúng ta chỉ là sử dụng model để tiên đoán ảnh chúng ta chọn:

Screen Shot 2017-06-12 at 2.17.15 PM.png

Lưu ý vì đầu vào của chúng ta là ảnh <BGR,224,224> (224 ở đây là width và height của ảnh) nên chúng ta phải resize về đúng width height này. Đến đây, chúng ta đã hoàn tất mọi công đoạn để có thể sử dụng 1 ảnh trong gallery làm đầu vào cho model, trong code là biến imgAsPixelBuffer.

Bước cuối cùng: CoreML sẽ giúp chúng ta phần việc tiên đoán còn lại, chỉ đơn giản bằng một câu lệnh: model.prediction():

Screen Shot 2017-06-12 at 2.21.14 PM.png

Đây là toàn bộ source code cho ViewController:

Screen Shot 2017-06-12 at 2.22.24 PM.png

 

==> Test kết quả:

5.gif

 

  • Nhét ảnh con sư tử –> ra lion, king of beasts,..
  • Nhét ảnh con mèo –> ra egytian cat (mèo ai cập).
  • Nhét ảnh con cún –> ra golden retriever (chú chó vàng).

 

Các bạn có thể download Source Code tại đây.

=============================================================

TỔNG KẾT

Qua blog này, các bạn cần nhớ được gì:

a. Căn bản ML, nó là cái gì: nó là quan hệ toán học giữa đầu vào và đầu ra, quá trình học máy là quá trình tìm cho ra hàm liên hệ này với xác suất gần đúng tốt nhất.

b. CoreML là gì và làm gì? Nó là một framework được Apple giới thiệu nhằm tích hợp model vào trong ứng dụng của Apple.

c. Dùng nó thế nào: Cần một model , import vào để nó gen class và dùng thôi.