卷积神经网络对所有标签输出相等概率

我目前正在用MNIST数据集训练一个CNN,随着训练的进行,输出概率(softmax)给出的结果是[0.1,0.1,…,0.1]。初始值并非均匀分布,所以我无法确定自己是否犯了什么愚蠢的错误?

我只训练了15个步骤,只是为了观察训练的进展;尽管这个数字很低,但我认为这不应该导致均匀的预测结果吧?

import numpy as npimport tensorflow as tfimport imageiofrom sklearn.datasets import fetch_mldatamnist = fetch_mldata('MNIST original')# Getting datafrom sklearn.model_selection import train_test_splitdef one_hot_encode(data):    new_ = []    for i in range(len(data)):        _ = np.zeros([10],dtype=np.float32)        _[int(data[i])] = 1.0        new_.append(np.asarray(_))    return new_data = np.asarray(mnist["data"],dtype=np.float32)labels = np.asarray(mnist["target"],dtype=np.float32)labels = one_hot_encode(labels)tr_data,test_data,tr_labels,test_labels = train_test_split(data,labels,test_size = 0.1)tr_data = np.asarray(tr_data)tr_data = np.reshape(tr_data,[len(tr_data),28,28,1])test_data = np.asarray(test_data)test_data = np.reshape(test_data,[len(test_data),28,28,1])tr_labels = np.asarray(tr_labels)test_labels = np.asarray(test_labels)def get_conv(x,shape):    weights = tf.Variable(tf.random_normal(shape,stddev=0.05))    biases = tf.Variable(tf.random_normal([shape[-1]],stddev=0.05))    conv = tf.nn.conv2d(x,weights,[1,1,1,1],padding="SAME")    return tf.nn.relu(tf.nn.bias_add(conv,biases))def get_pool(x,shape):    return tf.nn.max_pool(x,ksize=shape,strides=shape,padding="SAME")def get_fc(x,shape):    sh = x.get_shape().as_list()    dim = 1    for i in sh[1:]:        dim *= i    x = tf.reshape(x,[-1,dim])    weights = tf.Variable(tf.random_normal(shape,stddev=0.05))    return tf.nn.relu(tf.matmul(x,weights) + tf.Variable(tf.random_normal([shape[1]],stddev=0.05)))#Creating modelx = tf.placeholder(tf.float32,shape=[None,28,28,1])y = tf.placeholder(tf.float32,shape=[None,10])conv1_1 = get_conv(x,[3,3,1,128])conv1_2 = get_conv(conv1_1,[3,3,128,128])pool1 = get_pool(conv1_2,[1,2,2,1])conv2_1 = get_conv(pool1,[3,3,128,512])conv2_2 = get_conv(conv2_1,[3,3,512,512])pool2 = get_pool(conv2_2,[1,2,2,1])conv3_1 = get_conv(pool2,[3,3,512,1024])conv3_2 = get_conv(conv3_1,[3,3,1024,1024])conv3_3 = get_conv(conv3_2,[3,3,1024,1024])conv3_4 = get_conv(conv3_3,[3,3,1024,1024])pool3 = get_pool(conv3_4,[1,3,3,1])fc1 = get_fc(pool3,[9216,1024])fc2 = get_fc(fc1,[1024,10])softmax = tf.nn.softmax(fc2)loss = tf.losses.softmax_cross_entropy(logits=fc2,onehot_labels=y)train_step = tf.train.AdamOptimizer().minimize(loss)sess = tf.Session()sess.run(tf.global_variables_initializer())for i in range(15):    print(i)    indices = np.random.randint(len(tr_data),size=[200])    batch_data = tr_data[indices]    batch_labels = tr_labels[indices]    sess.run(train_step,feed_dict={x:batch_data,y:batch_labels})

非常感谢您。


回答:

您的代码中存在几个问题,包括一些基础错误。我强烈建议您先浏览Tensorflow的MNIST逐步教程,适合机器学习初学者的MNIST专家的深度MNIST

简而言之,关于您的代码:

首先,您的最后一层fc2不应该使用ReLU激活函数。

其次,您构建批次的方式,即

indices = np.random.randint(len(tr_data),size=[200])

只是在每次迭代中随机抽取样本,这远非正确的方法…

第三,您输入到网络中的数据没有标准化到[0, 1]的范围内,这是应该做的:

np.max(tr_data[0]) # 获取您的第一个训练样本的最大值# 255.0

第三点最初也让我感到困惑,因为在上述Tensorflow教程中似乎也没有对数据进行标准化。但仔细检查后发现了原因:如果您通过Tensorflow提供的工具函数(而不是像您在这里使用的那样使用scikit-learn函数)导入MNIST数据,它们已经标准化到[0, 1]的范围内了,而这一点在任何地方都没有提示:

from tensorflow.examples.tutorials.mnist import input_dataimport tensorflow as tfimport numpy as npmnist = input_data.read_data_sets("MNIST_data/", one_hot=True)np.max(mnist.train.images[0])# 0.99607849

这确实是一个奇怪的设计决定——据我所知,在所有其他类似的案例/教程中,标准化输入数据是管道的一个明确部分(例如,参见Keras示例),而且有充分的理由(当您以后使用自己的数据时,您肯定会被期望自己完成这一步)。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注