【问题标题】:Tensorflow cannot convert string to numberTensorflow 无法将字符串转换为数字
【发布时间】:2019-02-18 11:50:11
【问题描述】:

我使用的是 tensorflow-1.12,当我通过 tf.data.Dataset 从 csv 加载数据时,我无法将单元格值从字符串转换为数字。我的 csv 看起来像:

"string_col1","col1","col2", ...
"some value","23.502482","53.5", ...

我只想使用带有数字的列(col1、col2 等)作为输入,所以我有删除第一列的函数:

import tensorflow as tf

def slice_and_transform_to_float(line):
    line_splitted = tf.string_split([line], ",")
    str_data = tf.convert_to_tensor(line_splitted.values, dtype=tf.string)
    str_data = tf.slice(str_data, [1], [col_size])
    return tf.string_to_number(str_data, out_type=tf.float32) # here is a problem


map_func = lambda line: slice_and_transform_to_float(line)
dataset = tf.data.Dataset.from_tensor_slices(train_files)
dataset = dataset.map(map_func, num_parallel_calls=4)
iterator = dataset.make_initializable_iterator()

sess = tf.Session()
iterator = dataset.make_initializable_iterator()
sess.run([tf.global_variables_initializer(), iterator.initializer])
next_iter = iterator.get_next()
next_rows = sess.run(next_iter) # here we have exception


当我尝试运行它时出现错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError: StringToNumberOp could not correctly convert string: "23.502482"
     [[{{node StringToNumber}} = StringToNumber[out_type=DT_FLOAT](Slice)]]
     [[node IteratorGetNext (defined at script.py:100)  = IteratorGetNext[output_shapes=[[?,8]], output_types=[DT_FLOAT], _device="/job:localhost/replica:0/task:0/device:CPU:0"](IteratorV2)]]

我的字符串值似乎是一个数字,但 tensorflow 转换为浮点数时存在问题。我尝试了整数值和tf.float64,但没有任何改变。你知道什么可能是错误的吗?

我试图找到类似的问题,但我只是发现问题,当有人想将“字符串”转换为数字时,这不是我的情况。

【问题讨论】:

  • 您正在尝试转换为浮动字符串"23.502482",包括引号,而不是23.502482,这就是它失败的原因。
  • 非常感谢。这么简单……

标签: python tensorflow


【解决方案1】:

问题是您传递带有引号的数字字符串,不能将其解析为数字。您可以像这样删除引号:

import tensorflow as tf

def slice_and_transform_to_float(line):
    line_splitted = tf.strings.split([line], ",")
    str_data = tf.convert_to_tensor(line_splitted.values, dtype=tf.string)
    str_data = tf.slice(str_data, [1], [2])  # Fixed that to 2 for the example
    str_len = tf.strings.length(str_data)
    str_unquoted = tf.strings.substr(str_data, tf.ones_like(str_len), str_len - 2)
    return tf.strings.to_number(str_unquoted, out_type=tf.float32)

with tf.Graph().as_default(), tf.Session() as sess:
    print(sess.run(slice_and_transform_to_float('"some value","23.502482","53.5"')))
    # [23.502481 53.5     ]

【讨论】:

    【解决方案2】:

    因为有时 csv 文件可以有带或不带引号的行,例如:

    "col1", "col2", "col3", ...
    23.582, "53.5",  12   , ...
    

    我已通过以下方式更改了您的解决方案:

    def slice_and_transform_to_float(line):
        line_splitted = tf.string_split([line], ",")
        str_data = tf.convert_to_tensor(line_splitted.values, dtype=tf.string)
        str_data = tf.slice(str_data, [0], [2]) # Fixed that to 2 for the example
        str_data = tf.map_fn(lambda x: tf.regex_replace(x, '"', ""), str_data)
        return tf.string_to_number(str_data, out_type=out_type)
    

    现在值是否包含引号无关紧要。

    【讨论】:

    • 在 tensorflow 2.0 中,出现错误,模块 'tensorflow' 没有属性 'string_to_number'
    • 代码适用于 tf 1.x。基于documentation,您可以试试:tf.strings.to_number(input, out_type=tf.dtypes.float32, name=None) 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    相关资源
    最近更新 更多