สร้างโครงข่ายระบบประสาทเทียม (CNN) เพื่อปรับปรุงวิสัยทัศน์ของคอมพิวเตอร์

1. ข้อควรทราบก่อนที่จะเริ่มต้น

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้ CNN เพื่อปรับปรุงโมเดลการจัดประเภทรูปภาพ

ข้อกำหนดเบื้องต้น

Codelab นี้สร้างขึ้นจากการทํางานร่วมกันใน 2 ครั้งก่อนๆ ซึ่งก็คือสร้างโมเดลคอมพิวเตอร์วิทัศน์ ซึ่งเราจะแนะนําโค้ดบางส่วนที่คุณจะใช้ที่นี่ และ Codelab แบบสร้าง Context และดําเนินการแบบรวมซึ่งจะแนะนําการปฏิวัติและการรวมกลุ่ม

สิ่งที่จะได้เรียนรู้

  • วิธีปรับปรุงการมองเห็นคอมพิวเตอร์และความแม่นยําด้วยปฏิวัติ

สิ่งที่คุณจะสร้าง

  • เลเยอร์เพื่อปรับปรุงโครงข่ายระบบประสาทเทียม

สิ่งที่ต้องมี

คุณค้นหาโค้ดสําหรับส่วนที่เหลือของ Codelab ได้อยู่ใน Colab

นอกจากนี้คุณยังต้องติดตั้ง TensorFlow และไลบรารีที่ติดตั้งไว้ใน Codelab ก่อนหน้านี้ด้วย

2. ปรับปรุงความถูกต้องของคอมพิวเตอร์วิทัศน์ด้วยการสื่อสาร

ตอนนี้คุณทราบวิธีการรับรู้ภาพแฟชั่นโดยใช้ Deep Neural Network (DNN) ที่มี 3 เลเยอร์แล้ว ได้แก่ เลเยอร์อินพุต (ในรูปร่างของข้อมูลอินพุต), เลเยอร์เอาต์พุต (ในรูปของเอาต์พุตที่ต้องการ) และเลเยอร์ที่ซ่อนอยู่ คุณได้ทดลองใช้พารามิเตอร์หลายรายการที่ส่งผลต่อความแม่นยําสุดท้าย เช่น เลเยอร์ที่ซ่อนอยู่ขนาดต่างๆ และจํานวนการฝึก

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

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

ความแม่นยําของคุณอาจอยู่ที่ประมาณ 89% ในการฝึกและ 87% ของการตรวจสอบ ยิ่งไปกว่านั้นคือการใช้การปฏิวัติ ซึ่งจํากัดเนื้อหาของรูปภาพให้แคบลงเพื่อเน้นรายละเอียดที่เจาะจง

หากคุณเคยประมวลผลรูปภาพโดยใช้ฟิลเตอร์แล้ว การปฏิวัติจะดูคุ้นเคยมาก

สรุปก็คือคุณอัปโหลดอาร์เรย์ (โดยทั่วไปจะเป็น 3x3 หรือ 5x5) แล้วส่งผ่านรูปภาพ เมื่อเปลี่ยนแปลงพิกเซลที่เกี่ยวข้องตามสูตรภายในเมทริกซ์ คุณจะสามารถดําเนินการต่างๆ เช่น การตรวจหาขอบ เช่น โดยทั่วไปแล้วรูปภาพ 3x3 จะกําหนดไว้สําหรับการตรวจจับขอบที่เซลล์ตรงกลางเป็น 8 และเพื่อนบ้านทั้งหมดมีค่าเป็น -1 ในกรณีนี้ คุณจะคูณค่าในแต่ละพิกเซลด้วย 8 แล้วลบออกด้วยค่าของแต่ละเพื่อนบ้าน ทําเช่นนี้ได้ทุกพิกเซล แล้วภาพใหม่จะได้รับการปรับปรุงขอบให้คุณ

วิธีนี้เหมาะอย่างยิ่งสําหรับคอมพิวเตอร์วิทัศน์ เพราะการเพิ่มฟีเจอร์ต่างๆ เช่น ขอบช่วยให้คอมพิวเตอร์แยกแยะสิ่งที่ต้องการจากแต่ละรายการได้ ยิ่งไปกว่านั้น จํานวนข้อมูลที่ต้องการยังน้อยกว่ามาก เนื่องจากคุณจะฝึกเฉพาะฟีเจอร์ที่ไฮไลต์ไว้

และนี่ก็คือแนวคิดของโครงข่ายระบบประสาทเทียมระบบปฏิวัติ เพิ่มเลเยอร์เพื่อปฏิวัติก่อนที่จะมีเลเยอร์ที่หนาแน่น จากนั้นข้อมูลที่ส่งไปยังเลเยอร์ที่หนาแน่นขึ้นจะมีความเฉพาะเจาะจงมากขึ้นและอาจมีความแม่นยํามากขึ้น

