Dengesiz Veriler için Tensorflow Ayarlama Fonksiyonu


12

Dengesiz verilerle bir sınıflandırma problemim var. Aşırı ve yetersiz örneklemenin yanı sıra yeterince temsil edilmeyen kategorik çıktıların maliyetini değiştirmenin daha iyi uyuma yol açacağını okudum. Bu yapılmadan önce tensorflow her girdiyi çoğunluk grubu olarak sınıflandırır (ve anlamsız olduğu gibi% 90'ın üzerinde doğruluk kazanır).

Her grubun ters yüzdesinin günlüğünün, denediğim en iyi çarpanı yaptığını fark ettim. Maliyet fonksiyonu için daha standart bir manipülasyon var mı? Bu doğru bir şekilde uygulandı mı?

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)

Kayıp fonksiyonu için ağırlıkları ideal olarak nasıl seçtiğinize dair bilimsel bir referansınız var mı? Sana inanmadığım için değil, ama başka birinden çok ilham aldığını sanıyordum?
Gerhard Hagerer

Ve davidparks21'in daha önce sorduğu gibi, yaklaşımınızın sonuçları çok ilginç olurdu :).
Gerhard Hagerer

Yanıtlar:


4

Bu, kayıp fonksiyonu için iyi bir çözüm gibi görünüyor. Son zamanlarda benzer bir yaklaşımla başarılı oldum, ancak bence nerede çoğaldığınız yeri yeniden sıralamak istersiniz class_weight.

Mantıksal olarak class_weightdüşünüldüğünde, çıktı sabit bir sabit olacaktır, bu yüzden maliyet fonksiyonuna uygulandığı şekilde gradyana taşınacak ve uygulanacaktır. Yine de bir sorun var.

Sahip olduğunuz yol class_weight, tahmin değerini etkiler. Ancak, degradenin ölçeğini etkilemesini istiyorsunuz. Eğer yanılmıyorsam, işlem sırasını tersine çevirmek isteyeceğini düşünüyorum

# 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)

Bunun daha az temsil edilen sınıfın basitçe örneklemesine kıyasla nasıl bir performans gösterdiğini bilmek istiyorum. Eğer orada bir fikir kazanmak eğer Yani bu konuda yazı! :)

İlginç bir şekilde, son zamanlarda farklı bir problem alanında çok benzer bir tekniği başarıyla kullandım (bu beni bu yazıya getirdi):

Çok amaçlı öğrenme, belirli örnekleri "yok sayan" bir kayıp fonksiyonu bulma


2

Ödeme tf.nn.weighted_cross_entropy_with_logits():

Ağırlıklı bir çapraz entropiyi hesaplar.

Bu pos_weight dışında sigmoid_cross_entropy_with_logits () gibidir, negatif bir hataya göre pozitif bir hatanın maliyetini yukarı veya aşağı ağırlıklandırarak kişinin hatırlama ve kesinlik kazanmasına izin verir.

Bu istediğinizi yapmanıza izin vermelidir.


0

2 farklı uygulamam var:

  1. günlükleri olan 'normal' softmax ile: tf.nn.softmax_cross_entropy_with_logits

Class_weight'in bir yer tutucu olduğu yerlerde everey toplu yinelemesini doldururum.

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. ile tf.nn.softmax_cross_entropy_with_logits

Uygulanan tensorflow işlevini kullandığım ancak toplu işin ağırlıklarını hesaplamam gerekiyor. Dokümanlar biraz kafa karıştırıcı. Tf.gather ile yapmanın 2 yolu vardır:

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)

burada güzel bir tartışma var

Ve son olarak hiçbir uygulama ile evlenmek istemediğim için geçici olarak biraz tf.case ekledim ve kullanmak istediğim stratejiyi eğitim zamanına aktardım.

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.