วันจันทร์ที่ 17 กันยายน พ.ศ. 2561

โปรเจค หุ่นยนต์อ่านตัวเลข TensorFlow + Keras



โปรเจคหุ่นยนต์อ่านตัวเลข TensorFlow + Keras โปรเจคนี้จะใช้ การสร้างโครงข่ายประสาทเทียม CNN ด้วย Keras ในการอ่านค่าตัวเลขในกระดาษ และแยกแยะตัวเลขว่าเป็นเลขอะไร เมื่ออ่านค่าได้แล้ว จึงไปสั่งควบคุมหุ่นยนต์ โดย 2 ให้เดินหน้า ,  3 ให้ถอยหลัง , 4 ให้เลี้ยวซ้าย ,  5 ให้เลี้ยวขวา และ 8 ให้หยุด



อุปกรณ์ที่ใช้











ขั้นตอนการทำงาน


1.
 การติดตั้ง Linux ให้กับ Raspberry โดยใช้ไฟล์ image


2. การใช้งาน GPIO ใน Raspberry Pi ด้วย Python



3. การประกอบหุ่นยนต์ Raspberry Pi


4. วิธีเปิดใช้งาน Remote Desktop ไปยัง Raspberry Pi


5. ทดสอบการเคลื่อนที่ของหุ่นยนต์ Raspberry Pi



10.1 สร้างไฟล์ build_model.py

เป็นการสร้างโครงข่ายประสาทเทียมขนาดใหญ่สำหรับ MNIST

โดยมีขั้นตอนดังนี้
เปิดโปรแกรม เทอมินอล (Root Terminal)

สร้างโฟลเดอร์ number_robot โดยใช้คำสั่ง


mkdir number_robot


เปิดโปรแกรม Python 3 (IDLE) เขียนโค้ดดังนี้


# Larger CNN for the MNIST Dataset
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

# load data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][pixels][width][height]
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32')
# normalize inputs from 0-255 to 0-1
X_train = X_train / 255
X_test = X_test / 255
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]

