You are on page 1of 26

ĐẠI HỌC QUỐC GIA TP.

HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC BÁCH KHOA
KHOA ĐIỆN – ĐIỆN TỬ
BỘ MÔN TỰ ĐỘNG
---------------o0o---------------

THỊ GIÁC MÁY TÍNH


Bài tập lớn 2

Nhận diện kí tự

GVHD: TS. Nguyễn Trọng Tài


SVTH: Trần Bá Phong - 1412895
Nguyễn Hữu Tài - 1413371

TP. HỒ CHÍ MINH, 4 THÁNG 12 NĂM 2017

1
Tóm Tắt
Bài tập lớn sẽ tập trung vào giải thuật Convolution Neural Network (CNN) để nhận
diện kí tự. Kí tự bao gồm từ 0-9, a-z và A-Z. OpenCV sẽ dùng để tiền xử lý ảnh ngõ
vào trước khi cho vào mạng neural.

2
Mục Lục
1. Giới thiệu ..................................................................................4
2. Lý thuyết ................................................................................... 4
2.1. Deep neural network ..............................................................4
2.2. Convolution neural network ..................................................7
2.3. Thuật toán cải thiện hiệu năng ............................................... 9
3. Giải thuật ................................................................................... 11
3.1. Tạo ảnh huấn luyện ................................................................11
3.2. Cấu trúc mạng CNN............................................................... 13
3.3. Hàm cost ................................................................................15
3.4. Thuật toán ..............................................................................16
4. Kết quả ......................................................................................24
5. Tài liệu tham khảo..................................................................... 26

3
1. Giới thiệu

Nhận diện kí tự được dùng phổ biến rộng rãi ngày nay, đặc biệt là ứng dụng vào
OCR(Optical Character Recognition). Với OCR, con người không cần phải đánh
văn bản hay nhập dữ liệu từ 1 văn bản hay đoạn văn, thay vào đó OCR sẽ giúp trích
xuất dữ liệu hình ảnh khi quét văn bản và tự động tạo ra văn bản y chang trên máy
tính.

Có nhiều phương pháp để nhận diện kí tự bao gồm PCA(Principal Component


analysis), LDA(Linear Discriminant Analysis), DNN(Deep Neural Network) hay
CNN(Convolutional Neural Network). Trong bài báo cáo này, CNN sẽ được dùng
làm phương pháp chính cho nhận diện kí tự vì độ chính xác cao và khả năng nhận
dạng được nhiều vật thể. Thuật toán này hiện nay đang được phát triển và nghiên
cứu rất nhiều trên thế giới cho nên việc dùng phương pháp này vào nhận diện kí tự
là 1 hướng đi đúng đắn.

2. Lý thuyết
2.1. Deep neural network

Neuron network mô phỏng mạng thần kinh neural giống như bộ não của con người.
Mỗi neuron tiếp nhận tín hiệu từ các neuron khác và xử lý đặc trưng theo từng neuron
đó và xuất ra kết quả cho các neuron khác để tiếp tục xử lý.

Hình 1. Mạng neuron điển hình 2 lớp

4
Mạng neuron này gồm 3 lớp. Lớp ngõ vào, một lớp ẩn và lớp ngõ ra. Ngõ vào gồm
3 đơn vị (unit), lớp ẩn gồm 3 unit và lớp ngõ ra chỉ có 1 unit.
()
Ta đặt là “activation” của unit i tại lớp j, ( ) là ma trận hệ số chuyển từ lớp j
sang lớp j+1. Ta có giá trị của các nút như sau:

( ) ( ) ( ) ( ) ( )
= ( + + + )
( ) ( ) ( ) ( ) ( )
= ( + + + )
( ) ( ) ( ) ( ) ( )
= ( + + + )

( ) ( ) ( ) ( ) ( )
ℎ( ) = = ( + + + )

Để có được những giá trị , ta cần phải dùng thuật toán backpropagation để tính đạo
hàm của hàm cost và sau đó dùng gradient descent để tính ra các theta.

Hàm cost cho mạng neural trên có công thức như sau:

