类型错误:不支持使用带有估计器 input_fn 的数据集调用 [英] TypeError: unsupported callable using Dataset with estimator input_fn

查看:20
本文介绍了类型错误:不支持使用带有估计器 input_fn 的数据集调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试转换 Iris 教程 (https://www.tensorflow.org/get_started/estimator) 从 .png 文件而不是 .csv 读取训练数据.它使用 numpy_input_fn 工作,但当我从 Dataset 制作它时不起作用.我认为 input_fn() 返回了错误的类型,但并不真正理解它应该是什么以及如何做到这一点.错误是:

I'm trying to convert the Iris tutorial (https://www.tensorflow.org/get_started/estimator) to read training data from .png files instead of .csv. It works using numpy_input_fn but not when I make it from a Dataset. I think input_fn() is returning the wrong type but don't really understand what it should be and how to make it that. The error is:

  File "iris_minimal.py", line 27, in <module>
    model_fn().train(input_fn(), steps=1)
    ...
    raise TypeError('unsupported callable') from ex
TypeError: unsupported callable

TensorFlow 版本是 1.3.完整代码:

TensorFlow version is 1.3. Complete code:

import tensorflow as tf
from tensorflow.contrib.data import Dataset, Iterator

NUM_CLASSES = 3

def model_fn():
    feature_columns = [tf.feature_column.numeric_column("x", shape=[4])]
    return tf.estimator.DNNClassifier([10, 20, 10], feature_columns, "tmp/iris_model", NUM_CLASSES)

def input_parser(img_path, label):
    one_hot = tf.one_hot(label, NUM_CLASSES)
    file_contents = tf.read_file(img_path)
    image_decoded = tf.image.decode_png(file_contents, channels=1)
    image_decoded = tf.image.resize_images(image_decoded, [2, 2])
    image_decoded = tf.reshape(image_decoded, [4])
    return image_decoded, one_hot      

def input_fn():
    filenames = tf.constant(['images/image_1.png', 'images/image_2.png'])
    labels = tf.constant([0,1])
    data = Dataset.from_tensor_slices((filenames, labels))
    data = data.map(input_parser)
    iterator = data.make_one_shot_iterator()
    features, labels = iterator.get_next()
    return features, labels

model_fn().train(input_fn(), steps=1)

推荐答案

我注意到您的代码片段中有几个错误:

I've noticed several mistakes in your code snippet:

  • train 方法接受输入函数,所以应该是input_fn,而不是input_fn().
  • 这些特征应该是字典,例如{'x': features}.
  • DNNClassifier 使用 SparseSoftmaxCrossEntropyWithLogits 损失函数.稀疏意味着它假定序数类表示,而不是one-hot,所以你的转换是不必要的(这个问题 解释了 tf 中交叉熵损失之间的差异).
  • train method accepts the input function, so it should be input_fn, not input_fn().
  • The features are expected as a dictionary, e.g. {'x': features}.
  • DNNClassifier uses SparseSoftmaxCrossEntropyWithLogits loss function. Sparse means that it assumes ordinal class representation, instead of one-hot, so your conversion is unnecessary (this question explains the difference between cross-entropy losses in tf).

试试下面的代码:

import tensorflow as tf
from tensorflow.contrib.data import Dataset

NUM_CLASSES = 3

def model_fn():
    feature_columns = [tf.feature_column.numeric_column("x", shape=[4], dtype=tf.float32)]
    return tf.estimator.DNNClassifier([10, 20, 10], feature_columns, "tmp/iris_model", NUM_CLASSES)

def input_parser(img_path, label):
    file_contents = tf.read_file(img_path)
    image_decoded = tf.image.decode_png(file_contents, channels=1)
    image_decoded = tf.image.resize_images(image_decoded, [2, 2])
    image_decoded = tf.reshape(image_decoded, [4])
    label = tf.reshape(label, [1])
    return image_decoded, label

def input_fn():
    filenames = tf.constant(['input1.jpg', 'input2.jpg'])
    labels = tf.constant([0,1], dtype=tf.int32)
    data = Dataset.from_tensor_slices((filenames, labels))
    data = data.map(input_parser)
    data = data.batch(1)
    iterator = data.make_one_shot_iterator()
    features, labels = iterator.get_next()
    return {'x': features}, labels

model_fn().train(input_fn, steps=1)

这篇关于类型错误:不支持使用带有估计器 input_fn 的数据集调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