我目前正在尝试获取一个简单的张量流模型,以通过自定义输入管道提供的数据进行训练。它应该尽可能高效地工作。虽然我读了很多教程,但我无法让它工作。
数据
我将训练数据拆分到多个 csv 文件中。文件"a.csv"分别有20个样本,"b.csv"有30个样本。它们具有相同的结构和相同的标头:
feature1; feature2; feature3; feature4
0.1; 0.2; 0.3; 0.4
...
(没有标签,就像自动编码器一样。
代码
我已经编写了一个输入管道,并希望将数据从中馈送到模型。我的代码如下所示:
import tensorflow as tf
def input_pipeline(filenames, batch_size):
dataset = tf.data.Dataset.from_tensor_slices(filenames)
dataset = dataset.flat_map(
lambda filename: (
tf.data.TextLineDataset(filename)
.skip(1)
.shuffle(10)
.map(lambda csv_row: tf.decode_csv(
csv_row,
record_defaults=[[-1.0]]*4,
field_delim=';'))
.batch(batch_size)
)
)
return dataset.make_initializable_iterator()
iterator = input_pipeline(['/home/sku/data/a.csv',
'/home/sku/data/b.csv'],
batch_size=5)
next_element = iterator.get_next()
# Build the autoencoder
x = tf.placeholder(tf.float32, shape=[None, 4], name='in')
z = tf.contrib.layers.fully_connected(x, 2, activation_fn=tf.nn.relu)
x_hat = tf.contrib.layers.fully_connected(z, 4)
# loss function with epsilon for numeric stability
epsilon = 1e-10
loss = -tf.reduce_sum(
x * tf.log(epsilon + x_hat) + (1 - x) * tf.log(epsilon + 1 - x_hat))
train_op = tf.train.AdamOptimizer(learning_rate=1e-3).minimize(loss)
with tf.Session() as sess:
sess.run(iterator.initializer)
sess.run(tf.global_variables_initializer())
for i in range(50):
batch = sess.run(next_element)
sess.run(train_op, feed_dict={x: batch, x_hat: batch})
问题所在
尝试将数据馈送到模型时,出现错误:
ValueError: Cannot feed value of shape (4, 5) for Tensor 'in:0', which has shape '(?, 4)'
打印出批处理数据的形状时,例如:
(array([ 4.1, 5.9, 5.5, 6.7, 10. ], dtype=float32), array([0.4, 7.7, 0. , 3.4, 8.7], dtype=float32), array([3.5, 4.9, 8.3, 7.2, 6.4], dtype=float32), array([-1. , -1. , 9.6, -1. , -1. ], dtype=float32))
这是有道理的,但是我必须在哪里以及如何重塑它?此外,此附加信息 dtype 仅在批处理时出现。
我也认为我喂错了。我需要input_fn或类似的东西吗?我记得喂食命令是慢下来的。如果有人能给我一种有效的方法来准备和提供数据,我将不胜感激。
问候
我已经想出了一个解决方案,需要第二个映射函数。您必须将以下行添加到输入函数中:
def input_pipeline(filenames, batch_size):
dataset = tf.data.Dataset.from_tensor_slices(filenames)
dataset = dataset.flat_map(
lambda filename: (
tf.data.TextLineDataset(filename)
.skip(1)
.shuffle(10)
.map(lambda csv_row: tf.decode_csv(
csv_row,
record_defaults=[[-1.0]]*4,
field_delim=';'))
.map(lambda *inputs: tf.stack(inputs)) # <-- mapping required
.batch(batch_size)
)
)
return dataset.make_initializable_iterator()
这似乎将类似数组的输出转换为矩阵,可以馈送到网络。
但是,我仍然不确定通过feed_dict喂养它是否是最有效的方法。我仍然希望在这里得到支持!