Detecção de Pneumonia com Deep Learning
Deep Learning na área da saúde
Com o avanço do campo da Inteligência Artificial cada vez mais ela é aplicada nos mais diversos campos do conhecimento e na área da saúde não é diferente.
Atualmente a Inteligência Artificial está sendo aplicada em diversas situações dentro da medicina, algumas delas são:
- Aumentar a precisão de diagnósticos
- Alerta do quadro clínico do paciente
- Tratamento de Doenças
- Determinar estudos relevantes sobre um determinado tema
- Identificação e assimilação de sintomas
Deep Learning
A técnica conhecida como Deep Learning é com toda certeza uma das técnicas mais aplicadas nessa área, seu funcionamento é baseado nas Redes Neurais Artificias que tem como objetivo reproduzir o comportamento do cérebro humano para assimilar as informações informadas.
O comportamento das Redes Neurais Artificiais baseia-se no comportamento de um neurônio, com camadas dispostas de forma hierárquica, assim a informação vai de camada em camada, conduzindo a informação, até a camada de output
. A imagem a seguir ilustra esse processo.
Pneumonia: O que é?
A Pneumonia é caracterizada por uma condição inflamatória no pulmão que afeta principalmente os Alvéolos. Os principais fatores que podem levar a um quadro de pneumonia são:
- inalação de produtos tóxicos
- infecções virais ou bacterianas
Podem ser classificados como fatores de risco, ou seja fatores que podem aumentar as chances de desenvolver a doença, o tabagismo, o uso de ar-condicionado, também pode ser incluído pessoas com asma, Doença Pulmonar Obstrutiva Crônica (DPOC), diabetes, fibrose cística entre outras.
Qualquer pessoa está sujeita a desenvolver a doença, no entanto ela possui maior incidência em idosos e em crianças abaixo dos 5 anos, vale destacar que segundo a OMS, a Pneumonia é uma das principais causa de mortes em crianças abaixo dos 5 anos. Fonte.
Os sintomas podem variar conforme o causador, mas geralmente é comum apresentar febre alta (acima dos 37,5°C), dor no peito, tosse com secreção e falta de ar.
O Diagnóstico é feito com base em exames clínicos como:
- Radiografia do Tórax
- Hemograma
- Hemocultura
Vale destacar que a Radiografia do Tórax além de ajudar no diagnóstico, também contribui tanto para a avaliação da gravidade da doença, como a resposta do paciente ao tratamento.
O Tratamento pode variar de acordo com o agente causador. Em Pneumonias bacterianas geralmente o tratamento é feito com o uso de antibióticos, já com as Pneumonias virais o tratamento é feito com medicamentos para alívio dos sintomas e também pode ser usado medicamentos antivirais.
Obtenção dos dados
O dataset que vamos trabalhar é composto por três pastas, (train, test e valid) e as três estão subdividas em NORMAL e PNEUMONIA, ao total são 5863 imagens no formato JPEG.
O dataset originalmente foi publicado no site Mendeley Data Link e repostado no Kaggle Link, no entanto para facilitar coloquei Aqui um link direto para fazer o download.
Importando as bibliotecas e fazendo as configurações iniciais
Nesta primeira etapa, vamos importar todas as bibliotecas que vamos utilizar durante o desenvolvimento.
Ainda nesta etapa, também vamos adicionar uma pequena configuração para melhorar a visualização de imagens e gráficos no projeto.
Após fazer o download do dataset de imagens, você vai notar que o mesmo estará compactado, depois de adiciona-lo no drive, vamos conectar o colab ao Google drive e em seguida descompactar o dataset.
Organizando os diretórios
Após importar e descompactar os arquivos, você vai ter 3 pastas como mencionado, com as imagens de Treino, Teste e Validação, mas agora temos que organizar nossos diretórios em dataset_train
, dataset_test
, dataset_valid
e também adicionar os labels das imagens.
Você pode observar que nas dimensões da imagem na função cv2.imread()
colocamos 150 x 150 pixels, o motivo disso é que vamos configurar nossa rede neural para receber imagens com essas dimensões.
Separando o dataset
É de conhecimento de todos que temos que separar o dataset em X
e Y
, em nosso X
vamos carregar as imagens e no Y
vamos carregar os labels das respectivas imagens.
Atenção: Deve-se fazer isso para os 3 datasets, treino, teste e validação.
Exploração dos dados e Pré-processamento das imagens
Agora que separamos nossos dados em X
e Y
podemos iniciar a etapa de exploração de dados e Pré-processamento das imagens, dentro delas, vamoss ter sub-etapas que serão explicadas uma a uma.
Verificando se o dataset está balanceado
Quando estamos lidando com Deep Learning, sempre devemos estar atentos se os datasets estão balanceados.
Por mais que seja nítido, que o número de pessoas sem Pneumonia seja menor que o número de pessoas com a doença, trabalhar com os dados dessa forma, pode impactar negativamente de forma significativa no desempenho do nosso modelo.
Portanto, vamos visualizar como nosso dataset_train
que será usado para treinar a rede neural está distribuído.
O gráfico que plotamos nos mostra que o dataset não esta balanceado, logo vamos ter que realizar o processo de data augmentation que será explicado mais a frente.
Visualizando exemplos de imagens
Vamos visualizar uma imagem de um pulmão saudável e a imagem de um pulmão com pneumonia.
Normalizando os Pixels
Nesta etapa vamos fazer os valores de cada pixel, que como já foi mencionado está no intervalo [0,255], ficarem no intervalo [0,1], essencialmente queremos transformar os valores dos pixels para o tipo float
. Para fazer isso basta dividir todos os pixels pelo maior valor possível, nesse caso 255.0.
Para realizar essa etapa foi criada uma função Lambda, denominada f_norm
, para agilizar o processo, pois a normalização deve ser feita com os os 3 datasets
A saída obtida pela célula foi:
Shape x_train: (5216, 150, 150)
Shape x_valid: (16, 150, 150)
Shape x_test: (624, 150, 150)
Redimensionalizar as imagens
O TensorFlow espera uma lista com 4 dimensões e com base na saída que tivemos, pode-se notar que os datasets de treino, validação e teste estão nos retornando uma lista com 3 dimensões. A lista que o TensorFlow espera é da forma (m,a,l,c), onde
- m= Número de imagens
- a= Altura
- l= Largura
- c= Número de Canais
Como as imagens estão em escala cinza, o número de canais é 1
Shape x_train: (5216, 150, 150, 1)
Shape x_valid: (16, 150, 150, 1)
Shape x_test: (624, 150, 150, 1)
Agora temos uma lista com as 4 dimensões esperadas.
Converter X
e Y
para Array
Esta etapa é necessária para posteriormente treinarmos nosso dataset.
Data Augmentation
Está etapa é necessária uma vez que como já foi explicado, nosso dataset tem uma grande discrepância entre as imagens com pneumonia e sem a doença.
Este processo faz com que tenhamos mais dados, a partir dos já existentes, para isso ele aplica transformações de translação, rotação e inversão e com essas pequenas alterações nas imagens já existentes, nossa rede neural as considera como novas imagens.
Agora vamos treinar nosso data_gen
com as imagens de treino.
Criando o modelo
Breve explicação sobre o modelo:
A camada Conv2D
é uma camada de Convolução, ou seja, ela aplica filtros em toda a imagem para obter informações importantes.
A camada MaxPool2D
tem como objetivo passar um kernel pelos pixels da imagem, no nosso caso 2x2
dentro dessa área ele retornará o maior valor de pixels, sendo assim, essa camada simplifica a informação que ela obteve. Observe a imagem
A camada BatchNormalization
tem como objetivo normalizar as saídas da camada anterior, para isso ela aplica uma transformação em toda sua entrada, para que a saída seja próxima de 0 .
Com a camada dropout
buscamos reduzir o overfitting. A camada Flatten
nivela a saída da camada anterior para apresentar a informação em uma única coluna. E por fim, temos a camada Dense
que é a responsável por fazer toda a informação que caminhou pelas camadas anteriores passar por uma função de ativação.
Compilando o modelo
A linha model.summary()
nos fornece um resumo sobre nosso modelo, mostrando todas as camadas, com os respectivos parâmetros.
AplicandoReduceLROnPlateau
Algumas vezes, a aprendizagem do modelo estagna, quando usamos essa função, ela monitora uam quantidade, no caso, pedimos para ela monitorar a acurácia do nosso modelo e no momento em que esse valor se estagnar por mais de 2 épocas (patience=2
) ela penaliza o modelo reduzindo sua taxa de aprendizagem, evitando o Plateau do modelo.
Treinando a rede neural
E por fim, vamos avaliar nosso modelo, vamos primeiramente, plotar um gráfico que mostra a evolução do modelo durante as épocas.
Verificando a Acurácia
Na primeira célula vamos pedir para o modelo fazer a previsão dos valores do x_test
Já na segunda pedimos para retornar a acurácia de acertos com imagens de pulmão saudável e pulmão com pneumonia, notamos que nosso modelo conseguiu 93% de acurácia para detectar pneumonia e 89% de acurácia para detectar imagens com o pulmão saudável.
A segunda célula nos retornou
Aplicando o modelo a uma única imagem
Podemos testar nosso modelo com uma única imagem também, basta pegar qualquer imagem do diretório test e fazer os testes com imagens em que há a presença da doença e imagens onde não há.
Atenção: Para fazer isso observe que temos que aplicar todas as transformações do Pré-processamento de imagens.
em img
colocamos uma imagem que apresenta pneumonia, após aplicar as transformações necessárias, temos a nossa saída, caso ela for próxima de 1, significa que nosso modelo identificou que é um Pulmão infectado com a doença, caso for um número próximo de zero, o modelo identificou que é um pulmão sem a presença da doença. A saída obtida com a célula acima foi:
[[0.9930381]]
Logo nosso modelo acertou!!!
Caso queira ter acesso ao código completo, ele está hospedado no meu github, basta clicar (AQUI)