Qual é o benefício de dividir o arquivo tfrecord em shards?


17

Estou trabalhando no reconhecimento de fala com o Tensorflow e planejo treinar o LSTM NN com um conjunto de dados massivo de ondas. Devido aos ganhos de desempenho, pretendo usar os tfrecords. Existem vários exemplos na internet (Inception for ex.) Em que os arquivos tfrecords são divididos em shards. Minha pergunta é: qual é o benefício de ter arquivos tfrecords em shards? Existe algum ganho adicional de desempenho dessa divisão?

Respostas:


11

Ao pesquisar os benefícios da divisão em vários arquivos, a única resposta razoável veio de um dos membros do Google.

Eles disseram que os ganhos de desempenho são insignificantes, mas concordo que a divisão de arquivos pode ajudar, especialmente se você deseja transferir o conjunto de dados para outro local.

Lembre-se de que agora não é necessário embaralhar antes de salvar, porque (atualmente) o método recomendado para ler os usos do TFRecords tf.data.TFRecordDatasetque implementa o .shuffle()método muito útil .


2
.shuffle()O método não é uma solução ideal se você tiver um grande arquivo tfrecord. A saída aleatória está um pouco relacionada à ordem original se você não usar um tamanho de buffer grande. Acho que é necessário pré-embaralhar os dados antes de salvar em tfrecord ou dividir em shards quando você tiver um grande conjunto de dados.
Bruce Chou

7

Para aqueles que ainda se perguntam: é para que você possa embaralhar seus dados. Com seus TFrecords em um arquivo, você não pode embaralhar o pedido. Isso geralmente é necessário com o SGD.

No entanto, com os shards, você pode embaralhar a ordem dos shards, o que permite aproximar o embaralhamento dos dados como se você tivesse acesso aos registros TFR individuais. Isso é claramente melhor que nada, e claramente quanto mais fragmentos você tiver, melhor será essa aproximação.

A alternativa é pré-embaralhar seus dados através da duplicação ou não usar os registros TFR.


4

A divisão de arquivos TFRecord em shards ajuda a embaralhar grandes conjuntos de dados que não cabem na memória.

Imagine que você tem milhões de exemplos de treinamento salvos no disco e deseja executá-los repetidamente em um processo de treinamento. Além disso, suponha que, para cada repetição dos dados de treinamento (ou seja, cada época), você queira carregar os dados em uma ordem completamente aleatória.

Uma abordagem é ter um arquivo por exemplo de treinamento e gerar uma lista de todos os nomes de arquivos. Em seguida, no início de cada época, você embaralha a lista de nomes de arquivos e carrega os arquivos individuais. O problema com essa abordagem é que você está carregando milhões de arquivos de locais aleatórios no seu disco. Isso pode ser lento, especialmente em uma unidade de disco rígido. Mesmo uma matriz RAID 0 não ajudará com velocidade se você estiver carregando milhões de arquivos pequenos de locais aleatórios. O problema fica ainda pior se você estiver acessando os arquivos por uma conexão de rede.

Outra abordagem é ler os exemplos de treinamento em sequência a partir de um arquivo TFRecord grande e embaralhar os exemplos na memória usando um buffer aleatório. No entanto, o buffer aleatório normalmente não pode ser maior que a memória DDR disponível para sua CPU. E se o buffer de reprodução aleatória for significativamente menor que o seu conjunto de dados, ele poderá não reproduzir adequadamente os dados. Os dados podem ser embaralhados "localmente", mas não embaralhados "globalmente". Ou seja, os exemplos do início do conjunto de dados não podem ser embaralhados com os exemplos do final do conjunto de dados.

Uma boa solução é usar uma combinação equilibrada das duas abordagens acima, dividindo seu conjunto de dados em vários arquivos TFRecord (chamados shards). Durante cada época, você pode embaralhar os nomes dos arquivos de fragmentos para obter a reprodução aleatória global e usar um buffer de reprodução aleatória para obter a reprodução local. Um bom equilíbrio tornará os shards grandes o suficiente para evitar problemas de velocidade do disco, mas os manterá pequenos o suficiente para permitir uma embaralhamento adequado por um buffer de embaralhamento.

Aqui estão as etapas exatas:

  1. Coloque todos os exemplos de treinamento aleatoriamente em vários arquivos TFRecord (shards).
  2. No início de cada época, embaralhe a lista de nomes de arquivos do shard.
  3. Leia exemplos de treinamento dos fragmentos e passe-os por um buffer aleatório. Normalmente, o buffer de reprodução aleatória deve ser maior que o tamanho do fragmento para garantir uma boa reprodução entre fragmentos.
  4. Passe os exemplos embaralhados para o seu processo de treinamento.

3

A divisão de um arquivo TFRecords em vários shards possui essencialmente 3 vantagens:

  1. Mais fácil de embaralhar . Como outros salientaram, facilita a reprodução aleatória dos dados em um nível aproximado (antes de usar um buffer aleatório).
  2. Mais rápido para baixar . Se os arquivos estiverem espalhados por vários servidores, o download de vários arquivos de diferentes servidores em paralelo otimizará o uso da largura de banda (em vez de baixar um arquivo de um único servidor). Isso pode melhorar significativamente o desempenho em comparação com o download dos dados de um único servidor.
  3. Mais simples de manipular . É mais fácil lidar com 10.000 arquivos de 100 MB cada, em vez de com um único arquivo de 1 TB. Arquivos enormes podem ser difíceis de lidar: em particular, as transferências têm muito mais probabilidade de falhar. Também é mais difícil manipular subconjuntos de dados em um único arquivo.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.