簡體   English   中英

如何在tensorflow中實現圖像(2D數組)序列滑動窗口?

[英]How to implement an image(2D array) sequence sliding window in tensorflow?

上下文

我們有存儲在.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) 500,50,40,40,1 (500, 50, 40, 40, 1)Y作為(500, 3) 500,3 (500, 3)數組。

我設法通過過濾掉跨越邊界的窗口來做到這一點。 獲得解析后的功能后,對所有內容應用窗口,然后計算哪些窗口溢出並過濾掉它們:

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個樣本,因為0 % x == 0

請注意,這更像是一個黑客而不是一個真正的解決方案。 它與50%的重疊效果很好,但在其他百分比下,計算要丟棄的指數變得更加復雜(如果重疊> 50%,則多個窗口會溢出到下一個集合中,因此需要多個過濾器)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM