Classificação de imagens CNN no TensorFlow com etapas e exemplos
⚡ Resumo Inteligente
As Redes Neurais Convolucionais (CNNs) analisam uma imagem com pequenos filtros em vez de atribuir o mesmo peso a cada pixel, e é por isso que elas dominam a visão computacional. Este tutorial explica cada camada e, em seguida, classifica dígitos do MNIST com o TensorFlow.
O que é Rede Neural Convolucional?
Rede Neural ConvolucionalAs redes convolucionais (CNNs), também conhecidas como redes neurais convolucionais, são um método consagrado em aplicações de visão computacional. Trata-se de uma classe de redes neurais profundas utilizadas para analisar imagens visuais. Esse tipo de arquitetura é dominante para o reconhecimento de objetos em fotos ou vídeos. É empregado em aplicações como reconhecimento de imagem ou vídeo, processamento de linguagem natural e sistemas de recomendação.
Archiarquitetura de uma rede neural convolucional
Pense no Facebook de alguns anos atrás, depois de enviar uma foto para o seu perfil, você foi solicitado a adicionar manualmente um nome ao rosto da foto. Hoje em dia, o Facebook usa o convnet para marcar seu amigo na foto automaticamente.
Uma rede neural convolucional para classificação de imagens não é muito difícil de entender. Uma imagem de entrada é processada durante a fase de convolução e posteriormente recebe um rótulo.
Uma arquitetura típica de rede convolucional pode ser resumida na imagem abaixo. Primeiramente, uma imagem é enviada para a rede; essa é chamada de imagem de entrada. Em seguida, a imagem de entrada passa por uma série de etapas; essa é a parte convolucional da rede. Finalmente, a rede neural consegue prever o dígito na imagem.

