Aprendizado profundo com Keras - Guia rápido

Aprendizado profundo se tornou uma palavra da moda nos últimos dias no campo da Inteligência Artificial (IA). Por muitos anos, usamos o aprendizado de máquina (ML) para transmitir inteligência às máquinas. Nos últimos dias, o aprendizado profundo se tornou mais popular devido à sua supremacia em previsões em comparação com as técnicas tradicionais de ML.

Aprendizado profundo significa essencialmente treinar uma Rede Neural Artificial (RNA) com uma grande quantidade de dados. No aprendizado profundo, a rede aprende por si mesma e, portanto, requer dados enormes para o aprendizado. Enquanto o aprendizado de máquina tradicional é essencialmente um conjunto de algoritmos que analisam dados e aprendem com eles. Eles então usaram esse aprendizado para tomar decisões inteligentes.

Agora, chegando ao Keras, é uma API de redes neurais de alto nível que é executada em cima do TensorFlow - uma plataforma de aprendizado de máquina de código aberto de ponta a ponta. Usando o Keras, você define facilmente arquiteturas de RNA complexas para experimentar em seu big data. Keras também oferece suporte a GPU, que se torna essencial para processar grandes quantidades de dados e desenvolver modelos de aprendizado de máquina.

Neste tutorial, você aprenderá o uso de Keras na construção de redes neurais profundas. Veremos exemplos práticos de ensino. O problema em questão é reconhecer dígitos escritos à mão usando uma rede neural treinada com aprendizado profundo.

Apenas para deixá-lo mais animado com o aprendizado profundo, abaixo está uma captura de tela das tendências do Google no aprendizado profundo aqui -

Como você pode ver no diagrama, o interesse pelo aprendizado profundo está crescendo continuamente nos últimos anos. Existem muitas áreas, como visão computacional, processamento de linguagem natural, reconhecimento de fala, bioinformática, design de drogas e assim por diante, onde o aprendizado profundo foi aplicado com sucesso. Este tutorial irá ajudá-lo a começar rapidamente com o aprendizado profundo.

Continue lendo!

Como dito na introdução, o aprendizado profundo é um processo de treinamento de uma rede neural artificial com uma grande quantidade de dados. Depois de treinada, a rede será capaz de nos dar as previsões sobre dados não vistos. Antes de prosseguir na explicação do que é aprendizado profundo, vamos examinar rapidamente alguns termos usados ​​no treinamento de uma rede neural.

Redes neurais

A ideia de rede neural artificial foi derivada de redes neurais em nosso cérebro. Uma rede neural típica consiste em três camadas - entrada, saída e camada oculta, conforme mostrado na imagem abaixo.

Isso também é chamado de shallowrede neural, pois contém apenas uma camada oculta. Você adiciona mais camadas ocultas na arquitetura acima para criar uma arquitetura mais complexa.

Deep Networks

O diagrama a seguir mostra uma rede profunda que consiste em quatro camadas ocultas, uma camada de entrada e uma camada de saída.

À medida que o número de camadas ocultas é adicionado à rede, seu treinamento torna-se mais complexo em termos de recursos necessários e o tempo que leva para treinar totalmente a rede.

Treinamento de rede

Depois de definir a arquitetura de rede, você a treina para fazer certos tipos de previsões. Treinar uma rede é o processo de encontrar os pesos adequados para cada link na rede. Durante o treinamento, os dados fluem das camadas de entrada para saída por meio de várias camadas ocultas. Como os dados sempre se movem em uma direção da entrada para a saída, chamamos essa rede de Rede Feed-forward e chamamos a propagação de dados de Propagação Forward.

Função de Ativação

Em cada camada, calculamos a soma ponderada das entradas e a alimentamos para uma função de ativação. A função de ativação traz não linearidade para a rede. É simplesmente alguma função matemática que discretiza a saída. Algumas das funções de ativação mais comumente usadas são sigmóide, hiperbólica, tangente (tanh), ReLU e Softmax.

