我正在添加我的问题的摘要,以使其更易于理解: 我想确切地执行以下tensorflow示例中的操作: https://www.tensorflow.org/guide/datasets
# Reads an image from a file, decodes it into a dense tensor, and resizes it
# to a fixed shape.
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string)
image_resized = tf.image.resize_images(image_decoded, [28, 28])
return image_resized, label
# A vector of filenames.
filenames = tf.constant(["/var/data/image1.jpg", "/var/data/image2.jpg", ...])
# `labels[i]` is the label for the image in `filenames[i].
labels = tf.constant([0, 37, ...])
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(_parse_function)
唯一的区别是:我从具有更多功能的CSV读取数据,然后调用map方法:
dataset = tf.data.experimental.make_csv_dataset(file_pattern=CSV_PATH_TRAIN,
batch_size=2,
header=True,
label_name = 'label').map(_parse_function)
我的_parse_function看起来如何?如何访问图像路径功能,将其更新为图像表示形式,并返回图像的修改后的数字矩阵功能,而无需更改其他功能?
谢谢, 埃兰语
===================这是我的代码尝试:==================
我的代码读取带有功能列和标签的CSV。功能之一是图像路径,其他功能是字符串。 图像路径需要处理成图像编号矩阵。 我尝试使用以下选项进行操作。两种方式下,tf.read_file都会失败,并输入尺寸错误。 我的问题是如何一次将一张图像传递到map方法中
def read_image_png_option_1(image_path, depth=3, scale=False):
"""Reads the image from image_path (tf.string tensor) [jpg image].
Cast the result to float32 and if scale=True scale it in [-1,1]
using scale_image. Otherwise the values are in [0,1]
Reuturn:
the decoded jpeg image, casted to float32
"""
image = tf.image.convert_image_dtype(
tf.image.decode_png(tf.read_file(image_path), channels=depth),
dtype=tf.float32)
if scale:
image = scale_image(image)
return image
def read_image_png_option_2(features, depth=3, scale=False):
"""Reads the image from image_path (tf.string tensor) [jpg image].
Cast the result to float32 and if scale=True scale it in [-1,1]
using scale_image. Otherwise the values are in [0,1]
Reuturn:
the decoded jpeg image, casted to float32
"""
image = tf.image.convert_image_dtype(
tf.image.decode_png(tf.read_file(features['image']), channels=depth),
dtype=tf.float32)
if scale:
image = scale_image(image)
features['image'] = image
return features
def make_input_fn(fileName,batch_size=8, perform_shuffle=True):
"""An input function for training """
def _input_fn():
def decode_csv(line):
print('line is ',line)
filename_col,label_col,gender_col,ethinicity = tf.decode_csv(line,
[[""]]*amount_of_columns_csv,
field_delim=",",
na_value='NA',
select_cols=None)
image_col = read_image_png_option_1(filename_col)
d = dict(zip(['image','label','gender','ethinicity'], [image_col,label_col,gender_col,ethinicity])), label
return d
## OPTION 1:
# filenames could be more than one
# dataset = tf.data.TextLineDataset(filenames=fileName).skip(1).batch(batch_size).map(decode_csv)
## OPTION 2:
dataset = tf.data.experimental.make_csv_dataset(file_pattern=CSV_PATH_TRAIN,
batch_size=2,
header=True,
label_name = 'label').map(read_image_png_option_2)
#select_columns=[0,1]) #[tf.string,tf.string,tf.string,tf.string])
if perform_shuffle:
dataset = dataset.shuffle(buffer_size=256)
return dataset
return _input_fn()
train_input_fn = lambda: make_input_fn(CSV_PATH_TRAIN)
train_spec = tf.estimator.TrainSpec(input_fn=train_input_fn, max_steps=50)
eval_input_fn = lambda: make_input_fn(CSV_PATH_VAL)
eval_spec = tf.estimator.EvalSpec(eval_input_fn)
feature_columns = [tf.feature_column.numeric_column("image",shape=(224,224)), # here i need a pyhton method to transform
tf.feature_column.categorical_column_with_vocabulary_list("gender", ["ww","ee"]),
tf.feature_column.categorical_column_with_vocabulary_list("ethinicity",["xx","yy"])]
estimator = tf.estimator.DNNClassifier(feature_columns=feature_columns,hidden_units=[1024, 512, 256],warm_start_from=ws)
tf.estimator.train_and_evaluate(estimator, train_spec=train_spec, eval_spec=eval_spec)
选项2的错误: ValueError:形状必须为0级,但输入形状为[2]的“ ReadFile”(op:“ ReadFile”)为1级。
选项1的错误: ValueError:形状必须为0级,但输入形状为[?]的“ ReadFile”(op:“ ReadFile”)为1级。
感谢您的帮助。 谢谢
答案 0 :(得分:0)
首先,您需要将CSV文件读入数据集。
然后,您可以为CSV中的每一行调用解析函数。
def getInput(fileList):
# returns a dataset containing list of filenames
files = tf.data.Dataset.from_tensor_slices(fileList)
# Returs a dataset containing list of rows taken from all the files in file list.
# dataset is filled dynamically and not all entries are read at once
dataset = files.interleave(tf.data.TextLineDataset)
# call parse function for each row
# returned dataset will contain list of whatever the parse function is returning for the row
# we want the image path to be converted to decoded image in parse function
dataset = dataset.map(_parse_function, num_parallel_calls=8)
# return an iterator for the dataset which will be used to get elements.
return dataset.make_one_shot_iterator().get_next()
解析函数将仅传递一个参数,该参数将是CSV文件中的一行。您需要解码CSV并对每个值进行进一步处理。
假设您的CSV文件中有3列,每个列都是一个字符串。
def _parse_function(value):
columns_default = [[""], [""], [""]]
# this will be a tensor of columns in the row
columns = tf.decode_csv(value, record_defaults=columns_default,
field_delim=',')
col_names = ["label", "imagepath", "c3"]
features = dict(zip(col_names, columns))
for f, tensor in features.items():
# process imagepath to decoded image
if f == "imagepath":
image_string = tf.read_file(tensor)
image_decoded = tf.image.decode_jpeg(image_string)
image_resized = tf.image.resize_images(image_decoded, [28, 28])
features[f] = image_resized
labels = tf.equal(features.pop('label'), "1")
labels = tf.expand_dims(labels, 0)
return features, labels
编辑:
注释说明:
https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#train
我已经在上面的代码块中进行了编辑,以描述每个步骤将包含的数据集对象。
据我了解,您将图像路径作为CSV中的字段之一,并且想要将该路径转换为实际的解码图像,并将其用作功能之一。
由于图像将只是功能之一,因此您不应尝试仅使用图像文件来创建数据集。数据集对象将一次包含您的所有功能。
所以这样做是不正确的:
files = tf.data.Dataset.from_tensor_slices(ds['imagepath'])
dataset = files.interleave(tf.data.TextLineDataset)
如果您使用make_csv()函数读取csv,则它将csv的每一行转换为一条记录,其中一条记录将包含所有功能的列表,与csv的列相同。
因此返回的数据集中的每个元素应包含一个包含所有特征的张量。
在这里,您的图像路径将是功能之一。现在您想将该图像路径转换为解码图像。
我想您可以通过使用map()函数对数据集的元素应用parse函数来做到这一点,但这会有些棘手,因为所有功能都已经打包在一个张量中。