Keep Moving Forward

Wednesday, March 22, 2017

How to detect lines in image using Hough Line Transform (with code example)

5:16 PM Posted by Cáp Hữu Quân , 5 comments
Line detection has many applications in image processing, computer vision, and machine vision. A very simple example of line detection's application is SUDOKU Solver. If you want to solve SUDOKU which locates in an image, first, you have to detect SUDOKU grid and extract digits to recognize those numbers. Hough Line Transform is one of the popular techniques to detect lines in images.
This article will explain how to detect lines in an image using Hough Line Transform with OpenCV library and Python code example.

Detecting line in SUDOKU grid

Note that we only can use Hough Line Transform after we detected edges on the image. The detected edges image is the input of Hough Line Transform. There are many techniques to detect edges on the image such as Sobel or Canny algorithms. I will explain the idea of these techniques when I have enough time :). But here are very good explanation video of edges detection on Computerphile Channel (Check the link below)
1. Finding the Edges (Sobel Operator) - https://www.youtube.com/watch?v=uihBwtPIBxM
2. Canny Edge Detector - https://www.youtube.com/watch?v=sRFM5IEqR2w

The image after detect edge will be like this (Check the image below). This image will be a grayscale image. Every pixel on the edge will have a value of 255 or 1(white lines), otherwise, the pixel not located on the edge will have a value of 0 (black area).
Image after apply edge detection

Now, let's see how Hough Line Transform can detect lines in the image.

Theory


A line can be represented as  `rho = xcostheta + ysintheta`  where  `rho`  is the perpendicular distance from the origin to the line, and `theta` is the angle formed by this perpendicular line and horizontal axis. That direction varies on how you represent the coordinate system. This representation above is used in OpenCV. Any vertical line will have 0 degree and horizontal lines will have 90 degrees of `theta`. Normally, the origin point will be the top-left point in the image so the maximum `theta` is 90 degrees and minimum `theta` is 0 degree.

We know that every point on the line always satisfies this equation: `rho = xcostheta + ysintheta`  ` (1)`. If we know a pair (`rho, theta`), we always can draw a line.
So, the idea of Hough Transform is creating a 2D array `M` as a matrix to hold the values of two parameters (`rho` and `theta`). Let rows denote the `rho` and columns denote the `theta`. We assume there exists a line `d` with `rho = rho_1` and `theta = theta_1` on the image. If a point `A (x_1, y_1)` lie on `d` satisfies `(1)` `rho_1 = x_1costheta_1 + y_1sintheta_1`, we increase the value of `M[rho_1][theta_1]` by 1. We continue this process for every point on the line, increasing the value of `M[rho_1][theta_1]` by 1 if that point satisfies equation `(1)`. At the end, the value of `M[rho_1][theta_1]` will be must bigger than another cell in 2D array `M`. And the value of `M[rho_1][theta_1]` will be also the length of the line.
The size of the 2D array depends on the accuracy you need. Suppose you want the accuracy of angles to be 1 degree, you need 180 columns. For `rho`, the maximum distance possible is the diagonal length of the image. So taking one pixel accuracy, the number of rows can be the diagonal length of the image.

Example

Suppose we have an image with 20x20 pixels and contain 2 lines (black lines - d1 and d2) like this.

The perpendicular distance between `d1` and the origin is `rho=7` and the angle between this perpendicular line and the horizontal axis (`Ox`) is 0 degrees and the length of  `d1` is 15 (pixels). Similarly with `d2`, `rho=12`, `theta=90`, and the length is 8 (pixels)
If you want the accuracy of angles to be 1 degree and the maximum distance possible is the diagonal length of the image, you will need a 2D array with 180 columns and 28 rows (`20sqrt(2)~~28`).

After running Hough Line Transform on that image, we will have `M[7][0]=15` and `M[12][90]=8` corresponding to the length of `d1` and `d2`.
So now, let's impement a simple Python code to see how Hough Line Transform actually work.


import numpy as np
from sympy import *

# Create image with 20x20 pixel
img = np.zeros((20,20), dtype=np.int)
# Draw 2 lines correspond with above image
# Every pixel lies on a line will have value of 1
# Draw line d1, length = 15
for i in range(0,15):
    img[i+1][7]=1
# Draw line d2, length = 8
for i in range(11,19):
    img[12][i]=1

# Create a 2D array to holds the value of rho and theta
M = np.zeros((28,91), dtype=np.int)

