12/08/2018, 17:13

Sử dụng CNN trong bài toán nhận dạng mặt người ( Phần 2 )

Ở phần trước mình đã giới thiệu qua về thuật toán CNN, phần này hãy cùng áp dụng nó vào bài toán nhận dạng mặt người. Cài đặt môi trường Để thực hiện, mọi người cần cài đặt môi trường như sau: Python 3.6: https://www.python.org/downloads/ pip3: sudo apt install python3-pip NumPy, Pandas, ...

Ở phần trước mình đã giới thiệu qua về thuật toán CNN, phần này hãy cùng áp dụng nó vào bài toán nhận dạng mặt người.

Cài đặt môi trường

Để thực hiện, mọi người cần cài đặt môi trường như sau:

  • Python 3.6: https://www.python.org/downloads/
  • pip3: sudo apt install python3-pip
  • NumPy, Pandas, Matplotlib, Scikit-Learn: pip3 install --upgrade matplotlib numpy pandas scipy scikit-learn
  • opencv3: http://embedonix.com/articles/image-processing/installing-opencv-3-1-0-on-ubuntu/
  • Tensorflow: https://www.tensorflow.org/install/install_linux

Chuẩn bị dataset và tạo tập train + test

Về cơ bản, chúng ta sẽ chia tập dữ liệu thành 2 tệp, 1 tệp gồm các ảnh có xuất hiện mặt người, tệp còn lại bao gồm các ảnh không có mặt người. Bạn có thể tham khảo dataset có chứa mặt người tại đây: https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge/data Sau khi đã chuẩn bị xong dataset, tiến hành tạo tập train + test:

import tensorflow as tf
import cv2,os
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split

n_classes=2
path_pos='data/Face/Positive' # tập dữ liệu chứa mặt người 
path_neg='data/Face/Negative' # tập dữ liệu không chứa mặt người

def read_data(path,label):
    images = []
    labels = []
    dirs = os.listdir( path )
    for files in dirs:
        file_name=path+"/"+files
        image = cv2.imread(file_name,0)
        image=np.reshape(image, 40*100)
        images.append(image)
        labels.append(label)  
    return images, labels

images_pos,labels_pos=read_data(path_pos,1)
images_neg,labels_neg=read_data(path_neg,0)

images=images_pos+images_neg
labels=labels_pos+labels_neg

x_train, x_test,y_train,y_test = train_test_split(images, labels,test_size=0.1, random_state=41)

x_train=np.asarray(x_train)
y_train=np.asarray(y_train)

Thiết lập mạng CNN

Thông thường, một CNN gồm một stack các convolutional module, mỗi một module thực hiện việc extract feature. Mỗi module cũng bao gồm một convolutional layer theo sau là một pooling layer. Module convolutional cuối cùng bao gồm một hoặc nhiều các dense layer thực hiện việc phân lớp. Layer dense cuối cùng trong một CNN bao gồm một single node cho mỗi một lớp cụ thể trong model (tất cả các class khả thi mà model có thể dự đoán được). Với mỗi một node, ta sử dụng hàm kích hoạt softmax để generate ra giá trị predict (từ 0 - 1). Cụ thể như sau:

def conv_net(x):
    x = tf.reshape(x, shape=[-1, 28, 28, 1]) # input layer, image size input có kích thước 28x28
    conv1 = tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu,padding="SAME") # convolutional layer 1 
    conv1 = tf.layers.max_pooling2d(conv1, 2, 2,padding="SAME") # pooling layer 1
    conv2 = tf.layers.conv2d(conv1, 64, 5, activation=tf.nn.relu,padding="SAME") # convolutional layer 2
    conv2 = tf.layers.max_pooling2d(conv2, 2, 2,padding="SAME") # pooling layer 2
    
    # tạo dense layer
    fc1 = tf.contrib.layers.flatten(conv2)
    fc1 = tf.layers.dense(fc1, 512,activation=tf.nn.relu)
    out = tf.layers.dense(fc1, num_classes,name="output")
    
    return out

Như vậy, ta đã tạo được một hàm chung cho việc xây dựng mạng CNN. Tiếp theo, ta sẽ optimize mạng CNN bằng Adam optimizer:

Tìm correct và accuracy để đánh giá độ chính xác của mạng CNN.

x = tf.placeholder(tf.float32, [None, n_input],name="x")
y = tf.placeholder(tf.int32, [None],name="y")
pred = conv_net(x)

xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=pred, labels=y)
cost = tf.reduce_mean(xentropy)

optimizer = tf.train.AdamOptimizer()
training_op=optimizer.minimize(cost)

correct = tf.nn.in_top_k(pred, y, 1)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
init = tf.global_variables_initializer()

Thực hiện optimize

# Parameters
learning_rate = 0.001
batch_size = 20
display_step = 10
num_steps=200
# Network Parameters
n_input = 4000 
num_classes=2

def random_batch(x_train, y_train, batch_size):
    rnd_indices = np.random.randint(0, len(x_train), batch_size)
    x_batch = x_train[rnd_indices]
    y_batch = y_train[rnd_indices]
    return x_batch, y_batch


saver = tf.train.Saver()
sess= tf.Session() 
sess.run(init)
for step in range(1, num_steps+1):
    batch_x, batch_y = random_batch(x_train, y_train, batch_size)
    sess.run(training_op, feed_dict={x: batch_x, y: batch_y})
    if step % display_step == 0 or step == 1:
        acc = sess.run( accuracy, feed_dict={x: x_train,y: y_train})
        print('Step:',step, ', Accuracy:',acc)

print("Optimization Finished!")

Kết quả sau khi optimize:

  • Step: 1 , Accuracy: 0.525926
  • Step: 10 , Accuracy: 0.898413
  • Step: 20 , Accuracy: 0.660317
  • Step: 30 , Accuracy: 0.857143
  • Step: 40 , Accuracy: 0.928042
  • Step: 50 , Accuracy: 0.967196
  • Step: 60 , Accuracy: 0.982011
  • Step: 70 , Accuracy: 0.98836
  • Step: 80 , Accuracy: 0.991534
  • Step: 90 , Accuracy: 0.991534
  • Step: 100 , Accuracy: 0.990476
  • Step: 110 , Accuracy: 0.991534
  • Step: 120 , Accuracy: 0.990476
  • Step: 130 , Accuracy: 0.996825
  • Step: 140 , Accuracy: 0.997884
  • Step: 150 , Accuracy: 1.0
  • Step: 160 , Accuracy: 0.998942
  • Step: 170 , Accuracy: 0.997884
  • Step: 180 , Accuracy: 0.998942
  • Step: 190 , Accuracy: 1.0
  • Step: 200 , Accuracy: 1.0
  • Optimization Finished!

Vì mình thực hiện demo optimize nên để các param thấp nên optimize đạt kết quả cao, trong thực tế, lượng data lớn đòi hỏi batch_size , step rất lớn             </div>
            
            <div class=

0