我正在尝试将 CSV 输入管道构建到 TensorFlow 模型中,作为该管道的一部分,我想对标签进行一次性编码。
这是我的完整模型的代码:
from __future__ import print_function
import numpy as np
import tensorflow as tf
import math as math
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('dataset')
args = parser.parse_args()
# hyperparameters
num_labels = 2
def file_len(fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
def read_from_csv(filename_queue):
reader = tf.TextLineReader(skip_header_lines=1)
_, csv_row = reader.read(filename_queue)
record_defaults = [[0],[0],[0],[0],[0]]
col1,col2,col3,col4,colLabel = tf.decode_csv(csv_row, record_defaults=record_defaults)
features = tf.pack([col1,col2,col3,col4])
label = tf.pack([colLabel])
return features, label
def read_batches(batch_size, num_epochs=None):
filename_queue = tf.train.string_input_producer([args.dataset], num_epochs=num_epochs, shuffle=True)
example, label = read_from_csv(filename_queue)
min_after_dequeue = 10000
capacity = min_after_dequeue + 3 * batch_size
example_batch, label_batch = tf.train.shuffle_batch(
[example, label], batch_size=batch_size, capacity=capacity,
min_after_dequeue=min_after_dequeue)
return example_batch, label_batch
def reformat(dataset, labels):
dataset = tf.to_float(dataset)
labels = tf.reshape(labels, [-1])
# labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
return dataset, labels
def input_pipeline(batch_size, num_epochs=None):
example_batch, label_batch = read_batches(batch_size, num_epochs)
train_dataset, train_labels = reformat(example_batch, label_batch)
return train_dataset, train_labels
file_length = file_len(args.dataset) - 1
training_dataset, training_labels = input_pipeline(file_length, 1)
with tf.Session() as sess:
tf.initialize_all_variables().run()
# start populating filename queue
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
try:
while not coord.should_stop():
training_dataset_batch, training_labels_batch = sess.run([training_dataset, training_labels])
print("\nlabels:")
print(training_labels_batch)
print("\nlabels type:")
print(type(training_labels_batch))
print("\nlabels shape:")
print(training_labels_batch.shape)
print("\nlabels rank:")
print(tf.rank(training_labels_batch))
except tf.errors.OutOfRangeError:
print('\nDone training, epoch reached')
finally:
coord.request_stop()
coord.join(threads)
下面是一些适用于此模型的 CSV 示例:
col1,col2,col3,col4,label
0,0,0,0,0
0,15,0,0,0
0,30,0,0,1
0,45,0,0,1
1,0,0,0,2
1,15,0,0,2
1,30,0,0,3
1,45,0,0,3
如果我按原样运行这段代码,这就是我得到的输出——此时,我还没有启用任何单热编码,你在这里看到的或多或少是有道理的——我的标签数组有形状为 (8,) 因为有 8 个示例,等级为 0:
$ python model.py csv_test_data.csv
labels:
[0 2 2 0 3 3 1 1]
labels type:
<type 'numpy.ndarray'>
labels shape:
(8,)
labels rank:
Tensor("Rank:0", shape=(), dtype=int32)
Done training, epoch reached
(tensorflow)
当我启用这行代码以在 reformat
中对标签进行单热编码时,问题就来了:
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
我一介绍它,砰的一声——它让我大吃一惊:
$ python model.py csv_test_data.csv
Traceback (most recent call last):
File "model.py", line 51, in <module>
training_dataset, training_labels = input_pipeline(file_length, 1)
File "model.py", line 47, in input_pipeline
train_dataset, train_labels = reformat(example_batch, label_batch)
File "model.py", line 42, in reformat
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
File "/Users/rringham/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/array_ops.py", line 161, in _SliceHelper
raise TypeError("Bad slice index %s of type %s" % (s, type(s)))
TypeError: Bad slice index None of type <type 'NoneType'>
我真的不清楚为什么;我在其他 TensorFlow 模型中使用了相同的技术,并且它在几乎相同的标签类型上工作得很好——一个值数组,一个 (#,) 的形状,其中 # 是示例的数量,以及一个等级 0——例如:
关于为什么这行不通,我在这里明显遗漏了什么吗?
最佳答案
问题似乎是 NumPy 切片语法和 TensorFlow 切片语法之间的(另一个)不兼容。在 NumPy 中,labels[:, None]
是向返回数组添加新维度的简写,将长度为 N
的向量转换为大小为 的矩阵N x 1
。 TensorFlow 不理解这一点(目前),所以你使用了 tf.expand_dims()
op 而不是:
tf.expand_dims(labels, 1) # equivalent to `labels[:, None]` in NumPy.
但是,一旦您解决了这个问题,您可能会遇到其他问题:
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
由于 labels
是 TensorFlow 张量而不是 NumPy 数组,您将无法使用 NumPy 方法,例如 ==
运算符和 astype ()
就可以了。以下是使用 TensorFlow 运算符编写此行的方法:
labels = tf.cast(
tf.equal(tf.range(num_labels), tf.expand_dims(labels, 1)), tf.float32)
PS. 新tf.one_hot()
op 可能是将数据转换为单热编码的更简单方法。
关于python - 为什么我不能使用 TensorFlow 一次性编码我的标签? (坏切片索引 None of type <type 'NoneType' >),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37102621/