Retropropagação

A retropropagação é um algoritmo para aprendizagem supervisionada. Na retropropagação, os erros se propagam da saída para a camada de entrada. Dada uma função de erro, calculamos o gradiente da função de erro em relação aos pesos atribuídos em cada conexão. O cálculo do gradiente ocorre de trás para frente na rede. O gradiente da camada final de pesos é calculado primeiro e o gradiente da primeira camada de pesos é calculado por último.

Em cada camada, os cálculos parciais do gradiente são reutilizados no cálculo do gradiente da camada anterior. Isso é chamado de Gradient Descent.

Neste tutorial baseado em projeto, você definirá uma rede neural profunda feed-forward e a treinará com técnicas de retropropagação e gradiente descendente. Felizmente, Keras nos fornece todas as APIs de alto nível para definir a arquitetura de rede e treiná-la usando gradiente descendente. A seguir, você aprenderá como fazer isso no Keras.

Sistema de reconhecimento de dígitos manuscritos

Neste mini projeto, você aplicará as técnicas descritas anteriormente. Você criará uma rede neural de aprendizado profundo que será treinada para reconhecer dígitos escritos à mão. Em qualquer projeto de aprendizado de máquina, o primeiro desafio é coletar os dados. Especialmente, para redes de aprendizagem profunda, você precisa de dados enormes. Felizmente, para o problema que estamos tentando resolver, alguém já criou um conjunto de dados para treinamento. Isso é chamado de mnist, que está disponível como parte das bibliotecas Keras. O conjunto de dados consiste em várias imagens de 28x28 pixels de dígitos escritos à mão. Você treinará seu modelo na maior parte deste conjunto de dados e o restante dos dados será usado para validar seu modelo treinado.

Descrição do Projeto

o mnistO conjunto de dados consiste em 70000 imagens de dígitos manuscritos. Algumas imagens de amostra são reproduzidas aqui para sua referência

Cada imagem tem o tamanho de 28 x 28 pixels, perfazendo um total de 768 pixels de vários níveis de escala de cinza. A maioria dos pixels tende para o tom preto, enquanto apenas alguns deles são para o branco. Colocaremos a distribuição desses pixels em um array ou vetor. Por exemplo, a distribuição de pixels para uma imagem típica de dígitos 4 e 5 é mostrada na figura abaixo.

Cada imagem tem o tamanho de 28 x 28 pixels, perfazendo um total de 768 pixels de vários níveis de escala de cinza. A maioria dos pixels tende para o tom preto, enquanto apenas alguns deles são para o branco. Colocaremos a distribuição desses pixels em um array ou vetor. Por exemplo, a distribuição de pixels para uma imagem típica de dígitos 4 e 5 é mostrada na figura abaixo.

Claramente, você pode ver que a distribuição dos pixels (especialmente aqueles que tendem para o tom branco) difere, isso distingue os dígitos que eles representam. Alimentaremos essa distribuição de 784 pixels em nossa rede como sua entrada. A saída da rede consistirá em 10 categorias que representam um dígito entre 0 e 9.

Nossa rede consistirá em 4 camadas - uma camada de entrada, uma camada de saída e duas camadas ocultas. Cada camada oculta conterá 512 nós. Cada camada está totalmente conectada à próxima camada. Quando treinarmos a rede, estaremos computando os pesos para cada conexão. Treinamos a rede aplicando retropropagação e gradiente descendente que discutimos anteriormente.

Com esse pano de fundo, vamos agora começar a criar o projeto.

Configurando Projeto

Nós vamos usar Jupyter através Anacondanavegador para o nosso projeto. Como nosso projeto usa TensorFlow e Keras, você precisará instalá-los na configuração do Anaconda. Para instalar o Tensorflow, execute o seguinte comando na janela do console:

>conda install -c anaconda tensorflow

Para instalar o Keras, use o seguinte comando -