# Scan image to find some lines
for x in range(20):
    for y in range(20):
        if(img[x][y]==1):
            for rho in range(28):
                for theta in range(0,91):
                    if(rho==y*cos(theta*pi/180) + x*sin(theta*pi/180)
                        M[rho][theta] += 1

# Print the value of M[7][0] and M[12][90] to see the length of d1 and d2
print M[7][0]
# Result: 15
print M[12][90]
# Result: 8

Note that we will use cos, sin method and pi in sympy library instead of using numpy because pi in numpy (numpy.pi) is not actual pi value so you will get the wrong value when using numpy.cos(pi/2).

Try to run by yourself and see how Hough Line Transform works.

Hough Line Transform in OpenCV

In real problem, there are too many lines in image and quite complex to write a code and detect line by yourself. I prefer to use OpenCV - A strong Computer Vision library to deal with Line Detection problem.
We can simply use Hough Line Transform in OpenCV with cv2.HoughLines() function. It will returns an array of `(rho, theta)` values. `rho` is measured in pixels and `theta` is measured in radians.
The first parameter of cv2.HoughLines() function is a binary image, so apply thresholding or use canny edge detection before finding applying Hough Line Transform. The second and third parameters are `rho` and `theta` accuracies respectively. The final parameter is the threshold, which means minimum length of a line to be detected.

Here is the code I took from OpenCV online documents website with adding some explanations.


import cv2
import numpy as np

# Loading image contains lines
img = cv2.imread('lines.jpg')
# Convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Apply Canny edge detection, return will be a binary image
edges = cv2.Canny(gray,50,100,apertureSize = 3)
# Apply Hough Line Transform, minimum lenght of line is 200 pixels
lines = cv2.HoughLines(edges,1,np.pi/180,200)
# Print and draw line on the original image
for rho,theta in lines[0]:
 print(rho, theta)
 a = np.cos(theta)
 b = np.sin(theta)
 x0 = a*rho
 y0 = b*rho
 x1 = int(x0 + 1000*(-b))
 y1 = int(y0 + 1000*(a))
 x2 = int(x0 - 1000*(-b))
 y2 = int(y0 - 1000*(a))
 cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

# Show the result
cv2.imshow("Line Detection", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

I used this image to run Hough Line Transform in.
 And here is the result:

References:

[2] Hough Line Transform - Wikipedia - https://en.wikipedia.org/wiki/Hough_transform


Sunday, May 15, 2016

Install Caffe library on Ubuntu 14.04 Step-by-Step (with images instruction)

1:53 PM Posted by Cáp Hữu Quân , , No comments
Deep Learning hiện đang là mô hình hiệu quả để giải quyết rất nhiều vấn đề như Xử Lý Ảnh, Xử Lý Ngôn Ngữ Tự Nhiên..v.v. Việc hiện thực hóa các mô hình Deep Learning bây giờ không mấy khó khăn vì đã có rất nhiều thư viện hỗ trợ việc thiết kế mô hình mạng neural. Caffe là một trong những thư viện hỗ trợ Deep Learning có đông đảo người dùng nhất. Caffe rất mạnh trong việc xử lý ảnh và nó cũng có thể thiết kế các mô hình Deep Learning cho các vấn đề khác. Thư viện này có thể kết hợp với GPU của NVIDIA giúp cải thiện tốc độ huấn luyện mạng thông qua CUDA.

Bài viết này sẽ hướng dẫn cách cài Caffe chi tiết từng bước cho người mới bắt đầu trên hệ điều hành Ubuntu 14.04 LTS 64 bits.

Trước tiên, bạn cần tải bản mới nhất của Caffe về tại địa chỉ:
https://github.com/BVLC/caffe/archive/master.zip
Có thể sử dụng lệnh git clone http://github.com/BVLC/caffe.git nếu như máy bạn có cài git sẵn.
Sau khi tải về, các bạn xả nén Caffe vào 1 thư mục nào đó để dễ quản lý. Ở trường hợp này, Caffe sẽ lưu ở đường dẫn /home/caffe


Tiếp theo, cài đặt thư viện cần thiết để hỗ trợ compile và build caffe.
Lưu ý: Nếu máy tính không có card màn hình của hãng NVIDIA thì không cần cài thư viện CUDA. Trong lúc huấn luyện sẽ sử dụng CPU.

Bật terminal (Ctrl + Alt + T) và gõ vào Terminal những lệnh sau:

sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
sudo apt-get install libatlas-base-dev

Việc cài đặt sẽ mất một khoảng thời gian từ 5-10 phút tùy vào tốc độ mạng của bạn.
Sau khi cài đặt thành công những thư viện trên, ta cài đặt gói phần mềm Annaconda. 
Annaconda là gói phần mềm hỗ trợ quản lý và lưu trữ những thư viện cho Python (hỗ trợ luôn cài Python nếu máy chưa cài Python) miễn phí. Nếu bình thường, muốn cài đặt thêm gói tiện ích cho Python, ta phải tìm kiếm và xem thông tin của từng gói phần mềm để tương thích với bản Python của máy mình. Với Annaconda, mọi việc trở nên dễ dàng hơn khi bạn chỉ cần nhớ tên gói thư viện, những việc còn lại Annaconda sẽ xử lý.
Annaconda chưa hơn 400 packages cần thiết phục vụ cho xử lý liên quan đến Toán học, kỹ thuật, xử lý dữ liệu, xử lý ảnh, phân tích dữ liệu trên Python. Hơn nữa, Caffe hỗ trợ build với Annaconda, điều này khá tiện lợi và dễ dàng cho những ai mới bắt đầu sử dụng Caffe và Python trên Ubuntu.
Tải phiên bản cho Ubuntu 14.04 tại địa chỉ: https://www.continuum.io/downloads
Bài viết này sử dụng bản Annaconda 64 bits with Python 2.7
Sau khi tải về, cài đặt Annaconda trên Terminal như sau:
Ở trường hợp này file Anaconda2-4.0.0-Linux-x86_64.sh được lưu tại thư mục Downloads nên trước tiên phải trỏ tới thư mục Downloads bằng lệnh sau:

cd /Downloads

Sau đó cài Anaconda bằng lệnh sau:
sudo bash  Anaconda2-4.0.0-Linux-x86_64.sh

Lưu ý: phải gõ đúng tên file Anaconda.

Sau đó nhấn Enter và đọc kỹ điều khoản để cài Anaconda. Việc cài đặt diễn ra khoảng 5 phút.

Lưu ý: Khi cài đặt thành công, Anaconda sẽ hỏi bạn muốn thêm đường dẫn cài Anaconda vào đường dẫn hệ thống không. Lúc này hãy gõ “yes” và nhấn Enter.

Đã hoàn tất quá trình chuẩn bị các gói hỗ trợ cần thiết. Lúc này, ta sẽ sang công đoạn build Caffe.
Trước hết, để build Caffe, ta phải chỉnh sửa thông tin trong file config.
Ở cửa sổ Terminal, trỏ tới thư mục Caffe và thực hiện câu lệnh sau để tạo mới 1 file .config:

sudo cp Makefile.config.example Makefile.config

Tiếp theo mở file Makefile.config mới khỏi tạo này lên bằng trình Text Editor (gedit) và chỉnh sửa các thông tin như sau:
Ở dòng số 8, xóa comment (xóa ký tự #) để sử dụng CPU cho caffe (vì máy mềnh không có GPU NVIDIA nên không thể sử dụng CUDA. Nếu máy tính có card NVIDIA thì xóa comment để sử dụng CUDNN ở dòng USE_CUDNN := 1 )

CPU_ONLY := 1
Tiếp theo, nếu có sử dụng Matlab để code Caffe thì xóa comment tại dòng: 
“MATLAB_DIR := /usr/local” và thay “/usr/local” bằng đường dẫn tới Matlab.
Ví dụ:  MATLAB_DIR := /usr/local/MATLAB/R2014b

Tiếp đến, ta chỉnh thông số Anaconda bằng cách bỏ comment và thay thế đường dẫn tới thư mục Anaconda như sau:

ANACONDA_HOME := $(HOME)/anaconda2
PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
                        $(ANACONDA_HOME)/include/python2.7 \
                        $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include \

Đã xong, Save lại file Makefile.config.

Tiếp theo ta build Caffe bằng cách sau:

Trỏ tới thư mục Caffe trên Terminal và gõ lệnh sau:

make clean
make all

Sau khi chạy xong lệnh make all. Ta gõ tiếp lệnh: make test

Tiếp theo gõ lệnh: make runtest để chạy thử Caffe sau khi build có lỗi hay không.
Nếu sau khi chạy lệnh này không có lỗi nào thì bạn đã thành công 90% khi build Caffe.

Sau khi test thành công, ta chạy lệnh sau để tạo thư viện caffe chạy được trên Python.

make pycaffe

Tiếp theo, thêm đường dẫn pycaffe vào đường dẫn hệ thống bằng câu lệnh sau:

sudo echo export PYTHONPATH=<đường dẫn tới thư mục caffe/python>:$PYTHONPATH >> ~/.bashrc

Ví dụ: sudo echo export PYTHONPATH=~/caffe/python:$PYTHONPATH >> ~/.bashrc

Tương tự như với pycaffe, ta gõ lệnh: make matcaffe để biên dịch thư viện chạy trên Malab như sau:

Để sử dụng caffe cho Matlab, xem bài hướng dẫn tại đây (đang cập nhật sau)

Cuối cùng, ta gõ lệnh : make distribute để kết thúc quá trình cài đặt.

Chúc mừng bạn đã cài đặt thành công thư viên Caffe trên Ubuntu.

Demo với iPython Notebook (Python IDE base web browser)
Để kiểm tra thử xem Caffe có thể dùng được cho Python không. Hãy làm một vài phép thử và biết có lỗi để còn sửa :))

Các bạn mở Terminal và gõ lệnh: jupyter notebook để mở IDE lên.
Nếu bạn là người mới dùng iPython Notebook thì tại cửa sổ web mở ra bạn chọn New -> Python 2 để tạo một project python mới.
Tại đây, bạn gõ lệnh : import caffe rồi nhấn Shift + Enter để import thư viện Caffe vào project Python.
Nếu xuất hiện lỗi sau: ImportError: No module named google.protobuf.internal



Lỗi này là do máy tính bạn chưa cài đúng thư viện protobuf của Google (Thư viện cung cấp cơ chế đệm cho việc chạy các phần mềm khác nhanh hơn)

Các bạn mở Terminal mới và gõ lệnh sau để cài protobuf:

conda install -c https://conda.anaconda.org/anaconda protobuf



Lưu ý: Có thể lúc cài protobuf sẽ bị lỗi: 
Error: Missing write permissions ở thư mục cài anaconda2.

Hãy chạy dòng lệnh sau để sửa lỗi:

sudo chown -R <username hiện tại> <đường dẫn tới anaconda>

Ví dụ:  username của Ubuntu hiện tại là huuquan và đường dẫn vào thư mục anaconda là /home/huuquan/anaconda2

Thì chạy như sau:

sudo chown -R huuquan ~/anaconda2

Sau đó chạy lại lệnh trên để cài protobuf cho python.

Chạy lại iPython và import Caffe lần nữa. Có lẽ sẽ hết lỗi :))