Uma imagem é composta por uma matriz de pixels com altura e largura. Uma imagem em tons de cinza possui apenas um canal, enquanto uma imagem colorida possui três canais (um para vermelho, um para verde e um para azul). Os canais são sobrepostos. Neste tutorial, você usará uma imagem em tons de cinza com apenas um canal. Cada pixel possui um valor de 0 a 255 para refletir a intensidade da cor. Por exemplo, um pixel com valor 0 representará a cor branca, enquanto um pixel com um valor próximo a 255 será mais escuro.
Vamos dar uma olhada em uma imagem armazenada no Conjunto de dados MNISTA imagem abaixo mostra como representar a imagem à esquerda em formato de matriz. Observe que a matriz original foi padronizada para ter valores entre 0 e 1. Para cores mais escuras, o valor na matriz é aproximadamente 0.9, enquanto pixels brancos têm valor 0.
Operação convolucional
O componente mais crítico do modelo é a camada convolucional. Essa parte tem como objetivo reduzir o tamanho da imagem para cálculos mais rápidos dos pesos e melhorar a generalização.
Durante a parte convolucional, a rede mantém as características essenciais da imagem e exclui ruídos irrelevantes. Por exemplo, o modelo está aprendendo a reconhecer um elefante a partir de uma imagem com uma montanha ao fundo. Se você usar uma rede neural tradicional, o modelo atribuirá um peso a todos os pixels, inclusive aos da montanha, o que não é essencial e pode enganar a rede.
Em vez disso, um Keras A rede neural convolucional usará uma técnica matemática para extracA rede neural seleciona apenas os pixels mais relevantes. Essa operação matemática é chamada de convolução. Essa técnica permite que a rede aprenda características cada vez mais complexas em cada camada. A convolução divide a matriz em pequenas partes para aprender os elementos mais essenciais dentro de cada parte.
Componentes da Rede Neural Convolucional (ConvNet ou CNN)
Uma rede convolucional possui quatro componentes:
- Convolução
- Não Linearidade (ReLU)
- Pooling ou subamostragem
- Classificação (camada totalmente conectada)
Convolução
O objetivo da convolução é extracA rede neural aprende as características do objeto na imagem localmente. Isso significa que ela aprenderá padrões específicos dentro da imagem e será capaz de reconhecê-los em qualquer lugar da imagem.
A convolução é uma multiplicação elemento a elemento. O conceito é fácil de entender. O computador escaneia uma parte da imagem, geralmente com dimensões de 3×3, e a multiplica por um filtro. O resultado dessa multiplicação elemento a elemento é chamado de mapa de características. Esse processo é repetido até que toda a imagem seja escaneada. Observe que, após a convolução, o tamanho da imagem é reduzido.
O diagrama abaixo mostra um fragmento da imagem sendo multiplicado pelo filtro para produzir uma única célula do mapa de características.
A animação abaixo mostra a mesma convolução percorrendo toda a imagem.
Existem diversos filtros disponíveis. Abaixo, listamos alguns deles. Você pode ver que cada filtro tem uma finalidade específica. Observe que, na imagem abaixo, o kernel é um sinônimo do filtro.
Aritmética por trás da convolução
A fase convolucional aplicará o filtro em uma pequena matriz de pixels dentro da imagem. O filtro se moverá ao longo da imagem de entrada com um formato geral de 3×3 ou 5×5. Isso significa que a rede deslizará essas janelas por toda a imagem de entrada e calculará a convolução. A animação abaixo mostra como a convolução funciona. O tamanho do patch é 3×3 e a matriz de saída é o resultado da operação elemento a elemento entre a matriz da imagem e o filtro.
Você percebe que a largura e a altura da saída podem ser diferentes da largura e da altura da entrada. Isso acontece por causa do efeito fronteira.
Efeito de borda
A imagem possui um mapa de características de 5×5 e um filtro de 3×3. Há apenas uma janela no centro onde o filtro pode filtrar uma grade de 3×3. O mapa de características resultante diminui em duas unidades em cada eixo, deixando uma dimensão de 3×3.
Para obter a mesma dimensão de saída que a dimensão de entrada, é necessário adicionar preenchimento (padding). O preenchimento consiste em adicionar o número correto de linhas e colunas em cada lado da matriz. Isso permitirá que a convolução se ajuste ao centro de cada bloco de entrada. Na imagem abaixo, as matrizes de entrada e saída têm a mesma dimensão, 5×5.
Ao definir a rede, os recursos convolvidos são controlados por três parâmetros:
Profundidade: Define o número de filtros a serem aplicados durante a convolução. No exemplo anterior, você viu uma profundidade de 1, o que significa que apenas um filtro é usado. Na maioria dos casos, há mais de um filtro. A animação abaixo mostra as operações realizadas em uma situação com três filtros.
Passo: Define o número de "saltos de pixels" entre duas fatias. Se o passo for igual a 1, a janela se moverá com uma dispersão de um pixel. Se o passo for igual a 2, a janela saltará 2 pixels. Ao aumentar o passo, você terá mapas de características menores. Os dois diagramas abaixo comparam um passo de 1 com um passo de 2.
Exemplo de passada 1
passo 2
Preenchimento com zeros: O preenchimento (padding) é uma operação que consiste em adicionar um número correspondente de linhas e colunas em cada lado dos mapas de feições de entrada. Nesse caso, a saída tem a mesma dimensão que a entrada.
Não Linearidade (ReLU)
Ao final da operação de convolução, a saída é submetida a uma função de ativação para permitir a não linearidade. A função de ativação usual para uma rede convolucional é a ReLU. Todos os pixels com valor negativo serão substituídos por zero.
Pooling Operação
Esta etapa é fácil de entender. O objetivo do pooling é reduzir a dimensionalidade da imagem de entrada. As etapas são realizadas para reduzir a complexidade computacional da operação. Ao diminuir a dimensionalidade, a rede tem menos pesos para calcular, evitando assim o sobreajuste (overfitting).
Nesta etapa, você precisa definir o tamanho e o passo. Uma maneira padrão de agrupar a imagem de entrada é usar o valor máximo do mapa de características. Observe a imagem abaixo. O agrupamento irá filtrar quatro submatrizes do mapa de características 4×4 e retornar o valor máximo. O agrupamento pega o valor máximo de uma matriz 2×2 e então move essa janela em dois pixels. Por exemplo, a primeira submatriz é [3,1,3,2], então o agrupamento retornará o máximo, que é 3.
Existe outra operação de agrupamento, como a média.
Essa operação reduz drasticamente o tamanho do mapa de características.
Camadas totalmente conectadas
A última etapa consiste na construção de um tradicional rede neural artificial como você fez no tutorial anterior. Você conecta todos os neurônios da camada anterior à próxima camada. Você usa uma função de ativação softmax para classificar o número na imagem de entrada.
Recap:
Uma rede neural convolucional do TensorFlow compila diferentes camadas antes de fazer uma previsão. Uma rede neural possui:
- Uma camada convolucional
- função de ativação ReLU
- Poolincamada g
- Camada densamente conectada
As camadas convolucionais aplicam diferentes filtros em uma sub-região da imagem. A função de ativação ReLU adiciona não-linearidade, e as camadas de pooling reduzem a dimensionalidade dos mapas de características.
Todas essas camadas extracAs informações essenciais são extraídas das imagens. Por fim, os mapas de características são enviados para uma camada totalmente conectada com uma função softmax para realizar uma previsão.
Treine CNN com TensorFlow
Agora que você já conhece os componentes básicos de uma rede convolucional, está pronto para construir uma com... TensorFlow. Usaremos o conjunto de dados MNIST para classificação de imagens CNN.
A preparação dos dados é igual ao tutorial anterior. Você pode executar os códigos e ir diretamente para a arquitetura da CNN.
Você seguirá as etapas abaixo para classificação de imagens usando CNN:
- Etapa 1: fazer upload do conjunto de dados
- Etapa 2: camada de entrada
- Etapa 3: camada convolucional
- Passo 4: Poolincamada g
- Etapa 5: Segunda Camada Convolucional e Pooling Camada
- Etapa 6: camada densa
- Etapa 7: Camada Logit
Nota de versão: As listagens abaixo são direcionadas ao TensorFlow 1.x. No TensorFlow 2, o namespace `tf.layers` e a função `tf.estimator.inputs.numpy_input_fn` não existem mais; os equivalentes são `tf.keras.layers.Conv2D` e `Max`.Pooling2D, Dense e Dropout foram combinados em um tf.keras.Model e treinados com model.fit(). Leia as etapas para entender o funcionamento de cada camada e, em seguida, mapeie-as para a API do Keras.
Etapa 1: fazer upload do conjunto de dados
O conjunto de dados MNIST está disponível através do scikit-learn. Faça o download e salve-o na pasta Downloads. Você pode carregá-lo usando o comando `fetch_mldata('MNIST original')`.
Nota de versão: O site mldata.org foi desativado e a função fetch_mldata() foi removida no scikit-learn 0.22. Em qualquer instalação atual, carregue os mesmos dígitos com buscar_openml Em vez disso, use fetch_openml('mnist_784', version=1). O restante do pipeline permanece inalterado.
Crie um conjunto de treinamento/teste
Você precisa dividir o conjunto de dados com train_test_split.
Dimensione os recursos
Por fim, você pode dimensionar os recursos com MinMaxScaler, como mostrado no exemplo de classificação de imagens usando TensorFlow CNN abaixo.
import numpy as np import tensorflow as tf from sklearn.datasets import fetch_mldata #Change USERNAME by the username of your machine ## Windows USER mnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original') ## Mac User mnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original') print(mnist.data.shape) print(mnist.target.shape) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42) y_train = y_train.astype(int) y_test = y_test.astype(int) batch_size =len(X_train) print(X_train.shape, y_train.shape,y_test.shape ) ## resclae from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() # Train X_train_scaled = scaler.fit_transform(X_train.astype(np.float64)) # test X_test_scaled = scaler.fit_transform(X_test.astype(np.float64)) feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])] X_train_scaled.shape[1:]
Defina a CNN
Uma CNN utiliza filtros nos pixels brutos de uma imagem para aprender padrões de detalhes, em contraste com os padrões globais aprendidos por uma rede neural tradicional. Para construir uma CNN, você precisa definir:
- Uma camada convolucional: Aplique um número n de filtros ao mapa de características. Após a convolução, você precisa usar uma função de ativação ReLU para adicionar não linearidade à rede.
- PoolinCamada g: O próximo passo após a convolução é reduzir a resolução do mapa de características. O objetivo é diminuir a dimensionalidade do mapa de características para evitar sobreajuste e melhorar a velocidade de computação. O max pooling é a técnica convencional, que divide os mapas de características em sub-regiões (geralmente com tamanho 2×2) e mantém apenas os valores máximos.
- Camadas totalmente conectadas: todos os neurônios das camadas anteriores estão conectados às próximas camadas. A CNN classificará o rótulo de acordo com as características das camadas convolucionais e reduzidas com a camada de pooling.
Arquitetura CNN
- Camada convolucional: Aplica 14 filtros 5×5 (extracting sub-regiões de 5×5 pixels), com função de ativação ReLU
- PoolinCamada g: executa o agrupamento máximo com um filtro 2×2 e passo de 2 (que especifica que as regiões agrupadas não se sobrepõem)
- Camada Convolucional: Aplica 36 filtros 5×5, com função de ativação ReLU
- Pooling Camada #2: Novamente, executa o pool máximo com um filtro 2×2 e passo de 2
- 1,764 neurônios, com taxa de regularização de abandono de 0.4 (probabilidade de 0.4 de que qualquer elemento seja descartado durante o treinamento)
- Camada Densa (Camada Logits): 10 neurônios, um para cada classe alvo de dígito (0–9).
Existem três módulos importantes a serem usados para criar uma CNN:
- conv2d(). Constrói uma camada convolucional bidimensional com o número de filtros, tamanho do kernel do filtro, preenchimento e função de ativação como argumentos.
- max_pooling2d(). Constrói uma camada de pooling bidimensional usando o algoritmo max-pooling.
- denso(). Constrói uma camada densa com as camadas e unidades ocultas
Você definirá uma função para construir a CNN. Vamos ver em detalhes como construir cada bloco de construção antes de finalizar.ping Tudo junto na função.
Etapa 2: camada de entrada
def cnn_model_fn(features, labels, mode): input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Você precisa definir um tensor com a forma dos dados. Para isso, você pode usar o módulo tf.reshape. Neste módulo, você precisa declarar o tensor para remodelar e a forma do tensor. O primeiro argumento são as características dos dados, que são definidas no argumento da função.
Uma imagem possui altura, largura e canais. O conjunto de dados MNIST é uma imagem monocromática de tamanho 28×28. Definimos o tamanho do lote como -1 no argumento `shape` para que ele assuma o formato de `features["x"]`. A vantagem disso é tornar o tamanho do lote um hiperparâmetro ajustável. Se o tamanho do lote for definido como 7, o tensor receberá 5,488 valores (28*28*7).
Etapa 3: camada convolucional
# first Convolutional Layer conv1 = tf.layers.conv2d( inputs=input_layer, filters=14, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)
A primeira camada convolucional possui 14 filtros com um tamanho de kernel de 5×5 e o mesmo preenchimento (padding). O mesmo preenchimento significa que tanto o tensor de saída quanto o tensor de entrada devem ter a mesma altura e largura. O TensorFlow adicionará zeros às linhas e colunas para garantir o mesmo tamanho.
Você usa a função de ativação ReLU. O tamanho da saída será [28, 28, 14].
Passo 4: Poolincamada g
O próximo passo após a convolução é o cálculo de pooling. O cálculo de pooling reduzirá a dimensionalidade dos dados. Você pode usar o módulo `max_pooling2d` com um tamanho de 2×2 e um passo de 2. Use a camada anterior como entrada. O tamanho da saída será `[batch_size, 14, 14, 14]`.
# first Pooling Layer
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Etapa 5: Segunda Camada Convolucional e Pooling Camada
A segunda camada convolucional aplica 36 filtros, resultando em um tamanho de saída de [batch_size, 14, 14, 36]. A camada de pooling usa a mesma janela 2×2 e passo de 2 de antes, então ela divide cada eixo espacial pela metade e o formato da saída passa a ser [batch_size, 7, 7, 36].
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=36,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
Etapa 6: camada densa
Em seguida, você precisa definir a camada totalmente conectada. O mapa de características precisa ser achatado antes de ser conectado à camada densa. Você pode usar o módulo `reshape` com um tamanho de 7x7x36.
A camada densa conectará 1,764 neurônios. Você adiciona uma função de ativação ReLU. Além disso, adiciona um termo de regularização dropout com uma taxa de 0.3, o que significa que 30% das ativações serão definidas como 0. Observe que o dropout ocorre apenas durante a fase de treinamento. A função `cnn_model_fn` possui um argumento `mode` para declarar se o modelo precisa ser treinado ou avaliado, como mostrado no exemplo de classificação de imagens por CNN em TensorFlow abaixo.
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
Etapa 7: Camada Logit
Por fim, no exemplo de classificação de imagens do TensorFlow, você pode definir a última camada com a previsão do modelo. O formato da saída é igual ao tamanho do lote mais 10, o número total de classes alvo.
# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=10)
Você pode criar um dicionário contendo as classes e a probabilidade de cada classe. A função `tf.argmax()` retorna o índice do maior valor na camada de logits. A função `softmax` retorna a probabilidade de cada classe.
predictions = {
# Generate predictions
"classes": tf.argmax(input=logits, axis=1),
"probabilities": tf.nn.softmax(logits, name="softmax_tensor") }
Você só deseja retornar o dicionário de previsão quando o modo estiver definido como previsão. Adicione este código para exibir as previsões.
if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
O próximo passo consiste em calcular a perda do modelo. No último tutorial, você aprendeu que a função de perda para um modelo multiclasse é a entropia cruzada. A perda é facilmente calculada com o seguinte código:
# Calculate Loss (for both TRAIN and EVAL modes)
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
A etapa final do exemplo de CNN do TensorFlow é otimizar o modelo, ou seja, encontrar os melhores valores para os pesos. Para isso, utiliza-se um otimizador de descida de gradiente com uma taxa de aprendizado de 0.001. O objetivo é minimizar a perda.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
Você concluiu a configuração da CNN. No entanto, deseja exibir as métricas de desempenho durante o modo de avaliação. A métrica de desempenho para um modelo multiclasse é a acurácia. O TensorFlow possui um módulo de acurácia que recebe dois argumentos: os rótulos e os valores previstos.
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
É isso. Você criou sua primeira CNN e está pronto para agrupar tudo em uma função para usá-la para treinar e avaliar o modelo.
def cnn_model_fn(features, labels, mode): """Model function for CNN.""" # Input Layer input_layer = tf.reshape(features["x"], [-1, 28, 28, 1]) # Convolutional Layer conv1 = tf.layers.conv2d( inputs=input_layer, filters=32, kernel_size=[5, 5], padding="same", activation=tf.nn.relu) # Pooling Layer pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) # Convolutional Layer #2 and Pooling Layer conv2 = tf.layers.conv2d( inputs=pool1, filters=36, kernel_size=[5, 5], padding="same", activation=tf.nn.relu) pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) # Dense Layer pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36]) dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu) dropout = tf.layers.dropout( inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) # Logits Layer logits = tf.layers.dense(inputs=dropout, units=10) predictions = { # Generate predictions (for PREDICT and EVAL mode) "classes": tf.argmax(input=logits, axis=1), "probabilities": tf.nn.softmax(logits, name="softmax_tensor") } if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) # Calculate Loss loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) # Configure the Training Op (for TRAIN mode) if mode == tf.estimator.ModeKeys.TRAIN: optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) train_op = optimizer.minimize( loss=loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op) # Add evaluation metrics Evaluation mode eval_metric_ops = { "accuracy": tf.metrics.accuracy( labels=labels, predictions=predictions["classes"])} return tf.estimator.EstimatorSpec( mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
Nota sobre a função montada: A versão encapsulada acima define a primeira camada convolucional com 32 filtros e dropout em 0.4, enquanto os trechos de código passo a passo usam 14 filtros e 0.3. Ambos funcionam, mas escolha um par de valores e mantenha-o consistente para que as formas impressas correspondam à tabela de camadas.
As etapas abaixo são as mesmas dos tutoriais anteriores.
Primeiro de tudo, você define um estimador com o modelo CNN para classificação de imagens.
# Create the Estimator mnist_classifier = tf.estimator.Estimator( model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")
O treinamento de uma CNN leva muito tempo; portanto, você cria um mecanismo de registro (logging hook) para armazenar os valores das camadas softmax a cada 50 iterações.
# Set up logging for predictions tensors_to_log = {"probabilities": "softmax_tensor"} logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)
Você está pronto para estimar o modelo. Defina um tamanho de lote de 100 e embaralhe os dados. Observe que definimos 16,000 etapas de treinamento, o que pode levar bastante tempo. Tenha paciência.
# Train the model train_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": X_train_scaled}, y=y_train, batch_size=100, num_epochs=None, shuffle=True) mnist_classifier.train( input_fn=train_input_fn, steps=16000, hooks=[logging_hook])
Agora que o modelo está treinado, você pode avaliá-lo e imprimir os resultados.
# Evaluate the model and print results eval_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": X_test_scaled}, y=y_test, num_epochs=1, shuffle=False) eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn) print(eval_results)
A avaliação imprime o ponto de verificação restaurado, a etapa em que parou e o dicionário de métricas final.
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56 INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269 {'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}
Com a arquitetura atual, o dicionário de avaliação reporta uma acurácia de 0.9689286, aproximadamente 97%. Você pode alterar a arquitetura, o tamanho do lote e o número de iterações para melhorar a acurácia. A CNN teve um desempenho muito melhor do que uma rede neural artificial ou regressão logística: no tutorial sobre redes neurais artificiais, você obteve uma precisão de 96%, que é inferior à da CNN. O desempenho da CNN é impressionante com um conjunto de imagens maior, tanto em termos de velocidade de computação quanto de precisão.











