从CNN中提取Tensorflow中所有类的概率

时间:2017-10-24 01:48:27

标签: python-3.x tensorflow probability conv-neural-network

我有一个训练有素的CNN,它正在为确定预期的类产生正确的预测,但是我希望将每个类的概率看作一个列表。我试图添加一个softmax函数,但是我得到一个关于负尺寸的错误。我已经阅读了这个问题的多个版本,并且已经看到了似乎是多个解决方案,但是,似乎一个大小并不适合所有,并且我已经尝试了使用eval和run语句的各种解决方案;它们似乎都不适用于此模型。我使用的代码是:

import tensorflow as tf
import numpy as np
import csv
SpeciesID = {'None':0}

def extract_data(filename, CSV_Origin_File):
    print("extracting data...")

    NUM_LABELS = 113 
    NUM_FEATURES = 10816


    labels = []
    fvecs = []
    rowCount = 0


    for IDline in open(CSV_Origin_File):
        IDrow = IDline.split(',')
        INkey = IDrow[6]
        INvalue = IDrow[9]
        SpeciesID.update({INkey:INvalue})

    #iterate over the rows, split the label from the features
    #convert the labels to integers and features to floats

    for line in open(filename):
        rowCount = rowCount + 1
        row = line.split(',')
        labels.append(row[0])#(int(row[7]))

        for x in row [0:10816]: #was 3-10820
            #print("fvecs>>>", x)
            fvecs.append(float(x))

    #convert the array of float arrasy into a numpy float matrix
    fvecs_np = np.matrix(fvecs).astype(np.float32)

    #convert the array of int lables inta a numpy array
    labels_np = np.array(labels).astype(dtype=np.uint8)

    #convert the int numpy array into a one-hot matrix
    labels_onehot = (np.arange(NUM_LABELS) == labels_np[:, None]).astype(np.float32)
    print("arrays converted")
    return fvecs_np, labels_onehot

# Create some wrappers for simplicity
def conv2d(x, W, b, strides=1): #Layer 1 : Convolutional layer
    # Conv2D wrapper, with bias and relu activation
    #print("conv2d")
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') # Strides are the tensors...list of integers.  Tensors=data
    x = tf.nn.bias_add(x, b)  #bias is the tuning knob
    return tf.nn.relu(x) #rectified linear unit (activation function)


def maxpool2d(x, k=2): #Layer 2 : Takes samples from the image. (This is a 4D tensor)
    #print("maxpool2d")
    # MaxPool2D wrapper
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
                          padding='SAME')


def conv_net(x, wc1, wc2, wd1, Wout, bc1, bc2, bd1, Bout, dropout):
    #print("conv_net setup")
    # Reshape input picture
    x = tf.reshape(x, shape=[-1, 104, 104, 1])  #-->52x52 , -->26x26x64

    # Convolution Layer
    conv1 = conv2d(x, wc1, bc1) #defined above already
    # Max Pooling (down-sampling)
    conv1 = maxpool2d(conv1, k=2)
    #print(conv1.get_shape)

    # Convolution Layer
    conv2 = conv2d(conv1, wc2, bc2)  #wc2 and bc2 are just placeholders...could actually skip this layer...maybe
    # Max Pooling (down-sampling)
    conv2 = maxpool2d(conv2, k=2)
    #print(conv2.get_shape)

    # Fully connected layer
    # Reshape conv2 output to fit fully connected layer input
    fc1 = tf.reshape(conv2, [-1, wd1.get_shape().as_list()[0]])
    fc1 = tf.add(tf.matmul(fc1, wd1), bd1)
    fc1 = tf.nn.relu(fc1) #activation function for the NN
    # Apply Dropout
    #fc1 = tf.nn.dropout(fc1, dropout) #NO DROPOUT FOR TESTING!!!

    # Output, class prediction

    out = tf.add(tf.matmul(fc1, Wout), Bout)
    #print(out, "OUTPUT_________$$$")
    return out