# define the larger model
def larger_model():
# create model
model = Sequential()
model.add(Conv2D(30, (5, 5), input_shape=(1, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(15, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model


# build the model
model = larger_model()

# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=200)

# Save entire model to a HDF5 file
model.save('my_model.h5')
print ("Finished")




หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง


https://drive.google.com/open?id=1h1I8IXJAN64-OihiThKmMXjah5THVcMa


Save ไปที่ โฟลเดอร์ number_robot และตั้งชื่อเป็น build_model.py


ทดสอบการทำงาน Run Module




ตัวอย่างเช่นความแม่นยำในการฝึกอบรมและการทดสอบการตรวจสอบจะถูกพิมพ์ในแต่ละรอบและเมื่อสิ้นสุด เพื่อความแม่นยำ จึงใช้ epochs 20 รอบ  จึงใช้เวลานานประมาณ 6-7 ชั่วโมง ในการทำงานและรอจนขึ้นคำว่า Finished



และ จะเซฟไฟล์ HDF5 ชื่อ my_model.h5 เพิ่มเข้ามาในโฟลเดอร์ number_robot ซึ่งเราจะใช้ไฟล์นี้ในการทำงานในขั้นตอนต่อไป


ไฟล์ HDF5 คือ

HDF เป็นไฟล์รูปแบบข้อมูลลำดับชั้นไฟล์โดยที่พวกเขาเป็นรูปแบบแฟ้มมาตรฐานสำหรับการจัดเก็บข้อมูลทางวิทยาศาสตร์ ไฟล์เหล่านี้มีการแบ่งประเภท ส่วนใหญ่ที่ใช้ในการทดสอบ การใช้งานการบินและอวกาศวิทยาศาสตร์สิ่งแวดล้อม ไฟล์ HDF สามารถจัดการมองวิเคราะห์มองเห็นเช่นเดียวกับการแปลงเป็นข้อมูลทางวิทยาศาสตร์ที่มีความสัมพันธ์ระหว่างข้อมูลที่ซับซ้อนและยังมีรูปแบบที่มีความยืดหยุ่นมาก


10.2 แก้ไขไฟล์ 
/etc/default/motion

ถ้าเคยทำ "การติดตั้ง Motion และ ดูภาพกล้องผ่านทางหน้าเว็บเพจ" มาก่อน เพราะจะมีการแก้ค่าจาก no เป็น yes เอาไว้ (ถ้าไม่เคยทำก็ไม่ต้องแก้ไข) โดยแก้ไขให้กลับมาเป็น 
start_motion_daemon=no เหมือนเดิม

เปิดไฟล์ /etc/default/motion มาแก้ไข โดยใช้คำสั่ง


sudo nano /etc/default/motion



ค่าเดิม start_motion_daemon=yes แก้เป็น start_motion_daemon=no


จากนั้นบันทึก Ctrl + O แล้วตามด้วย Enter เพื่อบันทึกข้อมูลใหม่ แล้ว 
กด Ctrl + X เพื่อออกจากโปรแกรม
-เมื่อทำการอัพเดตเรียบร้อยต้องทำการรีบูทเครื่องใหม่


sudo reboot




10.3 ทดสอบการอ่านค่าตัวเลขของหุ่นยนต์ 


เสียบสาย USB ของ Power Bank ต่อเข้ากับ 5V  Micro USB ของบอร์ด Raspberry Pi

ให้ภาพตัวเลขอยูห่างจากหุ่นยนต์ประมาณ 12 -13 เซนติเมตร




ความสูงของตัวเลขห่างจากพื้นประมาณ 1.5 -2 เซนติเมตร




สร้างไฟล์ test_model.py
 เพื่อทดสอบการอ่านค่าตัวเลขของหุ่นยนต์


เปิดโปรแกรม Python 3 (IDLE) เขียนโค้ดดังนี้




from time import sleep
from picamera import PiCamera

camera = PiCamera()
camera.resolution = (800, 800)
camera.start_preview()

sleep(2)
camera.capture('/home/pi/number_robot/image.jpg')

from skimage.io import imread
import numpy as np


im = imread("image.jpg")

from skimage.transform import resize
# resize to 28 x 28
im_resize = resize(im,(28,28), mode='constant')
from skimage.color import rgb2gray
# turn the image from color to gray
im_gray = rgb2gray(im_resize)
# the color of the original set are inverted,so we invert it here
im_gray_invert = 255 - im_gray*255
#treat color under threshold as black
im_gray_invert[im_gray_invert<=90] = 0

from keras.models import load_model

model=load_model('my_model.h5')
im_final = im_gray_invert.reshape(1,1,28,28)

# the below output is a array of possibility of respective digit
ans = model.predict(im_final)
print(ans)

ans = ans[0].tolist().index(max(ans[0].tolist()))
print("the predicted digit is",ans)




หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง



Save ไปที่ โฟลเดอร์ number_robot และตั้งชื่อเป็น  test_model.py


ทดสอบการทำงาน Run Module


เริ่มที่ภาพตัวเลข 2 -> Run Module , ภาพตัวเลข 3 -> Run Module , ภาพตัวเลข 4 -> Run Module ,  ภาพตัวเลข 5 -> Run Module

จะแสดงค่าตัวเลขที่อ่านได้ ถ้าอ่านได้ตามภาพที่ให้ถ่าย แสดงว่า หุ่นยนต์สามารถอ่านค่าได้ถูกต้องแล้ว รอทำในขั้นตอนต่อไป



เมื่อเข้าไปตรวจสอบที่ File Manager  ในโฟลเดอร์ number_robot จะพบไฟล์  image.jpg เพิ่มเข้ามา

สามารถดูภาพที่ถ่าย โดยให้คลิกขวาที่ไฟล์  image.jpg เลือก Chromium Web Browser



จะแสดงภาพที่หุ่นยนต์ถ่ายไว้



10.4 ทดสอบการทำงาน 



สร้างไฟล์ robot_number.py โดย

เปิดโปรแกรม Python 3 (IDLE) เขียนโค้ดดังนี้




import RPi.GPIO as GPIO

#set GPIO numbering mode and define output pins
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(35,GPIO.OUT)
GPIO.setup(37,GPIO.OUT)

from time import sleep
from picamera import PiCamera

camera = PiCamera()
camera.resolution = (800, 800)
camera.start_preview()

sleep(2)
camera.capture('/home/pi/number_robot/image.jpg')

from skimage.io import imread
import numpy as np


im = imread("image.jpg")

from skimage.transform import resize
# resize to 28 x 28
im_resize = resize(im,(28,28), mode='constant')
from skimage.color import rgb2gray
# turn the image from color to gray
im_gray = rgb2gray(im_resize)
# the color of the original set are inverted,so we invert it here
im_gray_invert = 255 - im_gray*255
#treat color under threshold as black
im_gray_invert[im_gray_invert<=90] = 0

from keras.models import load_model

model=load_model('my_model.h5')
im_final = im_gray_invert.reshape(1,1,28,28)

# the below output is a array of possibility of respective digit
ans = model.predict(im_final)
print(ans)

ans = ans[0].tolist().index(max(ans[0].tolist()))
print("the predicted digit is",ans)

if ans == 8:
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
elif ans == 2:
    GPIO.output(11,True)
    GPIO.output(13,False)
    GPIO.output(35,True)
    GPIO.output(37,False)
    sleep(0.3)
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
elif ans == 3:
    GPIO.output(11,False)
    GPIO.output(13,True)
    GPIO.output(35,False)
    GPIO.output(37,True)
    sleep(0.4)
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
elif ans == 4:
    GPIO.output(11,True)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
    sleep(0.4)
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
elif ans == 5:
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,True)
    GPIO.output(37,False)
    sleep(0.4)
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)
else:
    GPIO.output(11,False)
    GPIO.output(13,False)
    GPIO.output(35,False)
    GPIO.output(37,False)            

GPIO.cleanup()



หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง



https://drive.google.com/open?id=1IgsAd5Utat5Nhptxw4qU2C67Hg9I0r4s



Save ไปที่ โฟลเดอร์ number_robot และตั้งชื่อเป็น  robot_number.py


เสียบสาย USB ของ Power Bank ต่อเข้ากับ 5V  Micro USB ของบอร์ด Raspberry Pi

เปิด เพาเวอร์สวิตซ์ จะมีไฟสีแดงติดที่ Motor Driver

ให้ภาพตัวเลขอยูห่างจากหุ่นยนต์ประมาณ 12 -13 เซนติเมตร


ความสูงของตัวเลขห่างจากพื้นประมาณ 1.5 -2 เซนติเมตร

ทดสอบการทำงาน Run Module

เริ่มที่ภาพตัวเลข 2 -> Run Module , ภาพตัวเลข 3 -> Run Module , ภาพตัวเลข 4 -> Run Module ,  ภาพตัวเลข 5 -> Run Module


วีดีโอผลลัพธ์การทำงานของ โปรเจคหุ่นยนต์อ่านตัวเลข TensorFlow + Keras



.....

วันอาทิตย์ที่ 16 กันยายน พ.ศ. 2561

การสร้าง โครงข่ายประสาทเทียม CNN ด้วย Keras



Deep Learning คือการกลับมาครั้งใหม่ของ Neural Network โดยคราวนี้เน้นที่โครงสร้างที่ลึกกว่าก่อนมาก และที่เป็นไปได้ตอนนี้เพราะ

1.เรามีข้อมูลเยอะพอ พวก big data ที่คนพูดๆ กัน
2.เรามีอุปกรณ์คำนวณที่เหมาะสมนั่นคือ GPU card สำหรับคำนวณ และ
3.เรามีเทคนิคในการ train network ที่มีโครงสร้างที่ลึกได้

นักวิจัยด้านการเรียนรู้ของ Machine ได้เสนอสถาปัตยกรรมการเรียนรู้หลายแบบบนหลักการของการเรียนรู้เชิงลึกนี้ ได้แก่ โครงข่ายประสาทเทียมแบบสังวัตนาการ (Convolutional Neural Networks)

Convolutional Neural Networks (CNN) หรือโครงข่ายประสาทเทียม เป็นแบบจำลองการทำงานของโครงข่ายประสาทจริง ในโครงข่ายประสาทจริงนั้นเซลล์ประสาทต่างก็เชื่อมต่อกัน แต่ละเซลล์รับกระแสประสาทจากเซลล์ข้างเคียงผ่านแขนงประสาท เมื่อแอมพลิจูดของสัญญาณที่รับมาสูงพอจะเกิดการชักนำให้เซลล์นี้สร้างกระแสประสาทใหม่และส่งออกไปให้เพื่อนบ้าน แนวความคิดนี้นำไปสู่แบบจำลองเซลล์ประสาทเทียม เซลล์เดียว


MNIST Data คือ ชุดข้อมูลถูกสร้างขึ้นจากชุดเอกสารที่สแกนแล้วจากสถาบันมาตรฐานและเทคโนโลยีแห่งชาติ (NIST) นี่คือที่มาของชุดข้อมูลมาจากชุดข้อมูล NIST หรือ MNIST ที่แก้ไขแล้ว

ภาพของตัวเลขถูกนำมาจากเอกสารที่สแกนหลายฉบับโดยมีขนาดและศูนย์กลางเป็นเท่าๆกัน ซึ่งทำให้เป็นชุดข้อมูลที่ยอดเยี่ยมสำหรับการประเมินโมเดล ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์สามารถมุ่งเน้นไปที่การเรียนรู้เกี่ยวกับการจัดเตรียมที่น้อยมาก

แต่ละภาพมีขนาด 28 x 28 พิกเซล (784 พิกเซล) เป็นมาตรฐานของชุดข้อมูล เพื่อใช้ประเมินและเปรียบเทียบโมเดล โดยใช้ภาพ 60,000 ภาพในการฝึกแบบจำลองและใช้ชุดทดสอบ 10,000 ภาพ

มี 10 หลัก (0 ถึง 9) ที่จะทำนาย ผลลัพธ์ถูกรายงานโดยใช้ข้อผิดพลาดในการทำนายซึ่งไม่มีอะไรมากไปกว่าความถูกต้องในการแยกแยะตัวเลข


ขั้นตอนการทำงาน


ก่อนการทำงานให้ติดตั้ง  TensorFlow และ Keras ตามลิงค์ด้านล่าง

การติดตั้ง TensorFlow และ Keras


เปิดโปรแกรม เทอมินอล (Root Terminal)

สร้างโฟลเดอร์ basic_mnist โดยใช้คำสั่ง


mkdir basic_cnn


เปิดโปรแกรม Python 3 (IDLE)


Simple Convolutional Neural Network for MNIST

เครือข่ายประสาทเทียมแบบเรียบง่ายสำหรับ MNIST ตอนนี้เราจะได้เห็นวิธีการโหลดชุดข้อมูล MNIST และฝึกรูปแบบ perceptron หลายชั้นที่เรียบง่าย ในการพัฒนาเครือข่ายประสาทเทียมที่ซับซ้อนมากขึ้นหรือ Convolutional Neural Networks (CNN)



ซึ่ง Keras มีความสามารถมากในการสร้างเครือข่ายประสาทเทียม

ในส่วนนี้เราจะสร้าง CNN ที่เรียบง่ายสำหรับ MNIST และแสดงให้เห็นถึงวิธีการใช้ทุกแง่มุมของการใช้งาน CNN อันทันสมัย ซึ่งได้แก่ Convolutional layers, Pooling layers และ Dropout layers.

เขียนโค้ดดังนี้

ขั้นตอนแรกคือการนำเข้า classes และฟังก์ชันที่จำเป็น

import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')

เราจะเริ่มต้นเครื่องเลือกตัวเลขแบบสุ่ม ให้ไปเป็นค่าคงที่ seed สำหรับการทำซ้ำของผลลัพธ์

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

ต่อไปเราต้องโหลดชุดข้อมูล MNIST ใหม่เพื่อให้เหมาะสมกับการฝึกอบรม CNN ใน Keras เลเยอร์ที่ใช้สำหรับการคำนวณสองมิติคาดว่าค่าพิกเซลจะมีขนาด [pixels] [width] [height]

ในกรณีของ RGB พิกเซลขนาดแรกจะเป็น 3 สำหรับองค์ประกอบ สีแดง เขียวและน้ำเงิน และจะเหมือนกับการใส่ข้อมูลภาพ 3 ภาพสำหรับภาพสีทุกภาพ ในกรณีของ MNIST ที่ค่าพิกเซลเป็นสีเทาขนาดพิกเซลจะถูกกำหนดเป็น 1

# load data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][pixels][width][height]
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32')


เช่นเคยเป็นความคิดที่ดีที่จะปรับค่าพิกเซลให้อยู่ในช่วง 0 และ 1 และหนึ่งจะเข้ารหัสตัวแปรเอาต์พุตได้

# normalize inputs from 0-255 to 0-1
X_train = X_train / 255
X_test = X_test / 255
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]


ต่อไปเราจะกำหนดรูปแบบเครือข่ายประสาทของเรา

เครือข่ายประสาทคอมเพล็กซ์มีความซับซ้อนมากกว่า perceptron หลายชั้นมาตรฐานดังนั้นเราจะเริ่มต้นด้วยการใช้โครงสร้างที่เรียบง่ายเพื่อเริ่มต้นด้วยองค์ประกอบที่ใช้องค์ประกอบทั้งหมดเพื่อให้ได้ผลลัพธ์ที่ทันสมัย ด้านล่างสรุปโครงสร้างเครือข่าย

1.ชั้นที่ซ่อนแรกคือชั้นแบบ Convolutional เรียกว่า Convolution2D เลเยอร์มีแผนที่คุณลักษณะ 32 ซึ่งมีขนาด 5 × 5 และฟังก์ชันการเปิดใช้งานเครื่องแก้ไขภาพ นี่คือเลเยอร์อินพุตที่คาดหวังให้รูปภาพที่มีเค้าร่างโครงร่างเหนือ [พิกเซล] [width] [height]

2. ถัดไปเรากำหนดเลเยอร์การรวมที่ใช้เวลาสูงสุดที่เรียกว่า MaxPooling2D มีการกำหนดค่าด้วยขนาดพูล 2 × 2

3. ชั้นถัดไปคือชั้นการจัดระเบียบโดยใช้ dropout เรียกว่า Dropout มีการกำหนดค่าให้สุ่มเลือก 20% ของเซลล์ประสาทในเลเยอร์เพื่อลดการขูดรีด

4. ถัดไปคือเลเยอร์ที่แปลงข้อมูลเมทริกซ์ 2D เป็นเวกเตอร์ที่เรียกว่า Flatten ช่วยให้เอาท์พุทประมวลผลโดยใช้ชั้นมาตรฐานที่เชื่อมต่อกันอย่างเต็มที่

5. ถัดไปชั้นเชื่อมต่ออย่างเต็มที่กับ 128 เซลล์และการเปิดใช้งานฟังก์ชัน rectifier

6.สุดท้ายเลเยอร์เอาท์พุทมี 10 เซลล์สำหรับ 10 คลาสและฟังก์ชันการเปิดใช้งาน softmax เพื่อสร้างการคาดการณ์ที่น่าจะเป็นไปได้สำหรับแต่ละคลาส

ก่อนหน้านี้แบบจำลองได้รับการฝึกอบรมโดยใช้การสูญเสียลอการิทึมและอัลกอริธึมการไล่ระดับสี ADAM

def baseline_model():
# create model
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model

เราประเมินแบบจำลองเช่นเดียวกับก่อนหน้าด้วย perceptron หลายชั้น เป็น CNN ที่มี แบบจำลองมีขนาดพอดีกับ epochs 10 รอบ ที่มีการอัปเดต batch ทุกๆ 200 ภาพ

# build the model
model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("CNN Error: %.2f%%" % (100-scores[1]*100))



โดยมีโค้ดทั้งหมดดังนี้



import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

# load data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][pixels][width][height]
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32')


# normalize inputs from 0-255 to 0-1
X_train = X_train / 255
X_test = X_test / 255
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]

