-
Como podemos
utilizar uma CNN
-
para classificar imagens
com o deep learning?
-
Nesse momento do curso,
-
você já conhece o que são
redes neurais artificiais,
-
o que é um deep learning
também e, sobretudo,
-
que existem diversas
arquiteturas
-
para trabalhar com redes
neurais profundas.
-
Aqui, vamos dar
um destaque na CNNs,
-
que são as bases para diversas
outras arquiteturas também,
-
inclusive para treinar outros
tipos de tarefas mais complexas,
-
como segmentação
e detecção de objetos.
-
Então, vamos começar o básico,
que é classificar imagens.
-
Será que, nessa imagem, nós
temos um objeto ou outro objeto?
-
Sem nos preocuparmos,
a princípio, onde eles estão,
-
em qual posição da imagem
eles estão, também,
-
o fato é saber a qual classe
essa imagem pertence.
-
Vamos para o código?
-
Bom, aqui no ambiente, eu estou
com o código já programado,
-
mas o meu ambiente
está desligado.
-
E, hoje, eu vou fazer
uma coisa diferente.
-
Normalmente, eu acabo
utilizando o código pronto
-
e vou executando
eles com vocês,
-
indicando, passo a passo,
o que está acontecendo.
-
Como esse código é um pouco
lento para ser reproduzido,
-
eu já vou trazer
o código executado
-
e vou fixar pontos de destaque
do código e da saída.
-
Convido vocês a pegarem
um código pronto,
-
reproduzirem no seu
ambiente, também,
-
testarem com outros parâmetros
e verificarem o impacto disso
-
em tempo de execução
e, também, nos resultados.
-
A primeira tarefa a ser executada
aqui é esse "pip install"
-
para nós estabelecemos as versões
do TensorFlow e do Keras.
-
É importante dar
esse destaque
-
para saber exatamente qual versão
das bibliotecas eu vou utilizar,
-
porque, dependendo do tipo
de versão que estamos utilizando,
-
pode haver alguma incompatibilidade
entre o código da versão antiga
-
e da versão nova, o que vai
quebrar nossa execução.
-
Quando a gente
estabelece exatamente
-
qual versão de biblioteca
nós vamos utilizar,
-
nós evitamos esse
tipo de problema.
-
É claro que, no desenvolvimento
padrão de bibliotecas,
-
a evolução é natural
e é constante,
-
mas os desenvolvedores
dessas bibliotecas
-
tendem a fazer uma versão
compatível com as anteriores.
-
No entanto, alterações podem
ocorrer quebrando códigos antigos,
-
então, nesse caso, é sempre
importante ficar de olho
-
nas versões das bibliotecas
que estamos utilizando
-
para evitar problemas futuros
no nosso código também.
-
Esse comando vai instalar,
aqui no nosso ambiente,
-
o TensorFlow e o Keras
nas versões aqui indicadas.
-
Se a gente não fala nada
e nem executa essa célula aqui,
-
já vai ter uma versão do TensorFlow
e do Keras instalada previamente.
-
O que nós queremos
fazer aqui é o seguinte:
-
desinstalar a versão anterior
-
e instalar estas versões
no nosso ambiente.
-
Note, pela saída
dessa célula,
-
que é um tempinho para poder
instalar o que necessário.
-
Esse erro aqui é natural, faz parte
do processo de tentativa e erro.
-
Inclusive, esse erro vai aparecer
porque ele está falando o seguinte:
-
"olha só, você pegou
um ambiente já pronto,
-
você está desinstalando coisas
e instalando novamente",
-
ou seja, reinicie o ambiente,
-
vai aparecer uma mensagem na tela
pedindo "reinicie o ambiente".
-
É só dar ok, reiniciar, dependendo
de como estiver na sua tela,
-
e ele vai ligar novamente
esse ambiente
-
e ligar novamente esse
ambiente de execução
-
já com as bibliotecas instaladas
nas versões que nós solicitamos.
-
Feito isso, nós podemos começar
com o código de verdade.
-
E, aqui, temos os imports
necessários
-
para esse tipo de trabalho.
-
Vamos importar
o TensorFlow, NumPy,
-
Seaborn para fazer
alguns gráficos também.
-
Da parte do sklearn, vamos
importar a matriz de confusão
-
para exibir melhores resultados.
-
Da parte de redes, vamos fazer
alguns imports de códigos específicos
-
para trabalhar
com o TensorFlow
-
para construir sistemas
com deep learning,
-
então redes sequenciais,
as camadas
-
das camadas, vamos importar várias
camadas que existem também.
-
O mecanismo
de early stopping,
-
rescaling para mudar a dimensão
das imagens também.
-
E note que, aqui, estou
importando também
-
a rede pronta do VGG16.
-
Poderia importar outra
rede pré-pronta também,
-
e estou importando aqui
o pré-processamento
-
das entradas que vão
alimentar essa rede VGG16.
-
Para treinar uma rede do zero,
isso ainda não será necessário,
-
mas guarde essa informação,
porque vamos voltar logo, logo,
-
quando falarmos
de transfer learning.
-
Pois bem, então temos, aqui,
as camadas, os modelos específicos,
-
e, agora, a gente começa
com o código de verdade.
-
A primeira parte do nosso
código, essa célula aqui,
-
é para carregar o dataset
para memória, ou seja,
-
eu não vou subir um arquivo
de dados aqui,
-
essa base de categorias de flores,
são 5 categorias possíveis,
-
já está dentro do TensorFlow, estou
importando isso aqui para memória.
-
Então, estou dando
um load, carregar,
-
o TensorFlow "flowers",
tipo de flores,
-
já na proporção
de treino e teste,
-
e ele já vai carregar para gente
uma divisão em duas tuplas:
-
a tupla de treinamento
e a tupla de teste.
-
Tanto do ponto de vista
do dado em si,
-
o dado de treinamento,
o dado de teste,
-
e os labels de treinamento
e de teste também.
-
Note que até esse processo,
também, demora um pouquinho,
-
não muito, mas demora
um pouquinho também
-
para ser carregado, porque
é uma base grande, de fato.
-
Aqui, eu posso mostrar
o tamanho desses arquivos,
-
então o meu arquivo
de treino tem 2.569 imagens
-
e a de teste tem 1.101 imagens.
-
Não importa se estou
no treino ou no teste,
-
nós temos as mesmas
dimensões desses dados,
-
ou seja, cada imagem é
expressa, originalmente,
-
em 442 por 1024 pixels
expressos em três canais, RGB.
-
Mesma coisa para o treino,
mesma coisa para o teste.
-
Agora, a gente começa
pré-processando esses dados.
-
Estou dizendo o seguinte:
-
eu vou trabalhar com
o tamanho de 150 por 150.
-
Ou seja, eu não vou trabalhar
com a imagem no tamanho original,
-
eu vou reescalá-las para esse
tamanho de 150 por 150.
-
Aí, você pode estar pensando: "mas,
Michel, a imagem é meio retangular,
-
você está escalando em algo
quadrado, não vai dar um problema?"
-
É, não vai ficar exatamente a mesma
imagem com a mesma proporção,
-
mas isso vai preservar
os elementos essenciais
-
que são necessários para
reconhecer se é uma rosa,
-
ou uma orquídea, ou qualquer
outro tipo de flor também.
-
Pois bem, dado esse tamanho
desejado, 150 por 150,
-
eu vou fazer um resizing
nos dados de treinamento,
-
passando o dado que eu quero, tanto
de treinamento quanto de teste,
-
e gerando novos dados,
digamos assim, já reescalados.
-
E, agora, eu estou transformando,
além de transformar o dado em si,
-
vou transformar o label
para um formato categórico.
-
Ou seja, em vez de falar
que temos as classes 0, 1, 2, 3, 4,
-
cada label vai ser um vetorzinho
com 5 posições,
-
com valores entre 0 e 1.
-
Cada posição indica um tipo de flor,
ou seja, deixei o label categórico.
-
E mostrando, aqui,
as novas dimensões,
-
temos, por exemplo,
aqui para o treinamento
-
continuam as mesmas
2569 imagens,
-
agora reescaladas
em 150 por 150 pixels,
-
e também continuam
expressas em três canais, RGB.
-
E o label fica exatamente
como tinha previsto.
-
Cada linha aqui é um label
de uma imagem diferente,
-
então essa primeira coluna
representa uma classe,
-
a segunda, terceira, quarta,
quinta, e assim por diante.
-
Ou seja, estou ativando a terceira
classe, entre aspas, aqui,
-
com 1 e 0 no resto.
-
Nesse ponto, eu posso começar
a construir nossos modelos.
-
Então, eu vou fazer o primeiro
modelo treinando do zero,
-
eu vou definir uma arquitetura
e vou treiná-la do zero
-
a partir dessas imagens.
-
Ou seja, eu vou começar
com uma rede
-
com pesos totalmente
aleatórios
-
e vou treinar, do zero,
como posicionar esses pesos
-
para, de fato, aprender
a classificar se, nessa imagem,
-
tem uma flor do tipo 1, tipo 2,
tipo 3, tipo 4 ou tipo 5.
-
Vamos ver o processo
para isso.
-
Então, essa célula aqui
está um pouquinho grande,
-
tem bastante código,
-
vamos entender ponta a ponta
o que estamos fazendo.
-
Nós sabemos que, para
definir o modelo profundo,
-
nós temos que definir
a arquitetura desse modelo.
-
Então, ele vai ser
um modelo sequencial,
-
ou seja, sai de uma camada,
vai para a próxima,
-
para a próxima,
para a próxima.
-
E, nesse modelo sequencial,
que eu chamo de "hand model"...
-
"Hand model" porque é
o modelo que vou fazer a mão,
-
vou fazer do zero.
-
Outras abordagens são
transfer learning, fine-tuning,
-
mas, para o começo, vamos por
uma rede simples, treinada do zero,
-
desenhada uma arquitetura à mão.
-
Então, vamos lá, eu vou desenhar
à mão essa arquitetura.
-
Ela é sequencial, ela começa
e eu vou adicionando camadas.
-
A primeira camada é uma camada
de reescalar o dado, ou seja,
-
entra uma imagem
de 150 por 150 pixels,
-
só que eu vou dividir
cada pixel por 255.
-
Por que a gente
vai fazer isso?
-
Lembra, cada pixel é
expresso de 0 até 255,
-
então quando eu divido
esse número por 255,
-
eu estou levando
os dados da matriz,
-
a matriz de pixels
da imagem, entre 0 e 1.
-
E fica um valor mais estável para
a rede conseguir aprender melhor
-
onde posicionar esses pesos
que modelam esse problema.
-
Beleza.
-
Então, no fundo, essa camada aqui
é uma camada de normalização.
-
Depois, eu já vou passar
para uma camada convolucional,
-
com 16 filtros, com ativação
de linear retificada
-
e um kernel de tamanho 10,
essa janela deslizante.
-
E vou engatar, aqui,
uma camada de max pooling.
-
Depois, eu faço uma outra
camada convolucional,
-
outra camada de max pooling,
outra camada convolucional,
-
outra camada de max pooling,
-
e, pronto, terminei aqui
a minha arquitetura CNN.
-
Ou seja, terminei, aqui,
o encadeamento de camadas
-
que extrai características
da minha imagem de entrada.
-
Não está a camada inteira ainda,
falta a camada de decisão,
-
mas eu fiz uma camada
de extração de features.
-
Será que essa é melhor
arquitetura que eu poderia fazer?
-
Não sei, provavelmente não.
-
Mas é uma camada inicial
para indicar o seguinte:
-
a arquitetura é
a gente que define,
-
então eu decidi encadear três
convoluções seguidas de pooling
-
em cada uma delas.
-
Poderia fazer diferente?
-
Poderia, cada arquitetura
tem as suas possibilidades
-
de serem construídas
com vantagens e desvantagens.
-
Aqui, eu quis criar
uma arquitetura simples.
-
Dada essa parte de extração,
vamos à parte de decisão,
-
ou seja, quando nós saímos
dessa última camada,
-
nós temos uma feature pronta.
-
Vamos, então,
alimentar essa feature,
-
extraída dos dados
de entrada,
-
para fazer a classificação
do modelo.
-
E eu vou começar com uma camada
de achatamento, ou seja,
-
não importa o que vai sair
dessa última camada,
-
eu quero que isso vire um vetor,
uma linha e tantas colunas.
-
Depois, eu vou trazer
duas camadas densas,
-
duas camadas densas fortemente
conectadas, totalmente conectadas,
-
que são camadas ocultas
de uma RNN tradicional.
-
E eu termino com uma outra camada
densa totalmente conectada, no caso,
-
com 5 neurônios, porque
nós temos 5 classes,
-
então vai ser alguma delas
que vai ser ativada.
-
Notem que a minha função
de ativação aqui é um softmax.
-
Ou seja, cada um dos neurônios
da última camada, dos 5 neurônios,
-
vai ser ativado
de alguma forma,
-
alguns muito pouco
e outros bem mais.
-
Qual vai ser o label final?
-
Max, o que está mais ativado.
-
Mas eles são ativados
de forma soft, ou seja,
-
cada um pode ser
um pouquinho ativado
-
caso tenha alguma
confusão entre as classes,
-
mas o label final é ativado
pelo que foi mais ativado.
-
Em todas essas etapas aqui, eu
defini a captura completa da rede,
-
desde de a etapa de CNN,
extração de características,
-
até etapa de aprendizado, de fato,
o que significa as características.
-
Agora, eu vou compilar o modelo
indicando qual vai ser o otimizador,
-
qual vai ser a minha loss,
-
qual vai ser a métrica que eu
vou otimizar também.
-
E, na sequência, eu vou definir
uma estratégia de early stopping,
-
ou seja, eu vou monitorar a acurácia
do conjunto de validação,
-
tendo uma paciência
de 5 épocas.
-
E, quando o early
stopping for ativado,
-
eu vou resgatar
os melhores pesos.
-
O que isso quer
dizer, gente?
-
Quer dizer o seguinte:
em tempo de treinamento,
-
a gente está constantemente
olhando o dado da validação,
-
os acertos e os erros.
-
Eu estou avaliando
a acurácia da validação.
-
Ou seja, se essa acurácia
no ______ de validação
-
não estiver melhorando
de forma significativa
-
por 5 épocas consecutivas, eu vou
parar o treinamento aí mesmo.
-
Não importa em que
época eu esteja,
-
eu vou parar porque não
há sinais de melhora.
-
E, depois que eu defino
todas as estratégias,
-
aí sim, eu vou fazer
o treinamento, fitting,
-
do meu modelo, modelo
aqui treinado na mão,
-
definindo na mão, de fato,
utilizando uma GPU.
-
Aqui, eu vou treinar utilizando
o dado treinamento
-
e seus labels também.
-
Aqui, só porque é um modelo
que demora para rodar,
-
eu coloquei que vou rodar
por, no máximo, 5 épocas.
-
Eu poderia colocar 50,
poderia colocar 500, tá?
-
Aqui, eu mantive pelo menos
5, é o mínimo do mínimo.
-
Falei o seguinte:
-
do dado de treinamento,
utilize 20% para a validação,
-
selecione 32 entre 2 imagens
para fazer o tamanho do meu batch.
-
E tem algum callback?
-
Tem algo que modifica
esse treinamento?
-
Sim, uma estratégia
de early stopping.
-
Note que aqui já
está executado,
-
então ele foi executando
a primeira época,
-
a segunda, a terceira,
a quarta, a quinta.
-
Notem que a minha loss,
a função de perda, os erros,
-
foram melhorando, a minha
acurácia está aumentando,
-
a acurácia na validação
está aumentando também.
-
É o que eu esperava.
-
Essa pequena saída já mostra
que tem espaço para melhoria sim.
-
Se eu tivesse o deixado
treinar por mais épocas,
-
com certeza esse
modelo ficaria melhor.
-
Mas aí a gente parou
com 5 épocas mesmo,
-
porque já era o suficiente
para entender um pouco
-
dos resultados que essa
rede definida do zero
-
poderia trazer como vantagem
ou desvantagem
-
como classificador de imagem.
-
Dado esse momento em que a rede
está treinada, temos que avaliá-la,
-
então eu vou dar
um ".evaluate"
-
passando dados
e os labels de teste,
-
indicando qual vai ser a loss
e qual vai ser a acurácia.
-
Note: a minha acurácia
no conjunto de teste foi 54%.
-
Não está muito bom.
-
Ok, ela aprendeu alguma coisa,
está um pouco acima do aleatório,
-
mas aprendeu pouco,
ou seja, tem chance,
-
tem chão para poder
conseguir aprender mais.
-
Só que como nós treinamos
por pouco tempo,
-
o máximo que ela
conseguiu aprender
-
foi para conseguir fazer
esse tipo de acerto, 54%.
-
No entanto, a acurácia pode ser
uma métrica global meio vaga.
-
Ok, ela acertou
54% no teste,
-
mas será que ela acertou mais
de uma classe, mais de outra?
-
Nós podemos tirar essa dúvida
com a matriz de confusão.
-
Aqui embaixo, temos a matriz
de confusão plotada,
-
e olhem só a distribuição
dos dados de teste nessa matriz.
-
Lembrem que a diagonal
principal são os acertos,
-
Então, temos 220 acertos aqui,
33 aqui, 130 nessa outra célula
-
e por aí vai.
-
Mas o que é fora da diagonal
principal são os erros,
-
e tem muito erro, tem muita
confusão entre as classes.
-
Ou seja, não foi
uma boa rede,
-
não foi um bom extrator
de características.
-
Podemos fazer melhor?
-
Com certeza.
-
E é aí que entra uma estratégia
muito importante,
-
que é o transfer learning.
-
No transfer learning,
-
eu transfiro o conhecimento
de uma rede pré-treinada
-
para outra tarefa de destino,
-
aproveitando pesos que foram bem
escrutinados, foram bem treinados,
-
que foram bem construídos
e posicionados.
-
Vamos ver
como isso funciona.
-
Então, aqui, vou começar
a trabalhar com o transfer learning
-
do modelo VGG16.
-
Então, note, eu vou voltar
um pouquinho lá nos imports
-
para reforçar
uma coisa importante.
-
Se eu vou fazer
um transfer da VGG16,
-
é ela que eu tenho
que importar,
-
se vou trabalhar com uma outra
rede, tipo uma ______,
-
seria ela que eu iria
importar aqui no caso.
-
E eu estou importando
o pré-processamento
-
não de uma rede qualquer,
mas da VGG16,
-
afinal, é essa a arquitetura
que me interessa.
-
Dado isso, vamos ver o processo
de construção do transfer learning.
-
Pronto, primeiro passo:
-
eu estou reconstruindo
o treinamento de teste
-
fazendo um pré-processamento
-
dos dados de entrada
do treinamento e de teste.
-
O que esse método faz?
-
Ele está pré-processando
essas imagens da sua tarefa
-
na mesma escala
daqueles dados grandes
-
que foram utilizados para
treinar a rede de origem
-
do transfer learning.
-
Então, vamos lá, a gente
está, basicamente,
-
fazendo uma normalização
dos dados de treinamento
-
e teste da nossa tarefa,
-
levando-os para a mesma
distribuição dos dados
-
que foram utilizados
para pré-treinar essa rede
-
na nossa tarefa original.
-
E, agora, eu vou começar a fazer
o transfer learning de fato.
-
Eu vou criar, aqui, o novo
modelo, o modelo de base,
-
que vem do quê?
-
Da VGG16, ou seja, eu
vou importar os pesos.
-
Que pesos?
-
Da rede VGG16 pré-treinada
no ImageNet.
-
Eu vou incluir a tarefa
de classificação,
-
as últimas camadas?
-
Não, eu vou defini-la
para a minha tarefa.
-
E qual vai ser o input
das imagens?
-
Qual o tamanho das imagens
aqui no caso?
-
É o tamanho do conjunto
de treinamento, por exemplo,
-
pegando o "shape", só para
ser condizente, de fato.
-
E outra coisa importante:
-
O meu base model
é "trainable"?
-
Ele é treinável?
-
Não, não é.
-
O que isso quer dizer?
-
Esse aqui é um ponto
muito importante,
-
que é a essência
do transfer learning.
-
Eu peguei aquela mesma
rede, as mesmas camadas,
-
copiando os mesmos pesos
já pré-treinados no ImageNet,
-
e falei: "essa rede
pode aprender?"
-
Não, não pode.
-
Assim como você copiou esses
pesos, mantenha como estão
-
e vamos utilizar esses
pesos pré-treinados
-
para fazer uma extração de features
do meu dado de entrada,
-
que é o conjunto, aqui,
de imagens de flores.
-
Eu posso, inclusive, verificar
o resumo da arquitetura de base.
-
E, olha só que interessante,
é bem maior do que a outra,
-
é o modelo VGG16.
-
Então, ele parte
de um conjunto de entrada,
-
no caso aqui, já em 150
por 150 pixels em 3 canais.
-
E aí, começam, no caso do VGG16,
duas camadas convolucionais,
-
uma camada de max pooling,
duas convolucionais,
-
outro max pooling
e assim sucessivamente.
-
Ou seja, eu não definir nada
disso, veio pronto da VGG16.
-
Ele tem um total de mais
de 14 milhões de parâmetros,
-
de pesos.
-
Quantos são treináveis?
-
Nenhum, ou seja, copia e cola,
usa esses pesos já bem avaliados,
-
bem construídos,
uma rede bem treinada
-
para extrair features para
nossa tarefa de destino.
-
O que falta fazer?
-
Colocar a camada de decisão,
-
porque minha tarefa
de classificação é outra.
-
Lembra que, no ImageNet,
nós tínhamos 20 mil classes,
-
mais de 20 mil classes,
aqui eu tenho só 5,
-
então a minha camada de decisão
vai ser diferente mesmo.
-
Vou definir minha
camada de decisão,
-
inclusive, da mesma forma
que eu fiz anteriormente.
-
É uma camada de entrada
de achatamento,
-
ou seja, criar
um vetor de features,
-
duas camadas densas
que são ocultas
-
e uma camada densa, também,
com 5 neurônios, também softmax.
-
Ou seja, é a mesma camada
do modelo feito à mão,
-
aqui eu só mudei um pouquinho
o formatinho dele.
-
Olha só, cada camada
foi salva em uma variável.
-
O meu modelo, de fato,
com o transfer learning,
-
é composto do quê?
-
Uma sequência de camadas.
-
Eu tenho várias camadas
no meu base model,
-
que veio da VGG16, então aquelas
várias camadas estão aqui,
-
eu passo para uma camada
de achatamento,
-
a camada densa um,
a segunda, e a última,
-
que é a camada de predição.
-
Pronto, estou com meu
modelo pronto aqui.
-
Se eu mostro, agora, o resumo
dele, olha como fica interessante:
-
é a VGG16 funcional.
-
Dizemos isso, porque é exatamente
a mesma arquitetura dela,
-
passando pelas
camadas de decisão.
-
Ele tem mais parâmetros ainda
para serem aprendidos,
-
passou de 14 milhões
para 15 milhões.
-
Aqui, no caso, 410
são treináveis.
-
Por que só 410 são treináveis
em um conjunto de 15 milhões?
-
Porque a maior parte desses
conjuntos de parâmetros,
-
desses pesos e baias, vieram
da VGG16, que já está pronta,
-
já não é treinável, está fixa.
-
Agora, essa parte de ser aprendida
é da tarefa de classificação.
-
Então, agora, eu tenho
que compilar o modelo também,
-
ou seja, vou dizer qual
vai ser o otimizador,
-
a loss, a métrica
a ser acompanhada,
-
também vou definir
meu early stopping,
-
da mesma forma que eu
fiz anteriormente,
-
e é aí que eu vou, de fato,
treinar o modelo.
-
Note: até antes
de treinar o modelo,
-
as configurações são as mesmas
do modelo feito à mão,
-
para fazer uma comparação justa.
-
Ou seja, eu mudei
a extração das features
-
No primeiro modelo, eu criei
um extrator de features,
-
feito por mim, uma arquitetura
que eu acabei de definir,
-
e, no segundo modelo, eu vou
utilizar um extrator de features
-
da VGG16 já treinada
por muito tempo,
-
muito bem construída
em cima do ImageNet,
-
uma base de dados
muito grande.
-
Agora sim, eu faço o treinamento
também utilizando a GPU.
-
então vou treinar com os dados
do treinamento, seus labels,
-
também para 5 épocas,
para ser uma comparação justa,
-
mesmo esquema
de validação, batch size
-
e qual callback vou utilizar.
-
E, aqui, nós temos a saída,
também por 5 épocas.
-
Novamente, essa
saída de 5 épocas
-
nos mostra que tem
espaço para melhoria.
-
Se eu tivesse deixado mais
tempo para treinar essa rede,
-
provavelmente o resultado
ficaria ainda melhor, notem.
-
A loss está diminuindo, a perda,
a acurácia está aumentando,
-
a acurácia na validação
também está aumentando.
-
Ou seja, com mais
tempo de treinamento,
-
poderia melhorar ainda mais.
-
Mas, mesmo assim, mesmo
com apenas 5 épocas,
-
esse modelo, quando avaliado,
é o mesmo código na essência.
-
Mas, aqui, eu estou verificando
a capacidade preditiva
-
do meu modelo feito
por transfer learning.
-
Olha a minha acurácia,
subiu para 92.
-
Ou seja, é um resultado muito melhor
do que eu tinha anteriormente.
-
Antes, eu tinha 54%,
agora, eu tenho 92.
-
Inclusive, notem como ficou
minha matriz de confusão:
-
com muito mais acertos
e muito menos erros.
-
Portanto, é modelo muito
mais estável, digamos assim.
-
E de onde vem essa vantagem
dessa estabilidade,
-
desse poder preditivo
desse modelo?
-
De utilizar a força do aprendizado
de uma rede mais profunda,
-
que foi treinada em uma base
muito grande por muito tempo.
-
Quando nós utilizamos a VGG16 como
um extrator de features para o modelo,
-
nós nos aproveitamos dos pesos
e baias bem treinados
-
para fazer um extrator de features
muito mais poderoso
-
do que aquele que eu
defini anteriormente.
-
Então, só o fato de fazer
transfer learning
-
já gerou um resultado muito melhor
do que o modelo treinado do zero
-
a partir de uma arquitetura
muito mais rasa.
-
Muito bom, nesse ponto,
nós temos a diferenciação
-
entre treinar o modelo
CNN do zero
-
ou utilizar uma estratégia
de transfer learning
-
para criar modelos mais
sofisticados, com pouco esforço.
-
Daria para fazer
algo diferente?
-
Sim, dá para combinar transfer
learning com fine-tuning.
-
O que isso quer dizer?
-
Quando nós fizemos
o transfer learning,
-
nós pegamos a rede
pré-treinada da VGG16,
-
tudo da camada de extração
de features, e congelamos os pesos.
-
Nós podemos falar o seguinte:
até certa camada fica congelada,
-
daí em diante, pode refinar
um pouquinho mais.
-
Ou seja, vou fazer um fine-tuning,
um ajuste fino do modelo pré-treinado
-
para a minha tarefa de destino,
no caso, a classificação de flores.
-
Como nós implementamos isso?
-
Da seguinte forma:
-
aqui, eu tenho
que dizer o seguinte:
-
o meu modelo baseline,
modelo de base aqui,
-
que é o VGG16,
é treinável?
-
Está falando que sim,
mas cuidado,
-
isso aqui liberaria o treinamento
de todas as camadas.
-
Aqui, eu posso
falar o seguinte:
-
em qual camada nós vamos
travar o treinamento?
-
O modelo possui 19 camadas,
-
vou fazer um fine-tuning
na camada 13 em diante.
-
Ou seja, eu vou pegar
o base model,
-
vou acionar ".layers",
todas as camadas dele,
-
e, da primeira até esse
ponto de corte, até a 13ª,
-
ela é treinável?
-
Não, ou seja, o que
nós fizemos?
-
A princípio eu falei o seguinte:
19 camadas, todas são treináveis.
-
Depois, eu voltei corrigindo: da 1ª
até a 13ª, ela não é treinável não,
-
só vai ser treinável da 13ª
em diante, até as últimas.
-
Ou seja, o ajuste fino está
nas últimas camadas
-
de extração de características.
-
E por que eu
quero fazer isso?
-
Porque eu quero dar
liberdade para rede
-
ajustar a extração de features
não para uma base qualquer,
-
grande, robusta,
como a ImageNet,
-
mas para a minha
tarefa de destino,
-
que é, simplesmente,
classificar tipos de flores.
-
A partir disso, nós definimos,
também, as mesmas camadas,
-
aqui até deixei comentado
-
para falar: vou utilizar exatamente
as que eu tinha anteriormente,
-
nem preciso redefinir.
-
E o meu modelo com fine-tuning
também é um modelo sequencial,
-
ou seja, sai de uma camada
para a próxima,
-
ele parte de base model, que nós
acabamos de alterar com fine-tuning,
-
e seguimos aqui para a camada
de achatamento das features,
-
as camadas ocultas
e a camada de decisão.
-
Quando eu exploro
o que é esse resumo,
-
é uma arquitetura parecida,
porque também temos, aqui,
-
a VGG16 como extratora de features
e, também, as camadas de decisão.
-
E, depois, eu preciso fazer os mesmos
processos de anteriormente.
-
Ou seja, não vou entrar
em detalhes aqui,
-
é o mesmo processo
de compilar o modelo,
-
criar estratégia de early stopping
e, aí sim, vou treinar essa rede.
-
Ou seja, vamos treinar essa rede,
agora do modelo com fine-tuning,
-
também com o modelo com o ____
de treinamento e seus labels,
-
mesma estratégia de épocas,
mesma divisão de validação,
-
também de batch, e utilizando
o early stopping também.
-
E aqui, novamente, para se
ter uma comparação justa,
-
eu deixei _____ treinar
por 5 épocas apenas.
-
De novo, a loss
está melhorando,
-
a acurácia na validação
está aumentando também,
-
mas tem chão, tem espaço
aqui para melhorar mais
-
se nós tivéssemos treinado
por, por exemplo, 50 épocas,
-
por 500 épocas.
-
Quanto mais tempo, pode ser
que ele teria refinado mais
-
e, mesmo que eu tivesse colocado,
por exemplo, 5000 épocas, um exagero,
-
a partir do momento
que a rede percebe
-
que ela não está melhorando
mais o aprendizado,
-
o mecanismo de early stopping
interromperia o treinamento
-
antes mesmo de chegar nesse
número exarcerbado de épocas.
-
Vou manter como 5.
-
Quando nós testamos isso,
-
nós vemos que, para aquele conjunto
de teste, nós temos o quê?
-
Que a loss foi essa,
mas a acurácia foi 62.
-
Hm, pode parecer
um pouco frustrante,
-
porque ficou pior que o modelo
de transfer learning.
-
Então, vamos recapitular
um pouquinho
-
as métricas que nós
temos aqui.
-
O modelo treinado do zero,
com uma arquitetura profunda,
-
mas não muito rebuscada,
gerou uma couraça de 54%.
-
O modelo de transfer learning
-
jogou esse resultado para
mais de 90% de acerto.
-
E, agora, o transfer learning
com o fine-tuning
-
derrubou um pouquinho
essa performance para 62%.
-
62 é melhor que 54, ou seja, fazer
um transfer learning com fine-tuning
-
é melhor do que treinar
uma rede do zero.
-
No entanto, faltou tempo
para refinar essa rede, ou seja,
-
quando eu vou fazer um transfer
learning com fine-tuning,
-
eu tenho que ajustar os pesos.
-
E o que isso quer dizer?
-
Que eu não consigo ajustar todos
esses pesos dessa rede profunda
-
com apenas 5 épocas, eu
precisaria de mais tempo, de fato.
-
De forma geral, a maioria
da performance tende a ser,
-
em teoria, da seguinte forma:
-
você treinar uma rede do zero
vai te dar uma resposta,
-
uma certa taxa de acerto.
-
Quando você faz transfer learning
de uma rede profunda, bem treinada,
-
esse resultado tende
a melhorar bastante.
-
Quando você faz transfer
learning com fine-tuning,
-
o resultado melhora
um pouquinho mais.
-
Não vai ser um salto
de melhoria tão grande
-
quanto do modelo
simples para o transfer,
-
mas ele melhora
um pouquinho.
-
No entanto, para verificarmos
seu efeito na prática,
-
é necessário tempo, ou seja,
-
temos que deixar a rede
treinando por mais tempo,
-
portanto, por mais épocas.