1 () () () ()
( )=− log ℎ + 1− log 1 − ℎ

()
+ ( , )
2

()
Ta kí hiệu ℎ là ngõ ra của kth trong vector y

Số hạng đầu tiên là tổng của tất cả các node trong ngõ ra từ k = 1 -> K.
Số hạng thứ 2 là dùng cho regularization. Tổng đầu tiên là lặp tất cả các theta trong
mạng neuron, tổng thứ 2 và 3 là lặp lại các phần tử theta để cộng lại.
Thuật toán backpropagation

Forward propagation

5
Hình 2. Mạng neuron sâu
Ta sẽ dùng forward propagation trong backpropagation.
Ta làm theo các bước sau
=
=
= ( )
=
= ( )
=
= ( )
Backpropagation
Thuật toán backpropagation làm minimize hàm cost
()
Đặt = “sai số” của node j tại lớp l

Với mỗi node trong output y ( lớp 4 như hình trên)


( ) ( )
= −
( ) ( )
= ( ) .∗ .∗ (1 − )

6
( ) ( )
= ( ) .∗ .∗ (1 − )
() ( )
()
( ) = ,
,

Kết hợp lại , ta có thuật toán backpropagation:


. Đưa ra chuỗi thử { (x(1), y(1)), …., (x(m), y(m))}
()
. Đặt Δ , = 0

. for t = 1 : m
. Đặt a(1) = x
. Dùng thuật toán forward propagation để tính a(l)
() ( ) ( )
. Từ y(t) tính ngược lại , ,….,
() () () ( )
.TínhΔ , = Δ , +
()
. () ( )= ∗ Δ ,
,

Thuật toán backpropagation giúp ta tính được đạo hàm của hàm ( ). Sau đó ta dùng
gradient descent để tính giá trị của theta.

2.2. Convolution neural network


Convolution trong ảnh nghĩa là tích chập. Tích chập 2 ảnh với nhau theo cách sau.

3 0 1 2 7 4
1 5 8 9 3 1 -5 -4 0 8
2 7 2 5 1 3 1 0 -1
= -10 -2 2 3
0 1 3 1 7 8 1 0 -1
* 0 -2 -4 -7
4 2 1 6 2 8 1 0 -1
-3 -2 -3 -16
2 4 5 2 3 9

Để tích chập được 2 hình ảnh với nhau, lấy hình ảnh thứ 2 và di chuyển tâm điểm
của hình tại vị trí (2,2) và áp vào hình 1, rồi nhân 2 hình lại với nhau.

7
Ví dụ: -5 = 3 * 1 + 0*0 + 1*(-1) + 1*1 + 5*0 + 8*(-1) + 2*1 + 7*0 + 2*(-1). Sau đó,
ta di chuyển sang trái 1 bước, nhân hai hình lại với nhau và ra kết quả là -4. Cứ đi
đến hết hình ảnh. Ta được kết quả hình bên phải.

Một mạng CNN điển hình

Hình 3. Mạng CNN Lenet-5


Một mạng CNN điển hình sẽ có lớp Convolution, lớp Pooling, lớp Full-Connected
và lớp ngõ ra.
Lớp Convolution sẽ dùng 1 mặt nạ ảnh có kích thước (nw,nh,nc,nc0), nw và nh là
chiều rộng và chiều cao của ảnh ngõ vào, nc là chiều sâu của ngõ vào, nc0 là chiều
sâu của mặt nạ. Lớp Convolution sẽ giảm kích cỡ của ảnh ngõ vào đi theo công thức
ℎ+2 − +2 −
( ℎ1, 1) = [ + 1, + 1]

