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