>conda install -c anaconda keras

Agora você está pronto para iniciar o Jupyter.

Iniciando Jupyter

Ao iniciar o navegador Anaconda, você verá a seguinte tela de abertura.

Clique ‘Jupyter’para começar. A tela mostrará os projetos existentes, se houver, em sua unidade.

Iniciando um Novo Projeto

Inicie um novo projeto Python 3 no Anaconda selecionando a seguinte opção de menu -

File | New Notebook | Python 3

A captura de tela da seleção do menu é mostrada para sua referência rápida -

Um novo projeto em branco aparecerá em sua tela, conforme mostrado abaixo -

Altere o nome do projeto para DeepLearningDigitRecognition clicando e editando no nome padrão “UntitledXX”.

Primeiro importamos as várias bibliotecas exigidas pelo código em nosso projeto.

Manipulação e plotagem de matriz

Normalmente, usamos numpy para manipulação de array e matplotlibpara plotagem. Essas bibliotecas são importadas em nosso projeto usando o seguinteimport afirmações

import numpy as np
import matplotlib
import matplotlib.pyplot as plot

Suprimindo avisos

Como o Tensorflow e o Keras continuam revisando, se você não sincronizar suas versões apropriadas no projeto, no tempo de execução você verá muitos erros de aviso. Como eles desviam a sua atenção do aprendizado, estaremos suprimindo todos os avisos neste projeto. Isso é feito com as seguintes linhas de código -

# silent all warnings
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
import warnings
warnings.filterwarnings('ignore')
from tensorflow.python.util import deprecation
deprecation._PRINT_DEPRECATION_WARNINGS = False

Keras

Usamos bibliotecas Keras para importar conjuntos de dados. Vamos usar omnistconjunto de dados para dígitos manuscritos. Importamos o pacote necessário usando a seguinte instrução

from keras.datasets import mnist

Estaremos definindo nossa rede neural de aprendizado profundo usando pacotes Keras. Nós importamos oSequential, Dense, Dropout e Activationpacotes para definir a arquitetura da rede. Nós usamosload_modelpacote para salvar e recuperar nosso modelo. Nós também usamosnp_utilspara alguns utilitários que precisamos em nosso projeto. Essas importações são feitas com as seguintes declarações do programa -

from keras.models import Sequential, load_model
from keras.layers.core import Dense, Dropout, Activation
from keras.utils import np_utils

Ao executar este código, você verá uma mensagem no console que diz que Keras usa TensorFlow no back-end. A captura de tela nesta fase é mostrada aqui -

Agora, como temos todas as importações exigidas por nosso projeto, prosseguiremos com a definição da arquitetura de nossa rede de Deep Learning.

Nosso modelo de rede neural consistirá em uma pilha linear de camadas. Para definir esse modelo, chamamos oSequential função -

model = Sequential()

Camada de entrada

Definimos a camada de entrada, que é a primeira camada em nossa rede usando a seguinte instrução do programa -

model.add(Dense(512, input_shape=(784,)))

Isso cria uma camada com 512 nós (neurônios) com 784 nós de entrada. Isso é ilustrado na figura abaixo -

Observe que todos os nós de entrada estão totalmente conectados à Camada 1, ou seja, cada nó de entrada está conectado a todos os 512 nós da Camada 1.

Em seguida, precisamos adicionar a função de ativação para a saída da Camada 1. Usaremos ReLU como nossa ativação. A função de ativação é adicionada usando a seguinte declaração do programa -

model.add(Activation('relu'))

A seguir, adicionamos Abandono de 20% usando a declaração abaixo. O dropout é uma técnica usada para evitar que o modelo seja superdimensionado.

model.add(Dropout(0.2))

Neste ponto, nossa camada de entrada está totalmente definida. Em seguida, vamos adicionar uma camada oculta.

Camada Oculta