Nếu có vấn đề gì, xin vui lòng bình luận ở dưới hoặc liên hệ qua email cho mình :)

Wednesday, May 4, 2016

Machine Learning là gì?

10:12 PM Posted by Cáp Hữu Quân 1 comment
Máy học là xu hướng phát triển mới của lĩnh vực Trí Tuệ Nhân Tạo và ngày càng có nhiều ứng dụng trong đời sống thực tế. Các ví dụ điển hình của máy học có thể kể đến như cỗ máy tìm kiếm Google. Hằng ngày bạn vào Google tìm kiếm và để ý rằng, Google có thể hiểu được ngữ nghĩa của từ khóa mà bạn tìm kiếm nhằm gợi ý và đưa ra các kết quả tìm kiếm tốt hơn hay gợi ý các kết quả tìm kiếm cho bạn. Hoặc như Facebook, có thể nhận dạng khuôn mặt ở chức năng tag ảnh, có thể gợi ý bài viết liên quan hoặc gợi ý kết bạn. Có khi nào bạn tự hỏi vì sao các ứng dụng có thể "thông minh" đến như thế? Nhờ vào thuật toán cụ thể nào để có thể đạt được như thế?
Bài viết này tôi sẽ chia sẻ về Machine Learning. Để bài viết phong phú, tôi sẽ tổng hợp từ vài nguồn có trên mạng cộng với kiến thức cá nhân về Machine Learning. Hãy bắt đầu nào :)

