使用csv的Tensorflow MNIST:低精度

时间:2017-12-01 07:45:18

标签: python tensorflow neural-network mnist

我正在尝试使用CSV输入在Tensorflow中实现MNIST图像分类。准确度非常低,约为10%。我在输出端使用3个完全连接的层和s​​oftmax熵。我将mnist数据集从here转换为csv,以使用以下代码作为输入:

import idx2numpy
import numpy as np
# Reading
filename = 'train-images'
flext1 = '.idx3-ubyte'
flext2 = '.csv'
ndarr = idx2numpy.convert_from_file(filename+flext1).reshape(60000, 784)
np.savetxt(filename,ndarr,delimiter=',')

然后我对标签进行了单热编码,如下所示:

import tensorflow as tf
import numpy as np
import pandas as pd

trainimages=pd.read_csv("train-images.csv",header=None,delimiter=',').values
trainlabels=pd.read_csv("train-labels.csv",header=None,delimiter=',').values

testimages=pd.read_csv("t10k-images.csv",header=None,delimiter=',').values
testlabels=pd.read_csv("t10k-labels.csv",header=None,delimiter=',').values

label_ph=tf.placeholder(tf.int64,shape=(None,1))
reshapeval=tf.Variable(100)
onehotencoding=tf.one_hot(label_ph,depth=10)
datalabels=tf.reshape(onehotencoding,shape=(reshapeval,10))

with tf.Session() as sess:
  onehottrainlabels=sess.run(datalabels,feed_dict={label_ph:trainlabels,reshapeval:trainlabels.shape[0]})
  onehottestlabels=sess.run(datalabels,feed_dict={label_ph:testlabels,reshapeval:testlabels.shape[0]})
  print("datalabels:",onehottrainlabels)
  print("datalabels:",onehottestlabels)
  #sess.run(datalabels)

np.savetxt("mnist_train_labels_onehot.csv",onehottrainlabels,delimiter=',')
np.savetxt("mnist_test_labels_onehot.csv",onehottestlabels,delimiter=',')

我尝试使用如上所示生成的csv文件来尝试和训练图像分类模型,如下所示:

import tensorflow as tf
import pandas as pd
import numpy as np

trainimages=pd.read_csv("train-images.csv",header=None,delimiter=',').values
trainlabels=pd.read_csv("mnist_train_labels_onehot.csv",header=None,delimiter=',').values
testimages=pd.read_csv("t10k-images.csv",header=None,delimiter=',').values
testlabels=pd.read_csv("mnist_test_labels_onehot.csv",header=None,delimiter=',').values
#%%
train_num=len(trainimages)
n_epochs=400
BATCH_SIZE = 50
N_FEATURES = 785
n_inputs =28*28
n_hidden1=300
n_hidden2=100
n_outputs = 10
learning_rate=0.01
X=tf.placeholder(tf.float32,shape=(None,n_inputs),name='X')
y=tf.placeholder(tf.int64,shape=(None,10),name='y')  
print("stage1")

with tf.name_scope("dnn"):
    hidden1=tf.contrib.layers.fully_connected(X,n_hidden1,scope="hidden1")
    hidden2=tf.contrib.layers.fully_connected(hidden1,n_hidden2,scope="hidden2")
    logits=tf.contrib.layers.fully_connected(hidden2,n_outputs,scope="outputs",activation_fn=None)
with tf.name_scope("loss"):
    xentropy =tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits)
    loss =tf.reduce_mean(xentropy,name="loss")
    loss_summary=tf.summary.scalar("log_loss",loss)
with tf.name_scope("train"):
    optimizer=tf.train.GradientDescentOptimizer(learning_rate)
    training_op=optimizer.minimize(loss)
with tf.name_scope("eval"):
    correct=tf.equal(tf.argmax(y, 1), tf.argmax(logits, 1))#tf.nn.in_top_k(logits,y,1)
    accuracy=tf.reduce_mean(tf.cast(correct,tf.float32))

init =tf.global_variables_initializer()
saver =tf.train.Saver()
print("stage 2")