Nossa camada oculta consistirá em 512 nós. A entrada para a camada oculta vem de nossa camada de entrada definida anteriormente. Todos os nós estão totalmente conectados como no caso anterior. A saída da camada oculta irá para a próxima camada na rede, que será nossa camada final e de saída. Usaremos a mesma ativação ReLU da camada anterior e um abandono de 20%. O código para adicionar esta camada é fornecido aqui -

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))

A rede nesta fase pode ser visualizada da seguinte forma -

A seguir, adicionaremos a camada final à nossa rede, que é a camada de saída. Observe que você pode adicionar qualquer número de camadas ocultas usando o código semelhante ao que você usou aqui. Adicionar mais camadas tornaria a rede complexa para treinamento; no entanto, dando uma vantagem definitiva de melhores resultados em muitos casos, embora não em todos.

Camada de Saída

A camada de saída consiste em apenas 10 nós, pois queremos classificar as imagens fornecidas em 10 dígitos distintos. Adicionamos essa camada, usando a seguinte declaração -

model.add(Dense(10))

Como queremos classificar a saída em 10 unidades distintas, usamos a ativação softmax. No caso de ReLU, a saída é binária. Adicionamos a ativação usando a seguinte declaração -

model.add(Activation('softmax'))

Neste ponto, nossa rede pode ser visualizada conforme mostrado no diagrama abaixo -

Neste ponto, nosso modelo de rede está totalmente definido no software. Execute a célula de código e se não houver erros, você receberá uma mensagem de confirmação na tela, conforme mostrado na imagem abaixo -

Em seguida, precisamos compilar o modelo.

A compilação é realizada usando uma única chamada de método chamada compile.

model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')

o compilemétodo requer vários parâmetros. O parâmetro de perda é especificado para ter tipo'categorical_crossentropy'. O parâmetro metrics está definido como'accuracy' e finalmente usamos o adamotimizador para treinar a rede. A saída nesta fase é mostrada abaixo -

Agora, estamos prontos para inserir os dados em nossa rede.

Carregando dados

Como disse antes, vamos usar o mnistconjunto de dados fornecido por Keras. Quando carregamos os dados em nosso sistema, vamos dividi-los nos dados de treinamento e teste. Os dados são carregados chamando oload_data método da seguinte forma -

(X_train, y_train), (X_test, y_test) = mnist.load_data()

A saída neste estágio se parece com o seguinte -

Agora, aprenderemos a estrutura do conjunto de dados carregado.

Os dados que nos são fornecidos são as imagens gráficas de tamanho 28 x 28 pixels, cada uma contendo um único dígito entre 0 e 9. Iremos exibir as primeiras dez imagens no console. O código para fazer isso é fornecido abaixo -

# printing first 10 images
for i in range(10):

plot.subplot(3,5,i+1)
plot.tight_layout()
plot.imshow(X_train[i], cmap='gray', interpolation='none')
plot.title("Digit: {}".format(y_train[i]))
plot.xticks([])
plot.yticks([])

Em um loop iterativo de 10 contagens, criamos um subplot em cada iteração e mostramos uma imagem de X_trainvetor nele. Nós intitulamos cada imagem do correspondentey_trainvetor. Observe que oy_train vetor contém os valores reais para a imagem correspondente em X_trainvetor. Removemos as marcações dos eixos xey chamando os dois métodosxticks e ytickscom argumento nulo. Ao executar o código, você verá a seguinte saída -

A seguir, prepararemos os dados para alimentá-los em nossa rede.

Antes de alimentarmos os dados em nossa rede, eles devem ser convertidos para o formato exigido pela rede. Isso é chamado de preparação de dados para a rede. Geralmente consiste em converter uma entrada multidimensional em um vetor unidimensional e normalizar os pontos de dados.

Remodelando o vetor de entrada

As imagens em nosso conjunto de dados consistem em 28 x 28 pixels. Isso deve ser convertido em um vetor unidimensional de tamanho 28 * 28 = 784 para alimentá-lo em nossa rede. Fazemos isso chamando oreshape método no vetor.

