Novas fontes de dados e recursos spark_apply(), melhores interfaces para extensões sparklyr e muito mais!


Sparklyr 1.7 já está disponível em CRAN!

Para instalar sparklyr 1.7 do CRAN, execute

Nesta postagem do weblog, desejamos apresentar os seguintes destaques do sparklyr Versão 1.7:

Fontes de dados binários e de imagem

Como um mecanismo de análise unificado para processamento de dados em larga escala, Apache Faísca
é conhecida por sua capacidade de enfrentar desafios associados ao quantity, à velocidade e, por último, mas não menos importante, à variedade de huge information. Portanto, não é surpreendente ver que – em resposta aos recentes avanços nas estruturas de aprendizagem profunda – o Apache Spark introduziu suporte integrado para
fontes de dados de imagem
e fontes de dados binários (nas versões 2.4 e 3.0, respectivamente). As interfaces R correspondentes para ambas as fontes de dados, ou seja,
spark_read_image() e
spark_read_binary()foram enviados recentemente como parte de sparklyr 1.7.

A utilidade das funcionalidades de fonte de dados, como spark_read_image() talvez seja melhor ilustrado por uma rápida demonstração abaixo, onde spark_read_image()por meio do Apache Spark padrão
ImageSchemaajuda a conectar entradas de imagens brutas a um extrator de recursos sofisticado e um classificador, formando um poderoso aplicativo Spark para classificações de imagens.

A demonstração

Novas fontes de dados e recursos spark_apply(), melhores interfaces para extensões sparklyr e muito mais!

Foto de Daniel Tuttle sobre
Remover respingo

Nesta demonstração, construiremos um pipeline Spark ML escalável capaz de classificar imagens de cães e gatos com precisão e eficiência, usando spark_read_image() e uma rede neural convolucional pré-treinada com codinome Inception (Szegedy et al. (2015)).

O primeiro passo para construir uma demonstração com máxima portabilidade e repetibilidade é criar um
extensão brilhante que realiza o seguinte:

Uma implementação de referência de tal sparklyr extensão pode ser encontrada em
aqui.

O segundo passo, claro, é fazer uso dos recursos mencionados acima. sparklyr extensão para realizar alguma engenharia de recursos. Veremos recursos de alto nível sendo extraídos de forma inteligente de cada imagem de gato/cachorro com base no que o pré-construído InceptionA rede neural convolucional -V3 já aprendeu classificando uma coleção muito mais ampla de imagens:

library(sparklyr)
library(sparklyr.deeperer)

# NOTE: the proper spark_home path to make use of is determined by the configuration of the
# Spark cluster you might be working with.
spark_home <- "/usr/lib/spark"
sc <- spark_connect(grasp = "yarn", spark_home = spark_home)

data_dir <- copy_images_to_hdfs()

# extract options from train- and test-data
image_data <- checklist()
for (x in c("practice", "take a look at")) {
  # import
  image_data((x)) <- c("canine", "cats") %>%
    lapply(
      operate(label) {
        numeric_label <- ifelse(an identical(label, "canine"), 1L, 0L)
        spark_read_image(
          sc, dir = file.path(data_dir, x, label, fsep = "/")
        ) %>%
          dplyr::mutate(label = numeric_label)
      }
    ) %>%
      do.name(sdf_bind_rows, .)

  dl_featurizer <- invoke_new(
    sc,
    "com.databricks.sparkdl.DeepImageFeaturizer",
    random_string("dl_featurizer") # uid
  ) %>%
    invoke("setModelName", "InceptionV3") %>%
    invoke("setInputCol", "picture") %>%
    invoke("setOutputCol", "options")
  image_data((x)) <-
    dl_featurizer %>%
    invoke("rework", spark_dataframe(image_data((x)))) %>%
    sdf_register()
}

Terceiro passo: munidos de recursos que resumem bem o conteúdo de cada imagem, podemos construir um pipeline Spark ML que reconhece cães e gatos usando apenas regressão logística

label_col <- "label"
prediction_col <- "prediction"
pipeline <- ml_pipeline(sc) %>%
  ml_logistic_regression(
    features_col = "options",
    label_col = label_col,
    prediction_col = prediction_col
  )
mannequin <- pipeline %>% ml_fit(image_data$practice)

Finalmente, podemos avaliar a precisão deste modelo nas imagens de teste:

predictions <- mannequin %>%
  ml_transform(image_data$take a look at) %>%
  dplyr::compute()

cat("Predictions vs. labels:n")
predictions %>%
  dplyr::choose(!!label_col, !!prediction_col) %>%
  print(n = sdf_nrow(predictions))

cat("nAccuracy of predictions:n")
predictions %>%
  ml_multiclass_classification_evaluator(
    label_col = label_col,
    prediction_col = prediction_col,
    metric_name = "accuracy"
  ) %>%
    print()