1. Machine Learning là gì?
Trước tiên đề có cái nhìn tổng quan về Trí Tuệ Nhân Tạo (Artificial Intelligence - AI) hãy nhìn 2 tấm hình bên dưới.
dddd
A Deep Dive in the Venture Landscape of Artificial Intelligence and Machine Learning - September 2015 Ajit Nazre Rahul Garg.
Machine Learning - http://www.humphreysheil.com/blog/deep-learning-and-machine-learning
Trí Tuệ Nhân Tạo là lĩnh vực rộng nhất của Khoa Học Máy Tính và có rất nhiều nhánh con như: Máy Học, Biểu Diễn Tri Thức và Suy Luận, Xử Lý Ngôn Ngữ Tự Nhiên, Thị Giác Máy Tính... Nói nôm na, AI là giấc mơ của con người nói chung là Khoa Học Máy Tính nói riêng để biến máy tính trở thành cỗ máy có trí thông mình gần giống với con người. Vấn đề này có vẻ khá mơ hồ và ở hiện tại vẫn chưa có cỗ máy nào có khả năng học hỏi được như một đứa bé 5 tuổi. Tuy nhiên, với sự bùng nổ của máy móc và các thuật toán AI, chúng ta hi vọng một ngày không xa sẽ xây dựng được hệ thống thông minh như con người và giúp ích cho cuộc sống (không gây hại là được :3 )

Nhìn vào cả 2 hình, có thể định nghĩa rằng, Máy Học là một nhánh nghiên cứu nhỏ trong lĩnh vực Trí Tuệ Nhân Tạo rộng lớn. Máy học cho phép máy tính có khả năng học hỏi và lấy kinh nghiệm như con người để có thể giải quyết một vấn đề cụ thể nào đó mà con người khó có thể làm được.
Máy Học là một phương pháp phân tích dữ liệu mà sẽ tự động hóa việc xây dựng mô hình phân tích. Sử dụng các thuật toán lặp để học từ dữ liệu, Máy Học cho phép máy tính tìm thấy những thông tin giá trị ẩn sâu mà không được lập trình một cách rõ ràng.[1]
Nói cách khác, các mô hình Máy Học chủ yếu dựa vào thống kê vì lượng dữ liệu để huấn luyện rất lớn và chắc chắn không có một đoạn code cụ thể nào để giải quyết (hard code) nên ta hi vọng máy tính có thể giải quyết chín xác bao nhiêu phần trăm bài toán (độ chín xác). Và đương nhiên kỳ vọng càng chín xác càng tốt.

