python - 为什么我不能使用 TensorFlow 一次性编码我的标签? (坏切片索引 None of type <type 'NoneType' >)

标签 python csv numpy tensorflow

我正在尝试将 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——例如: working one-hot encoding example

关于为什么这行不通,我在这里明显遗漏了什么吗?

最佳答案

问题似乎是 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/

相关文章:

python - 在scrapy中使用mysql插入数据

python - 加载和保存列表索引超出范围后的openpyxl(python)

linux - 比较两个 csv 文件并根据使用 awk 的比较更新字段

Python 2.7 : Saving a plot from pandas

python - 从 cpp、python 和 csv 文件中生成可执行文件?

python - Google Cloud Dataflow 访问云存储上的.txt 文件

python - 从字符串中提取列表

python - 为什么结果应该是整数,却是循环数?

python - 枚举与字符串作为函数中的参数

python - 如何生成具有预定义概率分布的随机数?