X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)

Agora, nosso vetor de treinamento consistirá em 60.000 pontos de dados, cada um consistindo em um vetor de dimensão única de tamanho 784. Da mesma forma, nosso vetor de teste consistirá em 10.000 pontos de dados de um vetor de dimensão única de tamanho 784.

Normalizando Dados

Os dados que o vetor de entrada contém atualmente têm um valor discreto entre 0 e 255 - os níveis da escala de cinza. Normalizar esses valores de pixel entre 0 e 1 ajuda a acelerar o treinamento. Como usaremos a descida gradiente estocástica, a normalização dos dados também ajudará a reduzir a chance de ficar preso em ótimos locais.

Para normalizar os dados, nós os representamos como tipo float e os dividimos por 255, conforme mostrado no seguinte trecho de código -

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

Vejamos agora como os dados normalizados se parecem.

Examinando Dados Normalizados

Para visualizar os dados normalizados, chamaremos a função de histograma conforme mostrado aqui -

plot.hist(X_train[0])
plot.title("Digit: {}".format(y_train[0]))

Aqui, traçamos o histograma do primeiro elemento do X_trainvetor. Também imprimimos o dígito representado por este ponto de dados. O resultado da execução do código acima é mostrado aqui -

Você notará uma densidade espessa de pontos com valores próximos a zero. Esses são os pontos pretos na imagem, que obviamente são a parte principal da imagem. O resto dos pontos da escala de cinza, que estão próximos da cor branca, representam o dígito. Você pode verificar a distribuição de pixels para outro dígito. O código a seguir imprime o histograma de um dígito no índice de 2 no conjunto de dados de treinamento.

plot.hist(X_train[2])
plot.title("Digit: {}".format(y_train[2])

O resultado da execução do código acima é mostrado abaixo -

Comparando as duas figuras acima, você notará que a distribuição dos pixels brancos em duas imagens difere, indicando uma representação de um dígito diferente - “5” e “4” nas duas imagens acima.

A seguir, examinaremos a distribuição de dados em nosso conjunto de dados de treinamento completo.

Examinando a distribuição de dados

Antes de treinar nosso modelo de aprendizado de máquina em nosso conjunto de dados, devemos saber a distribuição de dígitos únicos em nosso conjunto de dados. Nossas imagens representam 10 dígitos distintos que variam de 0 a 9. Gostaríamos de saber o número de dígitos 0, 1, etc., em nosso conjunto de dados. Podemos obter essas informações usando ounique método de Numpy.

Use o seguinte comando para imprimir o número de valores únicos e o número de ocorrências de cada um

print(np.unique(y_train, return_counts=True))

Ao executar o comando acima, você verá a seguinte saída -

(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([5923, 6742, 5958, 6131, 5842, 5421, 5918, 6265, 5851, 5949]))

Mostra que existem 10 valores distintos - 0 a 9. Existem 5923 ocorrências do dígito 0, 6742 ocorrências do dígito 1 e assim por diante. A captura de tela da saída é mostrada aqui -

Como uma etapa final na preparação de dados, precisamos codificar nossos dados.

Dados de codificação

Temos dez categorias em nosso conjunto de dados. Assim, codificaremos nossa saída nessas dez categorias usando codificação one-hot. Usamos o método to_categorial dos utilitários Numpy para realizar a codificação. Depois que os dados de saída são codificados, cada ponto de dados seria convertido em um vetor dimensional único de tamanho 10. Por exemplo, o dígito 5 agora será representado como [0,0,0,0,0,1,0,0,0 , 0].

Codifique os dados usando o seguinte trecho de código -

n_classes = 10
Y_train = np_utils.to_categorical(y_train, n_classes)

Você pode verificar o resultado da codificação imprimindo os primeiros 5 elementos do vetor Y_train categorizado.

Use o seguinte código para imprimir os primeiros 5 vetores -

for i in range(5):
   print (Y_train[i])

Você verá a seguinte saída -

[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]

O primeiro elemento representa o dígito 5, o segundo representa o dígito 0 e assim por diante.

Finalmente, você terá que categorizar os dados de teste também, o que é feito usando a seguinte instrução -

Y_test = np_utils.to_categorical(y_test, n_classes)

Nesse estágio, seus dados estão totalmente preparados para alimentação na rede.

A seguir, vem a parte mais importante que é treinar nosso modelo de rede.

O treinamento do modelo é feito em uma única chamada de método chamada fit que leva alguns parâmetros, conforme visto no código abaixo -

history = model.fit(X_train, Y_train,
   batch_size=128, epochs=20,
   verbose=2,
   validation_data=(X_test, Y_test)))

