卷积神经网络为所有标签输出相等的概率
Convolutional neural network outputting equal probabilities for all labels
我目前正在 MNIST 上训练 CNN,随着训练的进行,输出概率 (softmax) 为 [0.1,0.1,...,0.1]。初始值不统一,所以我不知道我是不是在做一些愚蠢的事情?
我只训练了15步,只是为了看看训练进度;尽管这是一个很小的数字,但我认为这不会导致统一的预测吗?
import numpy as np
import tensorflow as tf
import imageio
from sklearn.datasets import fetch_mldata
mnist = fetch_mldata('MNIST original')
# Getting data
from sklearn.model_selection import train_test_split
def 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 model
x = 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})
非常感谢。
您的代码有几个问题,包括基本问题。我强烈建议您先阅读 MNIST 的 Tensorflow 分步教程,MNIST For ML Beginners and Deep MNIST for Experts。
简而言之,关于您的代码:
首先,你的最后一层 fc2
应该 不 有 ReLU 激活。
其次,构建批次的方式,即
indices = np.random.randint(len(tr_data),size=[200])
是在每次迭代中只抓取随机样本,这与正确的做法相差甚远...
第三,您输入网络的数据未在 [0, 1] 中归一化,因为它们应该是:
np.max(tr_data[0]) # get the max value of your first training sample
# 255.0
第三点最初也让我感到困惑,因为在前面提到的 Tensorflow 教程中,它们似乎也没有对数据进行归一化。但仔细检查揭示了原因:如果您通过 Tensorflow 提供的实用函数导入 MNIST 数据(而不是 scikit-learn 函数,就像您在这里所做的那样),它们已经在 [0, 1] 中标准化,这是无处可去的提示:
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
np.max(mnist.train.images[0])
# 0.99607849
这是一个公认的奇怪设计决定 - 据我所知,在所有其他类似的 cases/tutorials 中,规范化输入数据是管道的明确部分(参见 Keras example ),并且有充分的理由(当您使用自己的数据时,您肯定会希望自己稍后做这件事)。
我目前正在 MNIST 上训练 CNN,随着训练的进行,输出概率 (softmax) 为 [0.1,0.1,...,0.1]。初始值不统一,所以我不知道我是不是在做一些愚蠢的事情?
我只训练了15步,只是为了看看训练进度;尽管这是一个很小的数字,但我认为这不会导致统一的预测吗?
import numpy as np
import tensorflow as tf
import imageio
from sklearn.datasets import fetch_mldata
mnist = fetch_mldata('MNIST original')
# Getting data
from sklearn.model_selection import train_test_split
def 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 model
x = 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})
非常感谢。
您的代码有几个问题,包括基本问题。我强烈建议您先阅读 MNIST 的 Tensorflow 分步教程,MNIST For ML Beginners and Deep MNIST for Experts。
简而言之,关于您的代码:
首先,你的最后一层 fc2
应该 不 有 ReLU 激活。
其次,构建批次的方式,即
indices = np.random.randint(len(tr_data),size=[200])
是在每次迭代中只抓取随机样本,这与正确的做法相差甚远...
第三,您输入网络的数据未在 [0, 1] 中归一化,因为它们应该是:
np.max(tr_data[0]) # get the max value of your first training sample
# 255.0
第三点最初也让我感到困惑,因为在前面提到的 Tensorflow 教程中,它们似乎也没有对数据进行归一化。但仔细检查揭示了原因:如果您通过 Tensorflow 提供的实用函数导入 MNIST 数据(而不是 scikit-learn 函数,就像您在这里所做的那样),它们已经在 [0, 1] 中标准化,这是无处可去的提示:
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
np.max(mnist.train.images[0])
# 0.99607849
这是一个公认的奇怪设计决定 - 据我所知,在所有其他类似的 cases/tutorials 中,规范化输入数据是管道的明确部分(参见 Keras example ),并且有充分的理由(当您使用自己的数据时,您肯定会希望自己稍后做这件事)。