สาเหตุทั่วไปของ nans ในระหว่างการฝึกอบรม


86

ฉันพบว่าเกิดขึ้นบ่อยในช่วงการฝึกอบรมNANs ได้รับการแนะนำ

บ่อยครั้งที่น้ำหนักในผลิตภัณฑ์ด้านใน / ชั้นที่เชื่อมต่อเต็มหรือ Convolution ถูกนำมาใช้

สิ่งนี้เกิดขึ้นเนื่องจากการคำนวณการไล่ระดับสีกำลังระเบิดหรือไม่? หรือเป็นเพราะน้ำหนักเริ่มต้น (ถ้าเป็นเช่นนั้นทำไมการเริ่มต้นน้ำหนักจึงมีผลเช่นนี้) หรือน่าจะเกิดจากลักษณะของข้อมูลเข้าหรือไม่

คำถามที่สรุปคือ: อะไรคือสาเหตุส่วนใหญ่ที่ทำให้ NAN เกิดขึ้นในระหว่างการฝึกอบรม? และประการที่สองมีวิธีใดบ้างในการต่อสู้กับสิ่งนี้ (และทำไมถึงได้ผล)?


คุณกำลังเรียกใช้ฟังก์ชัน MATLAB เฉพาะหรือไม่? เป็นรหัสของคุณเองทั้งหมดหรือไม่?
Matthew Gunn

2
@MatthewGunn ฉันไม่คิดว่าคำถามนี้เป็นคำถามเฉพาะ matlab แต่ค่อนข้างcaffeเกี่ยวข้อง
Shai

คำตอบ:


137

คำถามที่ดี.
ฉันเจอปรากฏการณ์นี้หลายครั้ง นี่คือข้อสังเกตของฉัน:


ไล่ระดับสีระเบิด

เหตุผล: การไล่ระดับสีขนาดใหญ่ทำให้กระบวนการเรียนรู้นอกเส้นทาง

สิ่งที่คุณควรคาดหวัง:ดูที่บันทึกรันไทม์คุณควรดูที่ค่าการสูญเสียต่อการวนซ้ำ คุณจะพบว่าการเริ่มต้นของการสูญเสียที่จะเติบโตอย่างมีนัยสำคัญnanจากการทำซ้ำไปซ้ำในที่สุดการสูญเสียจะมีขนาดใหญ่เกินไปที่จะแสดงโดยตัวแปรจุดลอยและมันจะกลายเป็น

คุณทำอะไรได้บ้าง:ลดbase_lr(ใน solver.prototxt) ตามลำดับขนาด (อย่างน้อย) หากคุณมีการสูญเสียชั้นหลาย ๆ คุณควรตรวจสอบการเข้าสู่ระบบเพื่อดูว่าชั้นเป็นผู้รับผิดชอบสำหรับการไล่ระดับสีระเบิดขึ้นและลดลงloss_weight(ใน train_val.prototxt) base_lrสำหรับชั้นเฉพาะที่แทนของทั่วไป


นโยบายและพารามิเตอร์อัตราการเรียนรู้ไม่ดี

เหตุผล: caffe ไม่สามารถคำนวณอัตราการเรียนรู้ที่ถูกต้องและได้รับ'inf'หรือ'nan'แทนอัตราที่ไม่ถูกต้องนี้จะคูณการอัปเดตทั้งหมดและทำให้พารามิเตอร์ทั้งหมดเป็นโมฆะ

สิ่งที่คุณควรคาดหวัง:เมื่อดูบันทึกรันไทม์คุณจะเห็นว่าอัตราการเรียนรู้นั้นกลายเป็น'nan'เช่น:

... sgd_solver.cpp:106] Iteration 0, lr = -nan

คุณสามารถทำอะไรได้บ้าง:แก้ไขพารามิเตอร์ทั้งหมดที่มีผลต่ออัตราการเรียนรู้ใน'solver.prototxt'ไฟล์ของคุณ
ตัวอย่างเช่นหากคุณใช้lr_policy: "poly"และลืมกำหนดmax_iterพารามิเตอร์คุณจะจบลงด้วย lr = nan...
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับอัตราการเรียนรู้ในคาเฟอีนโปรดดูหัวข้อนี้


ฟังก์ชันการสูญเสียที่ผิดพลาด

เหตุผล:บางครั้งการคำนวณการสูญเสียในชั้นการสูญเสียทำให้nans ปรากฏขึ้น ตัวอย่างเช่นInfogainLossชั้นการให้อาหารที่มีค่าที่ไม่เป็นมาตรฐานโดยใช้เลเยอร์การสูญเสียที่กำหนดเองพร้อมข้อบกพร่องเป็นต้น