Với nh, nw là chiều rộng và chiều cao của ngõ vào, p là số padding(padding tức thêm
0 vào các bên của ảnh ngõ vào), f là kích thước của mặt nạ, và s là stride (stride là
số trượt của mặt nạ trên ảnh).
Lớp Pooling có chức năng sẽ làm giảm kích cỡ của ngõ vào giống như lớp
Convolution, đồng thời trích xuất được đặc trưng của ảnh. Như trong hình, avg pool
sẽ lấy trung bình các giá trị của ảnh mà nó chọn. Thông thường, lớp pooling phổ
biến là lớp max pooling, tức lấy giá trị lớn nhất của ngõ vào, loại bỏ các giá trị nhỏ
đi.
Lớp Full Connected(FC) như bên phần Deep Neural Network, ngõ vào FC sẽ phải
lấy tất cả các pixels của ảnh ngõ vào và trải thành 1 cột. Lớp FC cuối cùng sẽ có
tổng ngõ ra bằng với số lớp cần nhận dạng. Lớp FC sẽ áp dụng forward propagation
và back-propagation để học các weights giữa các lớp.

8
2.3. Thuật toán cải thiện hiệu năng
a. Bộ dữ liệu Train/Test

Khi sử dụng mạng neural network làm phương pháp nhận diện, ta phải có 2 bộ dữ
liệu chính là tập huấn luyện và tập kiểm tra. 2 tập này được chia theo 90%/10% của
tổng bộ dữ liệu. Có 2 bộ này để ta có thể kiểm tra được độ chính xác của thuật toán,
kiểm tra được bias và variance, sau đó có thể hiệu chỉnh được các thông số của cả
hệ thống.

b. Bias và Variance
Bias và Variance là 2 thuật ngữ chỉ sai số của thuật toán. Khi thuật toán dự đoán
không chính xác thì hiện tượng bias xảy ra, khi thuật toán dự đoán rất chính xác tập
dữ liệu huấn luyện thì hiện tượng variance xảy ra.

Hình 4. Hiện tượng bias

Khi hiện tượng bias xảy ra như trong hình thì ta thấy đường dự đoán không chia
được chính xác 2 vùng miền đỏ và đen.

9
Hình 5. HIện tượng variance
Khi hiện tượng variance xảy ra thì ta thấy đường dự đoán chính xác 2 vùng miền.
Tuy nhiên, khi cho giá trị mới vào thì sẽ chưa chắc dự đoán đúng được vì ta chỉ đang
thực hiện trên tập huấn luyện chứ chưa thực hiện được tổng quát nhất.

Hình 6. Dự đoán hợp lý nhất


Khi thuật toán không chịu bias hoặc variance thì sẽ cho ta ra kết quả hợp lý nhất, gọi
là just right. Mặc dù với mẫu thử có 1 vài sai số nhưng nó sẽ là tổng quan nhất cho
tất cả các mẫu dữ liệu
c. Regularization
Regulariazation là 1 phương pháp để tránh High variance. Regularization sẽ áp dụng
vào hàm Cost và hệ số weights của mạng CNN và DNN.

10
1 ( ), ()
( , ) = + ‖ ‖
2

[] [] [ ] []
= . +
[ ] [] []
= −
d. Dropout

Hình 7. Dropout

Dropout là 1 phương pháp để loại bỏ bớt các nút trong mạng neural. Khi loại bỏ
các nút thì ngõ ra sẽ ít bị phụ thuộc vào các nút hơn, nó sẽ theo giá trị của ngõ
vào. Dropout sẽ giám overfitting, số lượng nút được tinh chỉnh bởi hệ số
keep_prob và thường dao động trong khoảng 0.5 – 0.9.

3. Giải thuật
3.1. Tạo ảnh huấn luyện
Ảnh huấn luyện gồm 62 chữ cái từ 0-9, a-z và A-Z, mỗi ảnh có kích thước là
128x128, định dạng png, nền trắng, chữ đen. Mỗi kí tự trung bình có trên 3000 ảnh,
được lấy từ nguồn https://www.nist.gov/srd/nist-special-database-19.

11
Hình 8. 62 thư mục chứa bộ ảnh huấn luyện

Sau khi có được ảnh huấn luyện, ta sẽ chạy file load_data.py để lấy ảnh huấn luyện
và lưu vào 1 file, chỉ toàn hệ số của ảnh đã được tối ưu hóa.
Đoạn code load_data

def load_data():
global count