3. ลองใช้โค้ด

เรียกใช้โค้ดต่อไปนี้ เป็นโครงข่ายระบบประสาทเทียมเหมือนกับก่อนหน้านี้ แต่ครั้งนี้ได้เพิ่มชั้นเกี่ยวกับการปฏิวัติก่อน กระบวนการนี้อาจใช้เวลานานกว่านี้ แต่ดูผลกระทบจากความแม่นยําได้ดังนี้

import tensorflow as tf
print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images / 255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(2, 2),
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

เป็นไปได้มากกว่า 93% ของข้อมูลการฝึกและ 91% ในข้อมูลการตรวจสอบ

จากนั้นลองเรียกใช้สําหรับ Epoch เพิ่มเติม เช่น ประมาณ 20 รายการและสํารวจผลลัพธ์ แม้ว่าผลลัพธ์การฝึกอบรมอาจดูดีมาก แต่ผลลัพธ์ที่ได้จากการตรวจสอบอาจลดลงจริงเนื่องจากปรากฏการณ์ที่เรียกว่าการปรับเปลี่ยนมากเกินไป

การเพิ่มประสิทธิภาพเกิดจากการที่เครือข่ายเรียนรู้ข้อมูลจากชุดการฝึกที่ดีเกินไป ระบบจึงพบว่าไม่สามารถจดจําเฉพาะข้อมูลนั้นได้ และทําให้ดูข้อมูลอื่นๆ ในสถานการณ์ทั่วไปได้น้อยลง เช่น หากคุณฝึกเฉพาะรองเท้าส้นรองเท้า เครือข่ายอาจระบุรองเท้าส้นสูงได้ดี แต่รองเท้าผ้าใบอาจสับสน

ดูที่โค้ดอีกครั้งและดูวิธีสร้างการปฏิวัติแบบทีละขั้นตอน

4. รวบรวมข้อมูล

ขั้นตอนแรกคือรวบรวมข้อมูล

คุณจะเห็นว่ามีการเปลี่ยนแปลงที่นี่และข้อมูลการฝึกอบรมที่ต้องมีการปรับเปลี่ยนรูปแบบ นั่นเป็นเพราะการปฏิวัติครั้งแรกต้องการเงื่อนไขเดียวที่มีทุกอย่าง ดังนั้นในรายการ 28x28x1 ที่มีมากกว่า 60,000 รายการ คุณจะมีรายการ 4 มิติรายการเดียวที่มีขนาด 60,000x28x28x1 และเหมือนกันสําหรับรูปภาพทดสอบ หากไม่ทําตาม ระบบจะแสดงข้อผิดพลาดเมื่อฝึกเพราะการปฏิวัติไม่รู้จักรูปร่าง

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images = training_images/255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images = test_images/255.0

5. กําหนดโมเดล

ต่อไป กําหนดโมเดล แทนที่จะเพิ่มเลเยอร์อินพุตที่ด้านบน คุณก็ต้องเพิ่มเลเยอร์ที่เป็นรูปธรรมขึ้นมา พารามิเตอร์ต่างๆ ได้แก่:

  • จํานวนรอบการสร้างที่ต้องการสร้าง ค่าอย่าง 32 เป็นจุดเริ่มต้นที่ดี
  • ขนาดของเมทริกซ์การปฏิวัติในกรณีนี้คือตารางกริด 3x3
  • ฟังก์ชันการเปิดใช้งานที่จะใช้ในกรณีนี้คือใช้ relu
  • ในรูปร่างแรก รูปร่างของข้อมูลอินพุต

คุณจะติดตามการปฏิวัติด้วยชั้นร่วมสูงสุด ซึ่งออกแบบมาเพื่อบีบอัดรูปภาพและคงเนื้อหาของลักษณะที่ไฮไลต์ไว้ในการปฏิวัตินี้ เมื่อระบุ (2,2) สําหรับการรวมเข้าด้วยกันสูงสุด ผลที่ได้คือลดขนาดของรูปภาพลงเป็นปัจจัย 4 โดยสร้างอาร์เรย์ 2x2 พิกเซลและเลือกค่าพิกเซลที่ใหญ่ที่สุดจะเปลี่ยน 4 พิกเซลเป็น 1 ฟีเจอร์นี้ใช้การคํานวณซ้ํารูปภาพดังกล่าว และลดจํานวนพิกเซลแนวนอนลงครึ่งหนึ่งและลดจํานวนพิกเซลแนวตั้ง

คุณโทรหา model.summary() เพื่อดูขนาดและรูปร่างของเครือข่ายได้ โปรดสังเกตว่าหลังจากเพิ่มชั้นสูงสุดที่กําหนดแล้ว ขนาดรูปภาพจะลดลงดังนี้

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 26, 26, 64)        640       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 11, 11, 64)        36928     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 1600)              0         
_________________________________________________________________
dense_4 (Dense)              (None, 128)               204928    
_________________________________________________________________
dense_5 (Dense)              (None, 10)                1290      
=================================================================