Có 2 định nghĩa khá rõ ràng về Machine Learning như sau:
Theo Arthur Samuel (1959): Máy học là ngành học cung cấp cho máy tính khả năng học hỏi mà không cần được lập trình một cách rõ ràng.
Theo Giáo sư Tom Mitchell - Carnegie Mellon University thì Machine Learning là: Một chương trình máy tính được nói là học hỏi từ kinh nghiệm E từ các tác vụ T và với độ đo hiệu suất P. Nếu hiệu suất của nó áp dụng trên tác vụ T và được đo lường bởi độ đo P tăng từ kinh nghiệm E. (Có vẻ hơi khó hiểu khi đọc lần đầu !!! Xuống phần ví dụ để rõ hơn xíu)

Ví dụ cho định nghĩa của Tom Mitchell
Ví dụ 1: Giả sử như bạn muốn máy tính xác định một tin nhắn có phải là SPAM hay không? Thì tác vụ T lúc này sẽ là: Xác định 1 tin nhắn có phải SPAM hay không?
Kinh nghiệm E: Xem lại những tin nhắn đánh dấu là SPAM xem có những đặc tính gì để có thể xác định nó là SPAM.
Độ đo P: Là phần trăm số tin nhắn SPAM được phân loại đúng.

Ví dụ 2: Chương trình nhận dạng số (số từ 0 -> 9)
T: Là nhận dạng được ảnh chứa ký tự số.
E: Đặc trưng để phân loại ký tự số từ tập dữ liệu số cho trước.
P: Độ chín xác của quá trình nhận dạng.

2. Các dạng Máy Học.
Máy học được phân làm 3 loại chính là: Học có giám sát (Supervised learning), học không giám sát (Unsupervised learning), học tăng cường (Reinforcement learning). Trong đó phổ biến nhất là 2 loại Supervised learning và Unsupervised learning. Riêng học tăng cường là một loại cải tiến từ các mô hình của học có giám sát.
Phần này sẽ giới thiệu về khái niệm và ứng dụng của Supervised learning và Unsupervised learning.

