Classificação de áudio simples com tocha

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

[ad_1]

[This article was first published on RStudio AI Blog, and kindly contributed to R-bloggers]. (Você pode relatar problemas sobre o conteúdo desta página aqui)


Quer compartilhar seu conteúdo em R-bloggers? clique aqui se você tiver um blog, ou aqui se não tiver.

Este artigo traduz o artigo ‘Classificação Simples de Áudio’ de Daniel Falbel de tensorflow/keras para torch/torchaudio. O principal objetivo é apresentar torchaudio e ilustrar suas contribuições para o torch ecossistema. Aqui, nos concentramos em um conjunto de dados popular, o carregador de áudio e o transformador de espectrograma. Um produto secundário interessante é o paralelo entre tocha e tensorflow, mostrando ora as diferenças, ora as semelhanças entre eles.

library(torch)
library(torchaudio)

Baixando e importando

torchaudio tem o speechcommand_dataset integrado. Ele filtra background_noise por padrão e nos permite escolher entre as versões v0.01 e v0.02.

# set an existing folder here to cache the dataset
DATASETS_PATH 
Uma amostra de forma de onda para um 'leito'.

(#fig: unnamed-chunk-4) Uma amostra de forma de onda para uma 'cama'.

Aulas

df $ classes
 [1] "cama" "pássaro" "gato" "cachorro" "baixo" "oito" "cinco"  
 [8] "quatro" "vá" "feliz" "casa" "esquerda" "marvin" "nove"  
[15] "não" "desligado" "ligado" "um" "certo" "sete" "sheila"
[22] "seis" "pare" "três" "árvore" "dois" "para cima" "uau"   
[29] "sim" "zero"  

Gerador Dataloader

torch::dataloader tem a mesma tarefa que data_generator definido no artigo original. Ele é responsável por preparar lotes - incluindo embaralhamento, preenchimento, codificação one-hot, etc. - e por cuidar do paralelismo / orquestração de E / S de dispositivo.

Na tocha, fazemos isso passando o subconjunto de trem / teste para torch::dataloader e encapsular toda a lógica de configuração do lote dentro de um collate_fn() função.

set.seed(6)
id_train 

At this point, dataloader(train_subset) would not work because the samples are not padded. So we need to build our own collate_fn() with the padding strategy.

I suggest using the following approach when implementing the collate_fn():

  1. begin with collate_fn .
  2. instantiate dataloader with the collate_fn()
  3. create an environment by calling enumerate(dataloader) so you can ask to retrieve a batch from dataloader.
  4. run environment[[1]][[1]]. Now you should be sent inside collate_fn() with access to batch input object.
  5. build the logic.
collate_fn 

The final collate_fn() pads the waveform to length 16001 and then stacks everything up together. At this point there are no spectrograms yet. We going to make spectrogram transformation a part of model architecture.

pad_sequence 

Batch structure is:

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
  • lote[[1]]: formas de ondatensor com dimensão (32, 1, 16001)
  • lote[[2]]: alvostensor com dimensão (32, 1)

Além disso, o torchaudio vem com 3 carregadores, av_loader, tuner_loader, e audiofile_loader– mais por vir. set_audio_backend() é usado para definir um deles como carregador de áudio. Suas performances diferem com base no formato de áudio (mp3 ou wav). Ainda não existe um mundo perfeito: tuner_loader é melhor para mp3, audiofile_loader é melhor para wav, mas nenhum deles tem a opção de carregar parcialmente uma amostra de um arquivo de áudio sem trazer todos os dados para a memória primeiro.

Para um determinado back-end de áudio, precisamos passá-lo para cada trabalhador por meio worker_init_fn() argumento.

ds_train 

Model definition

Instead of keras::keras_model_sequential(), we are going to define a torch::nn_module(). As referenced by the original article, the model is based on this architecture for MNIST from this tutorial, and I’ll call it ‘DanielNN’.

dan_nn % # (64, 1, 16001)
      self$spectrogram() %>% # (64, 1, 257, 101)
      torch::torch_add(0.01) %>%
      torch::torch_log() %>%
      self$conv1() %>%
      torch::nnf_relu() %>%
      torch::nnf_max_pool2d(kernel_size = c(2,2)) %>%
      
      self$conv2() %>%
      torch::nnf_relu() %>%
      torch::nnf_max_pool2d(kernel_size = c(2,2)) %>%
      
      self$conv3() %>%
      torch::nnf_relu() %>%
      torch::nnf_max_pool2d(kernel_size = c(2,2)) %>%
      
      self$conv4() %>%
      torch::nnf_relu() %>%
      torch::nnf_max_pool2d(kernel_size = c(2,2)) %>%
      
      torch::nnf_dropout(p = 0.25) %>%
      torch::torch_flatten(start_dim = 2) %>%
      
      self$dense1() %>%
      torch::nnf_relu() %>%
      torch::nnf_dropout(p = 0.5) %>%
      self$dense2() 
  }
)

model  #0 parameters
● conv1:  #320 parameters
● conv2:  #18,496 parameters
● conv3:  #73,856 parameters
● conv4:  #295,168 parameters
● dense1:  #1,835,136 parameters
● dense2:  #3,870 parameters

Ajuste do modelo

Ao contrário do tensorflow, não há model %>% compile(...) pisar na tocha, então vamos definir loss criterion, optimizer strategy e evaluation metrics explicitamente no loop de treinamento.

loss_criterion 

Training loop

library(glue)
library(progress)

pred_to_r 

Making predictions

We already have all predictions calculated for test_subset, let’s recreate the alluvial plot from the original article.

library(dplyr)
library(alluvial)
df_validation %
  mutate(correct = pred_class == class) %>%
  count(pred_class, class, correct)

alluvial(
  x %>% select(class, pred_class),
  freq = x$n,
  col = ifelse(x$correct, "lightblue", "red"),
  border = ifelse(x$correct, "lightblue", "red"),
  alpha = 0.6,
  hide = x$n 
predicted labels." width="336" />

(#fig:unnamed-chunk-15)Model performance: true labels predicted labels.

Model accuracy is 87,7%, somewhat worse than tensorflow version from the original post. Nevertheless, all conclusions from original post still hold.



[ad_2]

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
Leia Também  Como seus dados fluem? Usando R para ETL (conversa EdinbR)