for i in ['A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','white',
['a','b','c','d','e','f','g','h','i','j','k','l',
'm','n','o','p','q','r','s','t','u','v','w_','x','y','z',
0,1,2,3,4,5,6,7,8,9]
for z in all_directories:
output_vector = np.zeros((63,1))
path = parent_path + '/' + z

if z.startswith(str(i)) and os.path.isdir(path):

total_files = len(os.listdir(path))
if total_files <= 2000:
training_files = int(90/100 * total_files)
test_files = total_files - training_files
else:
training_files = int(90/100 * 2000)
test_files = 2000 - training_files
lim = 0
for file_name in os.listdir(path):
tva = imageprepare(path + '/' + file_name)
input_image = np.array(tva)

12
input_image = input_image.reshape(32,32,1)
if lim < training_files:
training_inputs.append(input_image)
output_vector[count] = 1
training_outputs.append(output_vector)
elif lim < training_files + test_files:
test_inputs.append(input_image)
output_vector[count] = 1
test_outputs.append(output_vector)
else:
break
lim += 1
count += 1

return training_inputs, training_outputs, test_inputs, test_outputs

Đoạn code trên sẽ lấy 2000 mẫu của mỗi kí tự, 90% sẽ làm training và 10% để làm
test. Trước khi ảnh được lưu vào file tương ứng, ảnh sẽ được resize thàng 32x32,
đồng thời, giá trị pixel được chuẩn hóa từ 0 đến 1.

3.2. Cấu trúc mạng CNN

CONV Max Pool CONV

f=4 f=4 f=2


“SAME” “SAME” “SAME”
32x32x1

FC Soft-max
Max Pool FC

f=4
“SAME”
63x1
256x1

512x1

13
Mạng CNN bao gồm 2 lớp Convolution, 2 lớp Max-Pooling, 2 lớp Full Connected
và 1 lớp Soft-max để có giá trị ngõ ra. Lớp ngõ vào chỉ có 32x32x1, giá trị pixel
trong khoảng 0-1.
Đoạn code cho CNN
def forward_propagation(X, keep_prob):
tf.set_random_seed(1)
# CONV 1
W1 = tf.get_variable("W1", [4,4,1,64], initializer =
tf.contrib.layers.xavier_initializer(seed = 0))
b1 = tf.get_variable("b1", [64,1], initializer = tf.zeros_initializer())
Z1 = tf.nn.conv2d(input = X, filter = W1, strides = [1,1,1,1], padding = "SAME")
A1 = tf.nn.relu(Z1)
# MAX POOL 1
P1 = tf.nn.max_pool(A1, ksize = [1,4,4,1], strides = [1,4,4,1], padding = "SAME")
# CONV 2
W2 = tf.get_variable("W2", [2,2,64,128], initializer =
tf.contrib.layers.xavier_initializer(seed = 0))
b2 = tf.get_variable("b2", [128,1], initializer = tf.zeros_initializer())
Z2 = tf.nn.conv2d(input = P1, filter = W2, strides = [1,1,1,1], padding = "SAME")
A2 = tf.nn.relu(Z2)
# MAX POOL 2
P2 = tf.nn.max_pool(A2, ksize = [1,4,4,1], strides = [1,4,4,1], padding = "SAME")
# FLATTEN
P2 = tf.contrib.layers.flatten(P2)
# FULL CONNECT 1
W3 = tf.get_variable('W3', [512, P2.shape[1:2].num_elements()], initializer =
tf.contrib.layers.xavier_initializer(seed=0))
b3 = tf.get_variable('b3', [512,1], initializer = tf.zeros_initializer())
Z3 = tf.add(tf.matmul(W3,tf.matrix_transpose(P2)), b3)
A3 = tf.nn.relu(Z3)
14
# FULL CONNECT 2
W4 = tf.get_variable('W4', [256, 512], initializer =
tf.contrib.layers.xavier_initializer(seed=0))
b4 = tf.get_variable('b4', [256,1], initializer = tf.zeros_initializer())
A4_drop = tf.nn.dropout(A3, keep_prob)
Z4 = tf.add(tf.matmul(W4,A4_drop), b4)
A4 = tf.nn.relu(Z4)
# FULL CONNECT 3
W5 = tf.get_variable('W5', [63,256], initializer =
tf.contrib.layers.xavier_initializer(seed=0))
b5 = tf.get_variable('b5', [63,1], initializer = tf.zeros_initializer())
A5_drop = tf.nn.dropout(A4, keep_prob)
Z5 = tf.add(tf.matmul(W5,A5_drop), b5)
Z5 = tf.matrix_transpose(Z5)
return Z5

Mạng neural trên dùng thư viện Tensor flow để viết vì sự phức tạp của back-
propagation khi dùng để hiệu chỉnh các hệ số trong mặt nạ mask và hệ số weight của
lớp Full Connected.
3.3. Giá trị hàm Cost

def compute_cost(Z3, Y):


cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = Z3, labels =
Y))