Supervised Learning
- Định nghĩa: Supervised Learning (SL) là một kĩ thuật học máy để học tập từ tập dữ liệu được gán nhãn cho trước. Tập dữ liệu cho trước sẽ chứa nhiều bộ dữ liệu. Mỗi bộ dữ liệu có cấu trúc theo cặp {x, y} với x được xem là dữ liệu thô (raw data) và y là nhãn của dữ liệu đó. Nhiệm vụ của SL là dự đoán đầu ra mong muốn dựa vào giá trị đầu vào. Dễ nhận ra, học có GIÁM SÁT tức là máy học dựa vào sự trợ giúp của con người, hay nói cách khác con người dạy cho máy học và giá trị đầu ra mong muốn được định trước bởi con người. Tập dữ liệu huấn luyện hoàn toàn được gán nhãn dựa vào con người. Tập càng nhỏ thì máy tính học càng ít.
SL cũng được áp dụng cho 2 nhóm bài toán chính là bài toán dự đoán (regression problem) và bài toán phân lớp (classification problem).
Kỹ thuật SL thực chất là để xây dựng một hàm có thể xuất ra giá trị đầu ra tương ứng với tập dữ liệu. Ta gọi hàm này là hàm h(x) và mong muốn hàm này xuất ra đúng giá trị y với một hoặc nhiều tập dữ liệu mới khác với dữ liệu được học. Hàm h(x) cần các loại tham số học khác nhau tùy thuộc với nhiều bài toán khác nhau. Việc học từ tập dữ liệu (training) cũng chính là tìm ra bộ tham số học cho hàm h(x).
- Ứng dụng: Các ứng dụng của SL có thể kể đến tương ứng với 2 dạng bài toán nêu trên như sau:
Bài toán dự đoán (regression problem): Bài toán dự đoán sẽ có đầu ra là một giá trị liên tục. Ví dụ: Bài toán dự đoán giá nhà, dự đoán xu hướng giá xăng, dự báo thời tiết....
Xét cụ thể bài toán dự báo giá nhà. Hãy đặt câu hỏi, đầu vào của bài toán và đầu ra của bài toán là gì?
Đầu vào là thông tin về nhà (diện tích, số phòng ngủ, gần đường hay không?, v.v..) và đầu ra là giá của ngôi nhà.
Tập dữ liệu để huấn luyện ở đây là thông tin có sẵn về nhà và giá của nó (có thể tự đi khảo sát để lấy thông tin hoặc dựa vào internet). Vì giá nhà là giá trị không thống nhất, có thể có nhiều giá trị thay đổi (giá trị liên tục) nên ta nói đây là bài toán dự báo.
Bài toán phân lớp (classification): Bài toán phân lớp sẽ có kết quả đầu ra cụ thể là các lớp được cho trước. Ví dụ bài toán nhận dạng ký tự số, bài toán phát hiện tin nhắn SPAM...
Xét cụ thể bài toán nhận dạng ký tự số thì khác với bài toán dự báo giá nhà, đầu ra của bài toán nhận dạng ký tự số chỉ là 10 lớp tương ứng với 10 số (từ 0 - 9). Các giá trị này là giá trị rời rạc.
Tập dữ liệu cũng tương tự như trên bài toán dự đoán, tuy nhiên giá trị đầu ra sẽ bị giới hạn bởi giá trị của các lớp cần phân loại. Trong trường hợp này y thuộc {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Unsupervised Learning
- Định nghĩa: Unsupervised Learning (UL) là một kĩ thuật của máy học nhằm tìm ra một mô hình hay cấu trúc bị ẩn bơi tập dữ liệu KHÔNG được gán nhãn cho trước. UL khác với SL là không thể xác định trước output từ tập dữ liệu huấn luyện được. Tùy thuộc vào tập huấn luyện kết quả output sẽ khác nhau. Trái ngược với SL, tập dữ liệu huấn luyện của UL không do con người gán nhãn, máy tính sẽ phải tự học hoàn toàn. Có thể nói, học KHÔNG GIÁM SÁT thì giá trị đầu ra sẽ phụ thuộc vào thuật toán UL.
- Ứng dụng: Ứng dụng phổ biến nhất của học không giám sát là gom cụm (cluster). Đương nhiên sẽ có nhiều ứng dụng khác, có cơ hội tôi sẽ đề cập thêm.
Ứng dụng này dễ nhận ra nhất là Google và Facbook. Google có thể gom nhóm các bài báo có nội dung gần nhau, hoặc Facebook có thể gợi ý kết bạn có nhiều bạn chung cho bạn.
Các bài báo có cùng nội dung sẽ được gom lại thành một nhóm (cluster) phân biệt với các nhóm khác. Dữ liệu huấn luyện là các bài báo từ quá khứ tới hiện tại và tăng dần theo thời gian. Dễ nhận ra rằng dữ liệu không thể gán nhãn bởi con người :)
Khi một bài báo mới được cho vào input, nó sẽ tìm cụm (cluster) gần nhất với bài báo đó và gợi ý những bài liên quan.
3. Máy Học và các ứng dụng thực tế.
Có rất nhiều ứng dụng mang tính thực tế cao của máy học mà khó có thể kể hết được. Những ứng dụng dưới đây là những ứng dụng phổ biến và được chọn lọc theo góc nhìn cá nhân. Hi vọng có thể truyền cảm hứng thêm cho đọc giả.
1. Nhận diện và phát hiện khuôn mặt: Nhận diện và phát hiện khuôn mặt là ứng dụng khá thú vị của máy học và được áp dụng khá nhiều vào đời sống. Tiêu biểu là tính năng phát hiện khuôn mặt ở máy chụp ảnh. Ứng dụng được phát triển thêm thành phát hiện chớp mắt, phát hiện cười....
2. Xe tự lái: Xe tự lái mặc dù phát triển từ đầu thập niên 90 nhưng cho tới nay vẫn còn là vấn đề được nhiều người quan tâm. Các hãng lớn như Google, NVDIA đang nỗ lực để tạo ra một cỗ máy có thể hoàn toàn tự động lái xe và giảm thiểu tai nạn cho con người.
3. Phân lớp ảnh: Tìm kiếm ảnh trên Google hiện rất quen thuộc với nhiều người. Ứng dụng của phân lớp ảnh giúp người dùng sử dụng ảnh làm từ khóa tìm kiếm thay thế cho việc tìm kiếm truyền thống trên Google. Bạn upload một ảnh lên và Google sẽ giúp bạn tìm kiếm những thông tin liên quan đến bức ảnh đó.
4. Nhận dạng giọng nói: Các trợ lý ảo như Siri, Conrtana hay Google Now là ví dụ điển hình cho nhận dạng giọng nói. Một ví dụ khác nữa là tính năng dịch thuật trực tuyến của Youtube. Với ứng dụng của Deep Learning, khả năng dịch thuật chín xác ngôn ngữ từ các video Youtube đang ngày một phát triển vượt bậc.
5. Anti-virus: Có thể nhiều người không nghĩ rằng các phần mềm diệt virus lại áp dụng máy học. Tuy nhiên, áp dụng máy học vào để phân tích và dự đoán xu hướng các loại virus sẽ giúp ích rất nhiều trong việc bảo vệ dữ liệu máy tính.

