Tensorflow: ввод инкапсулированного пакета данных через один заполнитель

Я вообще борюсь с тензорами индексации в тензорном потоке. У меня есть данные изображения и дополнительные скалярные данные. Я могу использовать только один заполнитель для ввода всех данных в нейронную сеть.

Изображения (img) представляют собой множество массивов с формой (84,84,3), и у меня есть данные a с формой (2) и b с формой (1).

Сейчас создаю единый образец

sample = np.reshape(np.array([img,a,b]),(3,1)) #shape (3,1)

Заполнитель

input = tf.placeholder(dtype=tf.float32,shape=[None] + list(sample.shape))

Теперь, когда TF читает пакет образцов, я хотел бы получить пакет изображений, пакет a и пакет b, потому что они должны вводиться в разных местах нейронной сети.

Вот минимальный пример:

import tensorflow as tf
from tensorflow.contrib import layers
import numpy as np

#Numpy
img = np.random.rand(84,84,3)
a = np.random.rand(2)
b = np.random.rand(1)
sample = np.reshape(np.array([img,a,b]),(3,1)) #shape (3,1)
batch = np.repeat(np.expand_dims(sample,axis=0),32,axis=0) #shape (32,3,1)

#TF
input = tf.placeholder(dtype=tf.float32,shape=[None] + list(sample.shape))

#TODO:
tf_img = tf.#get image batch from input
tf_a = tf.#get a batch from input
tf_b = tf.#get b batch from input

out = layers.convolution2d(tf_img,num_outputs=64,kernel_size=8,stride=2,activation_fn=tf.nn.relu)
out = layers.flatten(out)
out = tf.concat([out,tf_a,tf_b])
out = layers.fully_connected(out,10,activation_fn=tf.nn.relu)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    _ = sess.run(out,feed_dict={input:batch})

Как я могу извлечь отдельные части входных данных из тензора с формой (?,3,1), использовать данные изображения для создания вложения и объединить две другие части в это выходное вложение.

Есть ли лучший способ ввести данные? Мое единственное ограничение - это должен быть единственный заполнитель.


person user3142067    schedule 28.09.2017    source источник
comment
Пожалуйста, поясните, почему вы ограничены одним заполнителем! Если известны все размеры ваших входных данных, вы можете обернуть каждый образец в один тензор формы (None, 84*84*3+2+1) и использовать нарезка и изменение формы внутри графика.   -  person chrert    schedule 28.09.2017
comment
Спасибо за ответы. Я работаю с большим шаблоном кода и хочу менять как можно меньше, поскольку он довольно запутанный (и предполагает ввод одного изображения). также мне было интересно, возможно ли это. Не могли бы вы привести более крупный пример?   -  person user3142067    schedule 28.09.2017


Ответы (1)


Вот полный пример моего комментария выше:

import numpy as np
import tensorflow as tf

im_height = 84
im_width = 84
im_channels = 3
a_len = 2
b_len = 1

np_img = np.random.rand(im_height, im_width, im_channels)
np_a = np.random.rand(a_len)
np_b = np.random.rand(b_len)

# flatten the input and concatenate to a single 1D numpy array
np_sample = np.concatenate((np_img.reshape(-1), np_a.reshape(-1), np_b.reshape(-1)), axis=0)
# construct a pseudo batch
np_batch = np.repeat(np_sample[np.newaxis, :], 32, axis=0)

tf_batch = tf.placeholder(shape=(None, im_height*im_width*im_channels + a_len + b_len), dtype=tf.float32)

img_stop = im_height*im_width*im_channels
a_stop = img_stop+a_len

# you could also use tf.slice(...) here
tf_img = tf.reshape(tf_batch[:, 0:img_stop], (-1, im_height, im_width, im_channels))
tf_a = tf.reshape(tf_batch[:, img_stop:a_stop], (-1, a_len))
tf_b = tf.reshape(tf_batch[:, a_stop:], (-1, b_len))

with tf.Session() as sess:
    fetch_dict = {'img': tf_img, 'a': tf_a, 'b': tf_b}
    feed_dict = {tf_batch: np_batch}
    res = sess.run(fetch_dict, feed_dict=feed_dict)

assert(np.isclose(res['img'][0, ...], np_img).all())
assert(np.isclose(res['a'][0, :], np_a).all())
assert(np.isclose(res['b'][0, :], np_b).all())

Однако это не менее агрессивно, чем добавление в код соответствующих заполнителей. Кроме того, на мой взгляд, он гораздо менее читабелен.

person chrert    schedule 28.09.2017