2016-05-08 1 views
2

私はTensorFlowモデルにCSV入力パイプラインを構築しようとしています。そのパイプラインの一部として、私のラベルをワンホットエンコードしたいと思います。ここでTensorFlowでラベルをワンホットエンコードできないのはなぜですか? (不良スライスインデックスなしタイプ<type 'NoneType'>)

は私の完全なモデルのコードです:

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:

できるだけ早く私はブームが、ことを紹介して

labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 

- それは私に吹く::私はワンホットエンコードにこのコード行reformatのラベルを有効にすると

問題が来る

$ 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

なぜこれが機能しないのかここでは分かりませんか?

答えて

1

問題は、NumPyスライスの構文とTensorFlowスライスの構文との間に(別の)非互換性があるようです。 NumPyのlabels[:, None]は、返された配列に新しい次元を追加して、長さがNのベクトルをサイズN x 1の行列にするための省略形です。 labelsがあるので

labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 

tf.expand_dims(labels, 1) # equivalent to `labels[:, None]` in NumPy. 

をあなたはこれを修正しかし、一度、あなたが他の問題に遭遇することがあります。あなたの代わりにtf.expand_dims()オペアンプを使用しているのでTensorFlowは、(現在は)これを理解していませんNumPy配列ではなくTensorFlowテンソルを使用すると、==演算子やastype()などのNumPyメソッドを使用することはできません。 TensorFlow演算子を使用してこの行を書く方法は次のとおりです。

PS。新しいtf.one_hot() opは、データをワンホットエンコーディングに簡単に変換する方法です。

+1

両方のオプションが素晴らしい(tf.expand_dims()とtf.one_hot()の両方) –

関連する問題