วิธีการคำนวณหน่วยความจำ mini-batch มีผลกระทบอย่างไรเมื่อฝึกอบรมโมเดลการเรียนรู้ลึก


17

ฉันพยายามคำนวณจำนวนหน่วยความจำที่ GPU ต้องการในการฝึกอบรมโมเดลของฉันโดยอ้างอิงจากบันทึกนี้จาก Andrej Karphaty: http://cs231n.github.io/convolutional-networks/#computational-considerations

เครือข่ายของฉันมีการเปิดใช้งาน 532,752 รายการและพารามิเตอร์ 19,072,984 รายการ (น้ำหนักและอคติ) นี่คือค่าลอย 32 บิตดังนั้นแต่ละค่าใช้เวลา 4 ไบต์ในหน่วยความจำ

ภาพอินพุตของฉันคือ 180x50x1 (กว้าง x สูง x ลึก) = 9,000ค่าลอย 32 ฉันไม่ได้ใช้การเพิ่มรูปภาพดังนั้นฉันคิดว่าหน่วยความจำเบ็ดเตล็ดจะเกี่ยวข้องกับขนาดมินิแบทช์เท่านั้น ฉันใช้มินิแบทช์ขนาด 128 ภาพ

ตามคำแนะนำของ Andrej ฉันได้รับขนาดหน่วยความจำต่อไปนี้:

การเปิดใช้งาน: 532,752 * 4 / (1024 ^ 2) = 2.03 MB

พารามิเตอร์: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218.27 MB

เบ็ดเตล็ด: 128 * 9,000 * 4 / (1024 ^ 2) = 4.39 MB

ดังนั้นหน่วยความจำทั้งหมดในการฝึกอบรมเครือข่ายนี้จะ224,69 ล้านบาท

ฉันใช้ TensorFlow และฉันคิดว่าฉันขาดอะไรไป ฉันยังไม่ได้ทำการฝึกอบรม แต่ฉันค่อนข้างมั่นใจ (จากประสบการณ์ที่ผ่านมา) ว่าหน่วยความจำที่ใช้จะสูงกว่าที่ฉันคำนวณไว้มาก

ถ้าสำหรับแต่ละภาพในมินิแบทช์ TensorFlow จะเก็บการไล่ระดับสีไว้เพื่อที่จะสามารถทำให้เป็นมาตรฐานได้ในภายหลังสำหรับขั้นตอนการอัปเดตน้ำหนัก / อคติเดียวฉันคิดว่าหน่วยความจำควรคำนึงถึงค่า 532,752 * 128 อีกด้วย มินิแบทช์) หากเป็นเช่นนั้นฉันจะต้องเพิ่ม 260.13 MB ในการฝึกอบรมโมเดลนี้ด้วยรูปภาพ 128 รูป / ชุดมินิ

คุณช่วยฉันเข้าใจข้อควรพิจารณาเกี่ยวกับความจำสำหรับการฝึกอบรมรูปแบบการเรียนรู้ลึกของฉันได้หรือไม่? ข้อพิจารณาข้างต้นถูกต้องหรือไม่


โปรดดูของฉัน (เสนอ) ตอบคำถามของคุณที่นี่
Adam Hendry

คำตอบ:


5

ฉันคิดว่าคุณกำลังถูกทาง

ใช่คุณจะต้องจัดเก็บสัญญาซื้อขายล่วงหน้าของการเปิดใช้งานและพารามิเตอร์สำหรับการเผยแพร่กลับ

นอกจากนี้ตัวเลือกการเพิ่มประสิทธิภาพของคุณอาจมีความสำคัญ คุณกำลังฝึกอบรมโดยใช้ SGD หรือ Adam หรือ Adagrad หรือไม่ ทั้งหมดนี้จะมีข้อกำหนดด้านหน่วยความจำที่แตกต่างกัน ตัวอย่างเช่นคุณจะต้องจัดเก็บแคชขนาดขั้นตอนสำหรับวิธีการที่ใช้โมเมนตัมแม้ว่ามันควรจะเป็นรองเมื่อเทียบกับข้อควรพิจารณาเกี่ยวกับหน่วยความจำอื่น ๆ ที่คุณพูดถึง

ดังนั้นโดยรวมแล้วคุณดูเหมือนจะคำนวณข้อกำหนดของหน่วยความจำสำหรับการส่งต่อ Andrej Karpathyกล่าวว่าการย้อนหลังอาจใช้เวลาถึง 3 เท่าของหน่วยความจำของการส่งต่อดังนั้นนี่อาจเป็นเหตุผลที่คุณเห็นความแตกต่างดังกล่าว (เลื่อนลงไปที่ 'กรณีศึกษา' บนเว็บไซต์เพื่อดูตัวอย่างสำหรับ VGGNet)


