- Um experimento elevou a classificação de dígitos manuscritos do MNIST a cerca de 78% de acurácia usando apenas compressão GZIP e k-vizinhos mais próximos (k-NN), mostrando que a compressão pode ser usada como uma ferramenta de classificação sem modelo
- A distância de compressão normalizada (NCD) é calculada com base em quanto o tamanho muda ao comprimir duas amostras de imagem juntas, e isso é usado como métrica de similaridade entre imagens
- Cada amostra de teste é comparada com 100 amostras de treino, e o rótulo previsto é definido pela maioria entre os vizinhos com k=5 mais próximos
- Devido ao custo computacional, a acurácia foi medida com apenas parte das imagens de teste, e usar o conjunto completo pode tornar a avaliação mais precisa
- O exemplo público ainda contém um erro de refatoração: ele cria um cache dos comprimentos comprimidos, mas não o usa no cálculo real da NCD, então é necessário remover o cache ou refletir isso em
compute_ncd
Classificando o MNIST com GZIP + k-NN
- O experimento classifica o conjunto de dados de dígitos manuscritos MNIST com a combinação GZIP + k-NN
- O exemplo curto de código usa o tamanho do resultado de
gzip.compress(z.tobytes())como comprimento comprimido, calcula a NCD e depois escolhe o rótulo mais frequente entre os 5 vizinhos mais próximos - Há um exemplo executável em Jupyter Notebook
- O objetivo não é obter a melhor acurácia possível, mas validar de forma simples a ideia de usar a compressão como uma ferramenta de classificação sem modelo
- O código com menos de 10 linhas está mais para um elemento divertido de code golf do que para o núcleo do experimento
Cálculo de similaridade e procedimento de classificação
- A NCD mede a similaridade normalizando o quanto o custo de comprimir dois pontos de dados juntos difere de comprimi-los separadamente
- O comprimento comprimido é calculado da seguinte forma
Cx1 = len(gzip.compress(x1.tobytes()))Cx2 = len(gzip.compress(x2.tobytes()))Cx1x2 = len(gzip.compress((x1 + x2).tobytes()))
- A fórmula da NCD tem a forma
(Cx1x2 - min(Cx1, Cx2)) / max(Cx1, Cx2) - A classificação calcula a distância entre cada imagem de teste e as imagens de treino, ordena da menor para a maior e usa votação majoritária dos 5 mais próximos
- No experimento, a comparação foi feita com base em 100 amostras de treino e, por causa do custo computacional, também foi usada apenas parte do conjunto de teste
Ideias de referência e pontos de atenção no código
- Essa abordagem foi inspirada no texto text generation from data compression e no artigo parameter free text classification
- Depois de escrever o texto, o autor também encontrou a postagem MNIST by ZIP de Andreas Kirsch, que usava um método parecido em 2019
- O código de exemplo cria um cache dos comprimentos comprimidos das amostras de treino, mas não usa esses valores no loop real
- Tanto a versão normal quanto a ofuscada criam
compressed_lengthsoucls, mas não usam os comprimentos em cache no cálculo da NCD - Remover o cache e usar diretamente
training_set, ou alterarcompute_ncdpara aproveitar os valores em cache, faz a intenção do código voltar a bater com a implementação
- Tanto a versão normal quanto a ofuscada criam
1 comentários
Opiniões no Hacker News
Ao trocar a função de distância do código por métricas mais simples, a distância GZIP teve precisão menor e custo computacional muito maior na classificação do MNIST
Distância Gzip: cerca de 3 minutos, 78% de precisão / distância euclidiana: cerca de 0,5 s, 93% / distância de Jaccard: cerca de 0,7 s, 94% / dissimilaridade de Dice: cerca de 0,8 s, 94%
Jaccard e Dice foram medidos após binarizar as imagens
Não conheço muito bem o algoritmo GZIP, mas é interessante que o resultado seja tão baixo, e fico curioso se um algoritmo de compressão mais voltado a imagens seria melhor
O texto em si é criativo, e o código e a explicação também são bons, mas acho que esses baselines acima acrescentam contexto à pontuação do gzip
NMI skimage: cerca de 30 s, 95% de precisão / NMI numba: cerca de 0,6 s, 95% de precisão
Usei um código
numbafornecido pelo ChatGPT para calcular contagens conjuntas 2x2, entropia e informação mútua normalizadaPessoalmente, tenho interesse em treinamento rápido no CIFAR10, então esse tipo de abordagem parece poder ser bastante útil em outros domínios também
https://github.com/benjamin-recht/mnist_1_pt_2/tree/main
Também incluí zstandard, e Zstd(level=3) ficou com cerca de 3,5 s e 88% de precisão, muito mais rápido que gzip
Ao calcular
Cx1x2, se usar(x1-x2)*2em vez dex1+x2, o zstd sobe para 93% de precisãoSe, em vez de somar os dois arrays, você os empilhar um acima do outro, o desempenho desmorona totalmente e fica abaixo de 20%; é interessante porque, em classificação de strings, esse método parece funcionar bem
Comparando com outras técnicas, Linear SVC fica em 92%, SVC com kernel RBF em 96,4%, SVC com kernel polinomial em 94,5%, regressão logística em 89% e Naive Bayes em torno de 81%
Fonte: https://dmkothari.github.io/Machine-Learning-Projects/SVM_wi...
Pelos textos online, parece que só com K-NN já dá para obter resultados muito melhores, então talvez o autor tenha dificultado as coisas ao usar gzip
Gosto de começar com modelos simples e adicionar complexidade depois, mas ouvi muitas vezes que “regressão logística não funciona” mesmo em problemas nos quais ela de fato funciona bem
Quando pergunto qual acham que seria o desempenho de referência no MNIST, muita gente chuta 20~30%
Mesmo pessoas que trabalham com machine learning frequentemente subestimam a rapidez com que aparecem retornos decrescentes ao aumentar bastante a complexidade do modelo
Em muitos casos, quando um modelo simples não tinha bom desempenho, também era difícil obter desempenho excelente com um modelo mais complexo
O artigo original que apresentou o dataset MNIST também chegou a cerca de 98% de precisão, e redes neurais atuais chegam a 99,87%
https://paperswithcode.com/sota/image-classification-on-mnis...
A compressão serve justamente para tornar o problema mais difícil e, na prática, continua fazendo isso
Como outros modelos tendem a adicionar ruído em algum ponto, fico pensando em colocar engenharia de atributos antes do gzip
Por exemplo, parece possível aplicar primeiro Gaussian blur e convoluções e depois usar deep learning para seleção de atributos
O código pode ser elegante e curto, mas 78% de precisão no MNIST é muito ruim
Até um modelo dummy feito em TensorFlow chega facilmente a 90% de precisão, e o melhor modelo chega a 99,87%
Benchmark: https://paperswithcode.com/sota/image-classification-on-mnis...
A parte interessante é que dá para usar compressão em classificação mesmo sem treinar um modelo
Isso leva à pergunta de se outras métricas informacionais mais baratas e com perdas também poderiam ser usadas
To Compress or Not to Compress- Self-Supervised Learning and Information Theory: A Review
[https://arxiv.org/abs/2304.09355\)" class="ud link">https://arxiv.org/abs/2304.09355\](https://arxiv.org/abs/2304.09355\)*
O interessante não é saber se GZip alcança o estado da arte, e sim o fato de que ele consegue classificar de forma razoável
É como um urso tocando piano: o surpreendente não é ele reproduzir Mozart perfeitamente, mas conseguir tocar piano
Ainda assim, é 8 vezes melhor que o baseline e mostra que a compressão pode aprender representações
Se você trocar
compute_ncdpor distância euclidiana, a acurácia de teste sobe 15 pontos percentuais e o volume de cálculo também cai bastanteBasta mudar para algo como
distances = [(np.sqrt(np.sum(np.square(x1-x))), label) for x, _, label in compressed_lengths]O melhor livro que vi sobre as conexões profundas entre teoria da informação, compressão e algoritmos de aprendizado foi o MacKay
Para quem teve uma formação adequada, talvez isso seja conhecimento básico, mas, do ponto de vista de alguém que aprendeu machine learning prático de forma autodidata, ver esse tema se conectar a áreas como física de partículas e cosmologia foi um daqueles momentos intensos de “aha!”
Deixo aqui na esperança de que pelo menos uma pessoa tenha a mesma percepção
Achei bem impressionante quando descobri que a compressão Lempel-Ziv original, uma das bases do gzip, surgiu não apenas como uma tentativa de reduzir tamanho, mas a partir do estudo da “complexidade de sequências finitas”
https://ieeexplore.ieee.org/document/1055501
Para ser justo, o MNIST fica quase perfeitamente separado só de passar pelo UMAP
Hoje em dia, acho que é preciso se esforçar bastante para ter desempenho ruim no MNIST
https://github.com/lmcinnes/umap_paper_notebooks/blob/master...
Acho que já seria melhor aposentar esse dataset; datasets como o QuickDraw fazem muito mais sentido
Não acho que seja uma grande conquista por si só, mas ainda é interessante ver que funciona
Quando eu chegar em casa, vou acrescentar ao texto que resolver MNIST é relativamente fácil
Ainda assim, como a maioria dos algoritmos simples e razoáveis chega a 97% de acurácia, ele continua tendo valor como ferramenta educacional ou como dataset Hello world
Mesmo construindo as ferramentas do zero, ele cabe no tamanho de um exercício, e é uma tarefa útil que qualquer pessoa entende, como “reconhecimento de dígitos em correspondências”
Se você entende compressão, essa abordagem também é uma ideia bem simples, então poderia ter sido escrita no primeiro dia em que o MNIST foi publicado e ainda assim teria chegado a 78% de acurácia
É isso que me parece bem surpreendente
O repositório também não define UMAP, mas, se o ChatGPT estiver certo, UMAP é a sigla de Uniform Manifold Approximation and Projection, uma técnica de redução de dimensionalidade e visualização usada em machine learning e análise de dados
Essa área é só um hobby para mim, mas dados fortemente comprimidos não deveriam ter alta entropia, como dados criptografados?
Se você encontra padrões nos dados comprimidos para descobrir o dígito original, não deveria ser possível usar esses padrões para obter uma compressão melhor?
A ideia é que “7 7” deve comprimir melhor que “7 3”, e que “7 7” em imagens raster também deve comprimir melhor que “7 3”
A incompressibilidade é uma característica de operações criptográficas eficientes
Veja a seção sobre compressão no artigo sobre complexidade de Kolmogorov: https://en.wikipedia.org/wiki/Kolmogorov_complexity#Compress...
Um dos conceitos de que gosto em compressão é o princípio das gavetas, segundo o qual todo algoritmo de compressão necessariamente tem alguma saída que fica maior que a entrada
Você ainda pode tentar comprimir um payload criptografado bem projetado, mas, em média, a saída ficará maior que a entrada, tornando a compressão inútil; por isso o chamamos de “incompressível”
https://en.wikipedia.org/wiki/Pigeonhole_principle#Uses_and_...
Acho que, alguns anos atrás, houve um caso em que usaram o tamanho das imagens do MNIST como uma “meta-característica”, mas não consigo encontrar agora
Pelo que lembro, só com essa característica, sem nem olhar a imagem, a acurácia ficava por volta de 90%
É o tamanho comprimido com gzip? Se for simplesmente quão escura é a imagem do MNIST, isto é, apenas a proporção de pixels escuros, dá cerca de 20% de acurácia, duas vezes melhor que um palpite aleatório, mas ainda muito longe de 90%
Suspeito que os autores daquele artigo tenham cometido um erro e que os resultados tenham saltado para o topo do benchmark por causa disso
Depois daquele caso, passei a achar que a teoria não era consistente, mas ainda assim 78% de acurácia só com GZIP é impressionante
Independentemente de este problema ser ou não uma boa aplicação para truques de compressão, quem estiver fazendo experimentos deveria parar de usar
gzipe usarzlibSe você trocar a primeira linha de
gzip.compressparazlib.compress, terá a mesma performance de classificação com velocidade 3 vezes maior