with tf.Session() as sess:
  sess.run(init)
  print("stage 3")
  for epoch in range(n_epochs):
    #print("stage 4")
    for iteration in range(train_num//BATCH_SIZE):
      #print("stage 5")
      ind = np.random.choice(trainimages.shape[0],BATCH_SIZE)
      x_train_batch = trainimages[ind]
      y_train_batch = trainlabels[ind]
      sess.run(training_op,feed_dict={X:x_train_batch,y:y_train_batch})
      #print("stage 6")
    if epoch%20==0:
      #print(x_train_batch, y_train_batch)
      acc_train=sess.run(accuracy,feed_dict={X:x_train_batch,y:y_train_batch})
      acc_test=sess.run(accuracy,feed_dict={X:testimages,y:testlabels})

      print(epoch, "Train accuracy:", acc_train,"Test accuracy:",acc_test)

输出精度从未增加约0.15。如果有人可以就我在这里做错的事情向我提出建议,我将非常感激。

作为参考,上面的图形结构基于Tensorflow动手机器学习书中给出的示例。以下是原始代码,其准确度为98%。当然我已经修改了一点代码以便能够接受csv输入。

import tensorflow as tf
import numpy as np
import pandas as pd
import random
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/")


#%%
tf.reset_default_graph()
print("I reset graph")
n_inputs =28*28
n_hidden1=300
n_hidden2=100
n_outputs = 10
learning_rate=0.01
X=tf.placeholder(tf.float32,shape=(None,n_inputs),name='X')
y=tf.placeholder(tf.int64,shape=(None),name='y')                     



with tf.name_scope("dnn"):
    hidden1=tf.layers.dense(X,n_hidden1,name="hidden1",activation=tf.nn.relu)
    hidden2=tf.layers.dense(hidden1,n_hidden2,name="hidden2",activation=tf.nn.relu)
    logits=tf.layers.dense(hidden2,n_outputs,name="outputs")
with tf.name_scope("loss"):
    xentropy =tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
    loss =tf.reduce_mean(xentropy,name="loss")
    #loss_summary=tf.summary.scalar("log_loss",loss)
with tf.name_scope("train"):
    optimizer=tf.train.GradientDescentOptimizer(learning_rate)
    training_op=optimizer.minimize(loss)
with tf.name_scope("eval"):
    correct=tf.nn.in_top_k(logits,y,1)
    accuracy=tf.reduce_mean(tf.cast(correct,tf.float32))

init =tf.global_variables_initializer()
saver =tf.train.Saver()

#==============================================================================
# from tensorflow.examples.tutorials.mnist import input_data
# mnist=input_data.read_data_sets("/tmp/data/")
#==============================================================================

n_epochs=400
batch_size=100
print("graph construction over i start train and test")
with tf.Session() as sess:
    sess.run(init)
    for epoch in range(n_epochs):
        for iteration in range(mnist.train.num_examples//batch_size):
            X_batch, y_batch = mnist.train.next_batch(batch_size)

            #print(X_batch, y_batch)
            sess.run(training_op,feed_dict={X:X_batch,y:y_batch})
        print("iteration over")
        if epoch%5==0:
          acc_train=sess.run(accuracy,feed_dict={X:X_batch,y:y_batch})
          acc_test=sess.run(accuracy,feed_dict={X: mnist.validation.images, y: mnist.validation.labels})
          print(epoch, "Train accuracy:", acc_train,"Test accuracy:",acc_test)
    save_path=saver.save(sess,"./my_model_final.ckpt")

其他信息: 在减少批量大小后,我打印了一些迭代的神经网络输出logits。在10次左右的迭代后,输出似乎饱和。我尝试将优化器更改为AdamOptimizer,但仍然无法提高准确性。下面显示了logits输出的示例。

iteration  7
Y_train: [[0 1 0 0 0 0 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0]] 
 Logits: [[  2.26569266e+17   3.05248736e+22  -2.50115512e+23  -4.39891557e+14
    1.11553920e+23   3.07485097e+14   2.20944474e+17   4.47584162e+13
    1.08036284e+23   4.83180834e+14]
 [  3.86803140e+17   8.75195504e+22  -7.17081147e+23  -2.68349530e+15
    3.19824929e+23   8.67874780e+14   3.76970654e+17   4.52455091e+13
    3.09735965e+23   3.87887019e+14]
 [  2.38161056e+17   3.84007123e+22  -3.14640962e+23  -6.05196997e+14
    1.40332858e+23   3.16957379e+14   2.32241818e+17   4.01556080e+13
    1.35906927e+23   4.00997575e+14]]
Softmax_out: [  8.10290437e+22   2.32305379e+23   4.42593055e+21]
Accuracy: [False False False]


 iteration  8
Y_train: [[1 0 0 0 0 0 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]] 
 Logits: [[             inf              inf   1.66566635e+35              inf
              -inf   1.03125672e+30   1.62685693e+35   6.78127837e+30
   -4.95936289e+35   4.14895906e+30]
 [  1.38760797e+38   1.10565560e+38   3.23025301e+34   2.54545823e+38
              -inf   1.99993203e+29   3.15498898e+34   1.31510396e+30
   -9.61777107e+34   8.04613877e+29]
 [             inf              inf   2.54806070e+35              inf
              -inf   1.57756931e+30   2.48869187e+35   1.03736909e+31
   -7.58660917e+35   6.34688775e+30]]
Softmax_out: [ nan  nan  nan]
Accuracy: [ True False False]


 iteration  9
Y_train: [[0 0 0 0 0 1 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]] 
 Logits: [[ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
 [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
 [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]]
Softmax_out: [ nan  nan  nan]
Accuracy: [False False False]

2 个答案:

答案 0 :(得分:0)

十类问题的准确率为10%是随机输出;我的猜测是,您拨打reshape的电话正在扰乱您的输入。例如,请考虑以下代码:

import tensorflow as tf

initial = tf.constant([[1, 2, 3, 4],[5, 6, 7, 8]])
reshaped = tf.reshape(initial, [4, 2])

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)

    print(sess.run(initial))
    print(sess.run(reshaped))

我将2x4张量转换为4x2张量,这听起来好像我正在调换它,但事实上输出是

[[1 2 3 4]
 [5 6 7 8]]
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

我建议使用matplotlib来显示一些示例,看看它们是否仍然像数字。输出标签以确保它们仍然匹配也是一个好主意。

答案 1 :(得分:0)

我认为你应该像跟随一样构建层。

Convo有28输入+ relu + dropout(0.2)

Convo具有32个输入功能+ relu + dropout(0.2)

Convo具有32个输入功能+ relu + dropout(0.2)

flatten()

密集或完全连接的图层,带有512个dendries + dropout(0.5)

密集或完全连接128个具有softmax功能的输出杂物

我使用自己的mnist类型数据集实现了99.7%的准确率。

检查出来:Text Classification using Keras

注意:我有36节课。 10位数和26个字母