Невозможно преобразовать частично известный тензор в TensorFlow/TFLearn

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

Ошибка, которую я получаю, возникает на этапе регрессии:

  File "siamese.py", line 59, in <module>
    network = regression(y_pred, optimizer='adam',
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tflearn/models/dnn.py", line 63, in __init__
    best_val_accuracy=best_val_accuracy)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tflearn/helpers/trainer.py", line 120, in __init__
    clip_gradients)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tflearn/helpers/trainer.py", line 646, in initialize_training_ops
    ema_num_updates=self.training_steps)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tflearn/summaries.py", line 236, in add_loss_summaries
    loss_averages_op = loss_averages.apply([loss] + other_losses)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/training/moving_averages.py", line 292, in apply
    colocate_with_primary=(var.op.type == "Variable"))
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/training/slot_creator.py", line 106, in create_zeros_slot
    val = array_ops.zeros(primary.get_shape().as_list(), dtype=dtype)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py", line 1071, in zeros
    shape = ops.convert_to_tensor(shape, dtype=dtypes.int32, name="shape")
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 628, in convert_to_tensor
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py", line 198, in _tensor_shape_tensor_conversion_function
    "Cannot convert a partially known TensorShape to a Tensor: %s" % s)
ValueError: Cannot convert a partially known TensorShape to a Tensor: (?,)

Я не знаю, как решить эту проблему, если первое измерение должно быть None для размера пакета (поправьте меня, если я ошибаюсь).

Соответствующие части кода приведены ниже:

BATCH_SIZE=100
def contrastive_loss(y_pred, y_true, margin=1.0):
    return tf.mul(1-y_true, tf.square(y_pred)) + tf.mul(y_true, tf.square(tf.maximum((margin-y_pred),0)))

## Load dataset
f = h5py.File('./data/paired_training_data.hdf','r')
X1 = f["train_X1"]
X2 = f["train_X2"]
Y = f["train_Y_paired"]

## Inputs: 1 example (phoneme pair), dropout probability
inp_sound1 = input_data(shape=[None, 1, N_MFCC_CHANNELS, N_IN_CHANNELS])
networkL = conv_1d(inp_sound1, reuse=None, scope="conv1d")
networkL = max_pool_1x6(networkL)
networkL = fully_connected(networkL, n_units=N_FULLY_CONN, activation='relu', scope="fc1")
networkL = dropout(networkL, .5) # unshared?
networkL = fully_connected(networkL, n_units=N_FULLY_CONN, activation='relu', scope="fc2")

inp_sound2 = input_data(shape=[None, 1, N_MFCC_CHANNELS, N_IN_CHANNELS])
networkR = conv_1d(inp_sound2, reuse=True, scope="conv1d")
networkR = max_pool_1x6(networkR)
networkR = fully_connected(networkR, n_units=N_FULLY_CONN, activation='relu', reuse=True, scope="fc1")
networkR = dropout(networkR, .5)
networkR = fully_connected(networkR, n_units=N_FULLY_CONN, activation='relu', reuse=True, scope="fc2")

l2_loss = tf.reduce_sum(tf.square(tf.sub(networkL, networkR)), 1)
y_pred = tf.sqrt(l2_loss)
#y_true = input_data(shape=[None])

## Training
network = regression(y_pred, optimizer='adam',
            loss=contrastive_loss, learning_rate=0.0001, to_one_hot=False)
model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit([X1, X2], Y, n_epoch=10, batch_size=BATCH_SIZE, show_metric=True, validation_set=0.1)

Буду очень признателен за любую помощь, особенно с пониманием того, как самостоятельно отлаживать эти проблемы в будущем!


person Jess    schedule 15.11.2016    source источник
comment
Я бы начал с замены reuse=None на reuse=True (или False). Вы можете указать BATCH_SIZE, заменив везде None на BATCH_SIZE.   -  person sygi    schedule 15.11.2016
comment
@sygi Я установил первый слой reuse=None, потому что получил сообщение об ошибке, что область conv1d еще не существует - однако второй слой имеет reuse=True. Дайте мне знать, если это все еще неправильный способ сделать это.   -  person Jess    schedule 15.11.2016
comment
Кроме того, если я заменю None на BATCH_SIZE, TFLearn автоматически добавит первое измерение None (чтобы мой 4D-вектор стал 5D, и тогда он больше не работал со слоем conv).   -  person Jess    schedule 15.11.2016
comment
Тогда попробуйте удалить None? Я предполагаю, что он всегда добавляет None, и если у вас их два, он жалуется. Что касается reuse, этот параметр ожидает bool (см. документы) -- возможно, что None будет служить False, но я бы изменил его, чтобы убедиться, что проблема не в нем.   -  person sygi    schedule 15.11.2016
comment
К сожалению, удаление None по-прежнему вызывает ту же ошибку.   -  person Jess    schedule 15.11.2016


Ответы (1)


Похоже, TensorFlow не может определить форму вашего contrastive_loss. Попробуйте вызвать set_shape в вашей функции contrastive_loss, если вы заранее знаете ее выходную форму:

def contrastive_loss(y_pred, y_true, margin=1.0):
  loss = tf.mul(1-y_true, tf.square(y_pred)) + tf.mul(y_true, tf.square(tf.maximum((margin-y_pred),0)))
  loss.set_shape([...])
  return loss
person yuefengz    schedule 15.11.2016
comment
Я попытался установить форму потери и форму y_pred (поскольку он жаловался без нее) на [BATCH_SIZE,], но это вызывает больше несоответствий, которые я не знаю, как решить - Adam/ScalarSummary выдает ошибку, что tags and values not the same shape: [] != [100]. - person Jess; 16.11.2016
comment
Я предполагаю, что форма y_pred не будет [BATCH_SIZE,], иначе для фактических данных не будет измерения. - person yuefengz; 16.11.2016
comment
Извини, что ты имеешь ввиду? Я предполагаю, что это будет просто вектор скаляров BATCH_SIZE (0-мерные числа)? y_pred просто должно быть расстоянием между векторами, выдаваемыми левой и правой сетями. - person Jess; 16.11.2016
comment
Если это вектор скаляров BATCH_SIZE, то его форма должна быть [BATCH_SIZE, 1]. - person yuefengz; 16.11.2016
comment
У него все та же ошибка Adam/ScalarSummary, теперь [] != [100,1]. - person Jess; 16.11.2016