Otázka:
Jaká ztráta funkce pro úkoly s klasifikací více tříd a více štítků v neuronových sítích?
aKzenT
2016-04-17 19:28:38 UTC
view on stackexchange narkive permalink

Cvičím neuronovou síť pro klasifikaci sady objektů do n-tříd. Každý objekt může patřit do více tříd najednou (více tříd, více štítků).

Četl jsem, že u problémů s více třídami se obecně doporučuje použít softmax a kategorickou křížovou entropii jako ztrátu funkce místo mse a chápu víceméně proč.

Pro můj problém multi-labelu by samozřejmě nemělo smysl používat softmax, protože pravděpodobnost každé třídy by měla být nezávislá na druhé. Moje poslední vrstva jsou tedy jen sigmoidní jednotky, které squashují své vstupy do rozsahu pravděpodobnosti 0..1 pro každou třídu.

Teď si nejsem jistý, jakou funkci ztráty bych k tomu měl použít. Podíváme-li se na definici kategorické crossentropie, domnívám se, že by se na tento problém dobře nevztahovalo, protože bere v úvahu pouze výstup neuronů, který by měl být 1, a ostatní ignoruje.

Binární křížová entropie zní takhle by se vešel lépe, ale vidím to jen zmínku o problémech s binární klasifikací s jediným výstupním neuronem.

Používám python a keras pro trénink pro případ, že by to mělo význam.

Věřím, že softmax _is_ "sigmoidní jednotky, které stlačují své vstupy do rozsahu pravděpodobnosti 0..1 pro každou třídu".
Jako funkci ztráty můžete použít softmax a poté pomocí pravděpodobností vícevrstvá data.
šest odpovědi:
Alok Nayak
2016-09-12 19:38:23 UTC
view on stackexchange narkive permalink

Pokud používáte keras, jednoduše vložte sigmoidy na výstupní vrstvu a binary_crossentropy na vaši nákladovou funkci.

Pokud používáte tensorflow, můžete použít sigmoid_cross_entropy_with_logits. Ale v mém případě se tato funkce přímé ztráty nesbližovala. Takže jsem nakonec použil explicitní sigmoidní křížovou entropickou ztrátu $ (y \ cdot \ ln (\ text {sigmoid} (\ text {logits})) + (1-y) \ cdot \ ln (1- \ text {sigmoid} ( \ text {logits}))) $. Můžete si vytvořit vlastní, jako v tomto Příkladu

Sigmoid, na rozdíl od softmaxu nedává rozdělení pravděpodobnosti kolem $ n_ {tříd} $ jako výstup, ale nezávislé pravděpodobnosti.

Pokud je průměrně kterémukoli řádku přiřazeno méně štítků, můžete použít softmax_cross_entropy_with_logits, protože s touto ztrátou se třídy vzájemně vylučují, jejich pravděpodobnosti nemusí být. Vyžaduje se pouze to, aby každá řada štítků byla platnou distribucí pravděpodobnosti. Pokud tomu tak není, bude výpočet přechodu nesprávný.

Milý Aloku, můžeš OP vysvětlit, jak by tuto funkci využívali a proč má smysl?Jak uvidíte v [prohlídce], na webu nejsou podporovány odpovědi pouze na odkazy.
Pěkné krátké vysvětlení lze vidět v keras github: https://github.com/fchollet/keras/issues/741
Při použití křížové entropie se nedoporučuje psát vlastní nákladovou funkci - může * * podléhat problémům s numerickou stabilitou.Viz https://github.com/tensorflow/tensorflow/issues/2462 pro diskusi.
Jedna věc je vícevrstvá, druhá věc je vícevrstvá vícetřídová.Sigmoid rozmačká váš výstup mezi 0 a 1, ale OP má několik tříd, takže výstupy by měly být např.0 - 10. Takže výstupy by měly vypadat: [0,5,2,3,1] <--- to není to, co sigmoid dělá.
mám použít tf.round (logits) před použitím v nákladové funkci nebo mohu přímo použít logity ze skryté vrstvy na tf.nn.sigmoid ....?
shouldsee
2017-12-10 01:50:00 UTC
view on stackexchange narkive permalink

UPDATE (18/04/18): Stará odpověď se na mém modelu stále ukázala jako užitečná. Trik spočívá v samostatném modelování funkce oddílu a distribuce, čímž se využívá síla softmaxu.

