我一直在寻找最好的方法,这一周,我放弃了。
我正在尝试构建一个张量流模型,该模型从每个输入的三个不同特征中学习。问题是这些功能有不同的形状。
Ef。:
elem0 = {'feat0':[1,3,5],'feat1':[1,2],'feat2':[[0,1],[1,1]]}
elem1 = {'feat0':[0,5,1],'feat1':[2,9],'feat2':[[0,0],[1,0]]}
elem2 = {'feat0':[5,3,7],'feat1':[3,6],'feat2':[[1,1],[1,0]]}
我能做的最好的事就是在tf中创建三个“列”,如下所示:
x0 = tf.placeholder(tf.float32, shape = (None, 3), name = 'feat0')
x1 = tf.placeholder(tf.float32, shape = (None, 2), name = 'feat1')
x2 = tf.placeholder(tf.float32, shape = (None, 2, 2), name = 'feat2')
y0 = tf.layers.dense(x0, units = 1)
y1 = tf.layers.dense(x1, units = 1)
y2 = tf.layers.dense(x2, units = 1)
y_concat = tf.concat([y0,y1,y2],1)
y = tf.layers.dense(y_concat, units = 1)
与此有关的“问题”是我不知道我是否应该,如果是这样,如何在tensorflow中使用新的Dataset
类。
截至目前,我可以运行我的模型
init = tf.global_variables_initializer()
sess.run(init)
res = sess.run(y, {x0:[elem0[feat0],elem1[feat0],elem2[feat0]],
x1:[elem0[feat1],elem1[feat1],elem2[feat1]],
x2:[elem0[feat2],elem1[feat2],elem2[feat2]]
})
我真正想要的是有机会在我的元素上创建数据集迭代器,返回数据的三个“列”。
就像是:
def generate_tensor_set():
<some code, maybe getting my inputs from a SQL db>
return x0_batch, x1_batch, x2_batch
写完之后,我去阅读了一些关于新API的教程。
我设法解决,希望以“正确的”TF方式解决。
新的Dataset
API允许我这样做。
我的所有张量都来自发电机。此生成器返回3个numpy数组和每个输入数据实例的标签。
Ef。:
def generate_tensor_set(arg_example):
<get the data in some way, maybe using arg_example>
return x0, x1, x2, y
从生成器我创建了一个输入函数,它使用从生成器创建的数据集。 lambda
用于将参数传递给from_generator
中的生成器
def my_input_fn(batch_size):
ds = tf.data.Dataset().from_generator(lambda:generate_tensor_set(arg_example=an_arg),
output_types = (tf.float32, tf.float32, tf.float32, tf.int32)
output_shapes = (tf.Tensorshape([3]),
tf.Tensorshape([2]),
tf.Tensorshape([2,2])))
ds.batch(batch_size)
x0, x1, x2, label = ds.make_one_shot_iterator().get_next()
return {"x0": x0, "x1": x1, "x2": x2}, label
输入函数中的tf.int32
只是因为我使用了sparse_softmax_cross_entropy
,它想要一个int32
作为标签的输入(我猜,使用它解决了我的问题)。
然后是模型函数:
def model_function(features, labels, mode, params):
y0 = tf.layers.dense(features['x0'], units = 1)
y1 = tf.layers.dense(features['x1'], units = 1)
y2 = tf.layers.dense(features['x2'], units = 1)
y_concat = tf.concat([y0,y1,y2],1)
y = tf.layers.dense(y_concat, units = 1)
logits = tf.layers.dense(y_concat, units = 2)
<loss, train_op, a bunch of other stuff>
bunch of other stuff
在custom estimator documentation中得到了很好的描述
然后,
my_feature_columns = [ tf.feature_column.numeric_column("x0", shape=(3), dtype=tf.float32),
tf.feature_column.numeric_column("x1", shape=(2), dtype=tf.float32),
tf.feature_column.numeric_column("x2", shape=(2,2), dtype=tf.float32)]
classifier_mymodel = tf.estimator.Estimator(
model_fn = model_function,
params = {'feature_columns': my_feature_columns})
classifier_mymodel.train(input_fn = lambda: my_input_fn(batch_size = 16)