Antes mesmo de falarmos sobre novos recursos, vamos responder à pergunta óbvia. Sim, haverá uma segunda edição do Aprendizado profundo para R! Refletindo o que tem acontecido entretanto, a nova edição cobre um conjunto extenso de arquiteturas comprovadas; ao mesmo tempo, você descobrirá que os designs intermediários a avançados já presentes na primeira edição tornaram-se bastante mais intuitivos de implementar, graças aos novos aprimoramentos de baixo nível mencionados no resumo.
Mas não nos leve a mal – o escopo do livro permanece completamente inalterado. Ainda é a escolha perfeita para pessoas novas em aprendizado de máquina e aprendizado profundo. Começando com as ideias básicas, ele progride sistematicamente para tópicos intermediários e avançados, deixando você com uma compreensão conceitual e um conjunto de modelos de aplicativos úteis.
Agora, o que está acontecendo com Keras?
Estado do ecossistema
Comecemos com uma caracterização do ecossistema e algumas palavras sobre a sua história.
Neste submit, quando dizemos Kerasqueremos dizer R – em oposição a Python – Keras. Agora, isso se traduz imediatamente no pacote R keras
. Mas keras
sozinho não levaria você longe. Enquanto keras
fornece funcionalidade de alto nível – camadas de rede neural, otimizadores, gerenciamento de fluxo de trabalho e muito mais – a estrutura de dados básica operada, tensoresmora em tensorflow
. Em terceiro lugar, assim que você precisar realizar um pré-processamento menos trivial, ou não conseguir mais manter todo o conjunto de treinamento na memória devido ao seu tamanho, você vai querer dar uma olhada em tfdatasets
.
Então são esses três pacotes – tensorflow
, tfdatasets
e keras
– isso deve ser entendido por “Keras” no contexto atual. (O ecossistema R-Keras, por outro lado, é um pouco maior. Mas outros pacotes, como tfruns
ou cloudml
estão mais dissociados do núcleo.)
Combinando sua forte integração, os pacotes mencionados acima tendem a seguir um ciclo de lançamento comum, ele próprio dependente da biblioteca Python subjacente, TensorFlow. Para cada um tensorflow
, tfdatasets
e keras
a versão atual do CRAN é 2.7.0, refletindo a versão correspondente do Python. A sincronia de versionamento entre os dois Kerases, R e Python, parece indicar que seus destinos se desenvolveram de maneira semelhante. Nada poderia ser menos verdadeiro, e saber disso pode ser útil.
Em R, entre pacotes presentes desde o início tensorflow
e keras
as responsabilidades sempre foram distribuídas da forma como estão agora: tensorflow
fornecendo princípios básicos indispensáveis, mas muitas vezes permanecendo completamente transparentes para o usuário; keras
sendo o que você usa em seu código. Na verdade, é possível treinar um modelo Keras sem nunca usar conscientemente tensorflow
.
Do lado do Python, as coisas têm passado por mudanças significativas, onde, em certo sentido, o último desenvolvimento tem invertido o primeiro. No início, TensorFlow e Keras eram bibliotecas separadas, com o TensorFlow fornecendo um back-end – um entre vários – para Keras usar. Em algum momento, o código Keras foi incorporado à base de código do TensorFlow. Finalmente (a partir de hoje), após um longo período de ligeira confusão, Keras foi transferido novamente e começou a – novamente – crescer consideravelmente em recursos.
Foi exatamente esse rápido crescimento que criou, no lado R, a necessidade de extensa refatoração e aprimoramentos de baixo nível. (É claro que a nova funcionalidade voltada para o usuário também teve que ser implementada!)
Antes de chegarmos aos destaques prometidos, algumas palavras sobre como pensamos sobre Keras.
Pegue seu bolo e coma-o também: uma filosofia de (R) Keras
Se você já usou o Keras no passado, sabe o que ele sempre pretendeu ser: uma biblioteca de alto nível, facilitando (na medida em que tal coisa pode ser fácil) treinar redes neurais em R. Na verdade, não se trata apenas facilidade. Keras permite que os usuários escrevam códigos com aparência pure e idiomática. Isto, em alto grau, é conseguido permitindo a composição do objeto através do operador do tubo; é também uma consequência de seus abundantes wrappers, funções de conveniência e semântica funcional (sem estado).
No entanto, devido à forma como o TensorFlow e o Keras se desenvolveram no lado do Python – referindo-se às grandes mudanças arquitetônicas e semânticas entre as versões 1.xe 2.x, caracterizadas pela primeira vez de forma abrangente neste weblog aqui – tornou-se mais desafiador fornecer todas as funcionalidades disponíveis no lado Python para o usuário R. Além disso, manter a compatibilidade com diversas versões do Python TensorFlow – algo que R Keras sempre fez – torna-se cada vez mais desafiador quanto mais wrappers e funções convenientes você adiciona.
Portanto, é aqui que complementamos o acima “torne-o semelhante ao R e pure, sempre que possível” com “facilite a portabilidade do Python, quando necessário”. Com a nova funcionalidade de baixo nível, você não terá que esperar que os wrappers R façam uso de objetos definidos pelo Python. Em vez disso, os objetos Python podem ser subclassificados diretamente de R; e qualquer funcionalidade adicional que você gostaria de adicionar à subclasse é definida em uma sintaxe semelhante ao Python. O que isso significa, concretamente, é que traduzir o código Python para R se tornou muito mais fácil. Teremos um vislumbre disso no segundo de nossos três destaques.
Novidade no Keras 2.6/7: Três destaques
Entre os muitos novos recursos adicionados ao Keras 2.6 e 2.7, apresentamos rapidamente três dos mais importantes.
Camadas de pré-processamento ajudam significativamente a agilizar o fluxo de trabalho de treinamento, integrando manipulação e aumento de dados.
A capacidade de criar subclasses de objetos Python (já mencionada diversas vezes) é a nova magia de baixo nível disponível para o
keras
usuário e que fornece muitos aprimoramentos voltados para o usuário.Camadas de rede neural recorrente (RNN) ganham uma nova API em nível de célula.
Destes, os dois primeiros definitivamente merecem um tratamento mais profundo; postagens mais detalhadas virão.
Camadas de pré-processamento
Antes do advento dessas camadas dedicadas, o pré-processamento costumava ser feito como parte do tfdatasets
gasoduto. Você encadearia as operações conforme necessário; talvez, integrando transformações aleatórias para serem aplicadas durante o treinamento. Dependendo do que você queria alcançar, pode ter ocorrido um esforço de programação significativo.
Esta é uma área onde as novas capacidades podem ajudar. Existem camadas de pré-processamento para vários tipos de dados, permitindo a traditional “disputação de dados”, bem como aumento de dados e engenharia de recursos (como hash de dados categóricos ou vetorização de texto).
A menção à vetorização de texto leva a uma segunda vantagem. Ao contrário, digamos, de uma distorção aleatória, a vetorização não é algo que possa ser esquecido depois de concluída. Não queremos perder a informação unique, nomeadamente as palavras. O mesmo acontece, para dados numéricos, com a normalização. Precisamos manter as estatísticas resumidas. Isso significa que existem dois tipos de camadas de pré-processamento: as sem estado e as com estado. Os primeiros fazem parte do processo de formação; estes últimos são convocados com antecedência.
As camadas sem estado, por outro lado, podem aparecer em dois locais no fluxo de trabalho de treinamento: como parte do tfdatasets
pipeline ou como parte do modelo.
Esta é, esquematicamente, a aparência do primeiro.
library(tfdatasets)
dataset <- ... # outline dataset
dataset <- dataset %>%
dataset_map(operate(x, y) listing(preprocessing_layer(x), y))
Enquanto estiver aqui, a camada de pré-processamento é a primeira em um modelo maior:
enter <- layer_input(form = input_shape)
output <- enter %>%
preprocessing_layer() %>%
rest_of_the_model()
mannequin <- keras_model(enter, output)
Falaremos sobre qual caminho é preferível e quando, além de mostrar algumas camadas especializadas em uma postagem futura. Até então, sinta-se à vontade para consultar o – detalhado e rico em exemplos vinheta.
Subclassificando Python
Think about que você queira portar um modelo Python que make the most of a seguinte restrição:
class NonNegative(tf.keras.constraints.Constraint):
def __call__(self, w):
return w * tf.solid(tf.math.greater_equal(w, 0.), w.dtype)
Como podemos ter tal coisa em R? Anteriormente, existiam vários métodos para criar objetos baseados em Python, tanto baseados em R6 quanto em estilo funcional. O primeiro, exceto nos casos mais simples, pode exigir muito esforço e ser propenso a erros; o último, de estilo elegante, mas difícil de adaptar a requisitos mais avançados.
A nova maneira, %py_class%
agora permite traduzir o código acima assim:
NonNegative(keras$constraints$Constraint) %py_class% {
"__call__" <- operate(x) {
w * k_cast(w >= 0, k_floatx())
}
}
Usando %py_class%
subclassificamos diretamente o Pitão object tf.keras.constraints.Constraint
e substituir seu __call__
método.
Por que isso é tão poderoso? A primeira vantagem é visível no exemplo: traduzir código Python torna-se uma tarefa quase mecânica. Mas há mais: o método acima é independente do que tipo do objeto que você está subclassificando. Quer implementar uma nova camada? Um retorno de chamada? Uma perda? Um otimizador? O procedimento é sempre o mesmo. Não há necessidade de encontrar um objeto R6 predefinido no keras
base de código; um %py_class%
entrega todos eles.
Porém, há muito mais a dizer sobre esse assunto; na verdade, se você não querer usar %py_class%
diretamente, existem wrappers disponíveis para os casos de uso mais frequentes. Mais sobre isso em uma postagem dedicada. Até lá, consulte o vinheta para vários exemplos, açúcar sintático e detalhes de baixo nível.
API de célula RNN
Nosso terceiro ponto é pelo menos metade da atenção à documentação excelente do que o alerta para um novo recurso. A documentação em questão é uma nova vinheta em RNNs. A vinheta fornece uma visão geral útil de como os RNNs funcionam em Keras, abordando as questões usuais que tendem a surgir quando você não os usa há algum tempo: O que exatamente são estados versus saídas e quando uma camada retorna o quê? Como inicializo o estado de maneira dependente do aplicativo? Qual é a diferença entre RNNs com e sem estado?
Além disso, a vinheta aborda questões mais avançadas: Como passo dados aninhados para uma RNN? Como escrevo células personalizadas?
Na verdade, esta última questão nos leva ao novo recurso que gostaríamos de destacar: a nova API em nível de célula. Conceitualmente, com RNNs, há sempre duas coisas envolvidas: a lógica do que acontece em um único intervalo de tempo; e a segmentação do estado em intervalos de tempo. Os chamados “RNNs simples” preocupam-se apenas com o último aspecto (recursão); eles tendem a exibir o clássico problema dos gradientes de desaparecimento. Arquiteturas fechadas, como LSTM e GRU, foram especialmente projetadas para evitar esses problemas; ambos podem ser facilmente integrados em um modelo usando o respectivo layer_x()
construtores. E se você quiser, não um GRU, mas algo como uma GRU (usando algum novo método de ativação sofisticado, digamos)?
Com Keras 2.7, agora você pode criar uma célula RNN de passo único (usando o descrito acima %py_class%
API) e obter uma versão recursiva – uma camada completa – usando layer_rnn()
:
rnn <- layer_rnn(cell = cell)
Se você estiver interessado, confira o vinheta para um exemplo estendido.
Com isso encerramos nosso notícias de Keraspor hoje. Obrigado por ler e fique ligado para mais!
Foto de Hans-Jurgen Mager sobre Remover respingo