def TestModels(InputFile, RefFile):
        fvecs_np, labels_onehot = extract_data(InputFile, RefFile)

        print('RESTORING NN MODEL')

        weights = {}
        biases = {}
        sess=tf.Session()  
        init = tf.global_variables_initializer()

        #Load meta graph and restore weights

        ModelID = "CNN_PICORNA_UCONN2-1000.meta" 
        print("RESTORING:::", ModelID)

        saver = tf.train.import_meta_graph(ModelID)

        saver.restore(sess,tf.train.latest_checkpoint('./'))

        graph = tf.get_default_graph()
        x = graph.get_tensor_by_name("x:0")
        y = graph.get_tensor_by_name("y:0")
        keep_prob = tf.placeholder(tf.float32) 
        y_ = tf.placeholder("float", shape=[None, 113])

        wc1 = graph.get_tensor_by_name("wc1:0")
        wc2 = graph.get_tensor_by_name("wc2:0")
        wd1 = graph.get_tensor_by_name("wd1:0")
        Wout = graph.get_tensor_by_name("Wout:0")

        bc1 = graph.get_tensor_by_name("bc1:0")
        bc2 = graph.get_tensor_by_name("bc2:0")
        bd1 = graph.get_tensor_by_name("bd1:0")
        Bout = graph.get_tensor_by_name("Bout:0")

        weights = {wc1, wc2, wd1, Wout}
        biases = {bc1, bc2, bd1, Bout}

        pred = conv_net(x, wc1, wc2, wd1, Wout, bc1, bc2, bd1, Bout, keep_prob)

        prediction=tf.argmax(pred,1)
        best = sess.run([prediction],feed_dict={x: fvecs_np})

        probstesting = tf.nn.softmax(y,1)

        print("NEXTArgmax") 

        predY = prediction.eval(feed_dict={x: fvecs_np}, session=sess)

        PredSTR = str(predY[0])

        ProbBest = sess.run([probstesting], feed_dict={x: fvecs_np})

        print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
        print("Predicted::: ", predY,  (list(SpeciesID.keys())[list(SpeciesID.values()).index(PredSTR)]))
        print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")

TestModels("/users/rwbarrettemac/desktop/NN_DB/VirPlotOUT_TESTX.csv", "/users/rwbarrettemac/Picorna_NN/PicornaALL_INv2.csv")

虽然在运行测试样本时我得到了预期类的正确预测,但是我从尝试获取概率时得到以下错误,这是从行中抛出的:

ProbBest = sess.run([probstesting], feed_dict={x: fvecs_np})

它回来的错误陈述是:

2017-10-23 17:53:36.855270: W tensorflow/core/framework/op_kernel.cc:1148]    Invalid argument: Shape [-1,113] has negative dimensions
2017-10-23 17:53:36.855314: E tensorflow/core/common_runtime/executor.cc:644]  Executor failed to create kernel. Invalid argument: Shape [-1,113] has negative  dimensions
      [[Node: y = Placeholder[dtype=DT_FLOAT, shape=[?,113],  _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
2017-10-23 17:53:36.855424: W tensorflow/core/framework/op_kernel.cc:1148]   Invalid argument: Shape [-1,113] has negative dimensions
2017-10-23 17:53:36.855441: E tensorflow/core/common_runtime/executor.cc:644]  Executor failed to create kernel. Invalid argument: Shape [-1,113] has negative  dimensions
     [[Node: y = Placeholder[dtype=DT_FLOAT, shape=[?,113],   _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
Traceback (most recent call last):

...lots more of the same....

InvalidArgumentError (see above for traceback): Shape [-1,113] has negative dimensions
     [[Node: y = Placeholder[dtype=DT_FLOAT, shape=[?,113],   _device="/job:localhost/replica:0/task:0/cpu:0"]()]]

(tensorflow) aapnypi2vtrbarr:~ rwbarrettemac$

我也试过以下但没有运气:

probabilities=pred
print "probabilities", probabilities.eval(feed_dict={x: mnist.test.images},      session=sess)

在当天结束时,以下示例是我为此网络的输出设想的。假设我走错了路,有人会建议正确的代码来获得与下面的例子类似和概率产生类似数据的输出。谢谢。

[class] probability

[1] 0.0050
[2] 0.0124
[3] 0.8260
[4] 0.0001
 .
 .
 .
[113] 0.0008

1 个答案:

答案 0 :(得分:0)

所以我已经部分解决了这个问题。

我添加了一行:

y_ = tf.nn.softmax(tf.matmul(fc1,Wout) + Bout)

到conv_net(...)函数,然后将以下行添加到TestModels(...)函数中:

ProbOUT = probabilities.eval(feed_dict={x: fvecs_np}, session=sess)

通过ProbOUT迭代,给出了以下输出:

0.0.....Cardiovirus A[51]
0.0.....Cardiovirus B[52]
0.0.....Foot-and-mouth disease virus[53]
0.0.....Equine rhinitis A virus[54]
0.0.....Bovine rhinitis B virus[55]
0.0.....Bovine rhinovirus 1[56]
0.0.....Teschovirus A[57]
0.0.....Ljungan virus[58]
1.0.....Human parechovirus[59]
0.0.....Aichivirus A[60]
0.0.....Kobuvirus sheep/TB3/HUN/2009[61]
0.0.....Mouse kobuvirus M-5/USA/2010[62]

这很棒!,但为什么值为1或0?我认为通过softmax传递它应该会得到更精确的概率。这看起来像是通过argmax传递的。我错过了什么吗?