Classificação de desenhos manuscritos. Relatório no Yandex

Há alguns meses, nossos colegas do Google realizada no Kaggle uma competição para criar um classificador de imagens obtidas no sensacional o jogo "Desenho rápido!" A equipe, que incluía o desenvolvedor do Yandex, Roman Vlasov, ficou em quarto lugar na competição. No treinamento de aprendizado de máquina de janeiro, Roman compartilhou as ideias de sua equipe, a implementação final do classificador e práticas interessantes de seus oponentes.


- Olá a todos! Meu nome é Roma Vlasov, hoje vou falar sobre Quick, Draw! Desafio de reconhecimento de Doodle.

Classificação de desenhos manuscritos. Relatório no Yandex

Havia cinco pessoas em nossa equipe. Entrei logo antes do prazo de fusão. Tivemos azar, ficamos um pouco abalados, mas fomos abalados na posição monetária e eles foram abalados na posição ouro. E conquistamos um honroso quarto lugar.

(Durante a competição, as equipes se observaram em uma classificação, que foi formada com base nos resultados apresentados em uma parte do conjunto de dados proposto. A classificação final, por sua vez, foi formada em outra parte do conjunto de dados. Isso é feito assim que os participantes da competição não ajustam seus algoritmos a dados específicos. Portanto, nas finais, ao alternar entre as classificações, as posições tremem um pouco (do inglês shake up - to mix): em outros dados, o resultado pode acabar ser diferente. A equipe de Roman ficou em primeiro lugar entre os três primeiros. Nesse caso, os três primeiros são dinheiro, zona de classificação monetária, já que apenas os três primeiros colocados receberam prêmio em dinheiro. Após a mudança, a equipe já estava em quarto lugar. Da mesma forma, o outro time perdeu a vitória, a posição de ouro. - Ed.)

Classificação de desenhos manuscritos. Relatório no Yandex

A competição também foi significativa porque Evgeniy Babakhnin recebeu um grande mestre, Ivan Sosin recebeu um mestre, Roman Soloviev permaneceu um grande mestre, Alex Parinov recebeu um mestre, me tornei um especialista e agora já sou um mestre.

Classificação de desenhos manuscritos. Relatório no Yandex

O que é isso Rápido, Desenhar? Este é um serviço do Google. O Google tinha o objetivo de popularizar a IA e com este serviço queria mostrar como funcionam as redes neurais. Você vai lá, clica em Vamos desenhar, e uma nova página aparece onde lhe é dito: desenhe um zigue-zague, você tem 20 segundos para fazer isso. Você está tentando desenhar um ziguezague em 20 segundos, como aqui, por exemplo. Se você tiver sucesso, a rede diz que é um zigue-zague e você segue em frente. Existem apenas seis dessas fotos.

Se a rede do Google não reconhecesse o que você desenhou, uma cruz era colocada na tarefa. Mais tarde direi o que significará no futuro se um desenho será reconhecido pela rede ou não.

Este serviço reuniu um número bastante grande de usuários, e todas as imagens que os usuários desenharam foram registradas.

Classificação de desenhos manuscritos. Relatório no Yandex

Conseguimos coletar quase 50 milhões de imagens. A partir disso, foram formadas as datas de treino e teste da nossa competição. Aliás, a quantidade de dados do teste e o número de aulas estão destacados em negrito por um motivo. Falarei sobre eles um pouco mais tarde.

O formato dos dados foi o seguinte. Não são apenas imagens RGB, mas, grosso modo, um registro de tudo o que o usuário fez. Word é nosso alvo, countrycode é de onde vem o autor do doodle, timestamp é a hora. O rótulo reconhecido mostra apenas se a rede reconheceu a imagem do Google ou não. E o desenho em si é uma sequência, uma aproximação de uma curva que o usuário desenha com pontos. E horários. Este é o momento desde o início do desenho da imagem.

Classificação de desenhos manuscritos. Relatório no Yandex