Còn rất rất nhiều ứng dụng thực tế của máy học nữa. Mong rằng bài viết này sẽ giúp các bạn hiểu hơn về Máy Học. Chúc các bạn thành công.
4. Nguồn trích dẫn
[1] Machine Learning là gì và tại sao nó lại quan trọng? - https://techmaster.vn/posts/33836/machine-learning-la-gi-tai-sao-machine-learning-lai-quan-trong
[2] Machine Learning Course by Andrew Ng - https://www.coursera.org/learn/machine-learning
[3] Machine Learning - https://en.wikipedia.org/wiki/Machine_learning

Tuesday, December 1, 2015

Kết nối Prolog với C# trên Visual Studio

1:52 PM Posted by Cáp Hữu Quân 9 comments
Prolog là một ngôn ngữ mạnh mẽ chuyên phục vụ cho Trí Tuệ Nhân Tạo và Xử Lý Ngôn Ngữ Tự Nhiên. Đôi lúc, chúng ta cũng phải kết hợp Prolog với các ngôn ngữ khác để tăng sự trực quan cho ứng dụng. Bài viết này sẽ đề cập đến việc kết nối C# vào Prolog để lấy kết quả trả về từ Prolog.

Vào chuyên môn luôn nào :)
Các yêu cầu để hỗ trợ kết nối:
1. Prolog phiên bản 32 bits 6.6.5
2. SwiPlCs: Thư viện kết nối C# và Prolog phiên bản 1.1.60605.0
3. Visual Studio bản 2008 trở lên.

2 phần mềm Prolog 32 bits 6.6.5 và SwiPlCs tương ứng có thể tải tại đây
Visual Studio thì các bạn tự cài nhé :)

Lưu ý: Vì thư viện SwiPlCs ngưng phát triển nên nó chỉ hỗ trợ phiên bản Prolog tương ứng là Prolog 32bits 6.6.5. Vậy nên, những ai đang chạy phiên bản Prolog khác thì phải gỡ và cài đúng bản 32 bits 6.6.5 thì mới kết nối được.

Sau khi chuẩn bị xong, ta sẽ đi qua bước kết nối.
Trong phần này, tôi sẽ demo để truy vấn 1 file prolog có nội dung như sau:


s-->np,vp.
np-->nn,pp.
np-->nnp.
np-->nn.
np-->nn,nn.
vp-->rb,vb,pp.
vp-->vb,pp.
vp-->rb,vb,np.
vp-->vb,vp.
vp-->vb,np.
pp-->in,nnp.
pp-->in,nn.
pp-->in,np.

nn-->[gia,đình].
nn-->[tỉnh].
nn-->[nhà].
nn-->[ngành].
nn-->[công,nghệ,thông,tin].
nn-->[thành,phố].
in-->[của].
in-->[ở].
nnp-->[nam].
vb-->[sống].
vb-->[học].
vb-->[về].
vb-->[thích].

rb-->[đang].
rb-->[thường].

Trước tiên, tạo 1 project Windows Form trên C# với giao diện như sau:

Form có tên là Demo_Prolog và lớp chính mang tên Demo_Prolog.cs. Hai button Load và Query dùng để mở file prolog và truy vấn sau khi đã gõ lệnh truy vấn. Sau đó ta Build project bằng cách chọn Build -> Build Solution hoặc nhấn tổ hợp phím tắt Ctrl + Shift + B.
Sau khi build thành công project, ta có thêm thư mục Debug trong thư mục bin của project.


Lúc này, ta copy toàn bộ file trong thư mục SwiPlCs_1.1.60605.0 vào thư mục Debug nêu ở trên của Project.
Tiếp theo là bước quan trọng nhất. Ta sẽ thêm thư viện SwiPlCs vào project bằng cách từ giao diện project của Visual Studio chọn chuột phải vào References --> Add references.... Sau đó chọn Browse... rồi trỏ tới thư mục Debug của project và thêm 2 file SwiPlCs.dll và nunit.framework.dll vào References

Sau khi thêm thư viện, sẽ tới phần code.
Ta tạo 1 class Connect_Prolog.cs để load file và kết nối với C#. Code như sau



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SbsSW.SwiPlCs;
using System.Text.RegularExpressions;
using NUnit.Framework;


namespace Connect_Prolog
{
    class ConnectProlog
    {
        //Load prolog file from hard disk
        public void Load_file(string s)
        {
            s = s.Replace("\\", "//");
            s = "consult('" + s + "')";
            string query = s.Replace("\\", "//");
            //string[] p = { "-q", "-f", query };
            //PlEngine.Initialize(p);
            try
            {
                PlQuery q = new PlQuery(query);
                Assert.IsTrue(q.NextSolution());
            }
            catch (SbsSW.SwiPlCs.Exceptions.PlException e)
            {
                System.Windows.Forms.MessageBox.Show(e.ToString(), "Error");
            }
        }

