Esta página foi traduzida pela API Cloud Translation.
Switch to English

TF1 Hub format

Em seu lançamento em 2018, o TensorFlow Hub ofereceu um único tipo de ativo: o formato TF1 Hub para importação nos programas TensorFlow 1.

Esta página explica como usar o formato TF1 Hub no TF1 (ou o modo de compatibilidade TF1 do TF2) com a classe hub.Module e as APIs associadas. (A utilização típica é a construção de um tf.Graph , possivelmente dentro de um TF1 Estimator , através da combinação de um ou mais modelos em formato TF1 Hub tf.compat.layers ou tf.layers ).

Os usuários do TensorFlow 2 (fora do modo de compatibilidade com TF1) devem usar a nova API com hub.load() ou hub.KerasLayer . A nova API carrega o novo tipo de ativo TF2 SavedModel, mas também possui suporte limitado para carregar o formato TF1 Hub no TF2 .

Usando um modelo no formato TF1 Hub

Instanciando um modelo no formato TF1 Hub

Um modelo no formato TF1 Hub é importado para um programa TensorFlow criando um objeto hub.Module partir de uma sequência com seu URL ou caminho do sistema de arquivos, como:

 m = hub.Module("path/to/a/module_dir")
 

Isso adiciona as variáveis ​​do módulo ao gráfico atual do TensorFlow. A execução de seus inicializadores lerá seus valores pré-treinados do disco. Da mesma forma, tabelas e outros estados são adicionados ao gráfico.

Módulos de armazenamento em cache

Ao criar um módulo a partir de uma URL, o conteúdo do módulo é baixado e armazenado em cache no diretório temporário do sistema local. O local em que os módulos estão armazenados em cache pode ser substituído usando a variável de ambiente TFHUB_CACHE_DIR . Para detalhes, consulte Cache .

Aplicando um módulo

Uma vez instanciado, um módulo m pode ser chamado zero ou mais vezes, como uma função Python, das entradas e saídas do tensor:

 y = m(x)
 

Cada chamada adiciona operações ao gráfico atual do TensorFlow para calcular y de x . Se isso envolver variáveis ​​com pesos treinados, elas serão compartilhadas entre todos os aplicativos.

Os módulos podem definir várias assinaturas nomeadas para permitir a aplicação de mais de uma maneira (semelhante à maneira como os objetos Python têm métodos ). A documentação de um módulo deve descrever as assinaturas disponíveis. A chamada acima aplica a assinatura denominada "default" . Qualquer assinatura pode ser selecionada passando seu nome para o argumento opcional signature= .

Se uma assinatura tiver várias entradas, elas deverão ser passadas como um ditado, com as chaves definidas pela assinatura. Da mesma forma, se uma assinatura tiver várias saídas, elas poderão ser recuperadas como um as_dict=True passando as_dict=True , sob as chaves definidas pela assinatura (a chave "default" é para a saída única retornada se as_dict=False ). Portanto, a forma mais geral de aplicar um módulo é semelhante a:

 outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]
 

Um chamador deve fornecer todas as entradas definidas por uma assinatura, mas não há requisito para usar todas as saídas de um módulo. O TensorFlow executará apenas as partes do módulo que acabam como dependências de um destino em tf.Session.run() . De fato, os editores de módulos podem optar por fornecer várias saídas para usos avançados (como ativações de camadas intermediárias) junto com as saídas principais. Os consumidores do módulo devem lidar com saídas adicionais normalmente.

Experimentando módulos alternativos

Sempre que houver vários módulos para a mesma tarefa, o TensorFlow Hub incentiva a equipá-los com assinaturas (interfaces) compatíveis, de modo que experimentar diferentes seja tão fácil quanto variar a alça do módulo como um hiperparâmetro com valor de string.

Para esse fim, mantemos uma coleção de assinaturas comuns recomendadas para tarefas populares.

Criando um novo módulo

Nota de compatibilidade

O formato do TF1 Hub é voltado para o TensorFlow 1. Ele é apenas parcialmente suportado pelo TF Hub no TensorFlow 2. Considere a publicação no novo formato TF2 SavedModel .