return cost

Hàm cost cho ta được sai số của ngõ vào khi qua CNN so với ngõ ra được đánh dấu
sẵn do ta chỉ định. Hàm cost dùng softmax với logits là ngõ ra của CNN và labels là
do ta đánh dấu ngõ ra của ngõ vào. Hàm cost trong tensor flow sẽ tự động optimize
theo các weight mà không cần phải viết back-propagation.

15
3.4. Thuật toán
Bước 1. Load data từ file load_data.py
if __name__ == "__main__":
training_inputs, training_outputs, test_inputs, test_outputs = load_data()
np.save('training_inputs.npy', training_inputs)
np.save('training_outputs.npy', training_outputs)
np.save('test_inputs.npy', test_inputs)
np.save('test_outputs.npy', test_outputs)

Đoạn code sử dụng hàm load_data() như đã giải thích ở trên, sau khi chạy xong, sẽ
lưu ra 4 file bao gồm training_inputs.npy, training_outputs.npy, test_inputs.npy và
test_outputs.npy.
Bước 2. Chạy model từ file edit_cnn.py
def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.001, keep_prob_prob = 1,
num_epochs = 400, minibatch_size = 64, print_cost = True):

ops.reset_default_graph()
tf.set_random_seed(1)
seed = 3
m, n_H0, n_W0, n_C0 = X_train.shape
n_y = Y_train.shape[1]
costs = []

X, Y, keep_prob = create_placeholders(n_H0, n_W0, n_C0, n_y)

Z3 = forward_propagation(X, keep_prob)

cost = compute_cost(Z3, Y)

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

init = tf.global_variables_initializer()

with tf.Session() as sess:

sess.run(init)

for epoch in range(num_epochs):

16
minibatch_cost = 0
num_minibatches = int(m / minibatch_size)
seed = seed + 1
minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

for minibatch in minibatches:

minibatch_X, minibatch_Y = minibatch

_, temp_cost = sess.run([optimizer, cost], {X:minibatch_X, Y:minibatch_Y,


keep_prob :keep_prob_prob})
minibatch_cost += temp_cost / num_minibatches

if print_cost == True:
print("Cost after epoch %i %f" %(epoch, minibatch_cost))
costs.append(minibatch_cost)

plt.plot(np.squeeze(costs))
plt.ylabel('cost')
plt.xlabel('iterations (per tens)')
plt.title("Learning rate = " + str(learning_rate))
plt.show()
saver = tf.train.Saver()
saver.save(sess, 'my-model.ckpt')

predict_op = tf.argmax(Z3, 1)
correct_prediction = tf.equal(predict_op, tf.argmax(Y,1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))


print(accuracy)
train_accuracy = accuracy.eval({X: X_train, Y: Y_train, keep_prob:
keep_prob_prob})
test_accuracy = accuracy.eval({X: X_test, Y: Y_test, keep_prob: keep_prob_prob})
print("Train Accuracy:", train_accuracy)
print("Test Accuracy:", test_accuracy)

return None

Giải thích thuật toán

17
Trước tiên, ta sẽ lấy được kích thước của X và Y, lưu vào m, n_H0, n_W0, n_C0 để
tạo placeholder trong Tensor-flow. Khi được X,Y và keep_prob để dùng tối ưu bằng
dropout, ta sẽ cho vào mạng CNN bằng câu lệnh

