Part 1: Optical Character Recognition with TensorFlow and Keras

Sasiwut Chaiyadecha
4 min readDec 8, 2020

--

ไม่ได้ทำ Deep learning มานานแล้ว รู้สึกว่าไปเขียนเรื่องราวเกี่ยวกับ Stat ค่อนข้างเยอะ มันเกี่ยวข้องกับโปรเจคที่ทำอยู่ช่วงนี้ ทำให้ต้องยุ่งเกี่ยวกับ Stat อยู่พอสมควรเลย ยังมีอีกหลาย Networl model ที่ยังไม่ได้ลองทำ แต่ Blog ตอนนี้ได้แรงบันดาลใจจากซีรีส์เกาหลีเรื่อง Start-Up ที่กำลังดังมาก ๆ อยู่ใน Netflix ตอนนี้ (ฉายจบแล้ว)

Optical Character Recognition with TensorFlow and Keras startup

ขอสปอยด์เนื้อหาในซีรีส์บ้างเล็กน้อย

“ในซีรีส์ฉากที่ทีมบริษัทของพระเอกต้องสร้างโมเดลให้ประทับคณะกรรมการ เพื่อชิงเงินลงทุนสำหรับ Project startup จำนวน 100 ล้านวอน ทีมของพระเอกเลือกที่ข้อมูลลายมือ นำมาสร้างโมเดลเพื่อหาว่าลายมือนั้นเป็นของจริงหรือของปลอม”

ไม่ต้องทำโมเดลให้เหมือนกันในซีรีส์ก็ได้ เพราะจากความรู้ตอนนี้คงอีกยาวไกลกว่าจะเดินทางถึงขั้นนั้น วันนี้ขอเริ่มต้นสั้น ๆ ก่อน โดยเริ่มจากการทำ Optical Character Recognition

Optical Character Recognition

Optical Character Recognition with TensorFlow and Keras

Optical Character Recognition หรือที่เรียกกันอย่างย่อว่า OCR มันเป็นการอ่านตัวอักษรด้วยแสง ซึ่งสามารถอ่านข้อความที่เกิดจากการพิมพ์หรือเขียน ให้กลายเป็นข้อมูล Digital ซึ่งถูกเก็บอยู่ในรูปแบบตัวเลข

ณ ตอนนี้มี Application ในเชิงการทำงานในรูปแบบ OCR เยอะมาก มากไปกว่านี้แต่ละตัวมีความเก่งกาจจนการ Training model เองอาจไม่เรื่องจำเป็นอีกต่อไป แต่ไม่เป็นไร ถือว่าเป็นการเรียนรู้โมเดลในอีกรูปแบบ

Optical Character Recognition with TensorFlow and Keras line
ตัวอย่าง ocr บน application line

Dataset

เริ่มต้นจากแนวคิดที่ง่ายที่สุดก่อน การที่จะรู้จำตัวอักษรได้ โมเดลจำเป็นต้องมีข้อมูลที่เป็นตัวอักษรก่อน หลายคนอาจคุ้นเคยดีเกี่ยวกับ MNIST Dataset ที่เก็บข้อมูลลายมือเขียนตัวเลข 0–9 จำนวน 70,000 รูป ซึ่งถูกนำมาใช้เป็นแบบฝึกหัดในเรียนรู้โมเดลกันอย่างแพร่หลาย ซึ่งสามารถอ่านข้อมูลเพิ่มเติมได้จาก Link ด้านล่าง

ต่อมาคือข้อมูลตัวหนังสือที่ต้องใช้ ครั้งนี้ขอเริ่มจากภาษาอังกฤษก่อน เพราะมีความง่ายกว่าภาษาไทยอยู่พอสมควร โชคดีที่ข้อมูลตัวหนังสือ A-Z มีคนทำไว้ให้เป็นไฟล์ CSV อย่างเป็นระเบียบอยู่ใน Kaggle ซึ่งสามารถโหลดได้จาก Link ด้านล่าง

Data processing

แม้ว่าข้อมูลที่ใช้ในวันนี้ถูกทำเอาไว้เป็นอย่างดีแล้ว (เทียบกับโมเดลก่อน ๆ) แต่ยังมีความจำเป็นต้องทำ Data processing สำหรับ Neural network

เนื่องจาก MNIST Dataset สามารถโหลดได้โดยตรงจาก tensorflow.keras.datasets อยู่แล้ว ดังนั้นข้อมูลที่ต้อง Download เหลือแค่ A-Z Dataset ยังมีความโชคดีอยู่ เนื่องจากข้อมูล A-Z ถูกเก็บไว้บน Kaggle ดังนั้นจึงสามารถใช้ Kaggle API โหลดมาไว้ที่ Google ได้โดยตรงเลย ส่วนวิธีการใช้งาน API เคยสอนไว้ที่ Link นี้แล้ว

ตัวอย่าง code ที่ใช้งานใร download data จาก kaggle
Tensorflow version: 2.3.0
GPU is available

Import libraries ที่จำเป็นในการสร้าง OCR Model แต่ว่าตอนนี้คงยังไม่ได้แตะต้อง TensorFlow และ Keras มากนัก เพราะตั้งใจไว้ว่าจะจบถึงแค่ Data processing ที่ใช้งาน Numpy เป็นหลัก

Total rows: 372450, Total columns: 785

