使用 Tensorflow 的神经网络精度低
Posted
技术标签:
【中文标题】使用 Tensorflow 的神经网络精度低【英文标题】:Low accuracy in neural network with Tensorflow 【发布时间】:2018-07-07 08:10:15 【问题描述】:我在神经网络上关注Google code lab,我决定使用Cifar10 数据集而不是 MNIST 数据集来制作一个简单的图像分类器,但由于某种原因,我的准确率非常低且交叉熵很高。
训练后准确率约为 0.1(从不超过 0.2),交叉熵不低于 230。
我的代码:
import tensorflow as tf
import numpy as np
import matplotlib as mpt
# Just disables the warning, doesn't enable AVX/FMA
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
def unpickle(file):
import pickle
with open(file, 'rb') as fo:
dict = pickle.load(fo, encoding='bytes')
return dict
def returnMiniBatch(dictionary,start,number):
matrix=np.zeros([number,3072],dtype=np.int)
labels=np.zeros([number],dtype=np.int)
for i in range(0,number):
matrix[i]=dictionary[b'data'][i+start]
labels[i]=dictionary[b'labels'][i+start]
return matrix,labels
def formatLabels(labels,number):
lab=np.zeros([number,10])
for i in range(0,number):
lab[i][labels[i]]=1
return lab
data='D:/cifar-10-python/cifar-10-batches-py/data_batch_1'
dictionary=unpickle(data)
tf.set_random_seed(0)
L = 200
M = 100
N = 60
O = 30
X=tf.placeholder(tf.float32,[None,3072])
Y_=tf.placeholder(tf.float32,[None,10])
W1 = tf.Variable(tf.truncated_normal([3072,L],stddev=0.1))
B1 = tf.Variable(tf.ones([L])/10)
W2 = tf.Variable(tf.truncated_normal([L, M], stddev=0.1))
B2 = tf.Variable(tf.ones([M])/10)
W3 = tf.Variable(tf.truncated_normal([M, N], stddev=0.1))
B3 = tf.Variable(tf.ones([N])/10)
W4 = tf.Variable(tf.truncated_normal([N, O], stddev=0.1))
B4 = tf.Variable(tf.ones([O])/10)
W5 = tf.Variable(tf.truncated_normal([O, 10], stddev=0.1))
B5 = tf.Variable(tf.ones([10]))
Y1 = tf.nn.relu(tf.matmul(X, W1) + B1)
Y2 = tf.nn.relu(tf.matmul(Y1, W2) + B2)
Y3 = tf.nn.relu(tf.matmul(Y2, W3) + B3)
Y4 = tf.nn.relu(tf.matmul(Y3, W4) + B4)
Ylogits = tf.matmul(Y4, W5) + B5
Y = tf.nn.softmax(Ylogits)
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=Ylogits,
labels=Y_)
cross_entropy = tf.reduce_mean(cross_entropy)*100
correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(Y_,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
train_step = tf.train.AdamOptimizer(0.003).minimize(cross_entropy)
init=tf.global_variables_initializer()
sess=tf.Session()
sess.run(init)
def training_step(i):
global dictionary
val,lab=returnMiniBatch(dictionary,i * 100,100)
Ylabels=formatLabels(lab,100)
_,a,c = sess.run([train_step,accuracy, cross_entropy], feed_dict=X:
val, Y_: Ylabels)
print("Accuracy: ",a)
print("Cross-Entropy",c)
for i in range (0,100):
training_step(i%100)
【问题讨论】:
【参考方案1】:如果我没记错的话,那看起来像是一个非卷积网络。您需要寻找卷积网络架构。所以寻找一些使用 conv2d 的教程。
原因:MNIST 是单通道、二进制数据。 CIFAR 是具有 8 位颜色的 3 通道 (RGB)。仅仅增加输入占位符的大小是不够的。您需要告诉网络三个通道(和相邻像素)是相关的。您可以使用卷积网络架构来做到这一点。
0.1 表示不比随机机会好。网络没有学习任何泛化的东西。
【讨论】:
【参考方案2】:解决方案是标准化输入数据。 我添加了一个新函数来规范化数据
def formatData(values):
ret = values.reshape(100,3072).astype("float32")
ret/=255
return ret
并在将数据添加到提要字典之前对其进行格式化。
X_Data=formatData(val)
_,a,c = sess.run([train_step,accuracy, cross_entropy], feed_dict=X:
X_Data, Y_: Ylabels)
在此更改之后,网络开始正常学习(这里的卷积网络仍然要好得多,因为Pam 指向了指针)。
【讨论】:
以上是关于使用 Tensorflow 的神经网络精度低的主要内容,如果未能解决你的问题,请参考以下文章