Zvažte svůj pozorovací vektor $ y $, který obsahuje štítky $ m $. $ y_ {im} = \ delta_ {im} $ (1, pokud vzorek i obsahuje štítek m, jinak 0). Cílem by tedy bylo modelovat matici způsobem na vzorek. Proto model vyhodnocuje $ F (y_i, x_i) = - \ log P (y_i | x_i) $. Zvažte rozšíření $ y_ {im} = Z \ cdot P (y_m) $, abyste dosáhli dvou vlastností:

  1. Distribuční funkce: $ \ sum_m P (y_m) = 1 $
  2. Funkce oddílu: $ Z $ odhaduje počet štítků

Pak jde o modelování těchto dvou odděleně. Distribuční funkce se nejlépe modeluje pomocí vrstvy softmax a funkce oddílu lze modelovat pomocí lineární jednotky (v praxi jsem ji ořezal jako $ max (0,01, výstup) $. Sofistikovanější modelování jako Poisson jednotka by pravděpodobně fungovala lépe). Pak se můžete rozhodnout použít distribuovanou ztrátu (KL v distribuci a MSE v oddílu), nebo můžete vyzkoušet následující ztrátu na jejich produktu.

V praxi má volba optimalizátoru také obrovský rozdíl. Moje zkušenost s faktorizačním přístupem je, že to funguje nejlépe pod Adadelta (Adagrad pro mě nepracuje, ještě jsem nezkoušel RMSprop, výkon SGD podléhá parametru).

Side komentář k sigmoid: Určitě jsem zkoušel sigmoid + crossentropy a nevyšlo to. Model měl sklon předpovídat pouze $ Z $ a nepodařilo se mu zachytit odchylku distribuční funkce. (aka, je to docela užitečné pro modelování oddílu a může za tím být matematický důvod)

UPDATE: (Náhodné zamyšlení) Zdá se, že použití Dirichletova procesu by umožnilo začlenit některé předchozí do počtu štítků?

UPDATE: Experimentem je modifikovaná divergence KL stále nakloněna k poskytování výstupu více tříd spíše než výstupu několika štítků.


(Stará odpověď)

Moje zkušenost s křížovou entropií sigmoidu nebyla příliš příjemná. V tuto chvíli používám upravenou KL-divergenci. Má formu

$$ \ begin {zarovnáno} Ztráta (P, Q) & = \ sum_x {| P (x) -Q (x) | \ cdot \ left | \ log \ frac {P (x)} {Q (x)} \ right | } \\ & = \ sum_x {\ left | (P (x) -Q (x)) \ cdot \ log \ frac {P (x)} {Q (x)} \ vpravo | } \ end {zarovnáno} $$ Kde $ P (x) $ je cílová pseudodistribuce a $ Q (x) $ je předpokládaná pseudodistribuce (ale funkce je ve skutečnosti symetrická, takže na tom vlastně nezáleží)

Nazývají se pseudodistribuce, protože nejsou normalizovány. Takže můžete mít $ \ sum_x {P (x)} = 2 $, pokud máte 2 popisky pro konkrétní vzorek.

Impelmentace KERAS

  def abs_KL_div (y_true, y_pred):
    y_true = K.clip (y_true, K.epsilon (), žádný)
    y_pred = K.clip (y_pred, K.epsilon (), žádný)
    návrat K.sum (K.abs ((y_true- y_pred) * (K.log (y_true / y_pred))), axis = -1)
 
na mém konkrétním datovém souboru byl `adam` mnohem lepší než` rmsprop`
Pokud takovou ztrátu použijete pro trénink, jak na to ve fázi testování?Pro predikci použijte také softmax, ale jak vybrat prahovou hodnotu pro určení tříd více štítků?
Aaditya Ura
2019-11-12 18:19:53 UTC
view on stackexchange narkive permalink

Procházel jsem stejným problémem, po nějakém výzkumu je zde moje řešení:

Pokud používáte tensorflow:

Ztráta více štítků:

  cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits (logits = logits, labels = tf.cast (cíle, tf.float32))

    loss = tf.reduce_mean (tf.reduce_sum (cross_entropy, axis = 1))

    predikce = tf.sigmoid (logity)
    output = tf.cast (self.prediction > threshold, tf.int32)
    train_op = tf.train.AdamOptimizer (0,001). minimalizovat (ztráta)
 