Os primeiros dois parâmetros do método de ajuste especificam os recursos e a saída do conjunto de dados de treinamento.

o epochsé definido como 20; assumimos que o treinamento convergirá em no máximo 20 épocas - as iterações. O modelo treinado é validado nos dados de teste conforme especificado no último parâmetro.

A saída parcial da execução do comando acima é mostrada aqui -

Train on 60000 samples, validate on 10000 samples
Epoch 1/20
- 9s - loss: 0.2488 - acc: 0.9252 - val_loss: 0.1059 - val_acc: 0.9665
Epoch 2/20
- 9s - loss: 0.1004 - acc: 0.9688 - val_loss: 0.0850 - val_acc: 0.9715
Epoch 3/20
- 9s - loss: 0.0723 - acc: 0.9773 - val_loss: 0.0717 - val_acc: 0.9765
Epoch 4/20
- 9s - loss: 0.0532 - acc: 0.9826 - val_loss: 0.0665 - val_acc: 0.9795
Epoch 5/20
- 9s - loss: 0.0457 - acc: 0.9856 - val_loss: 0.0695 - val_acc: 0.9792

A captura de tela da saída é fornecida abaixo para sua referência rápida -

Agora, conforme o modelo é treinado em nossos dados de treinamento, avaliaremos seu desempenho.

Para avaliar o desempenho do modelo, chamamos evaluate método da seguinte forma -

loss_and_metrics = model.evaluate(X_test, Y_test, verbose=2)

Para avaliar o desempenho do modelo, chamamos evaluate método da seguinte forma -

loss_and_metrics = model.evaluate(X_test, Y_test, verbose=2)

Iremos imprimir a perda e precisão usando as duas declarações a seguir -

print("Test Loss", loss_and_metrics[0])
print("Test Accuracy", loss_and_metrics[1])

Ao executar as instruções acima, você verá a seguinte saída -

Test Loss 0.08041584826191042
Test Accuracy 0.9837

Isso mostra uma precisão de teste de 98%, o que deve ser aceitável para nós. O que significa para nós que em 2% dos casos, os dígitos manuscritos não seriam classificados corretamente. Também traçaremos as métricas de precisão e perda para ver como o modelo se comporta nos dados de teste.

Plotando métricas de precisão

Usamos o gravado historydurante nosso treinamento para obter um gráfico de métricas de precisão. O código a seguir traçará a precisão em cada época. Pegamos a precisão dos dados de treinamento (“acc”) e a precisão dos dados de validação (“val_acc”) para plotagem.

plot.subplot(2,1,1)
plot.plot(history.history['acc'])
plot.plot(history.history['val_acc'])
plot.title('model accuracy')
plot.ylabel('accuracy')
plot.xlabel('epoch')
plot.legend(['train', 'test'], loc='lower right')

O gráfico de saída é mostrado abaixo -

Como você pode ver no diagrama, a precisão aumenta rapidamente nas duas primeiras épocas, indicando que a rede está aprendendo rapidamente. Posteriormente, a curva é nivelada, indicando que não são necessárias muitas épocas para treinar mais o modelo. Geralmente, se a precisão dos dados de treinamento (“acc”) continua melhorando enquanto a precisão dos dados de validação (“val_acc”) piora, você está encontrando overfitting. Indica que o modelo está começando a memorizar os dados.

