Tensorflow การปรับฟังก์ชั่นต้นทุนสำหรับข้อมูลที่ไม่สมดุล


12

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

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

from collections import Counter
counts = Counter(category_train)
weightsArray =[]
for i in range(n_classes):
    weightsArray.append(math.log(category_train.shape[0]/max(counts[i],1))+1)

class_weight = tf.constant(weightsArray)
weighted_logits = tf.mul(pred, class_weight)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(weighted_logits, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

พวกคุณมีข้อมูลอ้างอิงทางวิทยาศาสตร์เกี่ยวกับวิธีที่คุณเลือกน้ำหนักสำหรับฟังก์ชันการสูญเสียหรือไม่? ไม่ใช่ว่าฉันไม่เชื่อคุณ แต่ฉันคิดว่าคุณเป็นคนที่ได้รับแรงบันดาลใจจากคนอื่น?
แกร์ฮาร์ดฮาเกอร์เกอร์

และตามที่ davidparks21 ถามแล้วผลลัพธ์ของวิธีการของคุณน่าสนใจมาก :)
Gerhard Hagerer

คำตอบ:


4

ดูเหมือนว่าจะเป็นทางออกที่ดีสำหรับฟังก์ชั่นการสูญเสีย ฉันประสบความสำเร็จด้วยวิธีการที่คล้ายกันเมื่อเร็ว ๆ นี้ แต่ฉันคิดว่าคุณต้องการเรียงลำดับที่คุณคูณclass_weightด้วย

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

วิธีที่คุณมีมันclass_weightจะส่งผลต่อค่าการทำนาย แต่คุณต้องการให้มันส่งผลต่อสเกลของการไล่ระดับสี หากฉันไม่ผิดฉันคิดว่าคุณต้องการย้อนกลับลำดับการดำเนินการ:

# Take the cost like normal
error = tf.nn.softmax_cross_entropy_with_logits(pred, y)

# Scale the cost by the class weights
scaled_error = tf.mul(error, class_weight)

# Reduce
cost = tf.reduce_mean(scaled_error)

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

ที่น่าสนใจฉันประสบความสำเร็จในการใช้เทคนิคที่คล้ายกันมากในโดเมนปัญหาที่แตกต่างกันเมื่อเร็ว ๆ นี้ (ซึ่งนำฉันมาที่โพสต์นี้):

การเรียนรู้แบบมัลติทาสก์ค้นหาฟังก์ชันการสูญเสียที่ "ละเว้น" ตัวอย่างบางอย่าง


2

ชำระเงินtf.nn.weighted_cross_entropy_with_logits():

คำนวณเอนโทรปีของการถ่วงน้ำหนัก

นี่เป็นเหมือน sigmoid_cross_entropy_with_logits () ยกเว้น pos_weight ที่อนุญาตให้หนึ่งแลกเปลี่ยนการเรียกคืนและความแม่นยำโดยการเพิ่มหรือลดน้ำหนักค่าใช้จ่ายของข้อผิดพลาดเชิงบวกเมื่อเทียบกับข้อผิดพลาดเชิงลบ

สิ่งนี้จะช่วยให้คุณทำสิ่งที่คุณต้องการ


0

ฉันมีการใช้งาน 2 แบบที่แตกต่างกัน:

  1. ด้วย softmax ปกติที่มีการบันทึก: tf.nn.softmax_cross_entropy_with_logits

ในกรณีที่ class_weight เป็นตัวยึดตำแหน่งฉันกรอกในการวนซ้ำแบตช์ Everey

self.class_weight  = tf.placeholder(tf.float32, shape=self.batch_size,self._num_classes], name='class_weight')    
self._final_output = tf.matmul(self._states,self._weights["linear_layer"]) + self._biases["linear_layer"] 
self.scaled_logits = tf.multiply(self._final_output, self.class_weight)
self.softmax = tf.nn.softmax_cross_entropy_with_logits(logits=self.scaled_logits,labels= self._labels)
  1. ด้วยtf.nn.softmax_cross_entropy_with_logits

ฉันจะใช้ฟังก์ชัน tensorflow ที่นำมาใช้ แต่ฉันจำเป็นต้องคำนวณน้ำหนักของแบตช์ เอกสารค่อนข้างสับสนเกี่ยวกับเรื่องนี้ มี 2 ​​วิธีในการทำกับ tf.gather หรือเช่นนี้:

self.scaled_class_weights=tf.reduce_sum(tf.multiply(self._labels,self.class_weight),1)
self.softmax = tf.losses.softmax_cross_entropy(logits=self._final_output,
                                                   onehot_labels=self._labels,weights=self.scaled_class_weights)

ที่นี่มีการสนทนาที่ดีเกี่ยวกับเรื่องนี้

และในที่สุดเมื่อฉันไม่ต้องการแต่งงานกับการกระทำใด ๆ ที่เพิ่มขึ้นมาเรื่อย ๆ ฉันเพิ่ม tf.case นิดหน่อยและฉันผ่านการฝึกฝนในเวลาที่ฉันต้องการใช้กลยุทธ์

self.sensitive_learning_strategy = tf.placeholder(tf.int32 , name='sensitive_learning_strategy')
self.softmax =tf.case([
            (tf.equal(self.sensitive_learning_strategy, 0), lambda: self.softmax_0),
            (tf.equal(self.sensitive_learning_strategy, 1), lambda: self.softmax_1),
            (tf.equal(self.sensitive_learning_strategy, 2), lambda: self.softmax_2)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.