将生成器对象转换为列表会导致值错误

时间:2018-05-14 13:33:38

标签: python-2.7 list tensorflow generator valueerror

我正在使用tensorflow API来获取估算器的预测。当我尝试打印预测时,我得到一个引用生成器对象的内存地址。当我搜索解决方案时,我发现很多文章建议我将生成器对象转换为列表以打印值,但这会导致值错误。

我使用的是Python 2.7,Ubuntu 16.04和Tensorflow 1.8.0

以下是我最初用于打印生成器对象的代码:

predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy[0]}, y=None, batch_size=1, num_epochs=None, shuffle=False)
prediction_results = classifier.predict(input_fn=predict_input_fn)
print (prediction_results)  

这导致以下输出:
<generator object predict at 0x7f2fbdffd460>

以下是我尝试将预测打印为值列表时所做的更改代码:

predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy[0]}, y=None, batch_size=1, num_epochs=None, shuffle=False)
prediction_results = classifier.predict(input_fn=predict_input_fn)
print (list(prediction_results))  

这是它产生的错误:

Traceback (most recent call last):
  File "vqa_training.py", line 107, in <module>
    print (list(prediction_results))
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/estimator/estimator.py", line 496, in predict
    features, None, model_fn_lib.ModeKeys.PREDICT, self.config)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/estimator/estimator.py", line 831, in _call_model_fn
    model_fn_results = self._model_fn(features=features, **kwargs)
  File "vqa_training.py", line 13, in cnn_model_fn
    input_layer = tf.reshape(features["images"], [-1, 200, 200, 3])
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_array_ops.py", line 6113, in reshape
    "Reshape", tensor=tensor, shape=shape, name=name)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py", line 787, in _apply_op_helper
    op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 3392, in create_op
    op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1734, in __init__
    control_input_ops)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1570, in _create_c_op
    raise ValueError(str(e))
ValueError: Dimension size must be evenly divisible by 120000 but is 600 for 'Reshape' (op: 'Reshape') with input shapes: [1,200,3], [4] and with input tensors computed as partial shapes: input[1] = [?,200,200,3].

我认为数字120000来自于train_data_numpy中的每个输入都是一个表示图像的numpy数组,其形状为(200,200,3)。 200 * 200 * 3 = 120000。

为什么会出现此错误?

额外信息,如果需要:这是我正在使用的完整python脚本

import numpy as np
import tensorflow as tf
import os
import cv2
from pprint import pprint



# CNN function
def cnn_model_fn(features, labels, mode):

    # define the layers of the cnn
    input_layer = tf.reshape(features["images"], [-1, 200, 200, 3])
    conv_layer = tf.layers.conv2d(inputs=input_layer, filters=32, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)
    pool_layer = tf.layers.max_pooling2d(inputs=conv_layer, pool_size=[2, 2], strides=2)
    conv_layer_two = tf.layers.conv2d(inputs=pool_layer, filters=64, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)
    pool_layer_two = tf.layers.max_pooling2d(inputs=conv_layer_two, pool_size=[2, 2], strides=2)
    flat_pool_two = tf.reshape(pool_layer_two, [-1, 50 * 50 * 64])
    dense_layer = tf.layers.dense(inputs=flat_pool_two, units=1024, activation=tf.nn.relu)
    logits = tf.layers.dense(inputs=dense_layer, units=2)

   # Generate predictions (for PREDICT and EVAL mode)
    predictions = {
        "classes": tf.argmax(input=logits, axis=1),
        "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
    }

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

    # Calculate Loss (for both TRAIN and EVAL modes)
    loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

    # Configure the Training Operation (for TRAIN mode)
    if mode == tf.estimator.ModeKeys.TRAIN:
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
        train_op = optimizer.minimize(loss=loss, global_step=tf.train.get_global_step())
        return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

    # Add evaluation metrics (for EVAL mode)
    eval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)




# Load and process dataset

filenames = []
images = []
unstable = []
labels = []

# load images from folders
for root, dirs, files in os.walk("images/cropped"):  
    for filename in files:
        filenames.append(filename)
for root, dirs, files in os.walk("images/unstable"):  
    for filename in files:
        unstable.append(filename)

# for each image in images, append the corresponding label to labels: 0 means unstable, 1 means stable
for filename in filenames:
    images.append(cv2.imread("images/cropped/"+filename))
    if filename in unstable:
        labels.append(0)
    else:
        labels.append(1)

# separate images and labels into train and test sets - 80% train, 20% evaluate
train_images = images[0:40]
train_labels = labels[0:40]
test_images = images[40:]
test_labels = labels[40:]

# convert dataset into numpy arrays
train_data_numpy = np.array(train_images, np.float32)
train_labels_numpy = np.array(train_labels, np.int32)
test_data_numpy = np.array(test_images, np.float32)
test_labels_numpy = np.array(test_labels, np.int32)



# Put images through CNN to get feature vector

# Create the Estimator
classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="temp/cnn")

# Set up logging for predictions
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=1)

# Train the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy}, y=train_labels_numpy, batch_size=1, num_epochs=None, shuffle=True)
classifier.train(input_fn=train_input_fn, steps=200, hooks=[logging_hook])

# Evaluate the model and print results
eval_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":test_data_numpy}, y=test_labels_numpy, num_epochs=1, shuffle=False)
eval_results = classifier.evaluate(input_fn=eval_input_fn)
print (eval_results)



# Use the CNN model to get predictions
predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy[0]}, y=None, batch_size=1, num_epochs=None, shuffle=False)
prediction_results = classifier.predict(input_fn=predict_input_fn)
print (list(prediction_results))

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,但我不确定为什么这解决了错误。

当我改变第一行时:
predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy[0]}, y=None, batch_size=1, num_epochs=None, shuffle=False)
于:
predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"images":train_data_numpy[0:1]}, y=None, batch_size=1, num_epochs=None, shuffle=False)
然后print(list(prediction_results))打印出一本字典。

我所做的更改是使用train_data_numpy[0:1]而不是train_data_numpy[0]