我们有存储在.tfrecord
文件中的数据,X
是我们的训练数据> 40x40
灰度图像和Y
:是标签。这些图像按顺序排序(顺序很重要)。我们想使用Tensorflows Estimator API输入这些图像,以使用GoogleML训练具有各种时间窗口大小和班次的神经网络模型(例如:LSTM)。
如何将要素的输入字符串整形为一定长度的序列,例如将1000
图像放入一个序列中,然后对这些序列执行加窗处理,例如获取50
图像的窗口,并移动窗口25
?
我们设法做到了这一点(下面的稀疏示例),而无需将第一个整形为1000个长度集,但是随后结果是窗口从一个集合的元素975到下一个集合的元素25跨越,我们这样做不想要。 我们需要重叠的窗口,这些窗口的范围从每组1000
图像的开始到结束,但不能跨越它们的边界。
import tensorflow as tf
# .tfrecord file consisting of data 'X' and labels 'Y'
dataset = tf.data.TFRecordDataset('.tfrecord file')
# define parse function for dataset.map function
def _parse_function(proto):
# define constants for parsing
image_size = 40
num_channels = 1
num_classes = 3
# define your tfrecord feature keys and
# reshape 1D arrays into 2D arrays (images)
keys_to_features = {'X': tf.FixedLenFeature([image_size, image_size, num_channels], tf.float32), # image height, image width, num_channels
'Y': tf.FixedLenFeature([], tf.int64)}
# Load one example
parsed_features = tf.parse_single_example(proto, keys_to_features)
# extract image and labels
image = parsed_features['X']
labels = tf.cast( parsed_features['Y'], tf.int32 )
labels = tf.one_hot( labels, depth=num_classes ) # one hot encoding
return image, labels
# reshape the data into parse format
dataset = dataset.map(_parse_function)
# define dataset parameters
window_size = 50
batch_size = 500
window_shift = int( window_size / 2 ) # 25
# implement sliding window
dataset = dataset.window(size=window_size, shift=window_shift, drop_remainder=True ).flat_map( lambda x: x.batch(window_size) )
# batch the data
dataset = dataset.batch(batch_size)
# create an iterator
# iterator = dataset.make_one_shot_iterator().get_next()
上面的iterator
将为X
数据返回形状张量(batch_size,window_size,image_height,image_width,通道数),在我们的情况下为(500, 50, 40, 40, 1)
和{{1} }作为Y
数组。
答案 0 :(得分:1)
我设法通过过滤掉跨越边界的窗户来做到这一点。拥有解析的功能后,对所有内容应用窗口,然后计算哪些窗口溢出并过滤掉它们:
ds = tf.data.TFRecordDataset( filename )
ds = ds.map( _parse_function )
# apply windowing
ds = ds.window( size=50, shift=25, drop_remainder=True ).flat_map( lambda x, y: tf.data.Dataset.zip( (x.batch(50), y.batch(50)) ) )
# enumerate dataset and filter every 40th window
ds = ds.apply( tf.data.experimental.enumerate_dataset(start=1) ).filter( lambda i, x: tf.not_equal( i % 40, 0) )
# get rid of enumerations
ds = ds.map( lambda i, x: x )
# batching, shuffling etc...
...
说明:每隔40个窗口就会过滤掉,因为如果您有1000个窗口组和25个窗口移位,则将有set_len / win_shift = 40
个窗口,而最后一个窗口(即第40个)将溢出到下一个窗口中。还要注意,枚举从1开始,因此从0 % x == 0
开始,不会取出第0个样本。
请注意,这比真正的解决方案更像是骇客。它与50%的重叠效果很好,但是以其他百分比计算要扔掉的索引会变得更加复杂(如果重叠> 50%,则下一个窗口会溢出一个以上的窗口,因此需要多个过滤器)。