อธิบายข้อมูล A-Z เพื่อให้เข้าใจมิติของข้อมูลมากขึ้น ข้อมูลมีทั้งหมด 372,450 Rows และ 785 Columns โดยข้อมูลแต่ละแถวรูปภาพตัวอักษร 1 ตัว ดังนั้น Column แรกจึงบ่งบอกตัวอักษร A ไปจนถึง Z ถูกเก็บด้วยเลข 0–25 (A = 0, …, Z = 25) ส่วน Columns ที่เหลือเป็นรูปภาพที่ถูกเก็บ Array number ขนาด 784 ดังนั้นรูปภาพจึงมีขนาดเท่ากับ 28 x 28 = 748 จาก Data structure แบบนี้ ทำให้สามารถออกแบบโปรแกรมเพื่อเก็บค่าให้เป็น Array สำหรับการ Training ได้

เก็บตัวแปรแยกกันระหว่างตัวหนังสือและรูปภาพ ประกาศ List ว่างไว้ 2 List ชื่อว่า az_labels และ az_images ตามลำดับ เริ่มต้น Loop function โดยให้เลือก Index ของ DataFrame ทีละ Index จากนั้นให้เก็บค่าตำแหน่งแรก [0] ไว้ที่ตัวแปร label และเก็บค่าตั้งแต่ตำแหน่งที่ 1 เป็นต้นไป [1:] แบบ Array ด้วยคำสั่ง .values ไว้ที่ตัวแปร image จากนั้น .append() ไว้ใน List ว่างทั้ง 2 ตามลำดับ สุดท้ายแปลง List เป็น Numpy array สำหรับ Neural network

Processing image done: 0
Processing image done: 50000
Processing image done: 100000
Processing image done: 150000
Processing image done: 200000
Processing image done: 250000
Processing image done: 300000
Processing image done: 350000
A-Z Labels shape: (372450,)
A-Z Images shape: (372450, 28, 28)

มิติของ Labels array มีขนาด 1 มิติ มีจำนวนสมาชิก 372,450 ตัว และมิติของ Images array มีขนาด 3 มิติ โดยมีจำนวนสมาชิกขนาด 28 x 28 ทั้งหมด 372,450 ตัว

Optical Character Recognition with TensorFlow and Keras a-z mnist

ทดลองแสดงรูปแรกของ Array ผลที่ได้ออกมาคือตัว A ซึ่งถูกแทนด้วยเลข 0 ซึ่งไปตามที่ออกแบบ Data structure เอาไว้ เนื่องจากข้อมูล A-Z เป็นภาพขาวดำ การแสดงผลด้วย plt.imshow() อาจได้สีไม่เหมือนแบบที่โชว์ เพราะโดน Default ของคำสั่งนี้จะพยายามเติมสีให้รูปเป็น RGB สีที่ออกมาจึงอาจผิดเพี้ยน หากต้องการให้การแสดงสีถูกต้องตามลักษณะข้อมูล (ป้องกันความสับสน) สามารถใช้ Option cmap = plt.cm.binary ได้ รูปที่แสดงออกมาจะได้มีที่เป็นขาวดำ

MNIST Train shape: (60000, 28, 28)
MNIST Test shape: (10000, 28, 28)

ต่อมาเป็นการทำข้อมูล MNIST ซึ่งข้อมูลมีลักษณะเป็น Array อยู่แล้ว เนื่องจาก Dataset นี้ได้ถูกแบ่งทั้ง Images และ Labels เป็น Training set และ Testing set มาแล้ว ดังนั้นการใช้งานจึงต้องให้ตัวแปรมารับทั้งหมด 4 ตัว โดยขนาดรูปภาพจาก MNIST มีขนาด 28 x 28 เช่นกัน

Optical Character Recognition with TensorFlow and Keras a-z mnist

ขั้นต่อไปเป็นการรวม Dataset MNIST และ A-Z เข้าด้วยกัน **ข้อควรระวังของขั้นตอนนี้คือ Labels ของ A-Z ที่ถูกแทนด้วยเลข 0–25 ถ้า Stack array เข้าด้วยกันตรง ๆ จะทำให้ Labels A-J ไปซ้ำกับเลข 0–9 ดังนั้นให้ทำการเลื่อนตำแหน่งของ A-Z Labels ก่อนทำการ Stack array

การเลื่อนตำแหน่งทำได้ง่าย ๆ ด้วยการ + 10 ให้กับ A-Z Labels เพราะข้อมูล Labels MNIST มีค่า 0–9 ดังนั้น Label A จึงเริ่มต้นที่ 10 แทน จากนั้นให้ทำการ Stack ข้อมูลทั้ง 2 ชุดเข้าด้วยกัน โดยที่ Labels ให้ใช้ numpy.hstack() ส่วน Images ให้ใช้ numpy.vstack() เพราะไม่ต้องการให้มิติข้อมูลเปลี่ยน สุดท้ายให้ทำการเปลี่ยนค่าใน Images array ให้เป็น Float32 ที่เหมาะสมกับ Neural network ที่สุด

Labels shape: (442450,)
Images shape: (442450, 28, 28)
Optical Character Recognition with TensorFlow and Keras a-z mnist

ทดลองสุ่มรูปขึ้นมา Plot เห็นได้ว่าเป็นรูปตัว A ดังนั้น Label ของตัว A ที่เปลี่ยนค่าไปแล้วจึงมีค่าเท่ากับ 10

ที่เขียนมาทั้งนี้เป็นการเตรียมข้อมูล สำหรับ Neural network ยังไม่ได้เข้าสู่การ Training model เนื่องจากการทำโมเดลมีรายละเอียดที่ต้อง Deep down ลงไป จึงขอจบตอนนี้ไว้เพียงเท่านี้ก่อน ตอนหน้าเป็นเรื่องเกี่ยวกับโมเดล Network ทั้งหมด

--

--

Sasiwut Chaiyadecha
Sasiwut Chaiyadecha

No responses yet

Write a response