Tarefa de classificação de rede e imagem VGG-16
Neste caderno, podes experimentar como as redes neurais convolucionais realmente funcionam. Vamos usar a rede VGG-16 e testá-la numa tarefa de classificação de imagem. Temos até 1000 aulas à nossa disposição! Logo no início, carregaremos as bibliotecas padrão necessárias para o trabalho futuro.
#%pip install pandas
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Especificamente, a partir da biblioteca TensorFlow, carregamos o modelo VGG-16 pré-treinado. Ao carregar esse modelo, precisamos indicar que queremos usar o modelo que foi treinado em imagens do conjunto de dados ImageNet. Fazemos isso definindo o argumento 'pesos' da função 'VGG16' como 'imagenet'. O carregamento do modelo em si pode levar um pouco de tempo.
#%pip install tensorflow
#%pip install --upgrade numpy
from tensorflow.keras.applications import VGG16
model = VGG16(weights='imagenet')
A seguir, vamos verificar as camadas que compõem essa rede. Não se confunda se não entender todos os detalhes exibidos. É importante saber que a entrada é esperada para ser uma imagem colorida de 224x224 pixels (daí o 224, 224, 3 ao lado da camada de entrada) e que a saída é uma das 1000 classes. Podes comparar a saída com o diagrama de modelo VGG-16 que discutimos para descobrir mais informações.
model.summary()

Podemos ver que o número de parâmetros desta rede é superior a 138 milhões. Não vamos treinar a rede, mas vamos usar apenas o modelo pré-treinado. Portanto, é importante não alterar os parâmetros do modelo durante a operação - cada um tem sua própria contribuição. A ideia é testar a rede com uma imagem arbitrária da web. Para conseguir isso, usaremos algumas bibliotecas. A biblioteca PIL é a biblioteca Python padrão para trabalhar com imagens, enquanto usaremos as bibliotecas urllib e io para carregar a imagem.
from PIL import Image
from urllib import request
from io import BytesIO
A função 'load_image' ajudar-nos-á a obter qualquer imagem que quisermos na Web. É suficiente fornecer-lhe o caminho da URL.
def load_image(url_path):
response = request.urlopen(url_path).read()
return Image.open(BytesIO(response))
Escolhemos uma imagem de um golden retriever! Ao alterar o caminho na variável 'image_url', podes definir a imagem desejada.
image_url = 'https://images.unsplash.com/photo-1558788353-f76d92427f16?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=738&q=80' # https://unsplash.com/photos/x5oPmHmY3kQ
test_image = load_image(url_path=image_url)
Agora vamos exibir a imagem carregada.
plt.imshow(test_image)
plt.axis('off')
plt.show()

Ao escolher uma imagem, é importante ter em mente que a classe do objeto na imagem deve ser conhecida pelo modelo. Como o modelo VGG-16 é treinado em mais de 1,2 milhão de imagens, ele reconhece muitos objetos, até mesmo 1000 diferentes. Como aprendeu sobre o golden retriever, podemos esperar um bom resultado. Se dermos ao modelo uma imagem com um objeto que ele não reconhece, ele nos dará previsões de classes cujas imagens mais se assemelham às nossas. Veremos no final quais classes de objetos se assemelham ao golden retriever. Como a imagem que precisamos passar para o modelo precisa ser especialmente preparada, a secção a seguir cobre os preparativos.
Também carregaremos algumas bibliotecas que facilitarão o nosso trabalho. É comum que a comunidade compartilhe todas as funcionalidades que acompanham e que são úteis nessas etapas ao compartilhar modelos.
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions
Primeiro, vamos preparar a imagem definindo suas dimensões para 224x224 e especificando que ela usa três canais de cor RGB.
test_image = test_image.resize((224, 224))
test_image = test_image.convert('RGB')
plt.imshow(test_image)
plt.axis('off')
plt.show()

Em seguida, garantiremos que a imagem esteja no formato matricial apropriado.
matrix_form_test_image = image.img_to_array(test_image)
print(matrix_form_test_image.shape)
Como sabes, as redes sempre funcionam com lotes de dados. Portanto, vamos criar um lote que contém a nossa imagem. Como seria de esperar, a sua dimensão será 1 x 224 x 224 x 3 porque temos apenas uma imagem no lote.
batch = np.expand_dims(matrix_form_test_image, axis=0)
print(f'(number_of_test_images, height, width, number_of_channels) = {batch.shape}')
Em seguida, é a parte que lida com o pré-processamento numérico da imagem na forma de normalização. Uma função especial 'preprocess_input' que acompanha o modelo nos ajudará com isso.
test_image_batch = preprocess_input(batch)
Uma vez terminada a preparação, podemos agora usar o modelo para a tarefa de classificação. A função que nos ajudará nesta parte chama-se 'prever'.
model_predictions = model.predict(test_image_batch)
As previsões do modelo obtido representam as probabilidades da nossa imagem pertencer a cada uma das 1000 classes.
model_predictions.shape
Para extrair a classe à qual nossa imagem pertence, podemos usar a função 'decode_predictions', que retornará as probabilidades e nomes das 5 classes mais prováveis. Isso nos dará uma visão de quão confiante o modelo está durante a classificação.
most_likely_classes = decode_predictions(model_predictions)[0]
print(most_likely_classes)
Como podemos ver, em primeiro lugar está a classe *golden retriever* com uma probabilidade de 0,8042132. Para acompanhar melhor a saída do modelo, também podemos exibi-la graficamente.
class_names = [item[1] for item in most_likely_classes]
class_probabilities = [item[2] for item in most_likely_classes]
plt.figure(figsize=(10, 4))
plt.bar(class_names, class_probabilities, color=['teal', 'yellow', 'green', 'blue', 'orange'])
plt.title('Top 5 Most Likely Classes')
plt.ylabel('Probability')
plt.show()

Verificamos que o modelo previu, com grande confiança, que a imagem que seleccionámos é de um golden retriever. Algumas das outras classes consideradas pelo modelo são outros tipos de retrievers. Curiosamente, uma bola de ténis também apareceu na lista de resultados.
- Make a submission