用于张量流管道的大图像切片
Large image slicing for tensorflow pipeline
我正在使用大型卫星 .JP2 图像进行图像分割。
图像形状:(10000, 10000, 13) 因为有 13 个波段(同一区域有 13 个不同波长的观测值)
uint32
我想构建最高效的 tensorflow 管道,但我没有太多经验。
我想轻松调整用于训练的波段数量(第一次训练使用 RGB,然后我会尝试添加更多波段以查看是否提高性能)
我想象了两条不同的管道:
我将我的 .JP2 转换 成一个 (10000 x 10000 x 13) numpy 数组。 然后管道被输入所需的切片(例如,如果我想要 RGB 图像,则为 128x128x3)
或者,我将我的大图像预处理到 13 个不同的文件夹(13 个波段)
然后输入管道使用所需的数据集构建
128 x 128 x (1-13) 输入图像
拍一张大图,随意切片,直接放到tensorflow pipeline中比较方便,因为我只需要一个10000x10000x13的numpy数组作为训练集。但是不知道是不是releavant/optimized/possible...
解决我的 pb 的最优化方法是什么?
(我有一个 11Gb 1080 GPU)
最有效的方法几乎总是迭代改进的产物。因此,作为一个坚实的开始,让我们考虑示例。出于演示目的,我使用了一个带有随机色块的玩具阵列,将其分成 13 个带并仅连接 3 个。为 batch_size
添加了第一个维度
init_image = np.random.randint(0,255,(1, 4, 4, 13))
bands = np.split(d, 13, axis=3)
image = np.concatenate((d_s[0], d_s[1], d_s[2]), axis=3)
首先,我们创建从数据集中提取单个大图像以从中提取补丁。
dataset = tf.data.Dataset.from_tensor_slices(image)
dataset = dataset.batch(1)
#This, if evaluated inside session, outputs array of shape (1, 4, 4, 3)
然后我们应用映射函数来提取补丁。这是通过 tf.image.extract_image_patches, parameters ksizes, strides and rates define geometric properties of a patch. You can find an excellent explanation 完成的。在这种情况下,我们将采用大小为 2x2 的补丁,彼此直接相邻。所以总共有4个补丁。 extract_image_patches
会将所有补丁放入最后一个维度,应用 o reshape
以获得形状为 2x2 的 3 个通道图像的 4 个补丁的所需输出。
def parse_func(image):
ksizes = [1, 2, 2, 1]
strides = [1, 2, 2, 1]
rates = [1, 1, 1, 1]
patches = tf.image.extract_image_patches(image, ksizes, strides, rates, 'SAME')
image_tensor = tf.reshape(patches, [-1, 2, 2, 3])
return image_tensor
然后我们将此函数应用于数据集,然后我们取消对输出进行批处理以对其进行洗牌,并从补丁中创建一个新批次。在这种情况下,批量大小和洗牌缓冲区大小等于补丁数。
dataset = dataset.map(pf)
dataset = dataset.apply(tf.data.experimental.unbatch())
dataset = dataset.shuffle(4).batch(4)
这将输出一批形状 (4, 2, 2, 3)
。如您所见,输出包含 4 个形状为 (2, 2, 3) 的补丁。如果不应用随机播放,将按从左上角到右下角的顺序排列。
另外,看看官方输入管道performance guide
我正在使用大型卫星 .JP2 图像进行图像分割。
图像形状:(10000, 10000, 13) 因为有 13 个波段(同一区域有 13 个不同波长的观测值)
uint32
我想构建最高效的 tensorflow 管道,但我没有太多经验。
我想轻松调整用于训练的波段数量(第一次训练使用 RGB,然后我会尝试添加更多波段以查看是否提高性能)
我想象了两条不同的管道:
我将我的 .JP2 转换 成一个 (10000 x 10000 x 13) numpy 数组。 然后管道被输入所需的切片(例如,如果我想要 RGB 图像,则为 128x128x3)
或者,我将我的大图像预处理到 13 个不同的文件夹(13 个波段) 然后输入管道使用所需的数据集构建 128 x 128 x (1-13) 输入图像
拍一张大图,随意切片,直接放到tensorflow pipeline中比较方便,因为我只需要一个10000x10000x13的numpy数组作为训练集。但是不知道是不是releavant/optimized/possible...
解决我的 pb 的最优化方法是什么? (我有一个 11Gb 1080 GPU)
最有效的方法几乎总是迭代改进的产物。因此,作为一个坚实的开始,让我们考虑示例。出于演示目的,我使用了一个带有随机色块的玩具阵列,将其分成 13 个带并仅连接 3 个。为 batch_size
init_image = np.random.randint(0,255,(1, 4, 4, 13))
bands = np.split(d, 13, axis=3)
image = np.concatenate((d_s[0], d_s[1], d_s[2]), axis=3)
首先,我们创建从数据集中提取单个大图像以从中提取补丁。
dataset = tf.data.Dataset.from_tensor_slices(image)
dataset = dataset.batch(1)
#This, if evaluated inside session, outputs array of shape (1, 4, 4, 3)
然后我们应用映射函数来提取补丁。这是通过 tf.image.extract_image_patches, parameters ksizes, strides and rates define geometric properties of a patch. You can find an excellent explanation extract_image_patches
会将所有补丁放入最后一个维度,应用 o reshape
以获得形状为 2x2 的 3 个通道图像的 4 个补丁的所需输出。
def parse_func(image):
ksizes = [1, 2, 2, 1]
strides = [1, 2, 2, 1]
rates = [1, 1, 1, 1]
patches = tf.image.extract_image_patches(image, ksizes, strides, rates, 'SAME')
image_tensor = tf.reshape(patches, [-1, 2, 2, 3])
return image_tensor
然后我们将此函数应用于数据集,然后我们取消对输出进行批处理以对其进行洗牌,并从补丁中创建一个新批次。在这种情况下,批量大小和洗牌缓冲区大小等于补丁数。
dataset = dataset.map(pf)
dataset = dataset.apply(tf.data.experimental.unbatch())
dataset = dataset.shuffle(4).batch(4)
这将输出一批形状 (4, 2, 2, 3)
。如您所见,输出包含 4 个形状为 (2, 2, 3) 的补丁。如果不应用随机播放,将按从左上角到右下角的顺序排列。
另外,看看官方输入管道performance guide