Моя нейронная сеть Tensorflow все еще довольно глупа, после долгих восстановительных занятий - PullRequest
0 голосов
/ 06 октября 2018

Я довольно новичок в классификации изображений и тензорном потоке, и я участвовал в небольшом игрушечном проекте для самообразования.Это проект классификации изображений, который сортирует фотографии автомобилей по 16 различным классам.Фотографии взяты с конкурса Kaggle Carvana, который преследовал разные цели и оценивался по другим критериям.

Что я пытаюсь сделать, так это выяснить, могу ли я сказать, что изображение автомобиля получено с автомобилем, направленным прямо на камеру или в любую из 16 радиальных точек вокруг автомобиля.Это должно быть довольно простой проблемой классификации изображений.

Что я делаю по сути, так это просмотр изображений в нейронной сети, которая выполняет две обратные связи, запускает AdamOptimizer (или другие, не лучше), затемзабивает их.Проблема, с которой я столкнулся, заключается в том, что сеть, кажется, никогда не учится - она ​​всегда показывает потерю права около 2,80 (иногда немного выше, иногда немного ниже) и никогда не кажется мудрой.Производительность никогда не бывает намного лучше, чем при случайном угадывании.Я долго настраивал, бормотал и смотрел.Я боюсь, что теряю здравомыслие.

Важный код для операций по потере, обучению и оценке опубликован ниже.Когда я вызываю это, жизненно важными параметрами являются:

--target carvana --numclasses 16   --batch_size 64  --show True --learning_rate 0.01 --epochs 10 --scale 8.0 --hidden1_units 128 --hidden2_units 32

Полный код в https://github.com/WascallyWabbit/estimator.

Спасибо, Wabbit

(image_placeholder, label_placeholder) = target.get_graph_placeholders(img_shape=IMG_SHAPE,
                                                                       batch_size=FLAGS.batch_size)

logits_op = target.inference(images_placeholder=image_placeholder,
                             hidden1_units=FLAGS.hidden1_units,
                             hidden2_units=FLAGS.hidden2_units)

loss_op = target.loss(logits=logits_op,
                      labels=label_placeholder)

train_op = target.training(learning_rate=FLAGS.learning_rate,
                           loss_op=loss_op)

evaluation_op = target.evaluation(logits=logits_op,
                                  labels=label_placeholder)

# blah, blah...
def get_graph_placeholders(self, img_shape=None, batch_size=10, num_classes=16):
    if img_shape == None:
        img_shape = self.img_shape

    pixel_num = ut.pixnum_from_img_shape(img_shape)

    images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, pixel_num), name='Images')
    labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size), name='Labels')

    return (images_placeholder, labels_placeholder)

def inference(self,
              images_placeholder,
              hidden1_units,
              hidden2_units,
              num_classes = 16,
              img_shape=None):

    if img_shape == None:
        img_shape = self.img_shape
    pixel_num = ut.pixnum_from_img_shape(img_shape)


    with tf.name_scope('inference'):
        #       with tf.name_scope('inference'):
        #       display_tensor = tf.reshape(tensor=images_placeholder, shape=[100,28,28,1])
        #      tf.summary.image(tensor=display_tensor, max_outputs=3,name="Carvana_images")
        display_tensor = tf.reshape(tensor=images_placeholder, shape=[64,img_shape[1],img_shape[0],1])
        tf.summary.image(tensor=display_tensor, max_outputs=320,name="Carvana_images")

        with tf.name_scope('hidden1'):
            weights1 = tf.Variable(
                tf.truncated_normal([pixel_num, hidden1_units],
                                          stddev=1.0/math.sqrt(float(pixel_num))),
                                          name='weights1')
            biases1 = tf.Variable(tf.zeros([hidden1_units]),
                                 name='biases1')

            hidden1 = tf.nn.relu(tf.matmul(images_placeholder, weights1) + biases1)
            tf.summary.histogram(name='weights1', values=weights1)
            tf.summary.histogram(name='biases1', values=biases1)


        with tf.name_scope('hidden2'):
            weights2 = tf.Variable(
                tf.truncated_normal([hidden1_units, hidden2_units],
                                          stddev=1.0 / math.sqrt(float(hidden1_units))),
                                          name='weights2')
            biases2 = tf.Variable(tf.zeros([hidden2_units]),
                                 name='biases2')

            hidden2 = tf.nn.relu(tf.matmul(hidden1, weights2) + biases2)
            tf.summary.histogram(name='weights2', values=weights2)
            tf.summary.histogram(name='biases2', values=biases2)

        with tf.name_scope('softmax_linear'):
            weights3 = tf.Variable(
                tf.truncated_normal([hidden2_units, num_classes],
                                          stddev=1.0 / math.sqrt(float(hidden2_units))),
                name='weights3')
            biases3 = tf.Variable(tf.zeros([num_classes]),
                                 name='biases3')

            logits = tf.nn.softmax(tf.matmul(hidden2, weights3) + biases3)

            tf.summary.histogram(name='weights3', values=weights3)
            tf.summary.histogram(name='biases3', values=biases3)
            tf.summary.histogram(name='logits', values=logits)

        return logits