C'โค้ดแบบเต็มของ CNN

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
#Add another convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
#Now flatten the output. After this you'll just have the same DNN structure as the non convolutional version
tf.keras.layers.Flatten(),
#The same 128 dense layers, and 10 output layers as in the pre-convolution example:
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])

6. คอมไพล์และฝึกโมเดล

คอมไพล์โมเดล เรียกใช้เมธอด Fit ในการฝึก และประเมินการสูญเสียและความแม่นยําจากชุดทดสอบ

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_acc*100))

7. แสดงภาพการปฏิวัติและการรวมกลุ่มเข้าด้วยกัน

โค้ดนี้แสดงการปฏิวัติโดยละเอียด print (test_labels[:100]) จะแสดงป้ายกํากับ 100 รายการแรกในชุดการทดสอบ คุณจะเห็นว่าป้ายกํากับที่ดัชนี 0, ดัชนี 23 และดัชนี 28 เป็นค่าเดียวกันทั้งหมด (9) และเป็นรองเท้าทั้งหมด ลองดูผลลัพธ์ของการเรียกใช้การปฏิวัติแต่ละครั้ง และคุณจะเริ่มเห็นคุณลักษณะทั่วไประหว่างการเปลี่ยนแปลงที่เกิดขึ้น ในขณะนี้ เมื่อ DNN ฝึกสอนข้อมูลนั้น ระบบจะทํางานโดยใช้ข้อมูลน้อยลงมากและ 'อาจพบสัญญาณร่วมกันระหว่างรองเท้าตามการปฏิวัติดังกล่าวและชุดค่าผสมของสระว่ายน้ํา

print(test_labels[:100])
[9 2 1 1 6 1 4 6 5 7 4 5 7 3 4 1 2 4 8 0 2 5 7 9 1 4 6 0 9 3 8 8 3 3 8 0 7
 5 7 9 6 1 3 7 6 7 2 1 2 2 4 4 5 8 2 2 8 4 8 0 7 7 8 5 1 1 2 3 9 8 7 0 2 6
 2 3 1 2 8 4 1 8 5 9 5 0 3 2 0 6 5 3 6 7 1 8 0 1 4 2]

ตอนนี้คุณเลือกรูปภาพที่เกี่ยวข้องบางส่วนสําหรับป้ายกํากับเหล่านั้นแล้วแสดงผลลักษณะของการปฏิวัติได้ ดังนั้นในโค้ดต่อไปนี้ FIRST_IMAGE, SECOND_IMAGE และ THIRD_IMAGE คือดัชนีทั้งหมดสําหรับค่า 9 ซึ่งเป็นข้อเท้าข้อเท้า

import matplotlib.pyplot as plt
f, axarr = plt.subplots(3,4)
FIRST_IMAGE=0
SECOND_IMAGE=23
THIRD_IMAGE=28
CONVOLUTION_NUMBER = 6
from tensorflow.keras import models
layer_outputs = [layer.output for layer in model.layers]
activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)
for x in range(0,4):
  f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[0,x].grid(False)
  f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[1,x].grid(False)
  f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[2,x].grid(False)

และคุณควรเห็นสิ่งต่างๆ ต่อไปนี้ ซึ่งการปฏิวัติเป็นส่วนสําคัญของรองเท้าเท่านั้น โดยการตรวจพบจุดเหล่านั้นว่าเป็นคุณลักษณะทั่วไปที่มาจากรองเท้าทุกประเภทได้อย่างมีประสิทธิภาพ

6c9109bcc640a1ec.png

8. การออกกำลังกาย

การออกกําลังกาย 1

ลองแก้ไขการปฏิวัตินี้ เปลี่ยนจํานวนปฏิวัติจาก 32 เป็น 16 หรือ 64 เรื่องนี้ส่งผลต่อความแม่นยําและเวลาในการฝึกอบรมอย่างไร

การออกกําลังกาย 2

โปรดนําการปฏิวัติขั้นสุดท้ายออก เรื่องนี้ส่งผลต่อเวลาหรือเวลาในการฝึกอบรมอย่างไร

การออกกําลังกาย 3

เพิ่มแนวคิดอื่นๆ และส่งผลอย่างไรบ้าง

การออกกําลังกาย 4

นําการปฏิวัติทั้งหมดออกก่อน และส่งผลอย่างไรบ้าง ทดลองใช้

9. ยินดีด้วย

คุณสร้าง CNN แรกเรียบร้อยแล้ว หากต้องการดูวิธีเพิ่มประสิทธิภาพโมเดลคอมพิวเตอร์วิทัศน์ของคุณ ให้ไปที่ใช้โครงข่ายระบบประสาทเทียม (CNN) ด้วยรูปภาพที่ซับซ้อน