Também traçaremos as métricas de perda para verificar o desempenho de nosso modelo.

Plotando Métricas de Perda

Novamente, representamos a perda nos dados de treinamento (“perda”) e teste (“val_loss”). Isso é feito usando o seguinte código -

plot.subplot(2,1,2)
plot.plot(history.history['loss'])
plot.plot(history.history['val_loss'])
plot.title('model loss')
plot.ylabel('loss')
plot.xlabel('epoch')
plot.legend(['train', 'test'], loc='upper right')

A saída deste código é mostrada abaixo -

Como você pode ver no diagrama, a perda no conjunto de treinamento diminui rapidamente nas duas primeiras épocas. Para o conjunto de teste, a perda não diminui na mesma taxa que o conjunto de treinamento, mas permanece quase constante por várias épocas. Isso significa que nosso modelo está generalizando bem para dados não vistos.

Agora, usaremos nosso modelo treinado para prever os dígitos em nossos dados de teste.

É muito fácil prever os dígitos de um dado invisível. Você simplesmente precisa ligar para opredict_classes método do model passando-o para um vetor que consiste em seus pontos de dados desconhecidos.

predictions = model.predict_classes(X_test)

A chamada do método retorna as previsões em um vetor que pode ser testado para 0 e 1 em relação aos valores reais. Isso é feito usando as duas instruções a seguir -

correct_predictions = np.nonzero(predictions == y_test)[0]
incorrect_predictions = np.nonzero(predictions != y_test)[0]

Por fim, imprimiremos a contagem de previsões corretas e incorretas usando as duas declarações do programa a seguir -

print(len(correct_predictions)," classified correctly")
print(len(incorrect_predictions)," classified incorrectly")

Ao executar o código, você obterá a seguinte saída -

9837 classified correctly
163 classified incorrectly

Agora, como você treinou satisfatoriamente o modelo, vamos salvá-lo para uso futuro.

Salvaremos o modelo treinado em nossa unidade local na pasta de modelos em nosso diretório de trabalho atual. Para salvar o modelo, execute o seguinte código -

directory = "./models/"
name = 'handwrittendigitrecognition.h5'
path = os.path.join(save_dir, name)
model.save(path)
print('Saved trained model at %s ' % path)

A saída após a execução do código é mostrada abaixo -

Agora, como você salvou um modelo treinado, você pode usá-lo mais tarde para processar seus dados desconhecidos.

Para prever os dados invisíveis, primeiro você precisa carregar o modelo treinado na memória. Isso é feito usando o seguinte comando -

model = load_model ('./models/handwrittendigitrecognition.h5')

Observe que estamos simplesmente carregando o arquivo .h5 na memória. Isso configura toda a rede neural na memória junto com os pesos atribuídos a cada camada.

Agora, para fazer suas previsões sobre dados invisíveis, carregue os dados, que sejam um ou mais itens, na memória. Pré-processe os dados para atender aos requisitos de entrada de nosso modelo, como você fez nos dados de treinamento e teste acima. Após o pré-processamento, envie-o para sua rede. O modelo produzirá sua previsão.

Keras fornece uma API de alto nível para a criação de redes neurais profundas. Neste tutorial, você aprendeu a criar uma rede neural profunda que foi treinada para localizar os dígitos em texto manuscrito. Uma rede multicamadas foi criada para este propósito. Keras permite definir uma função de ativação de sua escolha em cada camada. Usando gradiente descendente, a rede foi treinada nos dados de treinamento. A precisão da rede treinada em prever os dados não vistos foi testada nos dados de teste. Você aprendeu a traçar as métricas de precisão e erro. Depois que a rede estiver totalmente treinada, você salvou o modelo de rede para uso futuro.