def baseline_model():
# create model
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model

# build the model
model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("CNN Error: %.2f%%" % (100-scores[1]*100))


หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง




Save ไปที่ โฟลเดอร์ basic_cnn และตั้งชื่อเป็น simple_cnn.py



ทดสอบการทำงาน Run Module


ตัวอย่างเช่นความแม่นยำในการฝึกอบรมและการทดสอบการตรวจสอบจะถูกพิมพ์ในแต่ละรอบและเมื่อสิ้นสุด อัตราการผิดพลาดในการตรวจสอบ และจะใช้เวลานานประมาณ 3-4 ชั่วโมง

ถึงจะเห็นได้ว่าเครือข่ายประสบความสำเร็จในอัตราข้อผิดพลาด 1.01% หรือมีความแม่นยำ 98.99% ซึ่งดีกว่าแบบ TensorFlow กับรูปภาพตัวเลข MNIST Data เบื้องต้น ซึ่งมีความแม่นยำเพียง 91.62%


ถ้าใช้โปรแกรม FileZilla (ไฟล์ซิลลา) sftp เข้าไป ที่โฟลเดอร์ .keras/datasets จะพบ ไฟล์ mnist.npz ซึ่งเป็นไฟล์ฐานขอมูลของ MNIST Data ที่เราดาวน์โหลดมา และเรียกใช้ในการทำงานนั่นเอง


# ในกรณีดาวน์โหลดฐานข้อมูลยังไม่เสร็จแล้วปิดโปรแกรมลงไปก่อน จะมีปัญหาในการดาวน์โหลดฐานข้อมูลไม่ได้ในครั้งต่อไป ให้มาลบไฟล์ที่อยู่ในส่วนนี้เสียก่อน #



หมายเหตุ : เรียบเรียงและแก้ไขดัดแปลงจากบทความด้านล่าง

Handwritten Digit Recognition using Convolutional Neural Networks in Python with Keras