Classificação de Imagens RGB com SVM

CEAO-802 — Métodos de Análise de Dados

1T Generoso · 1T João Marcos · 1T Vitor Cesa

2026-06-17

Roteiro

  1. Contexto e objetivo
  2. Fundamentos: Transfer Learning e SVM
  3. Pipeline em R — código-chave
  4. Cinco modelos avaliados
  5. Comparação de resultados
  6. Validação cruzada K-Fold
  7. Discussão e conclusão

Contexto e Objetivo

  • Imagens RGB de cenas urbanas por drone — Guaratinguetá (SP)
  • 13 classes de cobertura do solo (C1–C13); dataset: RGB + TIR
  • Este trabalho: apenas canal RGB
  • Amostra: 50 imagens / classe · 650 imagens totais (de 1.248)
  • Divisão: 70% treino (~455) / 30% teste (~195), estratificada

Objetivo

Classificação supervisionada de cenas urbanas usando Transfer Learning como extrator de atributos e SVM como classificador.

Baseline aleatório (13 classes):

7,7%

Qualquer modelo acima disso aprende algo real.

As 13 Classes do Dataset

Classe Cobertura
C1 Vegetação Arbórea
C2 Vegetação Rasteira
C3 Solo Exposto
C4 Pavimento Asfáltico
C5 Solo Estabilizado
C6 Telhado Cerâmico
C7 Telhado de Fibrocimento
Classe Cobertura
C8 Telhado Metálico
C9 Placa Fotovoltaica
C10 Piscina
C11 Pedra Sabão
C12 Caixa D’água
C13 Veículos

Arquivo: C10_2023_06_M_01_RGB.tiff → classe C10, junho 2023, manhã. A classe é inferida do prefixo do nome — sem estrutura de subpastas.

Por que Transfer Learning?

Abordagem tradicional

Extrair atributos estatísticos manualmente: média, desvio-padrão, histogramas de cor

❌ Representação rasa — perde padrões espaciais e texturais complexos

Abordagem adotada

MobileNetV2 pré-treinada no ImageNet (>1 M imagens · 1.000 classes · Google)

  • Remove a camada classificadora final
  • Aplica pooling global médio
  • Gera vetor de 1.280 atributos por imagem

✅ Bordas, texturas e formas de alto nível, aprendidas em escala industrial

A CNN faz o trabalho de representação. O SVM recebe os 1.280 atributos e aprende a fronteira de decisão — sem re-treinar a CNN.

O que é SVM?

Ideia central

Encontrar o hiperplano que maximiza a margem entre as classes.

Parâmetros principais

  • cost — tolerância a erros; maior cost = fronteira mais rígida
  • gamma — alcance do kernel radial; maior gamma = vizinhança menor

Kernel trick

Kernel radial (RBF) permite fronteiras não-lineares projetando os dados em espaço de alta dimensão

Dois kernels testados

Kernel Fronteira Parâmetros
Linear Hiperplano cost
Radial Não-linear cost + gamma

SVM é sensível à escala → atributos devem ser padronizados antes do treino.

Pipeline Geral

650 imagens
RGB
MobileNetV2
1.280 atributos
center + scale
nearZeroVar
5 modelos
SVM · RF
Holdout
K-Fold k=5

Código — Leitura e Amostra

# Listar imagens e inferir classe do prefixo do nome
arquivos <- list.files(path = caminho_rgb,
  pattern = "\\.(jpg|jpeg|png|bmp|tif|tiff)$",
  recursive = TRUE, full.names = TRUE)

classe_inferida <- stringr::str_extract(nome_sem_extensao, "^C\\d+")

# Amostra estratificada e balanceada: 50 imagens/classe
set.seed(123)
metadados <- metadados_completo %>%
  group_by(classe) %>%
  group_modify(~ slice_sample(.x, n = min(50, nrow(.x)))) %>%
  ungroup()
# → 650 imagens totais (50 × 13 classes)

O que faz: lista os TIFFs, extrai a classe C1C13 do prefixo e sorteia 50 imagens por classe com semente fixa.

Código — Extração com MobileNetV2