O formato do hub TF1 é semelhante ao formato SavedModel do TensorFlow 1 em um nível sintático (mesmos nomes de arquivo e mensagens de protocolo), mas semanticamente diferente para permitir a reutilização, composição e treinamento do módulo (por exemplo, armazenamento diferente de inicializadores de recursos, marcação diferente) convenções para parágrafos). A maneira mais fácil de diferenciá-los no disco é a presença ou ausência do arquivo tfhub_module.pb .

Abordagem geral

Para definir um novo módulo, um editor chama hub.create_module_spec() com a função module_fn . Esta função constrói um gráfico representando a estrutura interna do módulo, usando tf.placeholder() para entradas a serem fornecidas pelo chamador. Em seguida, define assinaturas chamando hub.add_signature(name, inputs, outputs) uma ou mais vezes.

Por exemplo:

 def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)
 

O resultado de hub.create_module_spec() pode ser usado, em vez de um caminho, para instanciar um objeto de módulo em um gráfico TensorFlow específico. Nesse caso, não há um ponto de verificação e a instância do módulo usará os inicializadores de variáveis.

Qualquer instância do módulo pode ser serializada em disco através do método de export(path, session) . A exportação de um módulo serializa sua definição juntamente com o estado atual de suas variáveis ​​na session para o caminho passado. Isso pode ser usado ao exportar um módulo pela primeira vez, bem como ao exportar um módulo ajustado.

Para compatibilidade com os estimadores de TensorFlow, o hub.LatestModuleExporter exporta módulos do ponto de verificação mais recente, assim como tf.estimator.LatestExporter exporta o modelo inteiro do ponto de verificação mais recente.

Os editores de módulos devem implementar uma assinatura comum sempre que possível, para que os consumidores possam trocar facilmente módulos e encontrar a melhor para o seu problema.

Exemplo real

Dê uma olhada no nosso exportador de módulos de incorporação de texto para obter um exemplo real de como criar um módulo a partir de um formato comum de incorporação de texto.

Afinação

O treinamento das variáveis ​​de um módulo importado junto com as do modelo em torno dele é chamado de ajuste fino . O ajuste fino pode resultar em melhor qualidade, mas adiciona novas complicações. Aconselhamos os consumidores a analisar o ajuste fino somente depois de explorar ajustes de qualidade mais simples e somente se o editor do módulo o recomendar.

Para Consumidores

Para ativar o ajuste fino, hub.Module(..., trainable=True) o módulo com hub.Module(..., trainable=True) para tornar suas variáveis ​​treináveis ​​e importe REGULARIZATION_LOSSES do TensorFlow. Se o módulo tiver várias variantes gráficas, escolha a apropriada para o treinamento. Normalmente, é o que tem tags {"train"} .

Escolha um regime de treinamento que não estrague os pesos pré-treinados, por exemplo, uma taxa de aprendizado mais baixa do que para o treinamento do zero.

Para editores

Para facilitar o ajuste fino para os consumidores, lembre-se do seguinte:

  • O ajuste fino precisa de regularização. Seu módulo é exportado com a coleção REGULARIZATION_LOSSES , que é a escolha de tf.layers.dense(..., kernel_regularizer=...) etc. para o que o consumidor obtém de tf.losses.get_regularization_losses() . Prefira esta maneira de definir as perdas de regularização L1 / L2.

  • No modelo editor, evitar definir L1 / L2 regularização através dos l1_ e l2_regularization_strength parâmetros de tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer , e outros optimizadores proximais. Eles não são exportados juntamente com o módulo, e definir pontos fortes de regularização globalmente pode não ser apropriado para o consumidor. Exceto pela regularização L1 nos modelos amplo (isto é, linear esparso) ou amplo e profundo, deve ser possível usar as perdas individuais de regularização.

  • Se você usar desistência, normalização em lote ou técnicas de treinamento semelhantes, configure seus hiperparâmetros para valores que façam sentido em muitos usos esperados. A taxa de abandono pode ter que ser ajustada à propensão do problema alvo à super adaptação. Na normalização de lotes, o momento (também conhecido como coeficiente de decaimento) deve ser pequeno o suficiente para permitir o ajuste fino com conjuntos de dados pequenos e / ou lotes grandes. Para consumidores avançados, considere adicionar uma assinatura que exponha o controle sobre os hiperparâmetros críticos.