2017-04-06 2 views
0

入力番号が正か負かを予測するNNを記述しようとしているので、これをモデル化して訓練し、その精度をチェックしました。しかし、このモデルを使って、数値が正か負かを明示的にチェックすることはできません。私は唯一、正確さをチェックすることができます、私は関数のような個々の入力のためにこれを使用することはできません。テンソルの流れのランダムな入力に対して訓練されたネットワークの出力を見つける方法は?

これは私の試みです。

これは

import numpy as np 
import random 
import pickle 
import bitstring 
from collections import Counter 

def binary(num): 
    f1 = bitstring.BitArray(float=num, length=32) 
    return f1.bin 
def num2bin(num): 
    return [int(x) for x in binary(num)[0:]] 

pos=10*np.random.rand(1000) 
pos_test=10*np.random.rand(1000) 

neg=-10*np.random.rand(1000) 
neg_test=-10*np.random.rand(1000) 

これは32ビットの形式にトレーニングデータを変換して

def create_label_feature(pos,pos_test,ned,neg_test,test_size=0.1): 
featuresp=[] 
labelsp=[] 
for x in pos: 
    featuresp +=[num2bin(x)] 
    labelsp +=[[1,0]] 
featuresn=[] 
labelsn=[] 
for x in neg: 
    featuresn +=[num2bin(x)] 
    labelsn +=[[0,1]] 
featurespt=[] 
labelspt=[] 
for x in pos_test: 
    featurespt +=[num2bin(x)] 
    labelspt +=[[1,0]] 
featuresnt=[] 
labelsnt=[] 
for x in neg_test: 
    featuresnt +=[num2bin(x)] 
    labelsnt +=[[0,1]] 
test_x=featuresp+featuresn 
test_y=labelsp+labelsn 
train_x=featurespt+featuresnt 
train_y=labelspt+labelsnt 

return train_x, train_y, test_x, test_y 

train_x ,train_y ,test_x, test_y=create_label_feature(pos,pos_test,neg,neg_test) 

それをラベルこれはNNをトレーニングした後、正または負であるか否かを-5決定しようとトレーニングデータを作成します

import tensorflow as tf 
#from tensorflow.examples.tutorials.mnist import input_data 
import pickle 
import numpy as np 



n_nodes_hl1 = 1500 
n_nodes_hl2 = 1500 
n_nodes_hl3 = 1500 

n_classes = 2 
batch_size = 100 
hm_epochs = 10 

x = tf.placeholder('float',shape=[None,32]) 
y = tf.placeholder('float') 

hidden_1_layer = {'f_fum':n_nodes_hl1, 
        'weight':tf.Variable(tf.random_normal([len(train_x[0]), n_nodes_hl1])), 
        'bias':tf.Variable(tf.random_normal([n_nodes_hl1]))} 

# hidden_2_layer = {'f_fum':n_nodes_hl2, 
#     'weight':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])), 
#     'bias':tf.Variable(tf.random_normal([n_nodes_hl2]))} 

# hidden_3_layer = {'f_fum':n_nodes_hl3, 
#     'weight':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])), 
#     'bias':tf.Variable(tf.random_normal([n_nodes_hl3]))} 

output_layer = {'f_fum':None, 
       'weight':tf.Variable(tf.random_normal([n_nodes_hl1, n_classes])), 
       'bias':tf.Variable(tf.random_normal([n_classes])),} 


# Nothing changes 
def neural_network_model(data): 

    l1 = tf.add(tf.matmul(data,hidden_1_layer['weight']), hidden_1_layer['bias']) 
    l1 = tf.nn.relu(l1) 

#  l2 = tf.add(tf.matmul(l1,hidden_2_layer['weight']), hidden_2_layer['bias']) 
#  l2 = tf.nn.relu(l2) 

#  l3 = tf.add(tf.matmul(l2,hidden_3_layer['weight']), hidden_3_layer['bias']) 
#  l3 = tf.nn.relu(l3) 

    output = tf.matmul(l1,output_layer['weight']) + output_layer['bias'] 

    return output 