# Carregar MobileNetV2 sem a camada classificadora
modelo_base <- application_mobilenet_v2(
  include_top  = FALSE,      # remove o bloco de 1.000 classes
  weights      = "imagenet", # pesos pré-treinados no ImageNet
  pooling      = "avg",      # GlobalAveragePooling → vetor 1D
  input_shape  = c(224L, 224L, 3L)
)

# Normalização específica da MobileNetV2: pixels → [-1, 1]
batch_prep <- (batch_array / 127.5) - 1.0

# features: matriz  n × 1.280  (processado em lotes de 16)
features <- predict(modelo_base, batch_prep, verbose = 0L)

O que faz: carrega MobileNetV2, normaliza pixels para [−1, 1] e extrai 1.280 atributos por imagem. Resultado salvo em cache .rds.

Código — Pré-processamento e Treino

# Divisão estratificada 70/30
idx_treino <- createDataPartition(dados$classe, p = 0.70, list = FALSE)

# Remover atributos de variância quase nula
variaveis_nzv <- nearZeroVar(x_treino)

# Padronizar: média 0, desvio 1 (essencial para o SVM)
preproc       <- preProcess(x_treino, method = c("center", "scale"))
x_treino_norm <- predict(preproc, x_treino)
x_teste_norm  <- predict(preproc, x_teste)

# M1 — SVM linear
modelo_svm_linear <- svm(x = x_treino_norm, y = y_treino,
  kernel = "linear", cost = 1, scale = FALSE)

O que faz: divide 70/30, padroniza e treina. O mesmo fluxo se repete para cada um dos 5 modelos (parâmetros variam).

Os 5 Modelos

# Modelo Tipo Parâmetros
1 SVM linear Linear cost = 1
2 SVM radial RBF cost = 10 · gamma = 0,01 (fixos)
3 SVM radial ajustado RBF cost e gamma por grade 4×4 + CV
4 PCA + SVM radial RBF PCA (≥ 95% var., máx. 30 comp.) + RBF
5 Random Forest Ensemble 500 árvores · importance = TRUE

O PCA reduz os 1.280 atributos aos componentes que explicam ≥ 95% da variância antes de treinar o SVM, eliminando redundâncias.

Comparação — Holdout 70/30

Baseline aleatório (13 classes) = 7,7% — SVM linear (~40%) é 5,2× melhor que o acaso.

Melhor Modelo — SVM Linear

Métrica Holdout K-Fold
Acurácia 40,0% 40,2%
Kappa 0,350 0,352
F1 macro 0,402 0,409


Holdout e K-Fold concordam → resultado estável.

Validação Cruzada K-Fold (k = 5)

Por que k-fold? O holdout avalia uma única divisão aleatória. O k-fold usa todas as imagens para avaliação, em 5 rodadas independentes — estimativa mais robusta.

Holdout × K-Fold

Importância das Variáveis — Random Forest

feat_0472 e feat_0260 têm importância ~70% maior que a 3ª colocada. São índices de neurônios internos da CNN — sem interpretação visual direta.

Discussão

Resultado principal

  • Melhor modelo: SVM linear com acurácia k-fold de 40.2% (~5,2× acima do acaso)
  • Holdout e k-fold convergiram → resultado estável e confiável

Achado mais relevante — SVM linear superou o SVM radial com parâmetros fixos (14%). Os atributos da MobileNetV2 formam um espaço quase linearmente separável — o kernel linear é suficiente.

Trabalhos futuros

  • Outros extratores CNN: EfficientNetB0 · ResNet50 · VGG19
  • Incorporar o canal TIR ao vetor de atributos
  • Aumentar a amostra por classe (50 imagens/classe) e fazer fine-tuning da CNN

Conclusão


Transfer learning combina o poder representacional das CNNs com a interpretabilidade dos classificadores clássicos — sem treinar a rede do zero.


A abordagem é simples, reprodutível e já supera em 5× o baseline aleatório com apenas 50 imagens por classe — base sólida para extensões futuras.



Obrigado — Perguntas?


1T Generoso · 1T João Marcos · 1T Vitor Cesa

CEAO-802 — Métodos de Análise de Dados