Os dados foram apresentados em dois formatos. Este é o primeiro formato e o segundo é simplificado. Eles cortaram os tempos a partir daí e aproximaram esse conjunto de pontos com um conjunto menor de pontos. Para isso eles usaram Algoritmo Douglas-Pecker. Você tem um grande conjunto de pontos que simplesmente se aproxima de uma linha reta, mas na verdade você pode aproximar essa linha com apenas dois pontos. Essa é a ideia do algoritmo.

Os dados foram distribuídos da seguinte forma. Tudo é uniforme, mas existem alguns valores discrepantes. Quando resolvemos o problema, não olhamos para ele. O principal é que não existiam classes realmente poucas, não precisávamos fazer amostradores ponderados e sobreamostragem de dados.

Classificação de desenhos manuscritos. Relatório no Yandex

Como eram as fotos? Esta é a classe “avião” e exemplos dela com os rótulos reconhecidos e não reconhecidos. A proporção deles estava em torno de 1 para 9. Como você pode ver, os dados são bastante barulhentos. Eu acho que é um avião. Se você não reconhecer, na maioria dos casos é apenas ruído. Alguém até tentou escrever “avião”, mas aparentemente em francês.

A maioria dos participantes simplesmente pegou grades, desenhou dados dessa sequência de linhas como imagens RGB e os jogou na rede. Desenhei aproximadamente da mesma forma: peguei uma paleta de cores, desenhei a primeira linha com uma cor, que estava no início dessa paleta, a última - com outra, que estava no final da paleta, e entre eles Interpolei em todos os lugares usando esta paleta. A propósito, isso deu um resultado melhor do que desenhar como no primeiro slide - apenas em preto.

Outros membros da equipe, como Ivan Sosin, tentaram abordagens de desenho ligeiramente diferentes. Com um canal ele simplesmente desenhou uma imagem cinza, com outro canal ele desenhou cada traço com um gradiente do começo ao fim, de 32 a 255, e com o terceiro canal ele desenhou um gradiente sobre todos os traços de 32 a 255.

Outra coisa interessante é que Alex Parinov carregou informações na rede usando o código do país.

Classificação de desenhos manuscritos. Relatório no Yandex

A métrica utilizada na competição é a Precisão Média Média. Qual é a essência desta métrica para a concorrência? Você pode fornecer três previsões e, se não houver uma previsão correta nessas três, você obterá 0. Se houver uma correta, sua ordem será levada em consideração. E o resultado desejado será contado como 1 dividido pela ordem da sua previsão. Por exemplo, você fez três preditores, e o correto é o primeiro, então você divide 1 por 1 e obtém 1. Se o preditor estiver correto e sua ordem for 2, então divida 1 por 2, você obtém 0,5. Bem, etc.

Classificação de desenhos manuscritos. Relatório no Yandex

Com o pré-processamento de dados - como fazer desenhos e assim por diante - decidimos um pouco. Quais arquiteturas usamos? Tentamos usar arquiteturas gordas como PNASNet, SENet e arquiteturas já clássicas como SE-Res-NeXt, elas estão cada vez mais entrando em novas competições. Havia também ResNet e DenseNet.

Classificação de desenhos manuscritos. Relatório no Yandex

Classificação de desenhos manuscritos. Relatório no Yandex

Classificação de desenhos manuscritos. Relatório no Yandex

Como ensinamos isso? Todos os modelos que pegamos foram pré-treinados no imagenet. Embora existam muitos dados, 50 milhões de imagens, ainda assim, se você pegar uma rede pré-treinada no imagenet, ela apresentou resultados melhores do que se você simplesmente a treinasse do zero.

Que técnicas de ensino usamos? Este é o Cosing Annealing com Warm Restarts, sobre o qual falarei um pouco mais tarde. Esta é uma técnica que utilizo em quase todas as minhas competições recentes, e com elas acaba por treinar muito bem as grelhas, para conseguir um bom mínimo.

Classificação de desenhos manuscritos. Relatório no Yandex

