Reconhecimento de Câncer de Mama Usando CNN

  • Linguagem: Python 3.6.5
  • Ambiente de desevnolvimento: Jupyter Notebook
  • Bibliotecas: TensorFlow 2.4.1

Configuração da GPU

import tensorflow as tf

dispositivos_gpu = tf.config.list_physical_devices("GPU")
if dispositivos_gpu:
    dispositivo_gpu = dispositivos_gpu[0]
    tf.config.experimental.set_memory_growth(dispositivo_gpu, True)
    tf.config.set_visible_devices([dispositivo_gpu], "GPU")

import matplotlib.pyplot as plt
import os, PIL, pathlib
import numpy as np
import pandas as pd
import warnings
from tensorflow import keras

warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

Carregamento dos Dados

diretorio_dados = "./32-dados"
diretorio_dados = pathlib.Path(diretorio_dados)
numero_imagens = len(list(diretorio_dados.glob('*/*')))
print("Número total de imagens:", numero_imagens)

Número total de imagens: 13403

tamanho_lote = 16
altura_imagem = 50
largura_imagem = 50

conjunto_treino = tf.keras.preprocessing.image_dataset_from_directory(
    diretorio_dados,
    validation_split=0.2,
    subset="training",
    seed=12,
    image_size=(altura_imagem, largura_imagem),
    batch_size=tamanho_lote)

conjunto_validacao = tf.keras.preprocessing.image_dataset_from_directory(
    diretorio_dados,
    validation_split=0.2,
    subset="validation",
    seed=12,
    image_size=(altura_imagem, largura_imagem),
    batch_size=tamanho_lote)

nomes_classes = conjunto_treino.class_names
print(nomes_classes)

['0', '1']

Pré-processamento dos Dados

AUTOTUNING = tf.data.AUTOTUNE

def preprocessamento_imagem(imagem, rotulo):
    return imagem / 255.0, rotulo

conjunto_treino = (
    conjunto_treino.cache()
    .shuffle(1000)
    .map(preprocessamento_imagem)
    .prefetch(buffer_size=AUTOTUNING)
)

conjunto_validacao = (
    conjunto_validacao.cache()
    .shuffle(1000)
    .map(preprocessamento_imagem)
    .prefetch(buffer_size=AUTOTUNING)
)

Visualização dos Dados

plt.figure(figsize=(10, 8))
plt.suptitle("Exemplos de Imagens")

nomes_classes = ["Células de Câncer de Mama", "Células Normais"]

for imagens, rotulos in conjunto_treino.take(1):
    for i in range(15):
        plt.subplot(4, 5, i + 1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)

        plt.imshow(imagens[i])
        plt.xlabel(nomes_classes[int(rotulos[i])])

plt.show()

Criação do Modelo

modelo = tf.keras.Sequential([
    tf.keras.layers.Conv2D(16, (3, 3), padding="same", activation="relu", input_shape=[largura_imagem, altura_imagem, 3]),
    tf.keras.layers.Conv2D(16, (3, 3), padding="same", activation="relu"),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Conv2D(16, (3, 3), padding="same", activation="relu"),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Conv2D(16, (3, 3), padding="same", activation="relu"),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(2, activation="softmax")
])
modelo.summary()

Compilação do Modelo

modelo.compile(optimizer="adam",
               loss='sparse_categorical_crossentropy',
               metrics=['accuracy'])

Treinamento do Modelo

EPOCAS = 100
PACIENCIA = 5
VERBOSO = 1

ajustador_taxa_aprendizado = tf.keras.callbacks.LearningRateScheduler(lambda x: 1e-3 * 0.99 ** (x+EPOCAS))
parada_antecipada = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=PACIENCIA, verbose=VERBOSO)
salvador_modelo = tf.keras.callbacks.ModelCheckpoint('melhor_modelo.h5',
                                                      monitor='val_accuracy',
                                                      verbose=VERBOSO,
                                                      save_best_only=True,
                                                      save_weights_only=True)

historico_treino = modelo.fit(conjunto_treino,
                              epochs=EPOCAS,
                              verbose=VERBOSO,
                              validation_data=conjunto_validacao,
                              callbacks=[parada_antecipada, salvador_modelo, ajustador_taxa_aprendizado])

Avaliação do Modelo

Acurácia e Perda

acuracia = historico_treino.history['accuracy']
acuracia_val = historico_treino.history['val_accuracy']

perda = historico_treino.history['loss']
perda_val = historico_treino.history['val_loss']

epocas = range(len(acuracia))

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)

plt.plot(epocas, acuracia, label='Acurácia de Treino')
plt.plot(epocas, acuracia_val, label='Acurácia de Validação')
plt.legend(loc='lower right')
plt.title('Acurácia de Treino e Validação')

plt.subplot(1, 2, 2)
plt.plot(epocas, perda, label='Perda de Treino')
plt.plot(epocas, perda_val, label='Perda de Validação')
plt.legend(loc='upper right')
plt.title('Perda de Treino e Validação')
plt.show()

Matriz de Confusão

from sklearn.metrics import confusion_matrix
import seaborn as sns
import pandas as pd

def plotar_matriz_confusao(rotulos_reais, rotulos_preditos):
    matriz_confusao = confusion_matrix(rotulos_reais, rotulos_preditos)
    df_confusao = pd.DataFrame(matriz_confusao, index=nomes_classes, columns=nomes_classes)

    plt.figure(figsize=(8, 7))
    sns.heatmap(df_confusao, annot=True, fmt="d", cmap="BuPu")
    plt.title('Matriz de Confusão', fontsize=15)
    plt.ylabel('Valores Reais', fontsize=14)
    plt.xlabel('Valores Preditos', fontsize=14)

previsoes = []
rotulos_reais = []

for imagens, rotulos in conjunto_validacao:
    for imagem, rotulo in zip(imagens, rotulos):
        imagem_expandida = tf.expand_dims(imagem, 0)
        previsao = modelo.predict(imagem_expandida)

        previsoes.append(nomes_classes[np.argmax(previsao)])
        rotulos_reais.append(nomes_classes[rotulo])

plotar_matriz_confusao(rotulos_reais, previsoes)

Métricas de Avaliação

from sklearn import metrics

def relatorio_acuracia_teste(modelo):
    print(metrics.classification_report(rotulos_reais, previsoes, target_names=nomes_classes))
    pontuacao = modelo.evaluate(conjunto_validacao, verbose=0)
    print('Função de perda:', pontuacao[0], ', acurácia:', pontuacao[1])

relatorio_acuracia_teste(modelo)

Tags: tensorflow CNN Reconhecimento de Imagens Python

Publicado em 8-6 16:32