สารบัญ[ซ่อน][แสดง]
สมองเปรียบได้กับโครงข่ายประสาทเทียม นี่คือการเปรียบเทียบที่มักใช้เพื่อช่วยเหลือผู้ที่มาใหม่ในเรื่องให้เข้าใจแนวคิดเบื้องหลังการเรียนรู้ของเครื่องและโครงข่ายประสาทเทียม
เนื่องจากมีหลายชั้นของการคำนวณทางคณิตศาสตร์และสถิติที่เกิดขึ้นเบื้องหลัง การกำหนดเครือข่ายเหล่านี้เป็นฟังก์ชันทางคณิตศาสตร์เป็นวิธีการขั้นสูง
นี้มีไว้สำหรับผู้ที่มีความสนใจในการเรียนรู้ของเครื่องจริง ๆ และต้องการดูว่ารหัสเครือข่ายประสาทเทียมของ Python นั้นเขียนอย่างไร
ในบทความนี้ เราจะสาธิตวิธีสร้าง Deep Neural Network (DNN) ที่เชื่อมต่ออย่างสมบูรณ์ตั้งแต่เริ่มต้นใน หลาม 3.
ภาพรวมของโครงสร้างไฟล์สำหรับรหัส Python Neural Network ของเรา
จะมีสามไฟล์ที่สร้างขึ้นที่นี่ ไฟล์แรกคือไฟล์ nn.py แบบง่าย ซึ่งจะกล่าวถึงใน "การตั้งค่าฟังก์ชันตัวช่วย" และ "การสร้างเครือข่ายประสาทเทียมตั้งแต่เริ่มต้น"
เราจะมีไฟล์ชื่อ mnist loader.py เพื่อโหลดข้อมูลทดสอบ ตามที่อธิบายไว้ใน “กำลังโหลดข้อมูล MNIST”
สุดท้าย เราจะมีไฟล์ชื่อ test.py ซึ่งจะเปิดตัวในเทอร์มินัลเพื่อทดสอบโครงข่ายประสาทเทียมของเรา
ไฟล์นี้มีรายละเอียดอยู่ใน “การทดสอบการทำงาน”
การติดตั้ง
ต้องดาวน์โหลดไลบรารี NumPy Python เพื่อทำตามบทช่วยสอนนี้ คุณสามารถทำได้โดยใช้คำสั่งต่อไปนี้บนเทอร์มินัล:
การนำเข้าโมดูลและการตั้งค่าฟังก์ชัน Helper
ห้องสมุดสองแห่งที่เราต้องการคือสุ่มและ NumPy ซึ่งเราจะนำเข้าทันที สำหรับน้ำหนักเริ่มต้นของโครงข่ายประสาทเทียม เราจะสับเปลี่ยนมันโดยใช้ไลบรารีแบบสุ่ม
เพื่อให้การคำนวณของเราเร็วขึ้น เราจะใช้ NumPy หรือ np (ตามแบบแผน มักจะนำเข้าเป็น np) ฟังก์ชันตัวช่วยทั้งสองของเราจะถูกสร้างขึ้นหลังจากการนำเข้าของเรา สองฟังก์ชันซิกมอยด์: หนึ่งและซิกมอยด์ไพรม์
การถดถอยโลจิสติกจะจัดประเภทข้อมูลโดยใช้ฟังก์ชัน sigmoid ในขณะที่ backpropagation จะคำนวณเดลต้าหรือการไล่ระดับสีโดยใช้ฟังก์ชัน sigmoid prime
การสร้างคลาสเครือข่าย
การสร้างโครงข่ายประสาทเทียมที่เชื่อมโยงอย่างสมบูรณ์เป็นจุดสนใจเดียวของส่วนนี้ คลาสเครือข่ายจะรวมฟังก์ชันทั้งหมดที่ตามมา ฟังก์ชัน Object() { [native code] } จะถูกสร้างขึ้นในคลาสเครือข่ายของเราในขั้นต้น
ฟังก์ชัน Object() { [native code] } ต้องการอาร์กิวเมนต์ขนาดหนึ่งตัว ตัวแปรขนาดคือชุดของค่าตัวเลขที่แสดงจำนวนโหนดอินพุตที่มีอยู่ในแต่ละเลเยอร์ของโครงข่ายประสาทเทียมของเรา
เราเริ่มต้นคุณสมบัติสี่ประการในวิธี __init__ ของเรา ตัวแปรอินพุต ขนาด ใช้เพื่อกำหนดรายการขนาดเลเยอร์และจำนวนเลเยอร์ num เลเยอร์ตามลำดับ
ขั้นตอนแรกคือการสุ่มกำหนดอคติเริ่มต้นของเครือข่ายของเราให้กับแต่ละเลเยอร์ที่ตามหลังเลเยอร์อินพุต
สุดท้าย แต่ละลิงก์ระหว่างชั้นอินพุตและเอาต์พุตจะมีน้ำหนักที่สร้างขึ้นแบบสุ่ม Np.Random.Randn() ให้ตัวอย่างสุ่มที่ดึงมาจากการแจกแจงแบบปกติสำหรับบริบท
ฟังก์ชั่นฟีดไปข้างหน้า
ในโครงข่ายประสาทเทียม ข้อมูลจะถูกส่งต่อโดยฟังก์ชัน feedforward ฟังก์ชันนี้จำเป็นต้องมีอาร์กิวเมนต์ a ซึ่งระบุเวกเตอร์การเปิดใช้งานปัจจุบัน
ฟังก์ชันนี้จะประเมินการเปิดใช้งานในแต่ละเลเยอร์โดยวนซ้ำอคติและน้ำหนักทั้งหมดในเครือข่าย คำตอบที่ได้รับคือการทำนาย ซึ่งเป็นการเปิดใช้งานเลเยอร์สุดท้าย
โคตรไล่ระดับมินิแบทช์
ตัวช่วยของคลาส Network ของเราคือ Gradient Descent ในเวอร์ชันนี้ เราใช้การไล่ระดับสีแบบกลุ่มย่อย (สุ่ม) ซึ่งเป็นรูปแบบการไล่ระดับสีที่ปรับเปลี่ยนแล้ว
สิ่งนี้บ่งชี้ว่าจะใช้จุดข้อมูลกลุ่มเล็กๆ ในการอัปเดตโมเดลของเรา อาร์กิวเมนต์ที่จำเป็นสี่รายการและอาร์กิวเมนต์ที่เป็นทางเลือกหนึ่งรายการจะถูกส่งผ่านไปยังวิธีนี้ ตัวแปรที่จำเป็นสี่ตัว ได้แก่ ชุดข้อมูลการฝึก จำนวนยุค ขนาดของชุดย่อย และอัตราการเรียนรู้ (กทพ.)
ข้อมูลการทดสอบสามารถขอได้ เราจะให้ข้อมูลการทดสอบเมื่อเราประเมินเครือข่ายนี้ในที่สุด จำนวนตัวอย่างในฟังก์ชันนี้เริ่มต้นจากความยาวของรายการ เมื่อข้อมูลการฝึกถูกแปลงเป็นประเภทรายการ
เรายังใช้กระบวนการเดียวกันนี้ในการทดสอบข้อมูลที่ได้รับ เนื่องจากแทนที่จะส่งคืนให้เราเป็นรายการ กลับกลายเป็นซิปของรายการจริงๆ เมื่อเราโหลดตัวอย่างข้อมูล MNIST ในภายหลัง เราจะเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้
หากเราสามารถตรวจสอบให้แน่ใจว่าเราได้ให้ข้อมูลทั้งสองประเภทเป็นรายการ การแคสต์ประเภทนี้ก็ไม่จำเป็นเสมอไป
เมื่อเราได้ข้อมูลแล้ว เราจะข้ามช่วงการฝึกแบบวนซ้ำ ระยะเวลาการฝึกอบรมเป็นเพียงรอบหนึ่งของการฝึกอบรมโครงข่ายประสาทเทียม ก่อนอื่นเราสับเปลี่ยนข้อมูลในแต่ละยุคเพื่อให้แน่ใจว่ามีการสุ่มก่อนที่จะสร้างรายการชุดย่อย
ฟังก์ชันอัพเดตมินิแบตช์ ซึ่งจะกล่าวถึงด้านล่าง จะถูกเรียกสำหรับแต่ละชุดย่อย ความถูกต้องของการทดสอบจะถูกส่งกลับหากมีข้อมูลการทดสอบ
ฟังก์ชันตัวช่วยต้นทุนอนุพันธ์
มาพัฒนาฟังก์ชันตัวช่วยที่เรียกว่า cost Derivatives กันก่อนที่เราจะสร้างโค้ด backpropagation จริงๆ ถ้าเราทำผิดพลาดในชั้นผลลัพธ์ของเรา ฟังก์ชันอนุพันธ์ต้นทุนจะแสดงมัน
มันต้องการสองอินพุต: อาร์เรย์การเปิดใช้งานเอาต์พุตและพิกัด y ของค่าเอาต์พุตที่คาดการณ์ไว้
ฟังก์ชัน Backpropagation
เวกเตอร์การเปิดใช้งานปัจจุบันของเรา การเปิดใช้งาน ตลอดจนเวกเตอร์การเปิดใช้งาน การเปิดใช้งาน และ z-vectors, zs อื่น ๆ จะต้องจำไว้ทั้งหมด เลเยอร์ที่เรียกว่าเลเยอร์อินพุตจะถูกเปิดใช้งานก่อน
เราจะวนรอบอคติและน้ำหนักแต่ละรายการหลังจากวางมันแล้ว แต่ละลูปเกี่ยวข้องกับการคำนวณเวกเตอร์ z เป็นผลิตภัณฑ์ดอทของน้ำหนักและการเปิดใช้งาน เพิ่มลงในรายการ zs คำนวณการเปิดใช้งานใหม่ และเพิ่มการเปิดใช้งานที่อัปเดตลงในรายการการเปิดใช้งาน
ในที่สุดคณิตศาสตร์ เดลต้าซึ่งเท่ากับข้อผิดพลาดจากเลเยอร์ก่อนหน้าคูณด้วยซิกมอยด์ไพรม์ขององค์ประกอบสุดท้ายของเวกเตอร์ zs จะถูกคำนวณก่อนที่เราจะเริ่มต้นการย้อนกลับ
เลเยอร์สุดท้ายของ nabla b ถูกตั้งค่าให้เป็นเดลต้า และเลเยอร์สุดท้ายของ nabla w ถูกตั้งค่าให้เป็นผลิตภัณฑ์ดอทของเดลต้าและเลเยอร์ที่สองถึงเลเยอร์สุดท้ายของการเปิดใช้งาน (สลับเปลี่ยนเพื่อให้เราสามารถคำนวณได้จริง) .
เราดำเนินการเหมือนเดิม โดยเริ่มจากชั้นที่สองและปิดท้ายด้วยชั้นสุดท้าย และทำซ้ำขั้นตอนหลังจากเสร็จสิ้นชั้นสุดท้ายเหล่านี้ จากนั้น nablas จะได้รับกลับเป็นทูเพิล
กำลังอัปเดตการไล่ระดับสีแบบกลุ่มย่อย
วิธีการ SGD (stochastic gradient descent) ของเราจากก่อนหน้านี้รวมการอัพเดทแบบย่อย เนื่องจากมันถูกใช้ใน SGD แต่ยังต้องใช้ backprop ฉันจึงสงสัยว่าจะวางฟังก์ชันนี้ไว้ที่ใด
ในที่สุด ฉันก็เลือกที่จะโพสต์ที่นี่ มันเริ่มต้นด้วยการสร้างเวกเตอร์ 0 ตัวของ nablas ของอคติและน้ำหนัก เช่นเดียวกับฟังก์ชัน backprop ของเรา
ต้องใช้ mini-batch และอัตราการเรียนรู้ eta เป็นอินพุตสองตัว ใน mini-batch จากนั้นเราใช้ฟังก์ชัน backprop เพื่อรับ delta ของ nabla array แต่ละอันสำหรับอินพุต x และเอาต์พุต y แต่ละรายการ รายการ nabla จะได้รับการอัปเดตด้วยเดลต้าเหล่านี้
สุดท้าย เราใช้อัตราการเรียนรู้และ nablas เพื่ออัปเดตน้ำหนักและอคติของเครือข่าย แต่ละค่าจะได้รับการอัปเดตเป็นค่าล่าสุด หักด้วยอัตราการเรียนรู้ คูณด้วยขนาดมินิแบตช์ แล้วเพิ่มลงในค่า nabla
ฟังก์ชั่นการประเมิน
ฟังก์ชันประเมินเป็นฟังก์ชันสุดท้ายที่เราต้องเขียน ข้อมูลทดสอบเป็นเพียงอินพุตเดียวสำหรับฟังก์ชันนี้ ในฟังก์ชันนี้ เราเปรียบเทียบเฉพาะผลลัพธ์ของเครือข่ายกับผลลัพธ์ที่คาดไว้ y โดยการป้อนอินพุต x ไปข้างหน้า ผลลัพธ์ของเครือข่ายจะถูกกำหนด
กรอกรหัส
เมื่อเรารวมโค้ดทั้งหมดเข้าด้วยกัน โค้ดก็จะออกมาเป็นแบบนี้
การทดสอบโครงข่ายประสาทเทียม
กำลังโหลดข้อมูล MNIST
พื้นที่ ข้อมูล MNIST อยู่ในรูปแบบ .pkl.gz ซึ่งเราจะเปิดโดยใช้ GZIP และโหลดด้วย pickle มาเขียนวิธีการโหลดข้อมูลนี้เป็นทูเพิลขนาด XNUMX กันอย่างรวดเร็ว โดยแบ่งออกเป็นข้อมูลการฝึกอบรม การตรวจสอบความถูกต้อง และการทดสอบกัน
เพื่อให้ข้อมูลของเราจัดการได้ง่ายขึ้น เราจะเขียนฟังก์ชันอื่นเพื่อเข้ารหัส y ลงในอาร์เรย์ 10 รายการ อาร์เรย์จะเป็น 0 ทั้งหมด ยกเว้น 1 ที่ตรงกับตัวเลขที่ถูกต้องของรูปภาพ
เราจะใช้ข้อมูลการโหลดพื้นฐานและวิธีการเข้ารหัสแบบด่วนวิธีหนึ่งเพื่อโหลดข้อมูลของเราในรูปแบบที่อ่านได้ ฟังก์ชันอื่นจะถูกเขียนขึ้นเพื่อแปลงค่า x ของเราเป็นรายการขนาด 784 จับคู่กับ 784 พิกเซลของรูปภาพ และค่า y ของเราให้เป็นรูปแบบเวกเตอร์ที่เข้ารหัสแบบ hot เดียว
จากนั้นเราจะรวมค่า x และ y เพื่อให้ดัชนีหนึ่งตรงกับค่าอื่น สิ่งนี้ใช้กับชุดข้อมูลการฝึกอบรม การตรวจสอบความถูกต้อง และการทดสอบ จากนั้นเราจะส่งคืนข้อมูลที่เปลี่ยนแปลง
วิ่งทดสอบ
เราจะสร้างไฟล์ใหม่ชื่อ “mnist loader” ซึ่งจะนำเข้าทั้งโครงข่ายประสาทเทียมที่เราสร้างไว้ก่อนหน้านี้ (nn แบบง่าย) และตัวโหลดชุดข้อมูล MNIST ก่อนที่เราจะเริ่มการทดสอบ
ในไฟล์นี้ สิ่งที่เราต้องทำคือนำเข้าข้อมูล สร้างเครือข่ายที่มีขนาดเลเยอร์อินพุต 784 และขนาดเลเยอร์เอาต์พุต 10 เรียกใช้ฟังก์ชัน SGD ของเครือข่ายกับข้อมูลการฝึกอบรม จากนั้นทดสอบโดยใช้ข้อมูลทดสอบ
โปรดทราบว่าสำหรับรายการเลเยอร์อินพุตของเรา ตัวเลขใดๆ อยู่ระหว่าง 784 ถึง 10 ไม่ได้มีความแตกต่างกัน เราสามารถเปลี่ยนเลเยอร์อื่นๆ ได้ตามต้องการ เฉพาะขนาดอินพุตและเอาต์พุตเท่านั้นที่ได้รับการแก้ไข
ไม่จำเป็นต้องมีสามชั้น เราอาจใช้สี่ ห้า หรือแค่สองก็ได้ ขอให้สนุกกับการทดลองใช้
สรุป
ที่นี่โดยใช้ Python 3 เราสร้างโครงข่ายประสาทเทียมตั้งแต่เริ่มต้น นอกจากคณิตศาสตร์ระดับสูงแล้ว เรายังกล่าวถึงลักษณะเฉพาะของการนำไปปฏิบัติด้วย
เราเริ่มต้นด้วยการใช้ฟังก์ชันตัวช่วย เพื่อให้เซลล์ประสาททำงาน ฟังก์ชันไพรม์ซิกมอยด์และซิกมอยด์มีความสำคัญอย่างยิ่ง จากนั้นเราก็นำฟังก์ชัน feedforward ซึ่งเป็นกระบวนการพื้นฐานสำหรับการป้อนข้อมูลเข้าสู่โครงข่ายประสาทเทียม
ต่อไป เราสร้างฟังก์ชันการไล่ระดับสีใน Python ซึ่งเป็นกลไกที่ขับเคลื่อนโครงข่ายประสาทเทียมของเรา ในการระบุตำแหน่ง "จุดต่ำสุดเฉพาะที่" และปรับน้ำหนักและอคติให้เหมาะสม โครงข่ายประสาทเทียมของเราจะใช้การไล่ระดับสีแบบไล่ระดับสี เราสร้างฟังก์ชัน backpropagation โดยใช้ การไล่ระดับสี.
ด้วยการส่งข้อมูลอัปเดตเมื่อเอาต์พุตไม่ตรงกับป้ายกำกับที่เหมาะสม ฟังก์ชันนี้ช่วยให้เครือข่ายประสาทสามารถ "เรียนรู้"
ในที่สุด เราก็ใส่ Python . ใหม่ล่าสุดของเรา เครือข่ายประสาท เพื่อทดสอบโดยใช้ชุดข้อมูล MNIST ทุกอย่างทำงานได้อย่างราบรื่น
มีความสุขในการเข้ารหัส!
เขียนความเห็น