5

@StatsSorceress TL; DR:

ฉันกำลังทำกิจกรรมนี้เพื่อดูว่าฉันสามารถคำนวณหน่วยความจำที่ต้องใช้ตัวเองได้หรือไม่:

การเปิดใช้งาน: 532,752 * 2 * 4 / (1024 ^ 2) = 4.06 MB

พารามิเตอร์: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218.27 MB

เบ็ดเตล็ด: 128 * 9,000 * 4 / (1024 ^ 2) = 4.39 MB

หน่วยความจำทั้งหมด: (4.06 * 128 ) + 218.27 + 4.39 = 742.34 MB

(มีคนโปรดแก้ไขฉันด้วยถ้าไม่ถูกต้อง FYI คุณคูณคูณด้วย 128 แล้วนั่นเป็นเหตุผลว่าทำไมฉันไม่คูณด้วย 128 ข้างบน )


ฉันจะชี้ให้คุณไปที่บทความนี้และวิดีโอที่เกี่ยวข้อง พวกเขาช่วยให้ฉันเข้าใจสิ่งที่เกิดขึ้นมากขึ้น

หมายเหตุ: หน่วยความจำที่จำเป็นในการใช้เครือข่ายสำหรับการคาดการณ์นั้นน้อยกว่าที่จำเป็นสำหรับการฝึกอบรมด้วยเหตุผลสองประการ:

  • เมื่อคาดการณ์เราจะส่งภาพไปข้างหน้าผ่านเครือข่ายเท่านั้นและไม่ย้อนกลับ (ดังนั้นเราจะไม่คูณหน่วยความจำ X 3; ดูด้านล่าง)
  • มีการคาดการณ์หนึ่งภาพต่อภาพ (ดังนั้นเราจึงไม่จำเป็นต้องเพิ่มจำนวนหน่วยความจำที่จำเป็นสำหรับภาพหนึ่งภาพด้วยขนาดแบตช์เพราะเราไม่ได้ใช้ชุดคำสั่งในการทำนาย)

กระบวนการ (หน่วยความจำการฝึกอบรม)

  1. คำนวณหน่วยความจำที่จำเป็นในการฝึกอบรมในหนึ่งภาพ
  2. คูณจำนวนนี้ด้วยจำนวนภาพในแบทช์ของคุณ

( โปรดจำไว้ว่า: ชุดข้อมูล ขนาดเล็กบอกว่าเราใช้ชุดย่อยของข้อมูลของเราคำนวณการไล่ระดับสีและข้อผิดพลาดสำหรับแต่ละภาพในชุดย่อยจากนั้นเฉลี่ยค่าเหล่านี้และก้าวไปข้างหน้าในทิศทางของค่าเฉลี่ยสำหรับ Convnets น้ำหนักและอคติ จำนวนการเปิดใช้งานถูกปิดกั้นด้วยจำนวนภาพในแบทช์ )

ขั้นตอนที่ 1: หน่วยความจำสำหรับ 1 ภาพ

ในการฝึกอบรมหนึ่งภาพคุณต้องจองหน่วยความจำสำหรับ:

  • พารามิเตอร์โมเดล:

    น้ำหนักและอคติในแต่ละชั้นของพวกเขาไล่ระดับสีของพวกเขาและตัวแปรโมเมนตัม (ถ้าอดัม Adagrad, RMSProp ฯลฯ เพิ่มประสิทธิภาพถูกนำมาใช้)

    ในการประมาณหน่วยความจำสำหรับสิ่งนี้ให้คำนวณหน่วยความจำที่จำเป็นในการจัดเก็บน้ำหนักและอคติและคูณด้วย 3 (เช่น "คูณ 3" เพราะเรากำลังบอกจำนวนหน่วยความจำที่จำเป็นในการจัดเก็บน้ำหนักและอคติคือ ที่จำเป็นสำหรับการไล่ระดับสีและสำหรับตัวแปรโมเมนตัม)

    สมการ:

    convolutions:

    น้ำหนัก (n) = ความลึก (n) * (kernel_width * kernel_height) * ความลึก (n-1)

    อคติ (n) = ความลึก (n)

    เลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ (หนาแน่น):

    weights (n) = เอาต์พุต (n) * อินพุต (n)

    อคติ (n) = เอาท์พุท (n)

