TFRecord e Earth Engine

TFRecord é um formato binário para codificar com eficiência sequências longas de protótipos tf.Example. Os arquivos TFRecord são facilmente carregados pelo TensorFlow usando o pacote tf.data, conforme descrito aqui e aqui. Nesta página, descrevemos como o Earth Engine converte entre o formato ee.FeatureCollection ou ee.Image e o TFRecord.

Como exportar dados para o TFRecord

É possível exportar tabelas (ee.FeatureCollection) ou imagens (ee.Image) para arquivos TFRecord no Google Drive ou no Cloud Storage. A configuração da exportação depende do que você está exportando, conforme descrito abaixo. Todos os números exportados do Earth Engine para o TFRecord são convertidos para o tipo flutuante.

Exportar tabelas

Ao exportar um ee.FeatureCollection para um arquivo TFRecord, há uma correspondência de 1:1 entre cada ee.Feature na tabela e cada tf.train.Example (ou seja, cada registro) no arquivo TFRecord. Cada propriedade do ee.Feature é codificada como um tf.train.Feature com uma lista de números de ponto flutuante correspondentes ao número ou ee.Array armazenado na propriedade. Se você exportar uma tabela com matrizes nas propriedades, precisará informar ao TensorFlow o formato da matriz quando ela for lida. Uma tabela exportada para um arquivo TFRecord sempre será compactada com o tipo de compactação GZIP. Você sempre recebe exatamente um arquivo TFRecord para cada exportação.

O exemplo a seguir demonstra a análise de dados de uma tabela exportada de propriedades escalares ('B2',...,'B7', 'landcover'). A dimensão das listas de pontos flutuantes é [1], e o tipo é tf.float32:

Python

dataset = tf.data.TFRecordDataset(exportedFilePath)

featuresDict = {
  'B2': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'B3': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'B4': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'B5': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'B6': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'B7': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32),
  'landcover': tf.io.FixedLenFeature(shape=[1], dtype=tf.float32)
}

parsedDataset = dataset.map(lambda example: tf.io.parse_single_example(example, featuresDict))
        

Este exemplo ilustra a leitura de atributos escalares (ou seja, shape=[1]). Se você estiver exportando matrizes 2D ou 3D (por exemplo, patches de imagem), especifique a forma dos patches no momento da análise, por exemplo, shape=[16, 16] para um patch de pixel de 16 x 16.

Como exportar imagens

Quando você exporta uma imagem, os dados são ordenados como canais, altura, largura (CHW). A exportação pode ser dividida em vários arquivos TFRecord, cada um contendo um ou mais patches de tamanho patchSize, que é especificado pelo usuário na exportação. O tamanho dos arquivos em bytes é especificado pelo usuário no parâmetro maxFileSize. Há uma correspondência de 1:1 entre cada patch e cada tf.train.Example no arquivo TFRecord resultante. Cada banda da imagem é armazenada como um tf.train.Feature separado em cada tf.train.Example, em que o comprimento da lista de pontos flutuantes armazenada em cada atributo é a largura * altura do patch. As listas simplificadas podem ser divididas em vários pixels individuais, como mostrado neste exemplo. Ou o formato do patch exportado pode ser recuperado como neste exemplo.

Para ajudar a reduzir os efeitos de borda, os patches exportados podem se sobrepor. Especificamente, é possível especificar um kernelSize que vai resultar em blocos de tamanho:

[patchSize[0] + kernelSize[0], patchSize[1] + kernelSize[1]]
    

Cada bloco se sobrepõe aos blocos adjacentes em [kernelSize[0]/2, kernelSize[1]/2]. Como resultado, um kernel de tamanho kernelSize centralizado em um pixel de borda de um patch de tamanho patchSize contém dados totalmente válidos. A disposição espacial dos patches no espaço é ilustrada pela Figura 1, em que a dimensão de padding corresponde à parte do kernel que se sobrepõe à imagem adjacente:

Diagrama de imagem do TFRecord
Figura 1. Como os patches de imagem são exportados. A dimensão de padding é kernelSize/2.

formatOptions

Os parâmetros patchSize, maxFileSize e kernelSize são transmitidos para a chamada ee.Export (JavaScript) ou ee.batch.Export (Python) por um dicionário formatOptions, em que as chaves são os nomes dos parâmetros adicionais transmitidos para Export. Os possíveis formatOptions para uma imagem exportada para o formato TFRecord são:

PropriedadeDescriçãoTipo
patchDimensions Dimensões lado a lado sobre a área de exportação, cobrindo cada pixel na caixa delimitadora exatamente uma vez (exceto quando as dimensões do patch não dividem uniformemente a caixa delimitadora, caso em que os blocos de borda ao longo das maiores bordas x/y serão descartados). As dimensões precisam ser maiores que 0. Array<int>[2].
kernelSize Se especificado, os blocos serão armazenados em buffer pelas dimensões de margem de forma positiva e negativa, resultando em sobreposição entre patches vizinhos. Se especificado, duas dimensões precisam ser fornecidas (X e Y, respectivamente). Array<int>[2]. Padrão: [1, 1]
compressed Se for verdadeiro, compacta os arquivos .tfrecord com gzip e anexa o sufixo ".gz" Booleano. Padrão: true
maxFileSize Tamanho máximo, em bytes, de um .tfrecord exportado (antes da compactação). Um tamanho de arquivo menor resultará em maior fragmentação (e, portanto, mais arquivos de saída). Int. Padrão: 1 GiB
defaultValue O valor definido em cada banda de um pixel que está parcial ou completamente mascarado e o valor definido em cada valor em um recurso 3D de saída feito de uma banda de matriz em que o comprimento da matriz no pixel de origem era menor que a profundidade do valor do recurso (ou seja, o valor no índice 3 de um pixel de matriz de comprimento 2 em uma banda de matriz com uma profundidade de recurso correspondente de 3). A parte fracionária é descartada para bandas do tipo inteiro e fixada no intervalo do tipo de banda. O padrão é 0. Int. Padrão: 0
tensorDepths Mapeamento dos nomes das bandas da matriz de entrada para a profundidade dos tensores 3D que elas criam. As matrizes serão truncadas ou preenchidas com valores padrão para se ajustarem ao formato especificado. Para cada banda de matriz, é preciso ter uma entrada correspondente. Array<int>[]. Padrão: []
sequenceData Se for verdadeiro, cada pixel será gerado como um SequenceExample que mapeia bandas escalares para o contexto e bandas de matriz para as sequências do exemplo. Os SequenceExamples são gerados na ordem de linha principal de pixels em cada patch e, em seguida, na ordem de linha principal de patches de área na sequência de arquivos. Booleano. Padrão: false
collapseBands Se for verdadeiro, todas as bandas serão combinadas em um único tensor 3D, assumindo o nome da primeira banda na imagem. Todas as bandas são promovidas para bytes, int64s e, em seguida, flutuantes nessa ordem, dependendo do tipo mais distante nessa sequência em todas as bandas. As bandas de matriz são permitidas desde que tensor_depths seja especificado. Booleano. Padrão: false
maskedThreshold Proporção máxima permitida de pixels mascarados em um patch. Os patches que excederem essa permissão serão descartados em vez de gravados em arquivos. Se esse campo for definido como qualquer valor diferente de 1, o arquivo secundário JSON não será produzido. O padrão é 1. Ponto flutuante. Padrão: 1

O arquivo "mixer" do TFRecord

Ao exportar para o TFRecord, o Earth Engine vai gerar um arquivo secundário com seus arquivos TFRecord chamado "mixer". Esse é um arquivo JSON simples usado para definir a disposição espacial dos patches (ou seja, o georreferenciamento). Esse arquivo é necessário para fazer upload das previsões feitas nas imagens, conforme descrito na próxima seção.

Como exportar séries temporais

As exportações de imagens para Examples e SequenceExamples são compatíveis. Ao exportar para Examples, a região de exportação é cortada em patches, que são exportados em ordem de linha principal para um número de arquivos .tfrecord, com cada banda como um recurso próprio (a menos que você especifique collapseBands). Ao exportar para SequenceExamples, um SequenceExample por pixel será exportado, com esses SequenceExamples em ordem de linha principal em um patch e, em seguida, em ordem de linha principal de patches na região de exportação original (se você não tiver certeza, sempre presuma que as coisas estarão em ordem de linha principal de alguma forma). Observação: todas as bandas escalares de uma imagem serão empacotadas no contexto de um SequenceExample, enquanto as bandas de matriz se tornarão os dados reais da sequência.

Bandas de matriz

As bandas de matriz podem ser exportadas quando uma imagem é exportada para o formato TFRecord. A exportação de bandas de matrizes permite preencher as "FeatureLists" de SequenceExamples e criar tensores 3D ao exportar para Examples regulares. Para informações sobre como os comprimentos/profundidades das bandas de matriz são gerenciados, consulte collapseBands e/ou tensorDepths na tabela acima. Observação: o uso de collapseBands e a exportação para SequenceExamples (definindo o parâmetro sequenceData) vão resultar na redução de todas as bandas para uma única série temporal por pixel.

Como fazer upload de TFRecords para o Earth Engine

É possível fazer upload de tabelas (somente linha de comando) e imagens para o Earth Engine como arquivos TFRecord. Para tabelas, a relação de 1:1 descrita anteriormente se aplica na direção inversa (ou seja, tf.train.Example -> ee.Feature).

Upload de imagens

Se você gerar previsões em imagens exportadas, forneça o mixer ao fazer upload das previsões (como arquivos TFRecord) para receber imagens georreferenciadas. A parte sobreposta dos patches (dimensão de preenchimento na Figura 1) será descartada para resultar em cobertura contígua da região exportada. As previsões precisam ser organizadas como uma sequência tf.train.Example com o mesmo número e ordem dos exemplos de imagem exportados originalmente (mesmo entre um número arbitrário de arquivos).