def train_neural_network(x): 
    prediction = neural_network_model(x) 
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y)) 
    optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost) 

    with tf.Session() as sess: 
     saver = tf.train.Saver() 
     sess.run(tf.initialize_all_variables()) 

     for epoch in range(hm_epochs): 
      epoch_loss = 0 
      i=0 
      while i < len(train_x): 
       start = i 
       end = i+batch_size 
       batch_x = np.array(train_x[start:end]) 
       batch_y = np.array(train_y[start:end]) 

       _, c = sess.run([optimizer, cost], feed_dict={x: batch_x, 
                   y: batch_y}) 
       epoch_loss += c 
       i+=batch_size 

      print('Epoch', epoch+1, 'completed out of',hm_epochs,'loss:',epoch_loss) 
     correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1)) 

     accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 

     print('Accuracy:',accuracy.eval({x:test_x, y:test_y})) 
     a=num2bin(-5)   
     a=np.reshape(a,(1,32)) 
#  a=a[0,:] 

#  print(sess.run(prediction, {x:np.array(num2bin(5))})) 
     print(sess.run(prediction, {x:a})) 


train_neural_network(x) 

コードの最後の部分

a=num2bin(-5)   
    a=np.reshape(a,(1,32)) 
    print(sess.run(prediction, {x:a})) 

私はwheter -5が正または負であることを確認したいと思いますが、出力として[0,1]を持つことが予想されています。

しかし、その代わりに、私は

[[-29.49657059 123.97122192]]

を取得するので、問題はここ何ですか?

編集

次の部分をコードに追加します。

 for k in [-9,3, 5,-8,-77,-16,54.3]: 
       a=num2bin(k)   
       a=np.reshape(a,(1,32)) 
       a=sess.run(prediction, {x:a}) 
       prediction_tensor = tf.sigmoid(a)  
       print(sess.run(prediction_tensor)) 

その後、私の出力は

Accuracy: 0.999933 
[[ 0.   0.85150468]] 
[[ 8.66709650e-01 8.56608536e-32]] 
[[ 7.24581242e-01 8.87260485e-37]] 
[[ 0.   0.66523373]] 
[[ 0. 1.]] 
[[ 0.00000000e+00 8.08775063e-16]] 
[[ 1. 0.]] 

だから私のコードは、2つのコンポーネント出力を与え、最初の要素が第二より大きい場合、それは入力が正であることを意味していない場合、それはそのことを意味しています否定的です。

答えて

0

あなたの出力は、スケーリングされていない値であり、正常に見えます。損失関数は、クロスエントロピーを適用する前に、それらの値にシグモイド関数を適用しています。表示される値には、損失関数に入力するスケーリングされていない値があります。シグモイドを適用せずに数値を見ると、すべての負の数は0に近づき、0に近づくにつれて0に近づき、すべての正の数は1を予測し、近づくほど正になります。もちろんこれはSigmoid関数があなたのためにやっていることです。結果について確信が持てば、大規模な負の数値または大きな正の数値を出力するようにネットワークを訓練しました。

これらの値にシグモイドを適用した場合、〜[[0.00000001、0.9999999999999999999]]または[[0,1]]を丸めた場合、期待どおりの結果が得られます。

ちなみに、バイナリクラスの場合は2つの出力は必要ありません。ただ1つの出力しか使用できません。正または負のいずれかです。ネットワークはおそらく2つの出力よりもわずかに優れたパフォーマンスを発揮します。それが正と負の数を予測するのは難しいことではありません。:)

次のような別のテンソルを定義することによって、スケール(0,1)の値を取得することができます:

prediction_tensor = tf.sigmoid(a) 
+0

私の編集を参照してください。精度は0.999933ですが、すべての結果に対して[1 0]または[0 1]を得ることはできません。たとえば、入力3に対して[8.66709650e-01 8.56608536e-32]を取得します。最初の要素が大きいので肯定的です。しかし、それはこれのようになっています。私は、このモデルが標識を決定する上で非常に優れていると言うことができますか? – physshyp

+0

第1のクラスは「0.87」であり、第2のクラスは「0.0」(妥当な読み取り可能な値に丸められている)である。それは非常に正常に見えます! 0.5を超えるものは1(正)に切り上げられ、0.5未満のものは0(負)に切り上げられます。ここでもバイナリの分類であるため、1つの出力でよりうまくやっていますが、その結果は「最初の要素が真であることを確信しており、2番目の要素が偽であることを確信しています。もっと長いトレーニングをした場合、最初の要素の価値をより確かなものにすることができます(例:1に近づくかもしれない) –

関連する問題