โดยที่nคือเลเยอร์ปัจจุบันและn-1เป็นเลเยอร์ก่อนหน้าและเอาต์พุตคือจำนวนเอาต์พุตจากเลเยอร์ FC และอินพุตคือจำนวนอินพุตไปยังเลเยอร์ FC (หากเลเยอร์ก่อนหน้านี้ไม่ใช่เลเยอร์ที่เชื่อมต่อทั้งหมด จำนวนอินพุตเท่ากับขนาดของเลเยอร์นั้นแบน)

หมายเหตุ:หน่วยความจำสำหรับน้ำหนักและอคติเพียงอย่างเดียวรวมถึงหน่วยความจำสำหรับการเปิดใช้งานสำหรับหนึ่งภาพ (ดูด้านล่าง) คือจำนวนหน่วยความจำทั้งหมดที่คุณต้องการสำหรับการคาดการณ์ (ไม่รวมค่าโสหุ้ยสำหรับหน่วยความจำสำหรับ Convolutions และอื่น ๆ )

  • การเปิดใช้งาน (นี่คือ "Blobs" ใน Caffe):

(ฉันใช้คำศัพท์ที่นี่อดทนกับฉัน)

การบิดแต่ละครั้งในชั้นการบิดทำให้เกิดการเปิดใช้งาน" จำนวนพิกเซลในภาพ " (เช่นคุณส่งภาพผ่านการบิดเพียงครั้งเดียวคุณจะได้รับแผนที่คุณลักษณะเดียวซึ่งประกอบด้วยการเปิดใช้งาน " m " โดยที่ " m " คือจำนวนพิกเซลจาก ภาพ / input)

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

convolutions:

การเปิดใช้งาน (n) = image_width * image_height * image_num_channels

เลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ (หนาแน่น):

การเปิดใช้งาน (n) = เอาท์พุท (n)

โปรดทราบว่าการป้อนข้อมูลของคุณเป็นเพียงภาพที่จุดเริ่มต้นของเครือข่าย หลังจากการโน้มน้าวใจมันจะกลายเป็นอย่างอื่น (ฟีเจอร์แผนที่) ดังนั้นแทนที่ "image_width", "image_height" และ "image_num_channels" ด้วย "input_width", "input_height" และ "layer_depth" ให้แม่นยำยิ่งขึ้น (มันง่ายกว่าสำหรับฉันที่จะคิดถึงแนวคิดนี้ในแง่ของภาพ)

เนื่องจากเราต้องเก็บข้อผิดพลาดสำหรับการเปิดใช้งานในแต่ละเลเยอร์ (ใช้ในการย้อนกลับ) เราจึงคูณจำนวนการเปิดใช้งานด้วย 2 เพื่อให้ได้จำนวนเอนทิตีทั้งหมดที่เราต้องการเพื่อให้มีพื้นที่ว่างในพื้นที่เก็บข้อมูลของเรา จำนวนการเปิดใช้งานจะเพิ่มขึ้นตามจำนวนภาพในแบทช์ดังนั้นคุณจึงคูณจำนวนนี้ด้วยขนาดแบทช์

ขั้นตอนที่ 2: หน่วยความจำเพื่อฝึกอบรมแบทช์

รวมจำนวนน้ำหนักและอคติ (เท่า 3) และจำนวนการเปิดใช้งาน (คูณ 2 เท่าของขนาดแบทช์) คูณด้วย 4 และคุณจะได้จำนวนไบต์ที่ต้องใช้ในการฝึกอบรมแบทช์ คุณสามารถหารด้วย 1024 ^ 2 เพื่อให้ได้คำตอบเป็น GB


ทำไมคุณถึงพูดว่า "เราไม่ใช้ชุดคำทำนาย"? หากผู้ใช้จำเป็นต้องคาดการณ์จำนวนรูปภาพเป็นจำนวนมากผู้ใช้สามารถใช้กลุ่มในการทำนายได้
3731622

1

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

คุณสามารถเรียกใช้ส่วนของโปรแกรมที่คุณต้องการตรวจสอบในกระบวนการย่อยที่แตกต่างกันโดยใช้popenและตรวจสอบว่าเป็นหน่วยความจำและการใช้งาน CPU โดยใช้ PID

psutilฉันหาสิ่งที่ดีสำหรับงานดังกล่าว แม้ว่าจะมีคนอื่นอีกมากมาย

ฉันหวังว่านี่จะช่วยได้


3
ขอบคุณสำหรับคำตอบ @Anwar ฉันกำลังมองหาการคำนวณเชิงวิเคราะห์มากกว่าการสังเกตเชิงประจักษ์
barbolo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.