Z3 = forward_propagation(X, keep_prob)

Sau đó ngõ ra sẽ được tính hàm Cost bằng đoạn lệnh:

cost = compute_cost(Z3, Y)

Khi tính hàm Cost xong, ta sẽ dùng thuật toán tối ưu để tối ưu hàm Cost, đồng thời,
thuật toán tự tinh chỉnh các hệ số của mạng neural mà ta không cần viết. Thuật toán
này dùng AdamOptimizer để tinh chỉnh tối ưu.

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

Sau khi xong, ta sẽ tạo Session trong Tensorflow để chạy và bắt đầu chạy vòng lặp
sau đây:

for epoch in range(num_epochs):

minibatch_cost = 0
num_minibatches = int(m / minibatch_size)
seed = seed + 1
minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

for minibatch in minibatches:

minibatch_X, minibatch_Y = minibatch

_, temp_cost = sess.run([optimizer, cost], {X:minibatch_X, Y:minibatch_Y,


keep_prob :keep_prob_prob})
minibatch_cost += temp_cost / num_minibatches

if print_cost == True:
print("Cost after epoch %i %f" %(epoch, minibatch_cost))
costs.append(minibatch_cost)

plt.plot(np.squeeze(costs))

18
plt.ylabel('cost')
plt.xlabel('iterations (per tens)')
plt.title("Learning rate = " + str(learning_rate))
plt.show()
saver = tf.train.Saver()
saver.save(sess, 'my-model.ckpt')

Num_epochs trong đoạn code trên là số lần lặp, thông thường càng nhiều lần lặp thì
hàm Cost sẽ giảm được sai số tuy nhiên sẽ mất nhiều thời gian. Ta sẽ không dùng
hết tất cả các mẫu để chạy mà sẽ chạy từng 1 bộ theo số batch_size, ở đây ta sử dụng
Mini Batch Gradient Descent, với mỗi lần lặp sẽ lấy 64 mẫu chạy, trước khi chạy sẽ
shuffle để lấy random các mẫu. Với mỗi mini batch, ta sẽ chạy trong vòng lặp:
for minibatch in minibatches:

minibatch_X, minibatch_Y = minibatch

_, temp_cost = sess.run([optimizer, cost], {X:minibatch_X, Y:minibatch_Y,


keep_prob :keep_prob_prob})
minibatch_cost += temp_cost / num_minibatches

Với mỗi vòng lặp, ta sẽ tính hàm cost và cộng dồn với nhau. Sau khi chạy xong hết
mẫu, ta sẽ lưu vào biến costs để vẽ hàm cost theo vòng lặp.

Hình 9. Giá trị hàm Cost theo số vòng lặp


19
Ta thấy trên hình thì sau mỗi vòng lặp, giá trị hàm Cost sẽ giảm.
Sau khi chạy xong, ta sẽ dùng 2 đoạn lệnh sau để lưu session vào 1 file. Từ đó, ta có
thể load lại session này và chạy phần dự đoán sau đó.

saver = tf.train.Saver()
saver.save(sess, 'my-model.ckpt')

Bước 3. Kiểm tra kết quả


Đoạn code khi kiểm tra
if __name__ == "__main__":
cap = cv2.VideoCapture(0)
tf.set_random_seed(1)
seed = 3
m, n_H0, n_W0, n_C0 = 1, 32, 32, 1
X, Y, keep_prob = create_placeholders(n_H0, n_W0, n_C0, 63)
Z3 = forward_propagation(X, keep_prob)
init = tf.global_variables_initializer()
saver = tf.train.Saver()
new_saver = tf.train.import_meta_graph('my-model.ckpt.meta')

while True:
ret,frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame = preprocess(frame)

cv2.imshow('draw', frame)
cv2.imwrite('draw.jpg', frame)

#tva = imageprepare(Image.fromarray(frame))
tva = imageprepare('draw.jpg')

20
image = np.array(tva)
np.save('frame.npy', image)

cv2.imshow('love', image.reshape(n_H0,n_W0,1))

#print(image.shape)
image = image.reshape(1,n_H0,n_W0,1)
prediction = tf.argmax(Z3, 1)

