การทดสอบหน่วยเป็นเพื่อนของคุณ
มีคำพูดในหมู่นักเขียนว่า "การเขียนทั้งหมดเป็นการเขียนใหม่" - นั่นคือส่วนใหญ่ของการเขียนกำลังแก้ไข สำหรับโปรแกรมเมอร์ (หรืออย่างน้อยนักวิทยาศาสตร์ข้อมูล) การแสดงออกอาจถูกเขียนซ้ำอีกครั้งว่า "การเข้ารหัสทั้งหมดกำลังดีบั๊ก"
เมื่อใดก็ตามที่คุณเขียนโค้ดคุณต้องตรวจสอบว่ามันทำงานได้ตามที่ต้องการ วิธีที่ดีที่สุดที่ฉันเคยพบในการตรวจสอบความถูกต้องคือการแบ่งรหัสของคุณออกเป็นส่วนย่อย ๆ และตรวจสอบว่าแต่ละส่วนทำงานได้หรือไม่ ซึ่งสามารถทำได้โดยการเปรียบเทียบเอาต์พุตเซ็กเมนต์กับสิ่งที่คุณรู้ว่าเป็นคำตอบที่ถูกต้อง นี้เรียกว่าการทดสอบหน่วย การเขียนการทดสอบหน่วยที่ดีเป็นส่วนสำคัญของการเป็นนักสถิติ / นักวิทยาศาสตร์ข้อมูล / ผู้เชี่ยวชาญด้านการเรียนรู้เครื่อง / ผู้ปฏิบัติงานเครือข่ายประสาทที่ดี ไม่มีอะไรมาทดแทน
คุณต้องตรวจสอบว่ารหัสของคุณปราศจากข้อบกพร่องก่อนจึงจะสามารถปรับประสิทธิภาพเครือข่ายได้! ไม่เช่นนั้นคุณอาจจะจัดเก้าอี้อาบแดดบนRMS Titanicอีกครั้ง
มีคุณสมบัติสองอย่างของโครงข่ายประสาทที่ทำให้การตรวจสอบมีความสำคัญมากกว่าการเรียนรู้ของเครื่องหรือแบบจำลองทางสถิติอื่น ๆ
เครือข่ายนิวรัลไม่ใช่อัลกอริธึมแบบ "ไม่เก็บ" ในวิธีที่ฟอเรสต์แบบสุ่มหรือการถดถอยโลจิสติก แม้จะเป็นเครือข่ายที่เรียบง่ายและมีการส่งต่อไปยังเครือข่ายนั้นผู้ใช้ส่วนใหญ่จะทำการตัดสินใจมากมายเกี่ยวกับวิธีการกำหนดค่าเครือข่ายเชื่อมต่อเริ่มต้นและปรับให้เหมาะสม ซึ่งหมายถึงการเขียนรหัสและการเขียนรหัสหมายถึงการดีบัก
แม้ว่ารหัสเครือข่ายประสาทจะดำเนินการโดยไม่มีข้อยกเว้น แต่เครือข่ายก็ยังมีข้อบกพร่องได้! ข้อผิดพลาดเหล่านี้อาจเป็นประเภทร้ายกาจที่เครือข่ายจะฝึกอบรม แต่ติดอยู่ที่การแก้ปัญหาย่อยที่ดีที่สุดหรือเครือข่ายที่เกิดขึ้นไม่ได้มีสถาปัตยกรรมที่ต้องการ ( นี่เป็นตัวอย่างของความแตกต่างระหว่างข้อผิดพลาดทางไวยากรณ์และความหมาย )
โพสต์ขนาดกลางนี้" วิธีการเรียนรู้การทดสอบหน่วยรหัสเครื่อง" โดย Chase Roberts กล่าวถึงการทดสอบหน่วยสำหรับแบบจำลองการเรียนรู้ของเครื่องโดยละเอียด ฉันยืมตัวอย่างรหัส buggy นี้จากบทความ:
def make_convnet(input_image):
net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
return net
คุณเห็นข้อผิดพลาดหรือไม่? การดำเนินการที่แตกต่างกันจำนวนมากไม่ได้ใช้จริงเพราะผลลัพธ์ก่อนหน้าเขียนทับด้วยตัวแปรใหม่ การใช้รหัสบล็อกนี้ในเครือข่ายจะยังคงมีการฝึกอบรมและน้ำหนักจะอัปเดตและการสูญเสียอาจลดลง - แต่รหัสแน่นอนไม่ได้ทำในสิ่งที่ตั้งใจไว้ (ผู้เขียนไม่สอดคล้องกับการใช้คำพูดเดียวหรือสองคำ แต่เป็นโวหารล้วนๆ)
ข้อผิดพลาดทั่วไปในการเขียนโปรแกรมที่เกี่ยวข้องกับเครือข่ายประสาทคือ
- ตัวแปรถูกสร้างขึ้น แต่ไม่เคยใช้ (มักจะเป็นเพราะข้อผิดพลาดในการคัดลอกวาง);
- นิพจน์สำหรับการปรับปรุงการไล่ระดับสีไม่ถูกต้อง
- ไม่ใช้การอัปเดตน้ำหนัก
- ฟังก์ชั่นการสูญเสียไม่ได้วัดในระดับที่ถูกต้อง (ตัวอย่างเช่นการสูญเสียข้ามเอนโทรปีสามารถแสดงในแง่ของความน่าจะเป็นหรือการบันทึก)
- การสูญเสียไม่เหมาะสำหรับงาน (ตัวอย่างเช่นการใช้การสูญเสียข้ามเอนโทรปีอย่างเด็ดขาดสำหรับงานถดถอย)
คลานก่อนเดิน เดินก่อนวิ่ง
เครือข่ายประสาทที่กว้างและลึกและเครือข่ายประสาทที่มีการเดินสายแปลกใหม่เป็นสิ่งที่น่าสนใจในการเรียนรู้ของเครื่อง แต่เครือข่ายเหล่านี้ไม่ได้เกิดขึ้นอย่างสมบูรณ์ นักออกแบบสร้างขึ้นเพื่อพวกเขาจากหน่วยที่เล็กลง ขั้นแรกสร้างเครือข่ายขนาดเล็กที่มีเลเยอร์ที่ซ่อนอยู่เพียงชั้นเดียวและตรวจสอบว่าทำงานได้อย่างถูกต้อง จากนั้นเพิ่มความซับซ้อนของโมเดลเพิ่มเติมทีละส่วนและตรวจสอบว่าแต่ละชิ้นนั้นทำงานได้ดีเช่นกัน
มีเซลล์ประสาทในเลเยอร์น้อย เกินไปที่จะ จำกัด การเป็นตัวแทนที่เครือข่ายเรียนรู้ทำให้ไม่เหมาะสม เซลล์ประสาทมากเกินไปอาจทำให้เกิดความเหมาะสมมากเกินไปเนื่องจากเครือข่ายจะ "จดจำ" ข้อมูลการฝึกอบรม
แม้ว่าคุณจะสามารถพิสูจน์ได้ว่ามีทางคณิตศาสตร์เพียงจำนวนน้อยของเซลล์ประสาทที่จำเป็นในการจำลองปัญหาก็มักจะเป็นกรณีที่มี "อีกไม่กี่" เซลล์ประสาททำให้มันง่ายขึ้นสำหรับการเพิ่มประสิทธิภาพในการหาการตั้งค่า "ดี" (แต่ฉันไม่คิดว่าทุกคนจะเข้าใจว่าเหตุใดในกรณีนี้) ฉันให้ตัวอย่างสิ่งนี้ในบริบทของปัญหา XOR ที่นี่: การทำซ้ำของฉันไม่จำเป็นต้องฝึกอบรม NN สำหรับ XOR ด้วย MSE <0.001 สูงเกินไปหรือไม่ .
การเลือกจำนวนเลเยอร์ที่ซ่อนอยู่ทำให้เครือข่ายเรียนรู้สิ่งที่เป็นนามธรรมจากข้อมูลดิบ การเรียนรู้อย่างลึกซึ้งนั้นเป็นสิ่งที่ทุกวันนี้และเครือข่ายที่มีเลเยอร์จำนวนมากได้แสดงผลลัพธ์ที่น่าประทับใจ แต่การเพิ่มเลเยอร์ที่ซ่อนอยู่มากเกินไปอาจทำให้เกิดความเสี่ยงสูงเกินไปหรือทำให้ยากที่จะเพิ่มประสิทธิภาพเครือข่าย
การเลือกการเดินสายเครือข่ายที่ฉลาดสามารถช่วยคุณได้มาก แหล่งข้อมูลของคุณรองรับสถาปัตยกรรมเครือข่ายเฉพาะหรือไม่ เครือข่ายประสาทเทียม Convolutional สามารถบรรลุผลลัพธ์ที่น่าประทับใจในแหล่งข้อมูล "โครงสร้าง" ภาพหรือข้อมูลเสียง เครือข่ายประสาทที่เกิดขึ้นซ้ำสามารถทำได้ดีกับชนิดข้อมูลที่เรียงตามลำดับเช่นภาษาธรรมชาติหรือข้อมูลอนุกรมเวลา การเชื่อมต่อที่เหลือสามารถปรับปรุงเครือข่ายการส่งต่อลึก
การฝึกอบรมเครือข่ายนิวรัลเหมือนกับการเลือกล็อค
เพื่อให้บรรลุรัฐของศิลปะหรือแม้กระทั่งดีเพียงผลลัพธ์ที่คุณต้องมีเพื่อให้มีการตั้งค่าทั้งหมดของชิ้นส่วนการกำหนดค่าให้ทำงานได้ดีร่วมกัน การตั้งค่าโครงข่ายประสาทเทียมที่เรียนรู้ได้จริงนั้นเป็นเรื่องมากเช่นการเลือกล็อค: ชิ้นส่วนทั้งหมดจะต้องเรียงกันอย่างถูกต้อง เนื่องจากมันไม่เพียงพอที่จะมีแก้วน้ำใบเดียวในสถานที่ที่เหมาะสมและไม่เพียงพอที่จะมีเพียงสถาปัตยกรรมหรือเครื่องมือเพิ่มประสิทธิภาพเท่านั้นตั้งค่าอย่างถูกต้อง
การปรับแต่งตัวเลือกการกำหนดค่านั้นไม่ง่ายอย่างที่บอกว่าตัวเลือกการกำหนดค่าประเภทหนึ่ง (เช่นอัตราการเรียนรู้) มีความสำคัญมากกว่าหรือน้อยกว่า (เช่นจำนวนหน่วย) เนื่องจากตัวเลือกทั้งหมดเหล่านี้มีปฏิสัมพันธ์กับตัวเลือกอื่นทั้งหมด ทางเลือกที่สามารถทำได้ดีในการทำงานร่วมกับทางเลือกอื่นทำที่อื่น
นี่คือรายการที่ไม่ครบถ้วนสมบูรณ์ของตัวเลือกการกำหนดค่าซึ่งไม่ใช่ตัวเลือกการทำให้เป็นปกติหรือตัวเลือกการเพิ่มประสิทธิภาพเชิงตัวเลข
หัวข้อทั้งหมดเหล่านี้เป็นพื้นที่การวิจัยที่ใช้งานอยู่
การปรับให้เหมาะสมแบบไม่มีนูนนั้นยาก
ฟังก์ชั่นวัตถุประสงค์ของเครือข่ายนิวรัลเป็นเพียงการนูนเมื่อไม่มีหน่วยที่ซ่อนอยู่การเปิดใช้งานทั้งหมดเป็นแบบเชิงเส้นและเมทริกซ์การออกแบบเต็ม - เนื่องจากการกำหนดค่านี้เป็นปัญหาการถดถอยแบบปกติ
ในกรณีอื่น ๆ ทั้งหมดปัญหาการปรับให้เหมาะสมไม่ใช่แบบนูนและการปรับให้เหมาะสมแบบไม่นูนนั้นยาก ความท้าทายของการฝึกอบรมโครงข่ายประสาทเทียมเป็นที่รู้จักกันดี (ดู: ทำไมการฝึกโครงข่ายประสาทเทียมจึงเป็นเรื่องยาก? ) นอกจากนี้โครงข่ายใยประสาทเทียมมีพารามิเตอร์จำนวนมากซึ่ง จำกัด ให้เราใช้วิธีการสั่งซื้อครั้งแรกเท่านั้น (ดู: ทำไมวิธีการของนิวตันจึงไม่ได้ใช้อย่างกว้างขวางในการเรียนรู้ของเครื่อง? ) นี่เป็นงานวิจัยที่กระตือรือร้นมาก
การตั้งค่าอัตราการเรียนรู้ที่ใหญ่เกินไปจะทำให้การปรับให้เหมาะสมแตกต่างเพราะคุณจะกระโดดจากด้านหนึ่งของ "แคนยอน" ไปอีกด้านหนึ่ง การตั้งค่านี้เล็กเกินไปจะทำให้คุณไม่สามารถทำการคืบหน้าได้จริงและอาจทำให้เกิดเสียงรบกวนในหน่วยดอลลาร์สิงคโปร์เพื่อประเมินการไล่ระดับสีของคุณ
การไล่ระดับสีจะปรับขนาดบรรทัดฐานของการไล่ระดับสีใหม่หากสูงกว่าเกณฑ์ ฉันเคยคิดว่านี่เป็นพารามิเตอร์ set-and-forget ซึ่งปกติแล้วจะอยู่ที่ 1.0 แต่ฉันพบว่าฉันสามารถทำให้รูปแบบภาษา LSTM ดีขึ้นอย่างมากโดยตั้งเป็น 0.25 ฉันไม่รู้ว่าทำไม
การกำหนดตารางอัตราการเรียนรู้สามารถลดอัตราการเรียนรู้ในระหว่างการฝึกอบรม จากประสบการณ์ของฉันการลองใช้การกำหนดเวลาเป็นเหมือนregex : มันแทนที่ปัญหาหนึ่ง ("ฉันจะเรียนรู้ที่จะดำเนินการต่อหลังจากช่วงเวลาหนึ่งได้อย่างไร") มีสองปัญหา ("ฉันจะเรียนรู้ที่จะดำเนินต่อไปหลังจากช่วงเวลาหนึ่ง) ? "และ" ฉันจะเลือกตารางเวลาที่ดีได้อย่างไร ") คนอื่น ๆ ยืนยันว่าการกำหนดตารางเวลาเป็นสิ่งจำเป็น ฉันจะให้คุณตัดสินใจ
การเลือกที่ดีขนาด minibatchสามารถมีอิทธิพลต่อกระบวนการเรียนรู้ทางอ้อมตั้งแต่ minibatch ขนาดใหญ่จะมีแนวโน้มที่จะมีความแปรปรวนขนาดเล็ก ( กฎหมายของขนาดใหญ่ตัวเลข ) กว่า minibatch ขนาดเล็ก คุณต้องการให้ mini-batch มีขนาดใหญ่พอที่จะให้ข้อมูลเกี่ยวกับทิศทางของการไล่ระดับสี แต่มีขนาดเล็กพอที่ SGD สามารถทำให้เครือข่ายของคุณเป็นปกติ
มีหลายสายพันธุ์ในการไล่ระดับสีแบบสุ่มซึ่งใช้โมเมนตัมอัตราการเรียนรู้ที่ปรับตัวได้การปรับปรุง Nesterov และอื่น ๆ เพื่อปรับปรุงเมื่อวานิลลา SGD การออกแบบเครื่องมือเพิ่มประสิทธิภาพที่ดีขึ้นนั้นเป็นส่วนสำคัญของการวิจัย ตัวอย่างบางส่วน:
เมื่อมันออกมาเป็นครั้งแรกเครื่องมือเพิ่มประสิทธิภาพของอดัมสร้างความสนใจอย่างมาก แต่งานวิจัยเมื่อไม่นานมานี้พบว่า SGD ที่มีแรงผลักดันสามารถทำวิธีไล่ระดับสีแบบปรับตัวได้สำหรับเครือข่ายประสาทเทียม " คุณค่าส่วนต่างของวิธีการไล่ระดับสีแบบปรับตัวในการเรียนรู้ของเครื่อง " โดย Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro, Benjamin Recht
แต่ในทางกลับกันบทความล่าสุดนี้เสนอตัวปรับอัตราการเรียนรู้แบบปรับตัวแบบใหม่ซึ่งคาดว่าจะปิดช่องว่างระหว่างวิธีการปรับอัตรากับ SGD ด้วยแรงผลักดัน " ปิดช่องว่างทั่วไปของวิธีการไล่ระดับสีแบบปรับตัวในการฝึกอบรมเครือข่ายประสาทลึก " โดย Jinghui Chen, Quanquan Gu
วิธีการไล่ระดับสีแบบ Adaptive ซึ่งใช้ข้อมูลการไล่ระดับสีในอดีตเพื่อปรับอัตราการเรียนรู้โดยอัตโนมัติได้รับการสังเกตเพื่อพูดคุยที่เลวร้ายยิ่งกว่าเชื้อสายการไล่ระดับสีแบบสุ่ม (SGD) ด้วยโมเมนตัมในการฝึกอบรมโครงข่ายประสาทเทียม นี่จะทำให้วิธีปิดช่องว่างทั่วไปของวิธีการไล่ระดับสีแบบปรับตัวเป็นปัญหาเปิด ในงานนี้เราแสดงให้เห็นว่าวิธีการไล่ระดับสีแบบปรับตัวเช่นอดัมอัมสกราดบางครั้ง "ถูกดัดแปลง" เราออกแบบอัลกอริทึมใหม่ที่เรียกว่าวิธีการประมาณค่าโมเมนตัมที่ปรับตัวได้บางส่วน (Padam) ซึ่งรวม Adam / Amsgrad กับ SGD เพื่อให้ได้สิ่งที่ดีที่สุดจากทั้งสองโลก การทดสอบเกณฑ์มาตรฐานแสดงให้เห็นว่า Padam สามารถรักษาอัตราการบรรจบกันอย่างรวดเร็วเช่น Adam / Amsgrad ในขณะที่ใช้งานทั่วไปและ SGD ในการฝึกอบรมโครงข่ายประสาทเทียม
normalization
ขนาดของข้อมูลสามารถสร้างความแตกต่างใหญ่ในการฝึกอบรม
[ - 0.5 , 0.5 ]
การทำให้เป็นมาตรฐานของเลเยอร์สามารถปรับปรุงการฝึกอบรมเครือข่ายโดยการรักษาค่าเฉลี่ยการทำงานและค่าเบี่ยงเบนมาตรฐานสำหรับการเปิดใช้งานของเซลล์ มันไม่เข้าใจว่าทำไมจึงช่วยฝึกอบรมและยังคงเป็นพื้นที่ของการวิจัย
- "การทำความเข้าใจชุดการทำให้เป็นมาตรฐาน " โดย Johan Bjorck, Carla Gomes, Bart Selman
- " สู่ความเข้าใจทางทฤษฎีของการทำให้เป็นมาตรฐานแบบแบตช์ " โดย Jonas Kohler, Hadi Daneshmand, Aurelien Lucchi, Ming Zhou, Klaus Neymeyr, Thomas Hofmann
- " การทำให้เป็นมาตรฐานการปรับค่าใช้จ่ายช่วยให้เกิดประโยชน์สูงสุดได้อย่างไร (ไม่มันไม่เกี่ยวกับการเปลี่ยนแปลงภายในโควาเรต) " โดย Shibani Santurkar, Dimitris Tsipras, Andrew Ilyas, Aleksander Madry
regularization
การเลือกและการปรับจูนเครือข่ายให้สม่ำเสมอเป็นส่วนสำคัญของการสร้างแบบจำลองที่สรุปได้ดี (นั่นคือแบบจำลองที่ไม่เหมาะสมกับข้อมูลการฝึกอบรม) อย่างไรก็ตามในเวลาที่เครือข่ายของคุณกำลังพยายามลดการสูญเสียข้อมูลการฝึกอบรม - เมื่อเครือข่ายไม่ได้เรียนรู้ - การทำให้เป็นมาตรฐานสามารถปิดบังสิ่งที่เป็นปัญหา
เมื่อเครือข่ายของฉันไม่เรียนรู้ฉันจะปิดการทำให้เป็นมาตรฐานทั้งหมดและตรวจสอบว่าเครือข่ายที่ไม่ทำให้เป็นปกติทำงานได้อย่างถูกต้อง จากนั้นฉันเพิ่มชิ้นส่วนการทำให้เป็นปกติแต่ละชิ้นกลับมาและตรวจสอบว่าชิ้นงานแต่ละชิ้นทำงานไปพร้อมกัน
ชั้นเชิงนี้สามารถระบุตำแหน่งที่อาจทำให้การกำหนดมาตรฐานบางอย่างไม่ดี ตัวอย่างบางส่วนคือ
เก็บสมุดบันทึกการทดลอง
เมื่อฉันตั้งค่าเครือข่ายประสาทฉันไม่ได้ยากรหัสการตั้งค่าพารามิเตอร์ใด ๆ แต่ฉันทำเช่นนั้นในไฟล์การกำหนดค่า (เช่น JSON) ที่อ่านและใช้เพื่อเติมรายละเอียดการกำหนดค่าเครือข่ายตอนรันไทม์ ฉันเก็บไฟล์การกำหนดค่าเหล่านี้ทั้งหมด หากฉันแก้ไขพารามิเตอร์ใด ๆ ฉันจะสร้างไฟล์กำหนดค่าใหม่ ในที่สุดฉันก็ผนวกความคิดเห็นทั้งหมดของการสูญเสียต่อยุคสำหรับการฝึกอบรมและการตรวจสอบ
k
เป็นตัวอย่างฉันต้องการเรียนรู้เกี่ยวกับรูปแบบภาษา LSTM ดังนั้นฉันจึงตัดสินใจสร้างบอต Twitter ที่เขียนทวีตใหม่เพื่อตอบสนองผู้ใช้ Twitter คนอื่น ฉันทำงานนี้ในเวลาว่างระหว่างเรียนจบและงานของฉัน ใช้เวลาประมาณหนึ่งปีและฉันทำซ้ำโมเดลประมาณ 150 แบบก่อนที่จะไปยังแบบจำลองที่ทำในสิ่งที่ฉันต้องการ: สร้างข้อความภาษาอังกฤษใหม่ที่ (เรียงลำดับ) เข้าท่า (จุดยึดหลักหนึ่งจุดและส่วนหนึ่งของเหตุผลที่ต้องใช้ความพยายามหลายครั้งก็คือมันไม่เพียงพอที่จะทำให้เกิดการสูญเสียตัวอย่างน้อยเนื่องจากแบบจำลองการสูญเสียต่ำรุ่นแรก ๆ สามารถจดจำข้อมูลการฝึกอบรมได้ ดังนั้นมันจึงเป็นเพียงการสร้างบล็อคของคำต่อคำแบบข้อความเพื่อตอบสนองต่อข้อความแจ้ง - มันใช้เวลาปรับแต่งบางอย่างเพื่อทำให้แบบจำลองเป็นธรรมชาติมากขึ้นและยังคงมีการสูญเสียต่ำ)