Сверточная нейронная сеть, выводящая равные вероятности для всех меток

В настоящее время я обучаю CNN на MNIST, и выходные вероятности (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})

Большое спасибо.


person Pian Pawakapan    schedule 12.01.2018    source источник
comment
На вашем fc2 не должно быть активации ReLU - только softmax   -  person desertnaut    schedule 13.01.2018
comment
не могли бы вы добавить часть вашего кода, которая действительно печатает, и, возможно, также образец вывода?   -  person grovina    schedule 13.01.2018
comment
Ответы отнимают у респондентов драгоценное время; если ответ касается вашего вопроса, примите его (положительные отзывы тоже приветствуются) - спасибо   -  person desertnaut    schedule 13.01.2018


Ответы (1)


В вашем коде есть несколько проблем, в том числе элементарных. Я настоятельно рекомендую вам сначала пройти пошаговые руководства Tensorflow для MNIST, MNIST для начинающих ML. и Deep MNIST для экспертов.

Короче говоря, относительно вашего кода:

Во-первых, ваш последний слой 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 они, похоже, также не нормализуют данные. Но тщательный осмотр выявил причину: если вы импортируете данные MNIST с помощью служебных функций, предоставляемых Tensorflow (вместо функций 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

Это, по общему признанию, странное дизайнерское решение - насколько мне известно, во всех других подобных случаях / учебных пособиях нормализация входных данных является явной частью конвейера (см., Например, пример Keras) и не без оснований (это то, что вы наверняка будете делать сами позже, при использовании собственных данных).

person desertnaut    schedule 13.01.2018
comment
@PianPawakapan, тогда добро пожаловать, чтобы принять ответ - см. Что мне делать, если кто-то ответит на мой вопрос? - person desertnaut; 14.01.2018
comment
О, я вижу. Понятно. Извините, я новичок в stackoverflow - person Pian Pawakapan; 15.01.2018
comment
@PianPawakapan, у тебя все хорошо;) - person desertnaut; 15.01.2018