Próximo Reduza a taxa de aprendizagem no platô. Você começa a treinar a rede, define uma determinada taxa de aprendizado, continua a ensiná-la e sua perda converge gradativamente para um determinado valor. Você verifica isso, por exemplo, por dez épocas a perda não mudou em nada. Você reduz sua taxa de aprendizado em algum valor e continua aprendendo. Ele cai um pouco novamente, converge no mínimo e você diminui novamente a taxa de aprendizado, e assim por diante, até que sua rede finalmente convirja.

A seguir está uma técnica interessante: não diminua a taxa de aprendizado, aumente o tamanho do lote. Existe um artigo com o mesmo nome. Ao treinar uma rede, você não precisa reduzir a taxa de aprendizado, basta aumentar o tamanho do lote.

Essa técnica, aliás, foi usada por Alex Parinov. Ele começou com um lote igual a 408 e, quando sua rede atingiu algum patamar, ele simplesmente dobrou o tamanho do lote, etc.

Na verdade, não me lembro qual valor atingiu o tamanho do lote, mas o interessante é que havia equipes no Kaggle que usavam a mesma técnica, o tamanho do lote era cerca de 10000. Aliás, frameworks modernos para aprendizado profundo, como PyTorch, por exemplo, permite que você faça isso com muita facilidade. Você gera seu lote e o envia para a rede não como está, em sua totalidade, mas o divide em pedaços para que caiba em sua placa de vídeo, calcula os gradientes e, depois de calcular o gradiente para todo o lote, atualiza os pesos.

A propósito, lotes grandes ainda foram incluídos nesta competição, porque os dados eram muito barulhentos, e um tamanho de lote grande ajudou a aproximar o gradiente com mais precisão.

Pseudo-rotulagem também foi usada, principalmente usada por Roman Soloviev. Ele amostrou cerca de metade dos dados do teste em lotes e treinou a grade nesses lotes.

O tamanho das fotos importava, mas o fato é que você tem muitos dados, precisa treinar muito tempo, e se o tamanho da sua foto for muito grande você vai treinar por muito tempo. Mas isso não acrescentou muito à qualidade do seu classificador final, então valeu a pena usar algum tipo de compensação. E tentamos apenas fotos que não eram muito grandes.

Como tudo foi aprendido? Primeiro, foram tiradas fotos de tamanho pequeno, várias épocas foram executadas nelas, o que levou muito tempo. Aí foram dadas fotos grandes, a rede foi treinada, depois ainda mais, ainda mais, para não treinar do zero e não perder muito tempo.

Sobre otimizadores. Usamos SGD e Adam. Desta forma foi possível obter um modelo único, que deu uma velocidade de 0,941-0,946 na tabela de classificação pública, o que é bastante bom.

Se você agrupar os modelos de alguma forma, obterá algo em torno de 0,951. Se você usar mais uma técnica, obterá nota final de 0,954 no quadro público, assim como nós obtivemos. Mas falaremos mais sobre isso mais tarde. A seguir contarei como montamos os modelos e como conseguimos atingir essa velocidade final.

A seguir, gostaria de falar sobre Cosing Annealing com Warm Restarts ou Stochastic Gradient Descent com Warm Restarts. Grosso modo, em princípio, você pode usar qualquer otimizador, mas a questão é esta: se você apenas treinar uma rede e gradativamente ela convergir para um mínimo, então está tudo bem, você terá uma rede, ela comete alguns erros, mas você pode treiná-lo de maneira um pouco diferente. Você definirá uma taxa de aprendizado inicial e a diminuirá gradualmente de acordo com esta fórmula. Você abaixa, sua rede chega a um mínimo, então você salva os pesos e novamente define a taxa de aprendizado que estava no início do treinamento, subindo desse mínimo e diminuindo novamente sua taxa de aprendizado.

Assim, você pode visitar vários mínimos ao mesmo tempo, nos quais sua perda será, para mais ou para menos, a mesma. Mas o fato é que redes com esses pesos darão erros diferentes na sua data. Fazendo a média deles, você obterá algum tipo de aproximação e sua velocidade será maior.