        // Prosessing a query
        public string Query(string s)
        {
            s.Trim();
            Regex r = new Regex(@"[A-Z_][a-zA-Z_]*");
            MatchCollection matches = r.Matches(s);
            string result = "";
            try
            {
                PlQuery q = new PlQuery(s);
                bool HasSolution = false;
                foreach (PlQueryVariables v in q.SolutionVariables)
                {
                    HasSolution = true;
                    foreach (Match match in matches)
                    {
                        result += v[match.ToString()].ToString() + " ; ";
                    }
                }
                if (matches.Count == 0)
                    return HasSolution ? "true" : "false";
                return result;
            }
            catch (SbsSW.SwiPlCs.Exceptions.PlException ex)
            {
                return "Error query: " + ex.Message;
            }
        }
    }
}

Tiếp theo trong file Demo_Prolog.cs có nội dung như sau:



using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using SbsSW.SwiPlCs;
using NUnit.Framework;
using Connect_Prolog;

namespace Demo_Prolog
{
    public partial class Demo_Prolog : Form
    {
        Connect_Prolog.ConnectProlog connect;
        public Demo_Prolog()
        {
            connect = new ConnectProlog();
            InitializeComponent();
        }

        private void btn_Load_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Filter = "Prolog file|*.pl";
            op.ShowDialog();
            String FilePath = op.FileName;
            connect.Load_file(FilePath);
            MessageBox.Show("Load file success !");
            this.btn_Query.Enabled = true;
        }

        private void btn_Query_Click(object sender, EventArgs e)
        {
            if (this.txt_Query.Text != null)
            {
                String s = connect.Query(this.txt_Query.Text);
                this.txt_Result.Text = s;
            }
            else
            {
                MessageBox.Show("Please enter query !");
            }
        }
    }
}

Phần quan trọng nhất là điều chỉnh môi trường trong file Program.cs. Nội dung file Program.cs như sau:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using SbsSW.SwiPlCs;
using NUnit.Framework;

namespace Demo_Prolog
{
    static class Program
    {
        /// 

        /// The main entry point for the application.
        /// 

        [STAThread]
        static void Main()
        {
            Environment.SetEnvironmentVariable("SWI_HOME_DIR", @"C:\Program Files (x86)\swipl");
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (!PlEngine.IsInitialized)
            {
                String[] empty_param = { "" };
                PlEngine.Initialize(empty_param);
                Application.Run(new Demo_Prolog());
                PlEngine.PlCleanup();
            }
        }
    }
}
Lưu ý: Environment.SetEnvironmentVariable("SWI_HOME_DIR", @"C:\Program Files (x86)\swipl"); dùng để set môi trường cho việc kết nối bằng cách trỏ tới thư mục cài Prolog. Phải điền đúng đường dẫn vào thư mục cài đặt Prolog tùy thuộc vào hệ máy (32 hoặc 64 bits).

Xong rồi, giờ hãy chạy demo để xem kết quả.
Câu khi truy vấn ta cho kết quả như sau:

Hi vọng bài viết có thể giúp đỡ được các bạn. Chúc các bạn thành công !

Tuesday, August 4, 2015

Cài Đặt Genymotion Trên Windows 10

12:49 AM Posted by Cáp Hữu Quân 3 comments
Những ai lập trình android thì có lẽ đã quen thuộc với Genymotion - Phần mềm giả lập máy ảo Android với ưu điểm cực kỳ nhanh gọn và hoàn toàn miễn phí.
Phần mềm này được ưa chuộng là bởi nó nhanh và nhẹ hơn so với Android Emulator của SDK.

GenyMotion hỗ trợ các phiên bản Windows từ Windows Vista. Tuy nhiên, khi lên Windows 10 thì gặp lỗi Unable to load VirtualBox Engine mặc dù đã cài VirtualBox đầy đủ.

Nguyên nhân là do bản VirtualBox không tương thích với Windows 10. Bạn cần tải về bản mới của VirtualBox trên trang chủ là bản VirtualBox 5.0 for Windows hosts hoặc cao hơn tại link sau:
https://www.virtualbox.org/wiki/Downloads
Sau khi cài vào máy bạn mở VirtualBox lên dưới quyền Administrator, sau đó vào mục File -> Preferences...-> Network hoặc nhấn Ctrl + G và chọn tab host-only Networks để vào giao diện tùy chỉnh cho Network Host.
Chọn tiếp Edit (Dấu cây cờ lê nhỏ bôi đỏ) để tùy chỉnh thông số cho host ảo.
Thông số các bạn tùy chỉnh như sau;
Adapter Tab:
    IPv4 Address:        192.168.1.201
    IPv4 Network Mask:   255.255.255.0
DHCP Server Tab:
    Server Address:      192.168.1.100
    Server Mask:         255.255.255.0
    Lower Address Bound: 192.168.1.101
    Upper Address Bound: 192.168.1.199

Sau khi tùy chỉnh xong thì nhấn OK và tắt chương trình VirtualBox. Lúc này khởi động Genymotion lại và xem kết quả :-) 
Chúc các bạn thành công !