## Predictions vs. labels:
## # Supply: spark> (?? x 2)
##    label prediction
##          
##  1     1          1
##  2     1          1
##  3     1          1
##  4     1          1
##  5     1          1
##  6     1          1
##  7     1          1
##  8     1          1
##  9     1          1
## 10     1          1
## 11     0          0
## 12     0          0
## 13     0          0
## 14     0          0
## 15     0          0
## 16     0          0
## 17     0          0
## 18     0          0
## 19     0          0
## 20     0          0
##
## Accuracy of predictions:
## (1) 1

Novo spark_apply() capacidades

Otimizações e serializadores personalizados

Muitos sparklyr usuários que tentaram executar
spark_apply() ou
doSpark para paralelizar cálculos R entre os trabalhadores do Spark provavelmente encontraram alguns desafios decorrentes da serialização de fechamentos R. Em alguns cenários, o tamanho serializado do encerramento R pode tornar-se demasiado grande, muitas vezes devido ao tamanho do ambiente R envolvente exigido pelo encerramento. Em outros cenários, a serialização em si pode demorar muito, compensando parcialmente o ganho de desempenho da paralelização. Recentemente, várias otimizações foram feitas sparklyr para enfrentar esses desafios. Uma das otimizações foi aproveitar bem o
variável de transmissão
construa no Apache Spark para reduzir a sobrecarga de distribuição de estados de tarefas compartilhadas e imutáveis ​​entre todos os trabalhadores do Spark. Em sparklyr 1.7, também há suporte para customização spark_apply() serializadores, que oferecem controle mais refinado sobre a compensação entre velocidade e nível de compactação dos algoritmos de serialização. Por exemplo, pode-se especificar

choices(sparklyr.spark_apply.serializer = "qs")

,

que aplicará as opções padrão de qs::qserialize() para atingir um alto nível de compressão, ou

choices(sparklyr.spark_apply.serializer = operate(x) qs::qserialize(x, preset = "quick"))
choices(sparklyr.spark_apply.deserializer = operate(x) qs::qdeserialize(x))

,

que terá como objetivo uma velocidade de serialização mais rápida com menos compactação.

Inferindo dependências automaticamente

Em sparklyr 1,7, spark_apply() também fornece o experimento
auto_deps = TRUE opção. Com auto_deps habilitado, spark_apply() examinará o fechamento R que está sendo aplicado, inferirá a lista de pacotes R necessários e copiará apenas os pacotes R necessários e suas dependências transitivas para os trabalhadores do Spark. Em muitos cenários, o auto_deps = TRUE opção será uma alternativa significativamente melhor em comparação com o padrão packages = TRUE
comportamento, que é enviar tudo dentro .libPaths() para nós de trabalho do Spark ou o avançado packages = opção, que exige que os usuários forneçam a lista de pacotes R necessários ou criem manualmente um
spark_apply() pacote.

Melhor integração com extensões sparklyr

Foi feito um esforço substancial sparklyr 1.7 para facilitar a vida de sparklyr
autores de extensão. A experiência sugere duas áreas onde qualquer sparklyr extensão pode seguir um caminho friccional e não direto, integrando-se com
sparklyr são os seguintes:

Iremos detalhar os progressos recentes em ambas as áreas nas subseções abaixo.

Personalizando o dbplyr Ambiente de tradução SQL

sparklyr extensões agora podem ser personalizadas sparklyrde dbplyr Traduções SQL através do
spark_dependency()

especificação retornada de spark_dependencies() retornos de chamada. Este tipo de flexibilidade torna-se útil, por exemplo, em cenários onde um
sparklyr extensão precisa inserir conversões de tipo para entradas em UDFs Spark personalizados. Podemos encontrar um exemplo concreto disso em
sparklyr.sedonaum sparklyr extensão para facilitar análises geoespaciais usando
Apache Sedona. UDFs geoespaciais suportados pelo Apache Sedona, como ST_Point() e ST_PolygonFromEnvelope() exigir que todas as entradas sejam
DECIMAL(24, 20) quantidades em vez de DOUBLES. Sem qualquer personalização para
sparklyrde dbplyr Variante SQL, a única maneira de um dplyr
consulta envolvendo ST_Point() para realmente trabalhar em sparklyr seria implementar explicitamente qualquer conversão de tipo necessária para a consulta usando dplyr::sql()por exemplo,

my_geospatial_sdf <- my_geospatial_sdf %>%
  dplyr::mutate(
    x = dplyr::sql("CAST(`x` AS DECIMAL(24, 20))"),
    y = dplyr::sql("CAST(`y` AS DECIMAL(24, 20))")
  ) %>%
  dplyr::mutate(pt = ST_Point(x, y))

.