Classificação de desenhos manuscritos. Relatório no Yandex

Sobre como montamos nossos modelos. No início da apresentação eu disse para prestar atenção na quantidade de dados da prova e na quantidade de aulas. Se você adicionar 1 ao número de metas no conjunto de testes e dividir pelo número de classes, obterá o número 330, e isso foi escrito no fórum - que as classes no teste são balanceadas. Isso poderia ser usado.

Com base nisso, Roman Soloviev criou uma métrica, que chamamos de Proxy Score, que se correlacionou muito bem com a tabela de classificação. A questão é: você faz uma previsão, pega o primeiro dos seus preditores e conta o número de objetos para cada classe. A seguir, subtraia 1 de cada valor e some os valores absolutos resultantes.

Os seguintes valores foram obtidos. Isso nos ajudou não a criar uma tabela de classificação de sondagem, mas a validar localmente e selecionar coeficientes para nossos conjuntos.

Com um conjunto você poderia conseguir essa velocidade. O que mais eu poderia fazer? Suponha que você usou a informação de que as classes do seu teste estão balanceadas.

O equilíbrio era diferente. Um exemplo de um deles — equilíbrio dos caras que ficaram em primeiro lugar.

O que nós fizemos? Nosso balanceamento foi bastante simples, foi sugerido por Evgeny Babakhnin. Primeiro classificamos nossas previsões pelos primeiros 1 e selecionamos os candidatos a partir deles - para que o número de turmas não excedesse 330. Mas para algumas turmas você acaba com menos de 330 preditores. Ok, vamos também classificar pelos 2 primeiros e pelos 3 primeiros , e também selecionaremos candidatos.

Como nosso equilíbrio difere do equilíbrio do primeiro lugar? Eles usaram uma abordagem iterativa, pegando a classe mais popular e diminuindo as probabilidades dessa classe em um pequeno número até que essa classe não fosse mais a mais popular. Fizemos a próxima aula mais popular. Então eles continuaram a baixá-los até que o número de todas as classes se tornasse igual.

Todos usaram mais ou menos uma abordagem para treinar redes, mas nem todos usaram balanceamento. Usando o equilíbrio, você poderia entrar no ouro e, se tivesse sorte, no dinheiro.

Como pré-processar uma data? Todos pré-processaram a data, mais ou menos, da mesma maneira - fazendo recursos artesanais, tentando codificar tempos com diferentes cores de traço, etc. Alexey Nozdrin-Plotnitsky, que ficou em 8º lugar, falou sobre isso.

Classificação de desenhos manuscritos. Relatório no Yandex

Ele fez isso de forma diferente. Ele disse que todos esses seus recursos artesanais não funcionam, você não precisa fazer isso, sua rede deveria aprender tudo isso sozinha. Em vez disso, ele criou módulos de aprendizagem que pré-processavam seus dados. Ele jogou os dados originais neles sem pré-processamento - coordenadas de pontos e tempos.

Então ele pegou a diferença com base nas coordenadas e calculou a média de tudo com base nos tempos. E ele criou uma matriz bastante longa. Ele aplicou convolução 1D várias vezes para obter uma matriz de tamanho 64xn, onde n é o número total de pontos, e 64 é feito para alimentar a matriz resultante para a camada de qualquer rede convolucional, que aceita o número de canais - 64. obteve uma matriz 64xn, então a partir dela foi necessário criar um tensor de algum tamanho para que o número de canais fosse igual a 64. Ele normalizou todos os pontos X, Y na faixa de 0 a 32 para criar um tensor de tamanho 32x32. Não sei por que ele queria 32x32, simplesmente aconteceu assim. E nesta coordenada ele colocou um fragmento desta matriz de tamanho 64xn. Então acabou com um tensor 32x32x64 que você poderia colocar ainda mais em sua rede neural convolucional. Isso é tudo que eu queria dizer.

Fonte: habr.com

Adicionar um comentário