2016-08-28 18 views
2

私はチュートリアルDeep MNIST for Expertsをただ1つのクラスを検出するように調整しようとしています。画像にキティが含まれているかどうかを検出するとします。テンソルフロー:1クラス分類

これは私のコードの予測一部です:

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) 
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1])) 
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1)) 
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 
sess.run(tf.initialize_all_variables()) 
for i in range(20000): 
    batch = mnist.train.next_batch(50) 
    if i%100 == 0: 
    train_accuracy = accuracy.eval(feed_dict={ 
     x:batch[0], y_: batch[1], keep_prob: 1.0}) 
    print("step %d, training accuracy %g"%(i, train_accuracy)) 
    train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) 

print("test accuracy %g"%accuracy.eval(feed_dict={ 
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) 

問題は、一つのクラスで、ソフトマックスはあっても、常にブランクのイメージのために、1の自信を持って、そのクラスを返すということです。 softmaxとクロスエントロピーを修正しようとしましたが、解決できませんでした。

この問題にどのようなアプローチが推奨されているかを知る必要があります。 私は予測が画像がキティである確率であることを望んでいます。

私はこれがランダムな画像で訓練された第2のラベルを使用して解決できることを知っていますが、より良い解決策があるかどうかを知る必要があります。

ありがとうございました。

+0

コード全体を入力してください。また、1クラスあたりの電車とテスト画像の数はいくつですか? – rvinas

+0

全体のコードはチュートリアルのものです。テスト用に5Kのトレーニング用に50Kの画像を使用しています。すべての画像は一意のクラスに属します。 – cropmad1548

+0

あなたは2つのクラス、子猫ではなく子猫であるので、そのバイナリ分類です。 –

答えて

5

単一のクラスメンバーシップ予測にsoftmaxおよびmulti-classログロスを使用しないでください。代わりに、より一般的な設定は、バイナリクロスエントロピーによるシグモイド活性化です。あなたが正しい予測*のコスト/利益を最適化しない限り、> 0.5の閾値を「陽性」クラスに分類するように設定してください。

TensorFlowでは、コードが数か所だけ変更されます。

次の調整は、私が思うあなたのコードの先頭に適用されます:あなたは予測の信頼を気に問題に取り組んで、そしてどこに評価する必要がある場合

y_conv = tf.nn.sigmoid(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) 

# I've split the individual loss out because the line length was too long 
# The +1e-12 is for numerical stability in case of perfect 0.0 or 1.0 predictions 
# Note how this loss metric penalises incorrect predictions in both directions, 
# unlike the multiclass logloss which only assessed confidence in 
# correct class. 
loss = -(y_ * tf.log(y_conv + 1e-12) + (1 - y_) * tf.log(1 - y_conv + 1e-12)) 
cross_entropy = tf.reduce_mean(tf.reduce_sum(loss, reduction_indices=[1])) 

predict_is_kitty = tf.greater(y_conv,0.5) 
correct_prediction = tf.equal(tf.to_float(predict_is_kitty), y_) 

*しきい値を設定し、精度の代わりに通常のメトリックはarea under ROC curve, often known as AUROC or just AUCです。

+0

問題は彼のデータには1クラスが含まれていることです!これを訓練すれば、出力は常に1になるか、入力に関係なく1つのクラスに割り当てられた値になります。 – thang

+0

@thang:実際には、OPには2つのクラス(catまたはcatではない)と1つのバイナリラベルがありますが、1つの*出力でsoftmaxを使用しようとしていました。彼らはsoftmaxで2つの出力を使用することができます(そしてtrue/falseクラスをワンホットエンコードする、例えばfalseの場合は[1,0]、trueの場合は[0,1])、または答えと同じシグモイドの出力を使用し、 0]、[1] –

+1

OPは1クラスを持ち続けます。私は彼に2つのクラスがあると仮定しますが、彼のトレーニングデータには1しか含まれていません。これは通常、1つのクラス分類問題(OCC)と呼ばれます。この場合、訓練中、xen​​tropy softmaxで2つの出力を使用しているか、0と1で1つの出力を使用しているかに関わらず、訓練は常に1つのクラスの訓練データのみで縮退したソリューションに収束します。 OCCはわずかに異なり、同じ監督訓練レジームは機能しません。 – thang

関連する問題