สิ่งที่คุณควรคาดหวัง:เมื่อดูบันทึกรันไทม์คุณอาจไม่สังเกตเห็นสิ่งผิดปกติ: การสูญเสียกำลังลดลงเรื่อย ๆ และทันใดnanนั้นก็ปรากฏขึ้น

คุณสามารถทำอะไรได้บ้าง:ดูว่าคุณสามารถสร้างข้อผิดพลาดซ้ำได้หรือไม่เพิ่มงานพิมพ์ในเลเยอร์การสูญเสียและแก้ไขข้อผิดพลาด

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


การป้อนข้อมูลผิดพลาด

เหตุผล:คุณมีข้อมูลnanอยู่ในนั้น!

สิ่งที่คุณควรคาดหวัง:เมื่อกระบวนการการเรียนรู้ "ฮิต" การป้อนข้อมูลที่ผิดพลาดนี้ - nanส่งออกจะกลายเป็น เมื่อดูบันทึกรันไทม์คุณอาจไม่สังเกตเห็นสิ่งผิดปกติ: การสูญเสียกำลังลดลงเรื่อย ๆ และทันใดnanนั้นก็ปรากฏขึ้น

คุณสามารถทำอะไรได้บ้าง:สร้างชุดข้อมูลอินพุตของคุณใหม่ (lmdb / leveldn / hdf5 ... ) ตรวจสอบให้แน่ใจว่าคุณไม่มีไฟล์ภาพที่ไม่ดีในชุดการฝึกอบรม / การตรวจสอบความถูกต้อง สำหรับการดีบักคุณสามารถสร้างเน็ตง่ายๆที่อ่านเลเยอร์อินพุตโดยมีการสูญเสียดัมมี่อยู่ด้านบนและรันผ่านอินพุตทั้งหมด: หากหนึ่งในนั้นผิดพลาดเน็ตดัมมี่นี้ก็ควรสร้างnanขึ้นเช่นกัน


ก้าวใหญ่กว่าขนาดเคอร์เนลใน"Pooling"เลเยอร์

ด้วยเหตุผลบางประการการเลือกstride> kernel_sizeสำหรับการรวมกลุ่มอาจส่งผลด้วยnans ตัวอย่างเช่น:

layer {
  name: "faulty_pooling"
  type: "Pooling"
  bottom: "x"
  top: "y"
  pooling_param {
    pool: AVE
    stride: 5
    kernel: 3
  }
}

ผลลัพธ์ด้วยnans in y.


ความไม่เสถียรใน "BatchNorm"

มีรายงานว่าภายใต้"BatchNorm"เลเยอร์การตั้งค่าบางอย่างอาจส่งออกnanเนื่องจากความไม่แน่นอนของตัวเลข ปัญหา
นี้เกิดขึ้นใน bvlc / caffe และPR # 5136กำลังพยายามแก้ไข


เร็ว ๆ นี้ผมเริ่มตระหนักถึงdebug_infoธง: การตั้งค่าdebug_info: trueในการ'solver.prototxt'ที่จะทำให้การพิมพ์ Caffe เข้าสู่ระบบข้อมูลการแก้ปัญหาอื่น ๆ (รวมถึงการไล่ระดับสีขนาดและค่าเปิดใช้งาน) ในระหว่างการฝึก: ข้อมูลนี้สามารถช่วยในการจำ blowups ลาดและปัญหาอื่น ๆ ในขั้นตอนการฝึกอบรม


ขอบคุณเราตีความตัวเลขเหล่านั้นอย่างไร ตัวเลขเหล่านี้คืออะไร? pastebin.com/DLYgXK5vเหตุใดจึงมีเพียงหนึ่งหมายเลขต่อหนึ่งชั้นเอาต์พุต!? ตัวเลขเหล่านั้นควรมีลักษณะอย่างไรจึงจะมีคนรู้ว่ามีปัญหาหรือไม่มี!?
Rika

@Hossein นี่คือสิ่งที่โพสต์นี้เกี่ยวกับ
Shai

ขอบคุณสำหรับคำตอบนี้ ฉันได้รับการสูญเสีย NAN สำหรับแอปพลิเคชันการแบ่งส่วนภาพที่ได้รับการฝึกฝนด้วยการสูญเสีย DICE (แม้ว่าจะเพิ่มค่าคงที่ epsilon / ความเรียบเล็กน้อยแล้วก็ตาม) ชุดข้อมูลของฉันมีภาพบางภาพที่มีความจริงพื้นฐานที่สอดคล้องกันซึ่งไม่มีป้ายกำกับเบื้องหน้าใด ๆ และเมื่อฉันลบภาพเหล่านี้ออกจากการฝึกอบรมการสูญเสียก็คงที่ ฉันไม่แน่ใจว่าทำไมถึงเป็นเช่นนั้น?
samra irshad

