tf.nn.conv2d_transpose() двойная ширина и высота для динамических форм входного тензора

#python #tensorflow #machine-learning #deep-learning

Вопрос:

Когда я попытался использовать tf.nn.conv2d_transpose (), чтобы получить результат слоя, который удвоил ширину, высоту и уменьшил глубину вдвое, он работал при использовании указанного [пакет, ширина, высота, канал(вход и выход)].

Установив batch_size=»Нет», обучение хорошо работает для указанного размера пакета, а проверка хорошо работает для изображений(или изображения).

Теперь я пытаюсь создать сетевую структуру кодер-декодер, используя обучающие изображения [128 x 128 x 3]. (Эти обучающие изображения являются обрезанными изображениями из [ш x в x 3] исходных изображений)

Форма ввода [128 x 128 x 3], а форма вывода [128 x 128 x 3]. Первый слой-это слой свертки с k=3×3, шагами = 1, заполнением = 1 со структурой кодер-декодер.

Весь описанный выше процесс хорошо работает для заданной ширины и высоты (128 x 128).

Однако после завершения обучения с обучающими патчами [128 x 128 x 3] я хотел бы вывести изображение [ш x в x 3] с использованием обученной сети.

Я предполагаю, что все последовательности : свертка, maxpool дает правильные результаты, за исключением свертки транспонирования.

Когда я делаю вывод о фиксированной форме изображений [128 x 128 x 3] :

 InputImagesTensor = tf.placeholder(tf.float32, [None, 128, 128, 3], name='InputImages')
ResultImages = libs.Network(InputImagesTensor)
saver = tf.train.Saver()
w = 128
h = 128

sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver.restore(sess, 'output.ckpt')
for i in range(0, len(Datas.InputImageNameList)):
    temp = np.resize(getResizedImage(Datas.InputImageList[i]), (1, 128, 128, 3))
    resultimg = sess.run(ResultImages, feed_dict={InputImagesTensor: temp})
 

с сетью внутри :

 def Transpose2d(input, inC, outC):
    b, w, h, c = input.shape

    batch_size = tf.shape(input)[0]
    deconv_shape = tf.stack([batch_size, int(w*2), int(h*2), outC])
    kernel = tf.Variable(tf.random_normal([2, 2, outC, inC], stddev=0.01))
    output_shape = [None, int(w * 2), int(h * 2), outC]
    transConv = tf.nn.conv2d_transpose(input, kernel, output_shape=deconv_shape, strides=[1, 2, 2, 1], padding="SAME")

    return transConv
 

Теперь я попытался преобразовать их с фиксированной шириной и высотой в динамические ширину и высоту.
На мой взгляд, это сработало бы (однако это не удалось)

Изменить

 InputImagesTensor = tf.placeholder(tf.float32, [None, 128, 128, 3], name='InputImages')
temp = np.resize(getResizedImage(Datas.InputImageList[i]), (1, 128, 128, 3))
 

Для

 InputImagesTensor = tf.placeholder(tf.float32, [None, None, None, 3], name='InputImages')
temp = np.resize(getResizedImage(Datas.InputImageList[i]), (1, w, h, 3))
 

Однако эта строка выдает ошибку.

 deconv_shape = tf.stack([batch_size, int(w*2), int(h*2), outC])
 

Ошибка типа: int возвращает значение, отличное от int (тип NoneType)

Я думаю, это потому, что мы не можем удвоить значение None до 2*None.

Как я могу это сделать?? возможно ли это??

Ответ №1:

Самостоятельный ответ…

Я не могу придумать подходящее «стандартное» решение для установки w, h в качестве свойства None для свертки транспонирования.

Однако я решил проблему, указав форму свертки транспонирования как максимальную форму моих обучающих/проверочных изображений. Например, если максимальная ширина и высота моих изображений = [656 x 656], а тестовое изображение = [450 x 656], то я создаю нули np.ndarray [656 x 656] и просто заполняю область [450 x 656], используя RGB тестового изображения. (Примените концепцию заполнения нуля)