def loss(self,logits,labels):
    with tf.name_scope('loser'):
        labels=tf.to_int64(labels)
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
            labels=labels, logits=logits, name='xentropy')

        rm = tf.reduce_mean(cross_entropy, name='xentropy_mean')
        tf.summary.scalar('xentropy_reduced_mean', rm)
        return rm

def evaluation(self, logits, labels):
    with tf.name_scope('evaluation'):
        correct = tf.nn.in_top_k(logits,labels,1,name='correct_evaluation')
    #    tf.summary.scalar('Evaluation', correct)
        rs = tf.reduce_sum(tf.cast(correct,tf.int32), name='Reduce_sum')
        tf.summary.scalar('Reduced sum', rs)
        return correct

def training(self, loss_op, learning_rate):
    with tf.name_scope('training'):
        tf.summary.scalar('Training loss_op', loss_op)
        optimizer = tf.train.AdamOptimizer(learning_rate, name='Adam_Optimizer')
        global_step = tf.Variable(0, name='global_step', trainable=False)
        tf.summary.scalar('Training global_step', global_step)
        train_op = optimizer.minimize(loss_op, global_step=global_step)
        return train_op

def init_weights(self,pixel_num,hidden1_units,hidden2_units,num_classes):
    w1 = tf.Variable(
        tf.truncated_normal([pixel_num, hidden1_units],
                                  stddev=1.0 / math.sqrt(float(pixel_num)),
                                  name='weights1')
    )

    w2 = tf.Variable(
        tf.truncated_normal([hidden1_units, hidden2_units],
                                  stddev=1.0 / math.sqrt(float(pixel_num)),
                                  name='weights2')
    )

    w3 = tf.Variable(
        tf.truncated_normal([hidden2_units, num_classes],
                                  stddev=1.0 / math.sqrt(float(hidden2_units)),
                                  name='weights3')
    )

    return (w1,w2,w3)

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Хотя я согласен с другим ответом, в котором упоминается, что такой маленькой нейронной сети будет трудно справиться с такой задачей, особенно полностью подключенной, я думаю, что основная проблема здесь заключается в том, что вы применяетеsoftmax активация себя до выходного слоя.Это не правильно;при использовании функций cross_entropy_with_logits необходимо передать значения pre-softmax .Softmax выполняется внутри функции стоимости численно стабильным способом.Таким образом, вы должны удалить tf.nn.softmax из logits в функции inference.

0 голосов
/ 06 октября 2018

Возможно, ваша сеть слишком мала.Вы просто используете два скрытых слоя.Количество скрытых юнитов кажется довольно низким.Попробуйте увеличить номер и размер слоя.

Другая идея заключается в использовании слоев CNN для вашей задачи классификации, поскольку они имеют тенденцию быть лучше для классификации изображений, чем обычные нейронные сети с прямой связью.Взгляните на vgg 16, например

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...