Isto seria, até certo ponto, antitético dplyrO objetivo de liberar os usuários do R de soletrar laboriosamente consultas SQL. Considerando que ao personalizar sparklyrde dplyr Traduções SQL (conforme implementado em
aqui
e
aqui
), sparklyr.sedona permite que os usuários simplesmente escrevam

my_geospatial_sdf <- my_geospatial_sdf %>% dplyr::mutate(pt = ST_Point(x, y))

em vez disso, e as conversões de tipo Spark SQL necessárias são geradas automaticamente.

Interface aprimorada para invocar funções Java/Scala

Em sparklyr 1.7, a interface R para invocações Java/Scala teve uma série de melhorias.

Com versões anteriores do sparklyrmuitos sparklyr os autores da extensão teriam problemas ao tentar invocar funções Java/Scala aceitando um
Array(T) como um de seus parâmetros, onde T qualquer tipo é vinculado mais específico que java.lang.Object / AnyRef. Isso ocorreu porque qualquer array de objetos passados sparklyrA interface de invocação Java/Scala será interpretada simplesmente como uma matriz de java.lang.Objects na ausência de informações adicionais de tipo. Por esta razão, uma função auxiliar
jarray() foi implementado como parte sparklyr 1.7 como forma de superar o problema acima mencionado. Por exemplo, executar

sc <- spark_connect(...)

arr <- jarray(
  sc,
  seq(5) %>% lapply(operate(x) invoke_new(sc, "MyClass", x)),
  element_type = "MyClass"
)

atribuirá a arr um referência para um Array(MyClass) de comprimento 5, em vez de um Array(AnyRef). Posteriormente, arr torna-se adequado para ser passado como parâmetro para funções que aceitam apenas Array(MyClass)s como entradas. Anteriormente, algumas possíveis soluções alternativas para isso sparklyr limitação incluía alterar assinaturas de função para aceitar Array(AnyRef)é em vez de Array(MyClass)s, ou implementando uma versão “embrulhada” de cada função aceitando Array(AnyRef)
entradas e convertendo-as em Array(MyClass) antes da invocação actual. Nenhuma dessas soluções alternativas foi uma solução splendid para o problema.

Outro obstáculo semelhante que foi abordado em sparklyr 1.7 também envolve parâmetros de função que devem ser números de ponto flutuante de precisão simples ou matrizes de números de ponto flutuante de precisão simples. Para esses cenários,
jfloat() e
jfloat_array()

são as funções auxiliares que permitem que quantidades numéricas em R sejam passadas para
sparklyrinterface de invocação Java/Scala como parâmetros com os tipos desejados.

Além disso, embora versões anteriores de sparklyr falha ao serializar parâmetros com NaN valores corretamente, sparklyr 1,7 conservas NaNs conforme esperado em sua interface de invocação Java/Scala.

Outras notícias emocionantes

Existem vários outros novos recursos, melhorias e correções de bugs feitas para
sparklyr 1.7, todos listados no
NOTÍCIAS.md
arquivo do sparklyr repositório e documentado em sparklyrde
Referência HTML páginas. Por uma questão de brevidade, não descreveremos todos eles detalhadamente nesta postagem do weblog.

Reconhecimento

Em ordem cronológica, gostaríamos de agradecer às seguintes pessoas que foram autores ou coautores de pull requests que fizeram parte do sparklyr Versão 1.7:

Também somos extremamente gratos a todos que enviaram solicitações de recursos ou relatórios de bugs, muitos dos quais foram tremendamente úteis na definição sparklyr no que é hoje.

Além disso, o autor desta postagem do weblog agradece
@skeydan por suas incríveis sugestões editoriais. Sem seus insights sobre boa escrita e narração de histórias, exposições como esta teriam sido menos legíveis.

Se você deseja saber mais sobre sparklyrrecomendamos visitar
sparklyr.ai, spark.rstudio.come também lendo alguns anteriores sparklyr lançar postagens como
brilhante 1.6
e
brilhante 1.5.

Isso é tudo. Obrigado por ler!

2019. Pipelines de aprendizado profundo para Apache Spark (versão 1.5.0). https://spark-packages.org/bundle/databricks/spark-deep-learning.

Elson, Jeremy, John (JD) Douceur, Jon Howell e Jared Saul. 2007. “Asirra: um CAPTCHA que explora a categorização guide de imagens alinhada aos interesses.” Em Anais da 14ª Conferência ACM sobre Segurança de Computadores e Comunicações (CCS)Anais da 14ª Conferência ACM sobre Segurança de Computadores e Comunicações (CCS). Associação para máquinas de computação, Inc. https://www.microsoft.com/en-us/analysis/publication/asirra-a-captcha-that-exploits-interest-aligned-manual-image-categorization/.

Szegedy, Christian, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke e Andrew Rabinovich. 2015. “Indo mais fundo com as convoluções.” Em Visão computacional e reconhecimento de padrões (CVPR). http://arxiv.org/abs/1409.4842.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *