Реализация глубокого обучения в Tensorflow или Keras дает совершенно разные результаты

Контекст: Я использую полностью сверточную сеть для сегментации изображения. Обычно входом является изображение RGB shape = [512, 256], а целью является двухканальная двоичная маска, определяющая аннотированные области (2-й канал является противоположностью первого канала).

Вопрос: У меня такая же реализация CNN с использованием Tensorflow и Keras. Но модель Tensorflow не начинает учиться. На самом деле loss даже растет с числом эпох! Что не так в этой реализации Tensorflow, что мешает ему обучаться?

Настраивать: Набор данных разделен на 3 подмножества: наборы для обучения (78%), тестирования (8%) и проверки (14%), которые передаются в сеть пакетами из 8 изображений. Графики показывают эволюцию loss для каждого подмножества. На изображениях показан prediction после 10 эпох для двух разных изображений.


Tensorflow реализация и результаты

import tensorflow as tf

tf.reset_default_graph()
x = inputs = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 3])
targets = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 2])

for d in range(4):
    x = tf.layers.conv2d(x, filters=np.exp2(d+4), kernel_size=[3,3], strides=[1,1], padding = "SAME", activation=tf.nn.relu)
    x = tf.layers.max_pooling2d(x, strides=[2,2], pool_size=[2,2], padding = "SAME")
    
x = tf.layers.conv2d(x, filters=2, kernel_size=[1,1])
logits = tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True)
prediction = tf.nn.softmax(logits)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits))
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.001).minimize(loss)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        return sess.run([loss, optimizer], feed_dict = {inputs: x_batch, targets: y_batch})
    else:
        return sess.run([loss, prediction], feed_dict = {inputs: x_batch, targets: y_batch})

Реализация глубокого обучения в Tensorflow или Keras дает совершенно разные результатыРеализация глубокого обучения в Tensorflow или Keras дает совершенно разные результаты


Реализация и результаты Керас

import keras as ke

ke.backend.clear_session()
x = inputs = ke.layers.Input(shape=[shape[1], shape[0], 3])

for d in range(4):
    x = ke.layers.Conv2D(int(np.exp2(d+4)), [3,3], padding = "SAME", activation = "relu")(x)
    x = ke.layers.MaxPool2D(padding = "SAME")(x)

x = ke.layers.Conv2D(2, [1,1], padding = "SAME")(x)
logits = ke.layers.Lambda(lambda x: ke.backend.tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True))(x)
prediction = ke.layers.Activation('softmax')(logits)

model = ke.models.Model(inputs=inputs, outputs=prediction)
model.compile(optimizer = "rmsprop", loss = "categorical_crossentropy")

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        loss = model.train_on_batch(x=x_batch, y=y_batch)
        return loss, None
    else:
        loss = model.evaluate(x=x_batch, y=y_batch, batch_size=None, verbose=0)
        prediction = model.predict(x=x_batch, batch_size=None)
        return loss, prediction

Реализация глубокого обучения в Tensorflow или Keras дает совершенно разные результатыРеализация глубокого обучения в Tensorflow или Keras дает совершенно разные результаты


Между ними должна быть разница, но мое понимание документации ни к чему не привело. Мне было бы действительно интересно узнать, в чем разница. Заранее спасибо!

Я не понимаю, что это за сюжеты. Но единственное несоответствие, которое я обнаружил между вашими двумя версиями, - это то, что TF использует одно и то же заполнение для объединения слоев, что необычно и, вероятно, является источником ошибки.

Priyatham 29.03.2018 19:01

Спасибо, но это не имеет значения. Я ответил на вопрос более подробно и дал результаты с «одинаковым» заполнением как в TF, так и в K.

Jav 30.03.2018 10:20

Не могли бы вы попробовать использовать tf.reduce_sum за плату?

rvinas 30.03.2018 12:52

Спасибо за предложение, но это не помогает ...

Jav 30.03.2018 13:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
5
4
548
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ответ был в реализации Keras softmax, где они вычитали неожиданный max:

def softmax(x, axis=-1):
    # when x is a 2 dimensional tensor
    e = K.exp(x - K.max(x, axis=axis, keepdims=True))
    s = K.sum(e, axis=axis, keepdims=True)
    return e / s

Вот реализация Tensorflow, обновленная с помощью взлома max, и связанные с ней хорошие результаты.

import tensorflow as tf

tf.reset_default_graph()
x = inputs = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 3])
targets = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 2])

for d in range(4):
    x = tf.layers.conv2d(x, filters=np.exp2(d+4), kernel_size=[3,3], strides=[1,1], padding = "SAME", activation=tf.nn.relu)
    x = tf.layers.max_pooling2d(x, strides=[2,2], pool_size=[2,2], padding = "SAME")

x = tf.layers.conv2d(x, filters=2, kernel_size=[1,1])
logits = tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True)
# The misterious hack took from Keras
logits = logits - tf.expand_dims(tf.reduce_max(logits, axis=-1), -1)
prediction = tf.nn.softmax(logits)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits))
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.001).minimize(loss)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        return sess.run([loss, optimizer], feed_dict = {inputs: x_batch, targets: y_batch})
    else:
        return sess.run([loss, prediction], feed_dict = {inputs: x_batch, targets: y_batch})

Tensorflow loss evolutionTensorflow predictions after 10 epochs

Огромное спасибо Саймону за указание на это в реализации Keras :-)

Другие вопросы по теме