with tf.Session() as sess:


sess.run(init)
new_saver.restore(sess, tf.train.latest_checkpoint('./'))
result = sess.run(prediction, feed_dict = {X:image, keep_prob:0.9 })
draw(result)

cv2.waitKey(1)

Giải thích đoạn code:


Trước hết, chúng ta cũng lấy các kích thước của ngõ vào, ngõ ra để tạo placeholder.
Những bước này phải giống với phần chạy CNN, nếu không thì khi load phần session
được lưu sẽ bị lỗi. Sau đó thì load phần session đã lưu khi huấn luyện vào bằng 2
dòng code sau:
saver = tf.train.Saver()
new_saver = tf.train.import_meta_graph('my-model.ckpt.meta')

Sau đó, sẽ cho vòng lặp vô hạn, mỗi vòng lặp sẽ dùng openCV để lấy 1 frame ảnh,
và xử lý như khi load data từ bộ dữ liệu:
ret,frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame = preprocess(frame)

21
Tiếp tục, ta sẽ tạo prediction là phần tử cao nhất của ngõ ra Z3 từ
forward_propagation.
prediction = tf.argmax(Z3, 1)

Sau đó, ta sẽ tạo session, và restore session đã lưu khi huấn luyện và dự đoán kết
quả ngõ ra

with tf.Session() as sess:


sess.run(init)
new_saver.restore(sess, tf.train.latest_checkpoint('./'))
result = sess.run(prediction, feed_dict = {X:image, keep_prob:0.9 })
draw(result)

Hàm draw như sau:


def draw(result):
a = result[0]
print('------')
if a<=9:
print(a)
if a >= 10 and a <= 35:
print(chr(a+87))
else:
print(chr(a+29))

Hàm draw sẽ chuyển từ giá trị 0-63 thành giá trị các chữ số tương ứng.

22
4. Kết quả

Hình 10. Kết quả nhận diện kí tự Z

Nhìn từ trên hình, ta thấy khi kí tự là Z, thì phần terminal hiện lên chữ Z. Chữ này
có thể là z thường hoặc Z hoa. Khi nhận dạng dùng CNN không thể biết được các
dáng chữ giống nhau là chữ thường hay chữ hoa( ví dụ như z,Z, o,O, w,W).

23
Hình 10. Kết quả nhận diện kí tự q

Kí tự q được nhận diện chính xác. Q hoa và q thường là khác nhau nên không khó
để CNN có thể nhận dạng kí tự này.

24
Hình 12. Kết quả nhận diện số 3

Kết quả nhận diện số 3 cũng chính xác.

Kết quả của 3 hình này được dựa vào dữ liệu chung của các kí tự từ 0-9, a-z và A-
Z. Kết quả này sẽ chính xác hơn nữa nếu dùng dữ liệu nhiều hơn và số lần lặp tăng
lên. Việc sử dụng nhiều dữ liệu để huấn luyện sẽ gây giới hạn lên máy tính vì máy
tính yếu thì không thể chạy được nhiều dữ liệu, máy sẽ bị lổi memory. Cho nên 1
cách tốt nhất khi huấn luyện trên máy yếu là sử dụng ít dữ liệu và cho vòng lặp chạy
nhiều.

25
5. Tài liệu tham khảo
[1] Michael Nielsen (Aug 2017), Neural networks and Deep learning
[Online]. Available: http://neuralnetworksanddeeplearning.com/index.html

[2] Rafael C. Gonzalez and Richard E. Woods, Digital Image Processing(2nd


Edition), Pearson, 2002.
[3] Convolution Neural Network – Coursera[Online]. Available:
https://www.coursera.org/learn/convolutional-neural-networks/home/welcome
[4] Jan Erik Solem(June 2012), Programming Computer Vision with Python:
Tools and algorithms for analyzing images. O’Reilly Media; 1st edition
[5] Ian Goodfellow, Yoshua Bengio, Aaron Courville, Deep Learning(Adaptive
Computation and Machine Learning series). The MIT Press(November 2016)

26

You might also like