我正在尝试预处理包含约 20,000 张图像、它们的特征向量和它们的掩码(图像分割)的数据集。由于数据的大小,我无法执行内存预处理。
我使用这个函数加载数据:
@tf.function
def get_mask_cum_featvecs_dataset(files_paths):
paths_ds = tf.data.Dataset.list_files(files_paths)
ds = paths_ds.interleave(lambda tfrec_path: tf.data.TFRecordDataset(tfrec_path).map(
read_tfrec, num_parallel_calls=AUTO),
num_parallel_calls=AUTO)
return ds
预处理包括获取数据集中存在的所有图像与输入图像(由用户提供)之间的欧式距离,然后将所有欧式距离除以所有欧式距离中的最大欧式距离。为此,我使用以下给定的功能:
@tf.function
def euclidean_dist(comp_img_features, img_featvec):
euclidean_dist = tf.sqrt(tf.reduce_sum(tf.square(img_featvec-comp_img_features), 0))
return euclidean_dist
@tf.function
def preprocess(img_featvec, img_mask, mask_cum_featvecs_paths):
tensor_img_featvec = img_featvec
tensor_img_mask = img_mask
tensor_mask_cum_featvecs_paths = mask_cum_featvecs_paths
# the below given statements are used when this function
# is not wrapped by tf.function decorator:
#tensor_img_featvec = tf.constant(img_featvec)
#tensor_img_mask = tf.constant(img_mask)
#tensor_mask_cum_featvecs_paths = tf.constant(mask_cum_featvecs_paths)
compare_img_ds = get_mask_cum_featvecs_dataset(tensor_mask_cum_featvecs_paths)
get_img_euclidean_dists = partial(euclidean_dist, img_featvec=tensor_img_featvec)
print("Calculating Euclidean Distances......")
features_n_eucl_ds = compare_img_ds.map(lambda image_name, image, featvec, mask: (image_name, image, featvec, mask,
get_img_euclidean_dists(featvec)),
num_parallel_calls=AUTO)
print("Finding Maximum Euclidean Distance........")
num_of_loops = 2
eucl_val_ds = features_n_eucl_ds.map(lambda image_name, image, featvec, mask, eucl_val: eucl_val,
num_parallel_calls=AUTO)
def dataset_reduce_max(ds, i):
ds = ds.batch(5000)
ds = ds.map(lambda eucl_vals: tf.math.reduce_max(eucl_vals),
num_parallel_calls=AUTO)
i += 1
return ds, i
def loop_cond(ds, i):
return tf.less(i, num_of_loops)
eucl_val_ds, _ = tf.while_loop(loop_cond,
dataset_reduce_max,
[eucl_val_ds, tf.constant(0)])
max_eucl_dist = tf.constant(0, dtype=tf.float32)
#---------(I)---------#
for item in eucl_val_ds.take(1):
max_eucl_dist = item
ratio_eucl_ds = features_n_eucl_ds.map(
lambda image_name, image, featvec, mask, eucl_val: (image_name,
image,
featvec,
mask,
eucl_val/max_eucl_dist),
num_parallel_calls=AUTO)
return ratio_eucl_ds #----------(II)-----------#
没有内置函数可以在 tensorflow 数据集中的特定数据流中查找最大元素(这里,datastreams = image_names, image, featvecs, mask, eucl_dists)为了找到欧几里得距离的最大值,我创建了一个单独的 tf.dataset 包含欧几里得距离,我使用了数据集缩减策略。我创建了大小为 5000 的批次,并返回其中存在的最大元素。使用这种策略,我可以在 2 次迭代中有效地获得最大欧几里得距离。
问题:
当我使用 tf.function 装饰器时,整个函数将执行得非常快,然后卡在“return ratio_eucl_ds”(I)。如果我不使用 tf.function 装饰器,那么函数就会卡在 for-loop(II) 中。执行代码大约需要 12 分钟。当我在"max_eucl_dist"中随机放入任何值时,预处理函数就会无缝执行。因此,我想问题出在我试图提取"max_eucl_dist"值的方式上。