1. ภาพรวม
อัปเดตบทแนะนำนี้สำหรับ Tensorflow 2.2 แล้ว
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีการสร้างและฝึกโครงข่ายระบบประสาทเทียมที่จดจำตัวเลขที่เขียนด้วยลายมือ ในระหว่างที่ปรับปรุงโครงข่ายระบบประสาทเทียมให้มีความแม่นยำถึง 99% คุณจะได้ค้นพบเครื่องมือทางการค้าที่ผู้เชี่ยวชาญด้านการเรียนรู้เชิงลึกใช้เพื่อฝึกโมเดลอย่างมีประสิทธิภาพด้วย
Codelab นี้ใช้ชุดข้อมูล MNIST ซึ่งเป็นคอลเล็กชันตัวเลขที่ติดป้ายกำกับว่า 60,000 หลัก ทำให้ระดับปริญญาเอกหลายคนวุ่นวายกันมาเกือบ 2 ทศวรรษ คุณจะแก้โจทย์ด้วยโค้ด Python / TensorFlow น้อยกว่า 100 บรรทัด
สิ่งที่คุณจะได้เรียนรู้
- โครงข่ายประสาทคืออะไรและจะฝึกได้อย่างไร
- วิธีสร้างโครงข่ายระบบประสาทเทียม 1 ชั้นพื้นฐานโดยใช้ tf.keras
- วิธีเพิ่มเลเยอร์
- วิธีตั้งค่ากำหนดอัตราการเรียนรู้
- วิธีสร้างโครงข่ายประสาทแบบคอนโวลูชัน (Convolutional)
- วิธีใช้เทคนิคการสร้างมาตรฐาน: การออกกลางคัน การทำให้แบบกลุ่มเป็นมาตรฐาน
- อะไรคือการปรับมากเกินไป
สิ่งที่ต้องมี
เบราว์เซอร์เท่านั้น เวิร์กช็อปนี้สามารถดำเนินการทั้งหมดได้ด้วย Google Colaboratory
ความคิดเห็น
โปรดแจ้งให้เราทราบ หากคุณพบสิ่งที่ควรปรับปรุงในห้องทดลองนี้ หรือคุณคิดว่าเราควรปรับปรุง เราจัดการกับความคิดเห็นผ่านปัญหาเกี่ยวกับ GitHub [ feedback link]
2. คู่มือเริ่มต้นฉบับย่อสำหรับ Google Colaboratory
ห้องทดลองนี้ใช้ Google Colaboratory และคุณไม่จำเป็นต้องตั้งค่าใดๆ คุณสามารถเรียกใช้ได้จาก Chromebook โปรดเปิดไฟล์ด้านล่างและเรียกใช้เซลล์เพื่อทำความคุ้นเคยกับสมุดบันทึกของ Colab
ดูวิธีการเพิ่มเติมได้ที่ด้านล่าง
เลือกแบ็กเอนด์ GPU
ในเมนู Colab ให้เลือกรันไทม์ > เปลี่ยนประเภทรันไทม์ จากนั้นเลือก GPU การเชื่อมต่อกับรันไทม์จะเกิดขึ้นโดยอัตโนมัติในการดำเนินการครั้งแรก หรือคุณจะใช้การเชื่อมต่อ "เชื่อมต่อ" ก็ได้ ที่มุมบนขวา
การดำเนินการกับสมุดบันทึก
เรียกใช้ทีละเซลล์ด้วยการคลิกที่เซลล์แล้วกด Shift-ENTER นอกจากนี้ คุณยังเรียกใช้สมุดบันทึกทั้งหมดได้ด้วยรันไทม์ > เรียกใช้ทั้งหมด
สารบัญ
สมุดบันทึกทั้งหมดมีสารบัญ คุณสามารถเปิดได้โดยใช้ลูกศรสีดำทางด้านซ้าย
เซลล์ที่ซ่อนอยู่
บางเซลล์จะแสดงเฉพาะชื่อเท่านั้น ฟีเจอร์นี้เป็นฟีเจอร์สำหรับสมุดบันทึกของ Colab โดยเฉพาะ คุณสามารถดับเบิลคลิกเพื่อดูโค้ดที่อยู่ด้านในได้ แต่ปกติแล้วสิ่งนี้ไม่ค่อยน่าสนใจนัก โดยทั่วไปจะรองรับหรือฟังก์ชันการแสดงผล คุณยังต้องเรียกใช้เซลล์เหล่านี้เพื่อให้มีการกำหนดฟังก์ชันภายในเซลล์
3. ฝึกโครงข่ายประสาท
เราจะได้ดูรถไฟโครงข่ายระบบประสาทเทียมก่อน โปรดเปิดสมุดบันทึกด้านล่างและทํางานให้ครบทุกเซลล์ อย่าเพิ่งให้ความสำคัญกับโค้ด เราจะเริ่มอธิบายรหัสในภายหลัง
ขณะเรียกใช้สมุดบันทึก ให้เน้นที่การแสดงภาพ โปรดดูคำอธิบายด้านล่าง
ข้อมูลการฝึก
เรามีชุดข้อมูลของตัวเลขที่เขียนด้วยลายมือซึ่งมีการติดป้ายกำกับไว้เพื่อให้เราทราบว่าแต่ละภาพหมายถึงอะไร เช่น ตัวเลขตั้งแต่ 0 ถึง 9 คุณจะเห็นข้อความที่ตัดตอนมาในสมุดบันทึก
โครงข่ายประสาทที่เราจะสร้างในการจัดประเภทตัวเลขที่เขียนด้วยลายมือในชั้นเรียนจำนวน 10 ตัว (0, .., 9) โดยจะอิงตามพารามิเตอร์ภายในที่ต้องมีค่าที่ถูกต้องสำหรับการแยกประเภทเพื่อให้ทำงานได้ดี "ค่าที่ถูกต้อง" นี้ เรียนรู้ผ่านกระบวนการฝึกที่ต้องใช้ "ชุดข้อมูลที่ติดป้ายกำกับ" ด้วยภาพและคำตอบที่ถูกต้องที่เกี่ยวข้อง
เราจะรู้ได้อย่างไรว่าโครงข่ายประสาทที่ผ่านการฝึกทํางานได้ดีหรือไม่ การใช้ชุดข้อมูลการฝึกเพื่อทดสอบเครือข่ายอาจเป็นการโกง โดยได้เห็นชุดข้อมูลนั้นหลายครั้งระหว่างการฝึกและมีประสิทธิภาพสูงแล้ว เราต้องการชุดข้อมูลที่ติดป้ายกำกับอีกชุดหนึ่งซึ่งไม่เคยเห็นระหว่างการฝึก เพื่อประเมิน "การใช้งานจริง" ประสิทธิภาพของเครือข่าย ซึ่งเรียกว่า "ชุดข้อมูลการตรวจสอบ"
ฝึกอบรม
ขณะที่การฝึกดำเนินไป ข้อมูลการฝึกจะเริ่มต้นขึ้นครั้งละ 1 ชุด พารามิเตอร์โมเดลภายในจะได้รับการอัปเดต โมเดลจะพัฒนาขึ้นเรื่อยๆ ในการจดจำตัวเลขที่เขียนด้วยลายมือ คุณจะดูได้ในกราฟการฝึก ดังนี้
ทางด้านขวาจะเป็น "ความถูกต้อง" เป็นเพียงเปอร์เซ็นต์ของตัวเลขที่รู้จักอย่างถูกต้อง คะแนนจะเพิ่มสูงขึ้นเมื่อการฝึกเริ่มต้นขึ้น ซึ่งเป็นเรื่องที่ดี
ทางด้านซ้าย เราจะเห็น "loss" ในการกระตุ้นการฝึกอบรม เราจะนิยามคำว่า "การสูญเสีย" ซึ่งแสดงให้เห็นว่าระบบจดจำตัวเลขได้แย่แค่ไหนและพยายามย่อตัวเลขนั้นไว้ สิ่งที่เห็นก็คือความสูญเสียจะน้อยลงทั้งในส่วนของการฝึกและข้อมูลการตรวจสอบเมื่อการฝึกดำเนินไป ซึ่งเป็นเรื่องที่ดี แต่หมายความว่าโครงข่ายประสาทกำลังเรียนรู้
แกน X แสดงจำนวน "Epoch" หรือการทำซ้ำ ผ่านทั้งชุดข้อมูล
การคาดการณ์
เมื่อฝึกโมเดลแล้ว เราสามารถใช้โมเดลจดจำตัวเลขที่เขียนด้วยลายมือได้ ภาพถัดไปจะแสดงให้เห็นประสิทธิภาพการทำงานจากตัวเลข 2-3 หลักจากแบบอักษรในเครื่อง (บรรทัดแรก) ตามด้วยตัวเลข 10,000 หลักของชุดข้อมูลการตรวจสอบ คลาสที่คาดการณ์จะปรากฏใต้ตัวเลขแต่ละหลัก โดยแสดงเป็นสีแดงหากไม่ถูกต้อง
จากที่เห็น โมเดลเริ่มต้นนี้ยังทำงานได้ไม่ดีนักแต่ยังคงจดจำตัวเลขได้ถูกต้อง ความถูกต้องของการตรวจสอบครั้งสุดท้ายอยู่ที่ประมาณ 90% ซึ่งถือว่าไม่เลวร้ายสำหรับโมเดลง่ายๆ ที่เราเริ่มทำ แต่ก็ยังหมายความว่าโมเดลมีการตรวจสอบไม่ถึง 1, 000 หลักจาก 10,000 หลัก ข้อมูลเหล่านั้นก็เพิ่มขึ้นได้มาก ซึ่งทำให้ดูเหมือนว่าคำตอบทั้งหมดผิด (สีแดง)
Tensor
ข้อมูลจะจัดเก็บไว้ในเมทริกซ์ รูปภาพโทนสีเทาขนาด 28x28 พิกเซลจะพอดีกับเมทริกซ์ 2 มิติขนาด 28x28 แต่สำหรับรูปภาพสี เราต้องมีขนาดมากกว่านี้ แต่ละพิกเซลมีค่าสี 3 ค่า (แดง เขียว น้ำเงิน) ดังนั้นจะต้องใช้ตาราง 3 มิติที่มีขนาด [28, 28, 3] และหากต้องการจัดเก็บรูปภาพสี 128 รูป จะต้องใช้ตาราง 4 มิติที่มีมิติข้อมูล [128, 28, 28, 3]
ตารางหลายมิติข้อมูลเหล่านี้เรียกว่า "tensor" และรายการมิติข้อมูลคือ "รูปร่าง"
4. [INFO]: โครงข่ายระบบประสาทเทียมขั้นพื้นฐาน
สรุป
หากคุณทราบคำศัพท์ทั้งหมดในตัวหนาในย่อหน้าถัดไปแล้ว คุณสามารถย้ายไปยังแบบฝึกหัดถัดไป หากคุณเพิ่งเริ่มต้นในการเรียนรู้เชิงลึก ก็ยินดีและโปรดอ่านต่อไป
สำหรับโมเดลที่สร้างเป็นลำดับของเลเยอร์ Keras จะมี Sสัมผัสประสบการณ์ API ตัวอย่างเช่น ตัวแยกประเภทรูปภาพที่ใช้เลเยอร์แบบหนาแน่น 3 เลเยอร์สามารถเขียนด้วย Keras ดังนี้
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[28, 28, 1]),
tf.keras.layers.Dense(200, activation="relu"),
tf.keras.layers.Dense(60, activation="relu"),
tf.keras.layers.Dense(10, activation='softmax') # classifying into 10 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
เลเยอร์ที่หนาแน่นชั้นเดียว
ตัวเลขที่เขียนด้วยลายมือในชุดข้อมูล MNIST คือรูปภาพโทนสีเทาขนาด 28x28 พิกเซล วิธีที่ง่ายที่สุดในการแยกประเภทเหล่านี้คือการใช้ 28x28=784 พิกเซล เป็นอินพุตสำหรับเครือข่ายประสาทเทียม 1 ชั้น
"เซลล์ประสาท" แต่ละเซลล์ในโครงข่ายประสาทจะบันทึกผลรวมแบบถ่วงน้ำหนักของอินพุตทั้งหมด เพิ่มค่าคงที่ที่เรียกว่า "อคติ" แล้วส่งผลลัพธ์ผ่าน "ฟังก์ชันการเปิดใช้งาน" ที่ไม่ใช่แบบเชิงเส้น "น้ำหนัก" และ "อคติ" คือพารามิเตอร์ที่จะกำหนดผ่านการฝึก ค่าเหล่านี้จะเริ่มด้วยค่าแบบสุ่มในตอนแรก
ภาพด้านบนแสดงโครงข่ายระบบประสาทเทียม 1 ชั้นที่มีเซลล์ประสาทเอาต์พุต 10 เซลล์ เนื่องจากเราต้องการจำแนกตัวเลขออกเป็น 10 คลาส (0-9)
ด้วยการคูณเมทริกซ์
ต่อไปนี้คือวิธีที่เลเยอร์เครือข่ายประสาทเทียมที่ประมวลผลคอลเล็กชันรูปภาพสามารถแสดงด้วยการคูณเมทริกซ์
เราคำนวณผลรวมถ่วงน้ำหนักของพิกเซลทั้งหมดของภาพแรกด้วยการใช้คอลัมน์แรกในการถ่วงน้ำหนักในเมทริกซ์น้ำหนัก W ผลรวมนี้ตรงกับเซลล์ประสาทแรก ด้วยการใช้น้ำหนักคอลัมน์ที่ 2 เราทำแบบเดียวกันนี้กับเซลล์ประสาทตัวที่สอง และเป็นเช่นนี้ไปเรื่อยๆ จนถึงเซลล์ประสาทตัวที่ 10 จากนั้นเราสามารถทำซ้ำการดำเนินการสำหรับรูปภาพ 99 ภาพที่เหลือ หากเราเรียก X เมทริกซ์ที่มีภาพ 100 ภาพ ผลรวมที่ถ่วงน้ำหนักทั้งหมดสำหรับเซลล์ประสาท 10 ตัวที่คํานวณจากภาพ 100 ภาพนั้นเป็นเพียง X.W ซึ่งเป็นการคูณเมทริกซ์
ตอนนี้เซลล์ประสาทแต่ละเซลล์จะต้องเพิ่มการให้น้ำหนักพิเศษ (ค่าคงที่) ด้วย เนื่องจากเรามีเซลล์ประสาท 10 เซลล์ เราจึงมีค่าคงที่ของอคติ 10 เซลล์ เราจะเรียกเวกเตอร์ของ 10 ค่า b โดยจะต้องเพิ่มลงในแต่ละบรรทัดของเมทริกซ์ที่คำนวณไว้ก่อนหน้านี้ ใช้เวทมนตร์ที่เรียกว่า "การออกอากาศ" เราจะเขียนส่วนนี้ด้วยเครื่องหมายบวกง่ายๆ
ในที่สุดเราก็ใช้ฟังก์ชันเปิดใช้งาน เช่น "softmax" (อธิบายด้านล่าง) และรับสูตรที่อธิบายโครงข่ายประสาทแบบ 1 ชั้นเพื่อใช้กับรูปภาพ 100 รูป
ใน Keras
เราไม่จำเป็นต้องใช้สูตรนี้ ด้วยไลบรารีโครงข่ายระบบประสาทเทียมระดับสูงอย่าง Keras อย่างไรก็ตาม คุณควรเข้าใจว่าชั้นโครงข่ายระบบประสาทเทียมเป็นเพียงการคูณและการเพิ่มเติมเข้ามามากมาย ใน Keras เลเยอร์แบบหนาแน่นจะเขียนดังนี้
tf.keras.layers.Dense(10, activation='softmax')
เจาะลึก
การเป็นห่วงโซ่เลเยอร์โครงข่ายระบบประสาทเทียมเป็นเรื่องเล็กน้อย เลเยอร์แรกจะคำนวณผลรวมแบบถ่วงน้ำหนักของพิกเซล เลเยอร์ต่อๆ มาจะคำนวณผลรวมถ่วงน้ำหนักของเอาต์พุตของเลเยอร์ก่อนหน้า
ความแตกต่างเพียงอย่างเดียวนอกเหนือจากจำนวนเซลล์ประสาท จะเป็นตัวเลือกของฟังก์ชันการเปิดใช้งาน
ฟังก์ชันการเปิดใช้งาน: relu, softmax และ sigmoid
โดยปกติคุณใช้ "relu" ฟังก์ชันเปิดใช้งานสำหรับทุกเลเยอร์ ยกเว้นเลเยอร์สุดท้าย ชั้นสุดท้ายในตัวแยกประเภทจะใช้ "softmax" การเปิดใช้งาน
"เซลล์ประสาท" คำนวณผลรวมถ่วงน้ำหนักของอินพุตทั้งหมด แล้วเพิ่มค่าที่เรียกว่า "อคติ" และป้อนผลลัพธ์ผ่านฟังก์ชันการเปิดใช้งาน
ฟังก์ชันเปิดใช้งานที่ได้รับความนิยมสูงสุดเรียกว่า "RELU" สำหรับหน่วยเชิงเส้นแบบ Rectified ซึ่งเป็นฟังก์ชันที่เรียบง่ายมากตามที่คุณเห็นบนกราฟด้านบน
ฟังก์ชันการเปิดใช้งานแบบดั้งเดิมในโครงข่ายระบบประสาทเทียมคือ "sigmoid" แต่เป็น "relu" มีคุณสมบัติการบรรจบกันที่ดีกว่าเกือบทุกตำแหน่ง และในตอนนี้ก็เป็นคุณสมบัติที่แนะนำ
การเปิดใช้งาน Softmax สำหรับการแยกประเภท
ชั้นสุดท้ายของโครงข่ายประสาทของเรามีเซลล์ประสาท 10 เซลล์ เนื่องจากเราต้องการจำแนกตัวเลขที่เขียนด้วยลายมือออกเป็น 10 คลาส (0,..9) โดยควรแสดงตัวเลข 10 ตัวระหว่าง 0 ถึง 1 ซึ่งแสดงถึงความน่าจะเป็นที่ตัวเลขนี้จะเป็น 0, 1, 2 และต่อไปเรื่อยๆ สำหรับกรณีนี้ ในเลเยอร์สุดท้าย เราจะใช้ฟังก์ชันเปิดใช้งานที่เรียกว่า "softmax"
การใช้ซอฟต์แมกซ์กับเวกเตอร์ทำได้โดยนำเลขชี้กำลังของแต่ละองค์ประกอบมาทำให้เวกเตอร์เป็นมาตรฐาน โดยทั่วไปด้วยการหารด้วย "L1" (เช่น ผลรวมของค่าสัมบูรณ์) เพื่อให้ค่าปกติรวมกันได้ 1 และสามารถตีความเป็นความน่าจะเป็นได้
บางครั้งจะเรียกเอาต์พุตของเลเยอร์สุดท้ายก่อนการเปิดใช้งานว่า "logits" หากเวกเตอร์นี้คือ L = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9] ให้ดำเนินการดังนี้
การสูญเสียครอสเอนโทรปี
ตอนนี้ที่โครงข่ายประสาทของเราสร้างการคาดคะเนจากรูปภาพอินพุต เราจึงต้องวัดว่ารูปภาพนั้นมีคุณภาพดีเพียงใด เช่น ระยะห่างระหว่างสิ่งที่เครือข่ายแจ้งเรากับคำตอบที่ถูกต้อง ซึ่งมักเรียกว่า "ป้ายกำกับ" อย่าลืมว่าเรามีป้ายกำกับที่ถูกต้องสำหรับรูปภาพทั้งหมดในชุดข้อมูล
สามารถใช้ระยะทางเท่าใดก็ได้ แต่สำหรับปัญหาการจำแนกประเภท สิ่งที่เรียกว่า "ระยะทางแบบครอสเอนโทรปี" มีประสิทธิภาพมากที่สุด เราจะเรียกสิ่งนี้ว่า "ความผิดพลาด" หรือ "Loss" ฟังก์ชัน:
การไล่ระดับสี
"การฝึก" โครงข่ายประสาทหมายถึงการใช้ภาพและป้ายกำกับการฝึกเพื่อปรับน้ำหนักและน้ำหนัก เพื่อลดฟังก์ชันการสูญเสียครอสเอนโทรปี วิธีการทำงานมีดังนี้
ครอสเอนโทรปีเป็นฟังก์ชันของน้ำหนัก การให้น้ำหนักพิเศษ พิกเซลของรูปภาพที่ใช้ในการฝึก และคลาสที่รู้จัก
หากเราคำนวณอนุพันธ์ย่อยของครอสเอนโทรปีที่เกี่ยวข้องกับน้ำหนักทั้งหมดและความลำเอียงทั้งหมด เราได้รับ "การไล่ระดับสี" มาคำนวณสำหรับรูปภาพ ป้ายกำกับ และค่าปัจจุบันของน้ำหนักและความลำเอียง โปรดจำไว้ว่าเรามีน้ำหนักและอคติได้หลายล้านรายการ ดังนั้นการคำนวณการไล่ระดับสีจะเป็นงานหนัก โชคดีที่ TensorFlow ดำเนินการแทนเรา คุณสมบัติทางคณิตศาสตร์ของการไล่ระดับสีคือการชี้ "ขึ้น" เนื่องจากเราต้องการไปยังจุดที่ครอสเอนโทรปีต่ำ เราจึงไปในทิศทางตรงกันข้าม เราอัปเดตน้ำหนักและความเอนเอียงตามเศษส่วนของการไล่ระดับสี จากนั้น เราจะทำสิ่งเดียวกันนี้ซ้ำแล้วซ้ำอีกโดยใช้อิมเมจและป้ายกำกับการฝึกชุดถัดไป ในลูปการฝึก หวังว่าจุดนี้จะบรรจบกันในบริเวณที่การครอสเอนโทรปีมีเพียงเล็กน้อย แต่ก็ไม่มีอะไรรับประกันว่าค่าขั้นต่ำนี้จะไม่ซ้ำกัน
การใช้กลุ่มขนาดเล็กและโมเมนตัม
คุณสามารถคํานวณการไล่ระดับสีในรูปภาพตัวอย่างเพียงภาพเดียวและอัปเดตน้ำหนักและน้ำหนักค่าต่างๆ ได้ทันที แต่การไล่ระดับสี เช่น รูปภาพ 128 ภาพจะให้การไล่ระดับสีที่แสดงถึงข้อจำกัดที่กำหนดโดยรูปภาพตัวอย่างที่แตกต่างกันได้ดีกว่า และมีแนวโน้มที่จะบรรจบกันได้ดีกว่า ขนาดของมินิแบตช์เป็นพารามิเตอร์ที่ปรับได้
เทคนิคนี้ ซึ่งบางครั้งเรียกว่า "การไล่ระดับสีแบบสโตแคติก" มีประโยชน์ในทางปฏิบัติมากกว่าอีกข้อหนึ่ง คือการทำงานแบบกลุ่มยังหมายถึงการทำงานกับเมทริกซ์ขนาดใหญ่ และมักจะเพิ่มประสิทธิภาพให้กับ GPU และ TPU ได้ง่ายกว่า
การบรรจบกันอาจยังค่อนข้างยุ่งเหยิง และสามารถหยุดได้ถ้าเวกเตอร์การไล่ระดับสีเป็นเลข 0 ทั้งหมด หมายความว่าเราพบคะแนนขั้นต่ำแล้วใช่ไหม ไม่ได้เสมอไป คอมโพเนนต์การไล่ระดับสีอาจมีค่าต่ำสุดหรือสูงสุดเป็น 0 ได้ ด้วยเวกเตอร์การไล่ระดับสีที่มีองค์ประกอบนับล้าน ถ้าเป็นศูนย์ทั้งหมด ความน่าจะเป็นที่ทุกศูนย์จะสัมพันธ์กับค่าต่ำสุด และไม่มีองค์ประกอบใดถึงจุดสูงสุดค่อนข้างเล็ก ในพื้นที่ที่มีมิติหลากหลาย จุดหลักมักจะใช้กันทั่วไปและเราไม่อยากหยุดแค่จุดนั้น
ภาพประกอบ: จุดตัด การไล่ระดับสีมีค่า 0 แต่ไม่ได้มีค่าต่ำสุดในทุกทิศทาง (การระบุแหล่งที่มาของรูปภาพ Wikimedia: โดย Nicoguaro - ผลงานของตัวเอง CC BY 3.0)
วิธีแก้ไขคือให้เพิ่มแรงขับเคลื่อนบางส่วนให้อัลกอริทึมการเพิ่มประสิทธิภาพเพื่อให้แล่นผ่านจุดอานม้าได้โดยไม่หยุด
อภิธานศัพท์
กลุ่มหรือกลุ่มขนาดเล็ก: การฝึกจะดำเนินการกับกลุ่มของข้อมูลและป้ายกำกับการฝึกเสมอ ซึ่งจะช่วยให้อัลกอริทึมบรรจบกัน "กลุ่ม" ตามปกติแล้วเป็นมิติข้อมูลแรกของ Tensor ข้อมูล เช่น Tensor ของรูปร่าง [100, 192, 192, 3] จะมีภาพขนาด 192x192 พิกเซล 100 ภาพที่มี 3 ค่าต่อพิกเซล (RGB)
การสูญเสียการครอสเอนโทรปี: ฟังก์ชันการสูญเสียพิเศษที่มักใช้ในตัวแยกประเภท
ชั้นที่หนาแน่น: ชั้นของเซลล์ประสาทที่เซลล์ประสาทแต่ละเซลล์เชื่อมต่อกับเซลล์ประสาททั้งหมดในชั้นก่อนหน้านี้
features: อินพุตของโครงข่ายประสาทบางครั้งเรียกว่า "ฟีเจอร์" ศิลปะในการพิจารณาว่าส่วนใดของชุดข้อมูล (หรือการรวมส่วนต่างๆ) ที่จะป้อนลงในโครงข่ายระบบประสาทเทียมเพื่อรับการคาดการณ์ที่ดีเรียกว่า "Feature Engineering"
labels: อีกชื่อหนึ่งของ "ชั้นเรียน" หรือคำตอบที่ถูกต้องในโจทย์การจัดประเภทภายใต้การควบคุมดูแล
อัตราการเรียนรู้: เศษส่วนของการไล่ระดับสีที่มีการอัปเดตน้ำหนักและน้ำหนักพิเศษในแต่ละการวนซ้ำการฝึก
logits: เอาต์พุตของชั้นเซลล์ก่อนใช้ฟังก์ชันการเปิดใช้งานเรียกว่า "logits" คำนี้มาจาก "ฟังก์ชันโลจิสติก" หรือที่เรียกว่า "ฟังก์ชัน Sigmoid" ซึ่งเคยเป็นฟังก์ชันเปิดใช้งานที่ได้รับความนิยมสูงสุด "เอาต์พุตของประสาทก่อนฟังก์ชันโลจิสติกส์" ถูกย่อเป็น "logits"
loss: ฟังก์ชันข้อผิดพลาดที่เปรียบเทียบเอาต์พุตของโครงข่ายระบบประสาทเทียมกับคำตอบที่ถูกต้อง
เซลล์ประสาท: คำนวณผลรวมถ่วงน้ำหนักของอินพุต จะเพิ่มการให้น้ำหนักพิเศษ และป้อนผลลัพธ์ผ่านฟังก์ชันการเปิดใช้งาน
การเข้ารหัสแบบ One-Hot: คลาส 3 จาก 5 ได้รับการเข้ารหัสเป็นเวกเตอร์ขององค์ประกอบ 5 โดยค่า 0 ทั้งหมดยกเว้นค่าตัวที่ 3 ซึ่งก็คือ 1
relu: หน่วยเชิงเส้นที่แก้ไขแล้ว ฟังก์ชันการเปิดใช้งานยอดนิยมสำหรับเซลล์ประสาท
sigmoid: ฟังก์ชันเปิดใช้งานอีกอย่างที่เคยได้รับความนิยมและยังคงมีประโยชน์ในกรณีพิเศษ
softmax: ฟังก์ชันเปิดใช้งานพิเศษที่ดำเนินการกับเวกเตอร์ เพิ่มความแตกต่างระหว่างส่วนประกอบที่ใหญ่ที่สุดกับองค์ประกอบอื่นๆ ทั้งหมด และยังทำให้เวกเตอร์เป็นมาตรฐานเพื่อให้ได้ผลรวมของ 1 เพื่อให้สามารถตีความว่าเป็นเวกเตอร์ของความน่าจะเป็น ใช้เป็นขั้นตอนสุดท้ายในตัวแยกประเภท
tensor: A "tensor" คล้ายกับเมทริกซ์ แต่มีจำนวนมิติข้อมูลที่กำหนดเอง tensor 1 มิติคือเวกเตอร์ Tensor 2 มิติคือเมทริกซ์ และจากนั้นคุณสามารถมี Tensor ที่มีมิติข้อมูล 3, 4, 5 หรือมากกว่าได้
5. มาเริ่มที่โค้ดกันเลย
กลับไปที่สมุดบันทึกเตรียมสอบ และคราวนี้เรามาอ่านโค้ดกัน
มาดูเซลล์ทั้งหมดในสมุดบันทึกนี้กัน
"พารามิเตอร์" ของเซลล์
ขนาดกลุ่ม จำนวน Epoch การฝึก และตำแหน่งของไฟล์ข้อมูลจะกำหนดไว้ที่นี่ ไฟล์ข้อมูลโฮสต์ในที่เก็บข้อมูล Google Cloud Storage (GCS) ซึ่งเป็นเหตุผลที่ที่อยู่ขึ้นต้นด้วย gs://
"การนำเข้า" เซลล์
ระบบจะนำเข้าไลบรารี Python ที่จำเป็นทั้งหมด รวมถึง TensorFlow และ matplotlib สำหรับการแสดงภาพ
เซลล์ "visualization utilities [RUN ME]****"
เซลล์นี้มีโค้ดการแสดงภาพที่ไม่น่าสนใจ คอลัมน์นี้จะยุบโดยค่าเริ่มต้น แต่คุณสามารถเปิดและดูโค้ดได้เมื่อมีเวลาโดยดับเบิลคลิกที่รหัส
เซลล์ "tf.data.Dataset: แยกวิเคราะห์ไฟล์และเตรียมชุดข้อมูลการฝึกและการตรวจสอบ"
เซลล์นี้ใช้ tf.data.Dataset API เพื่อโหลดชุดข้อมูล MNIST จากไฟล์ข้อมูล คุณไม่จำเป็นต้องใช้เวลากับเซลล์นี้มากเกินไป หากคุณสนใจ tf.data.Dataset API โปรดดูบทแนะนำที่อธิบาย ไปป์ไลน์ข้อมูลความเร็ว TPU ในขณะนี้ วิธีการเบื้องต้นมีดังนี้
รูปภาพและป้ายกำกับ (คำตอบที่ถูกต้อง) จากชุดข้อมูล MNIST จะเก็บไว้ในระเบียนความยาวคงที่ใน 4 ไฟล์ ไฟล์โหลดได้ด้วยฟังก์ชันระเบียนแบบคงที่โดยเฉพาะ ดังนี้
imagedataset = tf.data.FixedLengthRecordDataset(image_filename, 28*28, header_bytes=16)
ตอนนี้เรามีชุดข้อมูลไบต์ของรูปภาพ โดยต้องถอดรหัสเป็นรูปภาพ เรานิยามฟังก์ชันสำหรับการดำเนินการดังกล่าว รูปภาพไม่ได้รับการบีบอัด ทำให้ไม่ต้องถอดรหัสใดๆ กับฟังก์ชัน (โดยทั่วไปแล้ว decode_raw
ไม่ได้ทำอะไรเลย) จากนั้นระบบจะแปลงรูปภาพเป็นค่าทศนิยมระหว่าง 0 ถึง 1 เราสามารถปรับรูปร่างที่นี่ให้เป็นรูปภาพ 2 มิติได้ แต่จริงๆ แล้วเราเก็บภาพนี้ไว้เป็นพิกเซลขนาด 28*28 ที่ราบเรียบ เพราะนั่นคือสิ่งที่เลเยอร์ความหนาแน่นเริ่มต้นที่เราคาดหวัง
def read_image(tf_bytestring):
image = tf.io.decode_raw(tf_bytestring, tf.uint8)
image = tf.cast(image, tf.float32)/256.0
image = tf.reshape(image, [28*28])
return image
เราใช้ฟังก์ชันนี้กับชุดข้อมูลโดยใช้ .map
และรับชุดข้อมูลของรูปภาพ:
imagedataset = imagedataset.map(read_image, num_parallel_calls=16)
เราจะอ่านและถอดรหัสรูปแบบเดียวกันสำหรับป้ายกำกับ และเราจะ.zip
รูปภาพและป้ายกำกับร่วมกัน ดังนี้
dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))
ตอนนี้เรามีชุดข้อมูลเป็นคู่ (รูปภาพ ป้ายกำกับ) นี่คือสิ่งที่โมเดลของเราคาดไว้ เรายังไม่พร้อมที่จะใช้ฟังก์ชันนี้ในฟังก์ชันการฝึก:
dataset = dataset.cache()
dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)
tf.data.Dataset API มีฟังก์ชันยูทิลิตีที่จำเป็นทั้งหมดสำหรับการเตรียมชุดข้อมูล ดังนี้
.cache
จะแคชชุดข้อมูลใน RAM นี่เป็นชุดข้อมูลขนาดเล็กที่ใช้ได้ .shuffle
จะสุ่มเพลงโดยใช้บัฟเฟอร์ 5,000 องค์ประกอบ สิ่งสำคัญคือต้องมีการสับเปลี่ยนข้อมูลการฝึกให้เหมาะสม .repeat
วนซ้ำชุดข้อมูล เราจะฝึกขั้นตอนนี้หลายครั้ง (หลายๆ ตอน) .batch
จะดึงรูปภาพและป้ายกำกับหลายรายการเข้าด้วยกันเป็นกลุ่มขนาดเล็ก สุดท้าย .prefetch
จะใช้ CPU เพื่อเตรียมกลุ่มถัดไปขณะฝึกกลุ่มปัจจุบันใน GPU ได้
ระบบจะจัดเตรียมชุดข้อมูลการตรวจสอบด้วยวิธีที่คล้ายกัน ตอนนี้เราพร้อมที่จะกำหนดโมเดลและใช้ชุดข้อมูลนี้เพื่อฝึกโมเดลแล้ว
เซลล์ "โมเดล Keras"
โมเดลทั้งหมดจะเป็นลำดับเลเยอร์แบบตรง เราจึงสามารถใช้รูปแบบ tf.keras.Sequential
ในการสร้างได้ ในตอนแรก ที่นี่จะเป็นชั้นที่หนาแน่นชั้นเดียว เซลล์นี้มี 10 เซลล์ เนื่องจากเรากำลังจำแนกตัวเลขที่เขียนด้วยลายมือออกเป็น 10 คลาส โดยใช้ "softmax" การเปิดใช้งานเพราะเป็นชั้นสุดท้ายในตัวแยกประเภท
โมเดล Keras ยังจำเป็นต้องรู้รูปร่างของอินพุตด้วย tf.keras.layers.Input
เพื่อนิยามความหมาย ในที่นี้ เวกเตอร์อินพุตคือเวกเตอร์แบบแบนของค่าพิกเซลความยาว 28*28
model = tf.keras.Sequential(
[
tf.keras.layers.Input(shape=(28*28,)),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='sgd',
loss='categorical_crossentropy',
metrics=['accuracy'])
# print model layers
model.summary()
# utility callback that displays training curves
plot_training = PlotTraining(sample_rate=10, zoom=1)
การกำหนดค่าโมเดลจะทำใน Keras โดยใช้ฟังก์ชัน model.compile
เราใช้เครื่องมือเพิ่มประสิทธิภาพพื้นฐาน 'sgd'
(Stochastic Gradient Descent) โมเดลการจัดประเภทต้องมีฟังก์ชันการสูญเสียครอสเอนโทรปีที่เรียกว่า 'categorical_crossentropy'
ใน Keras สุดท้าย เราขอให้โมเดลคำนวณเมตริก 'accuracy'
ซึ่งเป็นเปอร์เซ็นต์ของรูปภาพที่จัดประเภทอย่างถูกต้อง
Keras มียูทิลิตี model.summary()
ที่ดีมากที่จะพิมพ์รายละเอียดของโมเดลที่คุณสร้างขึ้น ผู้สอนชนิดของคุณได้เพิ่มยูทิลิตี PlotTraining
(ตามที่กำหนดไว้ในเซลล์ "ยูทิลิตีการแสดงภาพข้อมูล") ซึ่งจะแสดงเส้นโค้งการฝึกต่างๆ ในระหว่างการฝึก
เซลล์ "ฝึกและตรวจสอบโมเดล"
ซึ่งเป็นที่ที่การฝึกเกิดขึ้นด้วยการเรียกใช้ model.fit
และส่งผ่านทั้งในชุดข้อมูลการฝึกและการตรวจสอบ โดยค่าเริ่มต้น Keras จะเรียกใช้การตรวจสอบความถูกต้องรอบที่ท้ายแต่ละ Epoch
model.fit(training_dataset, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
validation_data=validation_dataset, validation_steps=1,
callbacks=[plot_training])
ใน Keras คุณสามารถเพิ่มพฤติกรรมที่กำหนดเองในระหว่างการฝึกได้โดยใช้ Callback ซึ่งเป็นวิธีจัดทำแผนการฝึกอบรมที่อัปเดตแบบไดนามิกสำหรับเวิร์กช็อปนี้
เซลล์ "แสดงภาพการคาดคะเน"
เมื่อฝึกโมเดลแล้ว เราจะรับการคาดการณ์จากโมเดลได้โดยโทรหา model.predict()
probabilities = model.predict(font_digits, steps=1)
predicted_labels = np.argmax(probabilities, axis=1)
ที่นี่เราได้จัดเตรียมชุดตัวเลขที่พิมพ์จากแบบอักษรในเครื่องเพื่อเป็นการทดสอบ อย่าลืมว่าโครงข่ายประสาทส่งคืนเวกเตอร์ของความน่าจะเป็น 10 จาก "softmax" ครั้งสุดท้าย เพื่อให้ได้ป้ายกำกับ เราต้องหาความน่าจะเป็นสูงสุด np.argmax
จากไลบรารี numpy เป็นอย่างนั้น
หากต้องการทําความเข้าใจสาเหตุที่ต้องใช้พารามิเตอร์ axis=1
โปรดทราบว่าเราได้ประมวลผลกลุ่มรูปภาพ 128 รูปแล้ว ดังนั้นโมเดลจึงแสดงเวกเตอร์ของความน่าจะเป็น 128 เวกเตอร์ รูปร่างของ Tensor เอาต์พุตคือ [128, 10] เรากำลังคำนวณค่าอาร์กแมกซ์จากความน่าจะเป็น 10 ผลลัพธ์สำหรับแต่ละรูปภาพ ดังนั้น axis=1
(แกนแรกคือ 0)
โมเดลง่ายๆ นี้จดจำตัวเลขได้ 90% แล้ว ไม่เลวทีเดียว แต่ตอนนี้คุณจะปรับปรุงสิ่งนี้ได้อย่างมาก
6. การเพิ่มเลเยอร์
เพื่อปรับปรุงความแม่นยำของในการจดจำ เราจะเพิ่มเลเยอร์เพิ่มเติมเข้าไปในโครงข่ายระบบประสาทเทียม
เราเก็บ Softmax ไว้เป็นฟังก์ชันเปิดใช้งานในเลเยอร์สุดท้ายเนื่องจากเป็นฟังก์ชันที่ทำงานได้ดีที่สุดสำหรับการจัดประเภท ในเลเยอร์ระดับกลาง แต่เราจะใช้ฟังก์ชันเปิดใช้งานแบบดั้งเดิมที่สุด นั่นคือ sigmoid:
ตัวอย่างเช่น โมเดลของคุณอาจมีหน้าตาดังนี้ (อย่าลืมคอมมา tf.keras.Sequential
จะใช้รายการเลเยอร์ที่คั่นด้วยคอมมา)
model = tf.keras.Sequential(
[
tf.keras.layers.Input(shape=(28*28,)),
tf.keras.layers.Dense(200, activation='sigmoid'),
tf.keras.layers.Dense(60, activation='sigmoid'),
tf.keras.layers.Dense(10, activation='softmax')
])
ดูที่ "สรุป" ของโมเดลของคุณ ตอนนี้ซึ่งมีพารามิเตอร์มากขึ้นอย่างน้อย 10 เท่า น่าจะดีกว่านี้อีก 10 เท่า! แต่มันไม่ใช่ ... ด้วยเหตุผลบางประการ
ดูเหมือนว่าความสูญเสียจะพุ่งทะลุหลังคาเหมือนกันนะครับ มีบางอย่างไม่ถูกต้อง
7. ดูแลเครือข่ายเชิงลึกเป็นพิเศษ
คุณเคยได้สัมผัสกับโครงข่ายระบบประสาทเทียมเพราะผู้คนเคยออกแบบโครงข่ายประสาทยุค 80 และ 90 ไม่น่าแปลกใจเลยที่ทั้ง 2 ฝ่ายล้มเลิกแนวคิดเดิม และทำให้เกิดสิ่งที่เรียกกันว่า "AI Winter" ขึ้นมา ที่จริงแล้ว เมื่อคุณเพิ่มเลเยอร์ โครงข่ายประสาทจะยากต่อการบรรจบกันมากขึ้น
ผลปรากฏว่าเครือข่ายประสาทเทียมระดับลึกที่มีหลายเลเยอร์ (20, 50 หรือ 100 เลเยอร์ในปัจจุบัน) สามารถทำงานได้ดีมาก ซึ่งเป็นลูกเล่นทางคณิตศาสตร์เล็กๆ น้อยๆ ในการทำให้แผนภูมิทั้งสองมาบรรจบกัน การค้นพบเคล็ดลับง่ายๆ เหล่านี้คือหนึ่งในเหตุผลของการเรียนรู้เชิงลึกในยุค 2010
การเปิดใช้งาน RELU
ฟังก์ชันการเปิดใช้งาน Sigmoid ค่อนข้างเป็นปัญหาในเครือข่ายที่มีระดับลึก มันจะบีบค่าทั้งหมดระหว่าง 0 ถึง 1 และเมื่อคุณทำเช่นนั้นซ้ำๆ เอาต์พุตของเซลล์ประสาทและการไล่ระดับสีอาจหายไปโดยสิ้นเชิง มีการกล่าวถึงเหตุผลในอดีต แต่เครือข่ายสมัยใหม่ใช้ RELU (Rectified Linear Unit) ซึ่งมีลักษณะดังนี้
อีกนัยหนึ่ง relu มีอนุพันธ์ของ 1 อย่างน้อยอยู่ด้านขวา เมื่อเปิดใช้งาน RELU แม้ว่าการไล่ระดับสีที่มาจากเซลล์ประสาทบางเซลล์จะเป็น 0 แต่ก็ยังมีการไล่ระดับสีอื่นๆ ที่ไม่เป็น 0 ที่ชัดเจนและการฝึกจะดำเนินไปได้ด้วยจังหวะที่เหมาะสม
เครื่องมือเพิ่มประสิทธิภาพที่ดีกว่า
ในพื้นที่ที่มีมิติมากอย่างที่นี่ เรามีการเรียงลำดับน้ำหนักและการให้น้ำหนักพิเศษ 10,000 จุด นั่นคือ "จุดรับอาน" เกิดขึ้นบ่อย จุดเหล่านี้ไม่ใช่จุดต่ำสุดในเครื่อง แต่การไล่ระดับสีจะเป็น 0 และเครื่องมือเพิ่มประสิทธิภาพการไล่ระดับสีจะคงอยู่เช่นนั้น TensorFlow มีชุดเพิ่มประสิทธิภาพเต็มรูปแบบที่พร้อมใช้งาน รวมถึงตัวเพิ่มประสิทธิภาพที่ทำงานกับความเฉื่อยมากขนาดหนึ่งและจะแล่นผ่านจุดอานม้าได้อย่างปลอดภัย
การเริ่มต้นแบบสุ่ม
ศิลปะในการเริ่มใช้อคติน้ำหนักก่อนการฝึกเป็นด้านหนึ่งของการค้นคว้าวิจัยโดยเฉพาะ และมีงานวิจัยจำนวนมากเกี่ยวกับหัวข้อดังกล่าว คุณดูเงื่อนไขเริ่มต้นทั้งหมดที่มีอยู่ใน Keras ได้ที่นี่ โชคดีที่ Keras ทำสิ่งที่ถูกต้องโดยค่าเริ่มต้นและใช้ตัวเริ่มต้น 'glorot_uniform'
ซึ่งดีที่สุดในเกือบทุกกรณี
คุณไม่จำเป็นต้องดำเนินการใดๆ เนื่องจาก Keras ทำสิ่งที่ถูกต้องอยู่แล้ว
ไม่ใช่ ???
สูตรครอสเอนโทรปีเกี่ยวข้องกับลอการิทึม และ log(0) ไม่ใช่ตัวเลข (NaN ซึ่งเป็นข้อขัดข้องที่เป็นตัวเลขหากคุณต้องการ) อินพุตของครอสเอนโทรปีเป็น 0 ได้ไหม อินพุตมาจาก Softmax ซึ่งโดยพื้นฐานแล้วเป็นเลขชี้กำลังและเลขชี้กำลังจะไม่เป็น 0 เราจึงปลอดภัย
คุณแน่ใจใช่ไหม ในโลกคณิตศาสตร์ที่สวยงาม เราคงปลอดภัย แต่ในโลกคอมพิวเตอร์ exp(-150) ที่แสดงในรูปแบบ Float32 กลับไร้ค่าอย่างที่คิด และเกิดการชนแบบครอสเอนโทรปี
โชคดีที่คุณไม่ต้องดำเนินการใดๆ อีก เนื่องจาก Keras จะดูแลเรื่องนี้และคำนวณ Softmax ตามด้วยครอสเอนโทรปีด้วยวิธีที่ระมัดระวังเป็นพิเศษเพื่อให้แน่ใจว่าตัวเลขมีความเสถียรและหลีกเลี่ยง NaN ที่ไม่น่ากังวล
สำเร็จ
ตอนนี้คุณน่าจะมีความแม่นยำ 97% แล้ว เป้าหมายในเวิร์กช็อปนี้คือการทำให้สูงกว่า 99% ได้อย่างมีนัยสำคัญ มาลุยกันต่อเลย
หากยังมีปัญหาอยู่ นี่คือวิธีแก้ไขในจุดนี้
8. ลดลงในอัตราการเรียนรู้
เราลองฝึกให้เร็วขึ้นได้นะ อัตราการเรียนรู้เริ่มต้นในเครื่องมือเพิ่มประสิทธิภาพ Adam คือ 0.001 มาเพิ่มระยะเวลากัน
เร่งความเร็วอาจจะไม่ช่วยอะไรมากนัก แล้วเสียงพวกนี้คืออะไรล่ะ
เส้นโค้งการฝึกจะได้ยินชัดเจนมากและดูที่เส้นโค้งตรวจสอบความถูกต้องทั้งคู่ นั่นคือการเพิ่มขึ้นและลง ซึ่งหมายความว่าเราเร็วเกินไป เรากลับไปใช้ความเร็วก่อนหน้านี้ได้ แต่ก็ยังมีวิธีที่ดีกว่า
วิธีแก้ไขที่ดีคือให้เริ่มต้นได้อย่างรวดเร็ว และลดอัตราการเรียนรู้ลงเป็นเท่าตัว ใน Keras คุณจะดำเนินการดังกล่าวได้ด้วย Callback tf.keras.callbacks.LearningRateScheduler
โค้ดที่เป็นประโยชน์สำหรับการคัดลอกและวาง
# lr decay function
def lr_decay(epoch):
return 0.01 * math.pow(0.6, epoch)
# lr schedule callback
lr_decay_callback = tf.keras.callbacks.LearningRateScheduler(lr_decay, verbose=True)
# important to see what you are doing
plot_learning_rate(lr_decay, EPOCHS)
อย่าลืมใช้ lr_decay_callback
ที่คุณสร้างไว้ เพิ่มลงในรายการ Callback ใน model.fit
:
model.fit(..., callbacks=[plot_training, lr_decay_callback])
การเปลี่ยนแปลงเพียงเล็กน้อยนี้ส่งผลอย่างมาก คุณจะเห็นว่าข้อผิดพลาดส่วนใหญ่หายไป และตอนนี้ความแม่นยำในการทดสอบสูงกว่า 98% อย่างต่อเนื่อง
9. การออกนอก การปรับมากเกินไป
โมเดลนี้ดูเหมือนว่าจะกำลังไปในทางที่ดีขึ้นในขณะนี้ เรามาลองเจาะลึกกัน
วิธีนี้ช่วยได้หรือไม่
ก็ไม่จริง ความถูกต้องยังคงค้างอยู่ที่ 98% และดูการสูญเสียการตรวจสอบ สูงขึ้นแล้ว! อัลกอริทึมการเรียนรู้จะทำงานกับข้อมูลการฝึกเท่านั้น และเพิ่มประสิทธิภาพการสูญเสียการฝึกอย่างเหมาะสม เครื่องมือไม่เคยเห็นข้อมูลการตรวจสอบ จึงไม่น่าแปลกใจที่หลังจากเวลาผ่านไประยะหนึ่งแล้ว การทำงานไม่ได้ส่งผลกระทบต่อการสูญเสียการตรวจสอบซึ่งจะหยุดการลดลง และบางครั้งก็ตีกลับไปด้วยเช่นกัน
สิ่งนี้จะไม่ส่งผลทันทีต่อความสามารถในการจดจำจริงของโมเดลของคุณ แต่จะขัดขวางไม่ให้คุณทำงานซ้ำหลายครั้ง และมักจะเป็นสัญญาณว่าการฝึกไม่มีผลกระทบในเชิงบวกอีกต่อไป
โดยปกติแล้วการยกเลิกการเชื่อมต่อนี้เรียกว่า "การปรับมากเกินไป" และเมื่อเห็นแบบนั้นแล้ว ก็อาจลองใช้เทคนิคการทำให้เป็นมาตรฐานที่เรียกว่า "Dropout" เทคนิคการออกนอกเซลล์จะยิงเซลล์ประสาทแบบสุ่มในการฝึกซ้ำแต่ละครั้ง
ทำงานได้ดีหรือไม่
นอยส์ปรากฏขึ้นอีกครั้ง (ไม่น่าแปลกใจเลยเมื่อทราบวิธีการทำงานของการขาดหาย) ดูเหมือนว่าการสูญเสียการตรวจสอบไม่ได้เพิ่มขึ้นอย่างต่อเนื่อง แต่ในภาพรวมสูงกว่าการไม่มีการยกเลิกกลางคัน ระบบตรวจสอบความถูกต้องได้ลดลงเล็กน้อย เรื่องนี้ค่อนข้างน่าผิดหวัง
ดูเหมือนว่าการออกกลางคันไม่ใช่วิธีแก้ไขที่ถูกต้อง หรืออาจ "มากเกินไป" เป็นแนวคิดที่ซับซ้อนมากขึ้น และสาเหตุบางอย่างอาจใช้ไม่ได้กับ "การขาดหาย" แก้ไข
"การปรับมากเกินไป" คืออะไร การเพิ่มประสิทธิภาพมากเกินไปเกิดขึ้นเมื่อโครงข่ายระบบประสาทเทียมเรียนรู้ "ไม่ดี" ในลักษณะที่ได้ผลกับตัวอย่างการฝึก แต่ไม่ดีนักกับข้อมูลจริง มีเทคนิคการทำให้เป็นมาตรฐาน เช่น การออกกลางคันที่อาจบังคับให้ระบบเรียนรู้ได้ดียิ่งขึ้น แต่การปรับมากเกินไปก็ทำให้มีรากฐานที่ลึกซึ้งกว่านั้น
การปรับอุปกรณ์พื้นฐานมักเกิดขึ้นเมื่อโครงข่ายระบบประสาทเทียมมีระดับความอิสระของปัญหามากเกินไป ลองจินตนาการว่าเรามีเซลล์ประสาทจำนวนมากที่เครือข่ายสามารถจัดเก็บรูปภาพการฝึกทั้งหมดของเรา และจดจำเซลล์เหล่านั้นด้วยการจับคู่รูปแบบได้ ไม่สามารถทำกับข้อมูลในโลกแห่งความเป็นจริงโดยสิ้นเชิงได้ โครงข่ายประสาทจะต้องค่อนข้างจำกัดเพื่อที่จะบังคับให้ต้องสรุปสิ่งที่เรียนรู้ระหว่างการฝึก
หากมีข้อมูลการฝึกน้อยมาก แม้แต่เครือข่ายเล็กๆ ก็อาจเรียนรู้ด้วยใจและคุณจะเห็นข้อความ "ทำงานเกินความจำเป็น" โดยทั่วไปแล้ว คุณต้องมีข้อมูลจำนวนมากเพื่อฝึกโครงข่ายระบบประสาทเทียมเสมอ
สุดท้าย หากคุณทำทุกอย่างในหนังสือ ทดสอบเครือข่ายขนาดต่างๆ เพื่อให้แน่ใจว่าระดับอิสระถูกจำกัด ใช้การออกนอกระบบ และฝึกฝนกับข้อมูลจำนวนมาก คุณอาจยังคงติดอยู่ที่ระดับประสิทธิภาพที่ดูเหมือนจะแก้ไขไม่ได้เลย ซึ่งหมายความว่าเครือข่ายประสาทเทียมของคุณซึ่งมีรูปแบบในปัจจุบันจะดึงข้อมูลเพิ่มเติมจากข้อมูลของคุณไม่ได้ตามที่เราเห็นด้านล่างนี้
จำวิธีที่เราใช้ภาพของเรา โดยทำให้แบนเป็นเวกเตอร์เดียวได้ไหม นั่นเป็นความคิดที่แย่มาก ตัวเลขที่เขียนด้วยลายมือนั้นสร้างจากรูปทรงต่างๆ และเราได้ทิ้งข้อมูลรูปร่างไปเมื่อแบนพิกเซล แต่ก็มีโครงข่ายระบบประสาทเทียมประเภทหนึ่งที่สามารถใช้ประโยชน์จากข้อมูลรูปร่าง นั่นก็คือ เครือข่ายคอนโวลูชัน (Convolutional Network) มาลองกันเลย
หากยังมีปัญหาอยู่ นี่คือวิธีแก้ไขในจุดนี้
10. [INFO] เครือข่ายคอนโวลูชัน (Convolutional Network)
สรุป
หากคุณทราบคำศัพท์ทั้งหมดในตัวหนาในย่อหน้าถัดไปแล้ว คุณสามารถย้ายไปยังแบบฝึกหัดถัดไป หากคุณเพิ่งเริ่มใช้โครงข่ายระบบประสาทเทียมแบบ Convolutional โปรดอ่านต่อ
ภาพประกอบ: การกรองรูปภาพด้วยฟิลเตอร์ต่อเนื่อง 2 รายการซึ่งมีน้ำหนัก 4x4x3=48 ที่เรียนรู้ได้ แต่ละตัวกรอง
นี่คือลักษณะของโครงข่ายประสาทแบบคอนโวลูชัน (Convolutional) แบบง่ายๆ ใน Keras
model = tf.keras.Sequential([
tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1)),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, activation='relu'),
tf.keras.layers.Conv2D(kernel_size=6, filters=24, strides=2, activation='relu'),
tf.keras.layers.Conv2D(kernel_size=6, filters=32, strides=2, activation='relu'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10, activation='softmax')
])
ในเลเยอร์ของเครือข่ายคอนโวลูชัน (Convolutional Network) จะมี "เซลล์ประสาท" 1 เซลล์ เป็นผลรวมถ่วงน้ำหนักของพิกเซลที่อยู่ด้านบนในพื้นที่เล็กๆ ของภาพเท่านั้น เซลล์นี้จะเพิ่มการให้น้ำหนักพิเศษและป้อนผลรวมผ่านฟังก์ชันเปิดใช้งาน เช่นเดียวกับที่เซลล์ประสาทในชั้นที่หนาแน่นปกติสามารถทำ การดำเนินการนี้จะทำซ้ำในทั้งรูปภาพโดยใช้น้ำหนักเดียวกัน อย่าลืมว่าในชั้นที่หนาแน่น เซลล์ประสาทแต่ละเซลล์มีน้ำหนักของตัวเอง ตรงนี้ เรามี "การแก้ไข" เพียงครั้งเดียว ของน้ำหนักที่เลื่อนผ่านภาพทั้ง 2 ทิศทาง ("Conversion") เอาต์พุตจะมีค่าเท่ากับจำนวนพิกเซลในรูปภาพ (แต่ต้องมีระยะห่างจากขอบบางจุด) ซึ่งเป็นการดำเนินการกรอง ในภาพประกอบด้านบน ตัวกรองใช้ฟิลเตอร์น้ำหนัก 4x4x3=48
อย่างไรก็ตาม น้ำหนัก 48 อาจไม่เพียงพอ หากต้องการเพิ่มองศาอิสระ เราจะดำเนินการซ้ำเดิมด้วยน้ำหนักชุดใหม่ ซึ่งจะสร้างเอาต์พุตตัวกรองชุดใหม่ ขอเรียกว่า "ช่อง" ของเอาต์พุตโดยการเปรียบเทียบกับช่อง R,G,B ในภาพอินพุต
น้ำหนักสองชุด (หรือมากกว่านั้น) สามารถสรุปเป็น 1 เซนเซอร์ได้โดยการเพิ่มมิติข้อมูลใหม่ ซึ่งทำให้เรามีรูปทรงทั่วไปของ Tensor น้ำหนักสำหรับชั้นคอนโวลูชัน (Convolutional) เนื่องจากจำนวนของแชแนลอินพุตและเอาต์พุตเป็นพารามิเตอร์ เราจึงสามารถเริ่มซ้อนและเชื่อมโยงเลเยอร์คอนโวลูชัน (Convolutional) ได้
ภาพ: โครงข่ายประสาทแบบคอนโวลูชัน (Convolutional) เปลี่ยนรูปแบบ "ลูกบาศก์" ของข้อมูลลงใน "ลูกบาศก์" อื่นๆ อีกด้วย
คอนโวลูชันแบบมีโครงสร้าง การรวมกันสูงสุด
การทำ Conversion ด้วยระยะก้าว 2 หรือ 3 ช่วยให้เราย่อลูกบาศก์ข้อมูลที่ได้ให้อยู่ในขนาดแนวนอนได้ วิธีทั่วไปมี 2 วิธีดังนี้
- Strided Convolution: ตัวกรองแบบเลื่อนตามด้านบนแต่มีระยะก้าว >1
- การรวมกลุ่มสูงสุด: หน้าต่างเลื่อนที่ใช้การดำเนินการ MAX (โดยปกติจะเป็นแพตช์ 2x2 ทำซ้ำทุก 2 พิกเซล)
ภาพ: การเลื่อนหน้าต่างการประมวลผลทีละ 3 พิกเซลจะทำให้ค่าเอาต์พุตลดลง Convolution ระยะก้าวหรือการรวมกันสูงสุด (สูงสุดในการเลื่อนหน้าต่างขนาด 2x2 ด้วยระยะก้าวที่ 2) เป็นวิธีย่อลูกบาศก์ข้อมูลในขนาดแนวนอน
ชั้นสุดท้าย
หลังชั้น Convolutional ชั้นสุดท้าย ข้อมูลจะอยู่ในรูปแบบ "ลูกบาศก์" มี 2 วิธีในการป้อนเข้าไปในชั้นที่หนาแน่นสุดท้าย
รายการแรกคือทำให้ลูกบาศก์ข้อมูลแบนเป็นเวกเตอร์ แล้วฟีดลงในเลเยอร์ซอฟต์แมกซ์ บางครั้งคุณอาจเพิ่มเลเยอร์ที่หนาแน่นก่อนเลเยอร์ซอฟต์แม็กซ์ได้ด้วย ซึ่งตัวเลขมีแนวโน้มที่จะแพงในแง่ของจำนวนน้ำหนัก ชั้นหนาแน่นที่ส่วนปลายของโครงข่ายประสาทแบบคอนโวลูชัน (Convolutional Network) อาจมีน้ำหนักมากกว่าครึ่งหนึ่งของโครงข่ายระบบประสาทเทียมทั้งหมด
แทนที่จะใช้เลเยอร์ที่หนาแน่นราคาแพง เรายังสามารถแยก "cube" ข้อมูลที่เข้ามาใหม่ เป็นส่วนๆ เท่าที่เรามีคลาส หาค่าเฉลี่ยของค่าต่างๆ และป้อนค่าเหล่านี้ผ่านฟังก์ชันการเปิดใช้งาน softmax วิธีสร้างส่วนหัวการแยกประเภทในลักษณะนี้จะมีน้ำหนักเป็น 0 ใน Keras มีเลเยอร์สำหรับ tf.keras.layers.GlobalAveragePooling2D()
ข้ามไปยังส่วนถัดไปเพื่อสร้างเครือข่ายคอนโวลูชัน (Convolution Network) สำหรับปัญหาที่กำลังเกิดขึ้น
11. เครือข่ายคอนโวลูชัน (Convolutional Network)
ให้เราสร้างเครือข่ายคอนโวลูชัน (Convolutional Network) สำหรับการจดจำตัวเลขที่เขียนด้วยลายมือ เราจะใช้เลเยอร์คอนโวลูชัน (Convolutional) 3 เลเยอร์ที่ด้านบน ส่วนเลเยอร์การอ่านแบบซอฟต์แมกซ์ดั้งเดิมอยู่ด้านล่างและเชื่อมต่อเลเยอร์ดังกล่าวกับเลเยอร์ที่เชื่อมต่ออย่างครบถ้วน 1 ชั้นดังนี้
โปรดสังเกตว่าเลเยอร์คอนโวลูชัน (Convolutional) ที่ 2 และ 3 มีระยะก้าวที่ 2 ซึ่งอธิบายสาเหตุที่ทำให้จำนวนค่าเอาต์พุตลดลงจาก 28x28 เป็น 14x14 และ 7x7
มาเขียนโค้ด Keras กัน
ต้องให้ความสนใจเป็นพิเศษก่อนชั้นคอนโวลูชัน (Convolutional) แรก จริงๆ แล้ว คาดหวังว่าจะเป็น "ลูกบาศก์" แบบ 3 มิติ แต่จนถึงขณะนี้ ชุดข้อมูลของเราได้มีการตั้งค่าไว้สำหรับเลเยอร์ที่หนาแน่น และพิกเซลทั้งหมดของภาพจะถูกทำให้แบนเป็นเวกเตอร์ เราจำเป็นต้องเปลี่ยนแปลงรูปร่างกลับไปเป็นรูปภาพขนาด 28x28x1 (1 ช่องสำหรับรูปภาพสีขาว-ดำ)
tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1))
คุณสามารถใช้เส้นนี้แทนเลเยอร์ tf.keras.layers.Input
ที่มีอยู่จนถึงตอนนี้
ใน Keras ไวยากรณ์สำหรับเลเยอร์ Convolutional "relu" คือ "relu"
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu')
สำหรับคอนโวลูชันแบบก้าวเดิน คุณจะต้องเขียนดังนี้
tf.keras.layers.Conv2D(kernel_size=6, filters=24, padding='same', activation='relu', strides=2)
ในการรวมข้อมูลลูกบาศก์ให้เป็นเวกเตอร์เพื่อให้ใช้เลเยอร์ที่หนาแน่นได้ ให้ทำดังนี้
tf.keras.layers.Flatten()
และสำหรับเลเยอร์ที่หนาแน่น ไวยากรณ์จะไม่เปลี่ยนแปลง
tf.keras.layers.Dense(200, activation='relu')
โมเดลของคุณทำลายอุปสรรคด้านความแม่นยำ 99% หรือไม่ เกือบถูกแล้ว... แต่ให้ดูที่เส้นโค้งการสูญเสียการตรวจสอบ นี่ใช่กระดิ่งไหม
อย่าลืมดูการคาดการณ์ด้วย เป็นครั้งแรกที่คุณจะเห็นว่าตัวเลขทดสอบส่วนใหญ่จาก 10,000 หลักถูกจดจำได้ถูกต้องแล้ว ยังมีการตรวจพบที่ไม่ถูกต้องอยู่เพียงประมาณ 41⁄2 แถวเท่านั้น (ตัวเลขประมาณ 110 หลักจาก 10,000 หลัก)
หากยังมีปัญหาอยู่ นี่คือวิธีแก้ไขในจุดนี้
12. ออกอีกครั้ง
การฝึกอบรมครั้งก่อนหน้านี้แสดงให้เห็นสัญญาณที่ชัดเจนของการปรับมากเกินไป (และยังคงมีความแม่นยำไม่ถึง 99%) เราควรลองออกอีกครั้งไหม
กิจกรรมครั้งนี้เป็นอย่างไรบ้าง
ดูเหมือนว่าการออกฟีเจอร์ใหม่ได้ผลในช่วงเวลานี้ การสูญเสียการตรวจสอบไม่ได้คืบหน้าอีกต่อไป และความแม่นยำสุดท้ายควรสูงกว่า 99% ยินดีด้วย
ครั้งแรกที่เราพยายามนำเครื่องมือออกนอกระบบ เราคิดว่าเราเจอปัญหามากเกินไป ทั้งที่ความจริงแล้วปัญหาอยู่ที่โครงสร้างของโครงข่ายระบบประสาทเทียม เราไม่สามารถไปไกลกว่านี้ได้หากไม่มีเลเยอร์คอนโวลูชัน (Convolutional) และไม่มีสิ่งใดที่ไม่มีช่วงที่ลดลงนี้
คราวนี้ดูเหมือนว่าการที่มากเกินไปคือสาเหตุของปัญหาและการออกกลางคันได้ช่วยได้จริงๆ โปรดทราบว่ามีหลายสิ่งที่อาจทำให้เกิดการตัดการเชื่อมต่อระหว่างเส้นโค้งการฝึกและการสูญเสียการตรวจสอบ โดยการสูญเสียการตรวจสอบกำลังคืบหน้าขึ้นเรื่อยๆ การกำหนดทิศทางมากเกินไป (อิสระมากเกินไป เครือข่ายใช้อย่างไม่เหมาะสม) เป็นเพียงอย่างหนึ่งเท่านั้น หากชุดข้อมูลเล็กเกินไปหรือสถาปัตยกรรมของโครงข่ายระบบประสาทเทียมไม่เพียงพอ คุณอาจเห็นลักษณะการทำงานที่คล้ายกันในเส้นโค้ง Loss แต่การออกจากเซลล์จะไม่ช่วยอะไร
13. การแปลงข้อมูลเป็นกลุ่ม
สุดท้ายลองเพิ่มการปรับให้เป็นมาตรฐานกลุ่ม
นี่คือทฤษฎี ในทางปฏิบัติ เพียงแค่จดจำกฎ 2 ข้อต่อไปนี้
มาดูตัวอย่างหนังสือและเพิ่มเลเยอร์ Norm แบบแบทช์ลงในเลเยอร์โครงข่ายระบบประสาทเทียมแต่ละชั้น ยกเว้นชั้นสุดท้าย อย่าเพิ่มลงใน "softmax" สุดท้าย ไม่มีประโยชน์ที่นั่น
# Modify each layer: remove the activation from the layer itself.
# Set use_bias=False since batch norm will play the role of biases.
tf.keras.layers.Conv2D(..., use_bias=False),
# Batch norm goes between the layer and its activation.
# The scale factor can be turned off for Relu activation.
tf.keras.layers.BatchNormalization(scale=False, center=True),
# Finish with the activation.
tf.keras.layers.Activation('relu'),
ความแม่นยำตอนนี้เป็นอย่างไรบ้าง
เพียงปรับแต่งเล็กน้อย (BATCH_SIZE=64, พารามิเตอร์ลดลงของอัตราการเรียนรู้ 0.666, อัตราการออกจากเลเยอร์ในเลเยอร์ที่หนาแน่น 0.3) และด้วยความโชคดี คุณก็จะได้สูงถึง 99.5% การปรับอัตราการเรียนรู้และการลดหย่อนได้ดำเนินการตาม "แนวทางปฏิบัติแนะนำ" สำหรับการใช้มาตรฐานกลุ่ม:
- Batch Norm ทำให้โครงข่ายประสาทบรรจบกัน และมักจะช่วยให้คุณฝึกได้เร็วขึ้น
- Batch Norm เป็นตัวปรับรูปแบบ โดยปกติแล้วคุณสามารถลดจำนวนการออกกลางคันที่คุณใช้ หรือแม้แต่ไม่ใช้การออกเลยเลยก็ได้
สมุดบันทึกของโซลูชันมีการฝึกทำงาน 99.5%:
14. ฝึกใช้ฮาร์ดแวร์ประสิทธิภาพสูงในระบบคลาวด์: AI Platform
คุณจะเห็นโค้ดเวอร์ชันที่พร้อมใช้งานในระบบคลาวด์ในโฟลเดอร์ mlengine บน GitHub พร้อมกับวิธีเรียกใช้โค้ดใน Google Cloud AI Platform คุณจะต้องสร้างบัญชี Google Cloud และเปิดใช้การเรียกเก็บเงินก่อน จึงจะเรียกใช้ส่วนนี้ได้ ทรัพยากรที่จำเป็นในการทำห้องทดลองให้เสร็จสมบูรณ์ควรต่ำกว่า 2-3 ดอลลาร์ (สมมติว่าต้องใช้เวลาฝึก 1 ชั่วโมงใน GPU 1 ตัว) วิธีเตรียมบัญชี
- สร้างโปรเจ็กต์ Google Cloud Platform ( http://cloud.google.com/console)
- เปิดใช้การเรียกเก็บเงิน
- ติดตั้งเครื่องมือบรรทัดคำสั่ง GCP ( GCP SDK ที่นี่)
- สร้างที่เก็บข้อมูล Google Cloud Storage (ป้อนในภูมิภาค
us-central1
) โดยจะใช้เพื่อแสดงโค้ดการฝึกและจัดเก็บโมเดลที่ฝึกไว้ของคุณ - เปิดใช้ API ที่จำเป็นและขอโควต้าที่จำเป็น (เรียกใช้คำสั่งการฝึกครั้งเดียว แล้วคุณควรจะได้รับข้อความแสดงข้อผิดพลาดที่แจ้งว่าควรเปิดใช้อะไร)
15. ยินดีด้วย
คุณได้สร้างโครงข่ายระบบประสาทเทียมแห่งแรกและฝึกให้มีความแม่นยำถึง 99% เทคนิคที่เรียนรู้ระหว่างทางไม่ได้มีเพียงแค่ชุดข้อมูล MNIST เท่านั้น แต่จริงๆ แล้วมีการใช้กันอย่างแพร่หลายเมื่อทำงานกับโครงข่ายประสาท "โน้ตจากหน้าผา" เพื่อเป็นการส่งต่อของขวัญ สำหรับ Lab ในเวอร์ชันการ์ตูน คุณสามารถใช้โปรแกรมนี้เพื่อจดจำสิ่งที่คุณได้เรียนรู้ เช่น
ขั้นตอนถัดไป
- หลังจากที่เชื่อมต่ออย่างสมบูรณ์และเชื่อมต่อแบบคอนโวลูชันแล้ว คุณควรดูโครงข่ายระบบประสาทเทียมแบบเกิดซ้ำ
- Google Cloud มี AI Platform เพื่อเรียกใช้การฝึกหรือการอนุมานในระบบคลาวด์บนโครงสร้างพื้นฐานแบบกระจาย
- สุดท้ายนี้ เราให้ความสำคัญกับความคิดเห็น โปรดแจ้งให้เราทราบ หากคุณพบสิ่งที่ควรปรับปรุงในห้องทดลองนี้ หรือคุณคิดว่าเราควรปรับปรุง เราจัดการกับความคิดเห็นผ่านปัญหาเกี่ยวกับ GitHub [ feedback link]
ผู้เขียน: Martin GörnerTwitter: @martin_gorner |
ภาพการ์ตูนทั้งหมดในลิขสิทธิ์ของห้องทดลองนี้: ภาพสต็อก alexpokusay / 123RF