@samrairshad คุณลองเพิ่ม epsilon ในการสูญเสีย DICE หรือไม่?
Shai

ใช่ฉันทำ. ฉันเปิดโพสต์ที่ stack-overflow และวางวิวัฒนาการการสูญเสียสำหรับบางยุค นี่คือข้อมูลอ้างอิง: stackoverflow.com/questions/62259112/…
samra irshad

5

ในกรณีของฉันการไม่ตั้งค่าความลำเอียงในเลเยอร์การแปลง / การแยกตัวเป็นสาเหตุ

วิธีแก้ไข:เพิ่มสิ่งต่อไปนี้ในพารามิเตอร์เลเยอร์คอนโวลูชั่น

bias_filler {type: "constant" value: 0}


ใน matconvnet จะเป็นอย่างไร ฉันมีบางอย่างเช่น 'biases'.init_bias * ones (1,4, single)
h612

4

คำตอบนี้ไม่เกี่ยวกับสาเหตุnanของ s แต่เป็นการเสนอวิธีที่จะช่วยแก้ไขข้อบกพร่อง คุณสามารถมีเลเยอร์ python นี้:

class checkFiniteLayer(caffe.Layer):
  def setup(self, bottom, top):
    self.prefix = self.param_str
  def reshape(self, bottom, top):
    pass
  def forward(self, bottom, top):
    for i in xrange(len(bottom)):
      isbad = np.sum(1-np.isfinite(bottom[i].data[...]))
      if isbad>0:
        raise Exception("checkFiniteLayer: %s forward pass bottom %d has %.2f%% non-finite elements" %
                        (self.prefix,i,100*float(isbad)/bottom[i].count))
  def backward(self, top, propagate_down, bottom):
    for i in xrange(len(top)):
      if not propagate_down[i]:
        continue
      isf = np.sum(1-np.isfinite(top[i].diff[...]))
        if isf>0:
          raise Exception("checkFiniteLayer: %s backward pass top %d has %.2f%% non-finite elements" %
                          (self.prefix,i,100*float(isf)/top[i].count))

การเพิ่มเลเยอร์นี้ในtrain_val.prototxtบางจุดที่คุณสงสัยว่าอาจทำให้เกิดปัญหา:

layer {
  type: "Python"
  name: "check_loss"
  bottom: "fc2"
  top: "fc2"  # "in-place" layer
  python_param {
    module: "/path/to/python/file/check_finite_layer.py" # must be in $PYTHONPATH
    layer: "checkFiniteLayer"
    param_str: "prefix-check_loss" # string for printouts
  }
}

1

อัตราการเรียนรู้สูงและควรลดลงความแม่นยำในรหัส RNN คือ nan โดยเลือกค่าต่ำสำหรับอัตราการเรียนรู้ที่แก้ไขได้


-1

ฉันพยายามสร้างตัวเข้ารหัสอัตโนมัติแบบกระจัดกระจายและมีหลายชั้นในนั้นเพื่อกระตุ้นให้เกิดการเบาบาง ในขณะที่ใช้เน็ตฉันเจอ NaN เมื่อลบเลเยอร์บางส่วนออก (ในกรณีของฉันฉันต้องลบ 1) ฉันพบว่า NaN หายไป ดังนั้นฉันเดาว่าความเบาบางมากเกินไปอาจนำไปสู่ ​​NaN ได้เช่นกัน (อาจมีการเรียกใช้การคำนวณ 0/0!?)


คุณสามารถเจาะจงมากขึ้นได้ไหม คุณสามารถให้รายละเอียดเกี่ยวกับการกำหนดค่าที่มีnans และการกำหนดค่าคงที่ได้หรือไม่? เลเยอร์ประเภทไหน? พารามิเตอร์อะไร
Shai

1
@shai ฉันเคยใช้ InnerProduct หลายตัว (lr_mult 1, Decay_mult 1, lr_mult 2, Decay_mult 0, xavier, std: 0.01) แต่ละเลเยอร์ตามด้วย ReLU (ยกเว้นอันสุดท้าย) ฉันทำงานกับ MNIST และถ้าฉันจำไม่ผิดสถาปัตยกรรมคือ 784 -> 1,000 -> 500 -> 250 -> 100 -> 30 (และเฟสตัวถอดรหัสแบบสมมาตร) การลบเลเยอร์ 30 พร้อมกับ ReLU ทำให้ NaN หายไป
LKB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.