Vysvětlení:

Například pokud jsou Logity z modelu a štítků:

  logits = array ([[1.4397182, -0.7993438, 4.113389, 3.2199187, 4.5777845]),
       [0,30619335, 0,10168511, 4,253479, 2,3782277, 4,7390924],
       [1.124632, 1.6056736, 2.9778094, 2.0808482, 2.0735667],
       [0,7051575, -0,10341895, 4,990803, 3,7019827, 3,8265839],
       [0,6333333, -0,76601076, 3,2255085, 2,7842572, 5,3817415]],
      dtype = float32)

štítky = pole ([[1, 1, 0, 0, 0],
       [0, 1, 0, 0, 1],
       [1, 1, 1, 1, 0],
       [0, 0, 1, 0, 1],
       [1, 1, 1, 1, 1]])

pak

cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits (logits = logits, labels = tf.cast (cíle, tf.float32))

dá vám:

[[0,21268466 1,170648 4,129609 3,2590992 4,58801]
 [0,85791767 0,64359653 4,2675934 2,466893 0,00870855]
 [0,28124034 0,18294993 0,04965096 0,11762683 2,1920042]
 [1,1066352 0,64277405 0,00677719 3,7263577 0,02155003]
 [0,42580318 1,147773 0,03896642 0,059942 0,00458926]]

a

prediction = tf.cast (tf.sigmoid (one_placeholder) > 0.5, tf.int32)

dá vám:

[[1 0 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 0 1 1 1]
 [1 0 1 1 1]]
 

Nyní máte předpokládané štítky a skutečné štítky. Přesnost můžete snadno vypočítat.

Pro více tříd:

Štítky musí být kódovány jedním souborem

  cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2 (logits = logits, labels = one_hot_y)
loss = tf.reduce_sum (cross_entropy)

optimizer = tf.train.AdamOptimizer (learning_rate = self.lr) .minimize (ztráta)

predictions = tf.argmax (logits, axis = 1, output_type = tf.int32, name = 'predictions')
přesnost = tf.reduce_sum (tf.cast (tf.equal (předpovědi, true_labels), tf.float32))
 

Další příklad

  # ZTRÁTA A OPTIMALIZÁTOR
loss = tf.reduce_mean (tf.nn.softmax_cross_entropy_with_logits_v2 (logits = output, labels = y))
optimizer = tf.train.AdamOptimizer (learning_rate = learning_rate,
                                   beta1 = 0,9,
                                   beta2 = 0,999,
                                   epsilon = 1e-08) .minimize (ztráta, global_step = global_step)


# VÝPOČET PŘEDPISŮ A PŘESNOSTI
correct_prediction = tf.equal (y_pred_cls, tf.argmax (y, axis = 1))
přesnost = tf.reduce_mean (tf.cast (correct_prediction, tf.float32))
 
mintaka
2016-08-05 02:25:00 UTC
view on stackexchange narkive permalink

Keras jsem zatím nepoužíval. Vezmeme-li například kávu, můžete použít SigmoidCrossEntropyLossLayer pro problémy s více štítky.

Chcete vysvětlit, proč je to dobrý přístup?
an unique monkey
2016-12-08 11:23:46 UTC
view on stackexchange narkive permalink

Ve skutečnosti v tensorsflow stále můžete použít sigmoid_cross_entropy_mean jako funkci výpočtu ztráty v multi-labelu, velmi to potvrzuji

Dejte nám odkaz na dokumentaci
Willy satrio nugroho
2017-07-03 13:28:31 UTC
view on stackexchange narkive permalink

Jsem zde nováček, ale zkusím to zkusit s touto otázkou.Hledal jsem to samé jako ty a nakonec jsem našel velmi dobrý výukový program klasifikace více tříd keras @ http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/.

Autor tohoto tutoriálu používá kategorickou funkci ztráty křížové entropie a existuje další vlákno, které vám může pomoci najít řešení @ zde.

Není to jen více tříd, je to také více štítků.


Tyto otázky a odpovědi byly automaticky přeloženy z anglického jazyka.Původní obsah je k dispozici na webu stackexchange, za který děkujeme za licenci cc by-sa 3.0, pod kterou je distribuován.
Loading...