O que é Rede Neural Convolucional?
A rede neural convolucional, também conhecida como convnets ou CNN, é um método bem conhecido em aplicações de visão computacional. Este tipo de arquitetura é dominante para reconhecer objetos de uma imagem ou vídeo.
Neste tutorial, você aprenderá como construir um convnet e como usar o TensorFlow para resolver o conjunto de dados escrito à mão.
Neste tutorial, você aprenderá
- Rede Neural Convolucional
- Arquitetura de uma rede neural convolucional
- Componentes de Convnets
- Treine CNN com TensorFlow
- Etapa 1: fazer upload do conjunto de dados
- Etapa 2: camada de entrada
- Etapa 3: camada convolucional
- Etapa 4: camada de pooling
- Etapa 5: segunda camada convolucional e camada de pooling
- Etapa 6: camada densa
- Etapa 7: Camada Logit
Arquitetura de uma rede neural convolucional
Pense no Facebook há alguns anos: depois que você carregou uma foto em seu perfil, foi solicitado que você adicionasse um nome ao rosto na foto manualmente. Hoje em dia, o Facebook usa convnet para marcar seu amigo na foto automaticamente.
Uma rede neural convolucional não é muito difícil de entender. Uma imagem de entrada é processada durante a fase de convolução e posteriormente atribuída um rótulo.
Uma arquitetura convnet típica pode ser resumida na imagem abaixo. Em primeiro lugar, uma imagem é enviada para a rede; isso é chamado de imagem de entrada. Em seguida, a imagem de entrada passa por um número infinito de etapas; esta é a parte convolucional da rede. Finalmente, a rede neural pode prever o dígito na imagem.
Uma imagem é composta por uma matriz de pixels com altura e largura. Uma imagem em tons de cinza tem apenas um canal, enquanto a imagem colorida tem três canais (cada um para vermelho, verde e azul). Um canal é empilhado um sobre o outro. Neste tutorial, você usará uma imagem em tons de cinza com apenas um canal. Cada pixel tem um valor de 0 a 255 para refletir a intensidade da cor. Por exemplo, um pixel igual a 0 mostrará uma 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 MNIST. A imagem abaixo mostra como representar a imagem da esquerda em formato de matriz. Observe que, a matriz original foi padronizada para ficar entre 0 e 1. Para cores mais escuras, o valor na matriz é cerca de 0,9, enquanto os pixels brancos têm um valor de 0.
Operação convolucional
O componente mais crítico do modelo é a camada convolucional. Esta parte visa reduzir o tamanho da imagem para cálculos mais rápidos dos pesos e melhorar sua generalização.
Durante a parte convolucional, a rede mantém as características essenciais da imagem e exclui ruídos irrelevantes. Por exemplo, a modelo está aprendendo a reconhecer um elefante em uma imagem com uma montanha ao fundo. Se você usar uma rede neural tradicional, o modelo atribuirá um peso a todos os pixels, incluindo os da montanha, o que não é essencial e pode enganar a rede.
Em vez disso, uma rede neural convolucional usará uma técnica matemática para extrair apenas os pixels mais relevantes. Essa operação matemática é chamada de convolução. Essa técnica permite que a rede aprenda recursos cada vez mais complexos em cada camada. A convolução divide a matriz em pequenos pedaços para aprender a maioria dos elementos essenciais dentro de cada pedaço.
Componentes de Convnets
Existem quatro componentes de um Convnets
- Convolução
- Não linearidade (ReLU)
- Pooling ou subamostragem
- Classificação (camada totalmente conectada)
- Convolução
O objetivo da convolução é extrair localmente as características do objeto na imagem. Isso significa que a rede aprenderá padrões específicos dentro da imagem e será capaz de reconhecê-los em todos os lugares da imagem.
A convolução é uma multiplicação elementar. O conceito é fácil de entender. O computador irá escanear uma parte da imagem, geralmente com uma dimensão de 3x3 e multiplicá-la em um filtro. A saída da multiplicação por elemento é chamada de mapa de características. Esta etapa é repetida até que toda a imagem seja digitalizada. Observe que, após a convolução, o tamanho da imagem é reduzido.
Abaixo, há um URL para ver em ação como funciona a convolução.
Existem vários canais disponíveis. Abaixo, listamos alguns dos canais. Você pode ver que cada filtro tem uma finalidade específica. Observe, na imagem abaixo; o Kernel é sinônimo de filtro.
Fonte
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 uma forma geral de 3x3 ou 5x5. Isso significa que a rede deslizará essas janelas por toda a imagem de entrada e calculará a convolução. A imagem abaixo mostra como funciona a convolução. O tamanho do patch é 3x3, e a matriz de saída é o resultado da operação elemento a elemento entre a matriz da imagem e o filtro.
Fonte
Você percebe que a largura e a altura da saída podem ser diferentes da largura e da altura da entrada. Acontece por causa do efeito de borda.
Efeito de borda
A imagem tem um mapa de recursos 5x5 e um filtro 3x3. Há apenas uma janela no centro onde o filtro pode filtrar uma grade 3x3. O mapa de recursos de saída será reduzido em dois blocos ao lado de uma dimensão 3x3.
Para obter a mesma dimensão de saída que a dimensão de entrada, você precisa adicionar preenchimento. O preenchimento consiste em adicionar o número certo 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, a matriz de entrada / saída tem a mesma dimensão 5x5
Quando você define 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 figura abaixo mostra as operações realizadas em uma situação com três filtros
- Stride: define o número de "salto do pixel" entre duas fatias. Se a distância for igual a 1, as janelas se moverão com a propagação de um pixel. Se a distância for igual a dois, as janelas saltarão 2 pixels. Se você aumentar a passada, terá mapas de recursos menores.
Exemplo de passo 1
Passo 2 da imagem
- Preenchimento de zeros: um preenchimento é uma operação de adição de um número correspondente de linhas e colunas em cada lado dos mapas de recursos de entrada. Nesse caso, a saída tem a mesma dimensão da entrada.
- Não linearidade (ReLU)
No final da operação de convolução, a saída está sujeita a uma função de ativação para permitir a não linearidade. A função de ativação usual para convnet é o Relu. Todos os pixels com valor negativo serão substituídos por zero.
- Operação Max-pooling
Esta etapa é fácil de entender. O objetivo do pool é 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 pesos menores para computar, evitando overfitting.
Nesta fase, você precisa definir o tamanho e a passada. Uma maneira padrão de agrupar a imagem de entrada é usar o valor máximo do mapa de características. Olhe para a foto abaixo. O "pooling" selecionará uma submatriz de quatro do mapa de recursos 4x4 e retornará o valor máximo. O agrupamento pega o valor máximo de uma matriz 2x2 e, em seguida, move essa janela em dois pixels. Por exemplo, a primeira submatriz é [3,1,3,2], o agrupamento retornará o máximo, que é 3.
Há outra operação de agrupamento, como a média.
Esta operação reduz agressivamente o tamanho do mapa de características
- Camadas totalmente conectadas
A última etapa consiste em construir uma rede neural artificial tradicional como você fez no tutorial anterior. Você conecta todos os neurônios da camada anterior à próxima. Você usa uma função de ativação softmax para classificar o número na imagem de entrada.
Recapitular:
A rede neural convolucional compila camadas diferentes antes de fazer uma previsão. Uma rede neural tem:
- Uma camada convolucional
- Função de ativação Relu
- Camada de pooling
- Camada densamente conectada
As camadas convolucionais aplicam filtros diferentes em uma sub-região da imagem. A função de ativação Relu adiciona não linearidade, e as camadas de agrupamento reduzem a dimensionalidade dos mapas de feições.
Todas essas camadas extraem informações essenciais das imagens. Por fim, o mapa de características é alimentado para uma camada primária totalmente conectada com uma função softmax para fazer uma previsão.
Treine CNN com TensorFlow
Agora que você está familiarizado com o bloco de construção de um convnets, está pronto para construir um com o TensorFlow. Usaremos o conjunto de dados MNIST para classificação de imagens.
A preparação dos dados é a mesma do tutorial anterior. Você pode executar os códigos e pular diretamente para a arquitetura da CNN.
Você seguirá as etapas abaixo:
Etapa 1: fazer upload do conjunto de dados
Etapa 2: camada de entrada
Etapa 3: camada convolucional
Etapa 4: camada de pooling
Etapa 5: segunda camada convolucional e camada de pooling
Etapa 6: camada densa
Etapa 7: Camada Logit
Etapa 1: fazer upload do conjunto de dados
O conjunto de dados MNIST está disponível com o scikit para aprender neste URL. Faça o download e armazene-o em Downloads. Você pode carregá-lo com fetch_mldata ('MNIST original').
Crie um conjunto de treinamento / teste
Você precisa dividir o conjunto de dados com train_test_split
Dimensione os recursos
Finalmente, você pode dimensionar o recurso com MinMaxScaler
import numpy as npimport tensorflow as tffrom sklearn.datasets import fetch_mldata#Change USERNAME by the username of your machine## Windows USERmnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')## Mac Usermnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')print(mnist.data.shape)print(mnist.target.shape)from sklearn.model_selection import train_test_splitX_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 )## resclaefrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()# TrainX_train_scaled = scaler.fit_transform(X_train.astype(np.float64))# testX_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 usa filtros no pixel bruto de uma imagem para aprender a comparação do padrão de detalhes com o padrão global com uma rede neural tradicional. Para construir uma CNN, você precisa definir:
- Uma camada convolucional: aplique n número de filtros ao mapa de feições. Após a convolução, você precisa usar uma função de ativação Relu para adicionar não linearidade à rede.
- Camada de pooling: A próxima etapa após a convolução é reduzir a resolução do máximo do recurso. O objetivo é reduzir a dimensionalidade do mapa de recursos para evitar overfitting e melhorar a velocidade de computação. O agrupamento máximo é a técnica convencional, que divide os mapas de recursos em sub-regiões (geralmente com um tamanho 2x2) e mantém apenas os valores máximos.
- Camadas totalmente conectadas: todos os neurônios das camadas anteriores sã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 5x5 (extraindo sub-regiões de 5x5 pixels), com função de ativação ReLU
- Camada de pooling: executa pooling máximo com um filtro 2x2 e passo de 2 (que especifica que as regiões agrupadas não se sobrepõem)
- Camada convolucional: Aplica 36 filtros 5x5, com função de ativação ReLU
- Camada de pool # 2: Novamente, executa o pooling máximo com um filtro 2x2 e passo de 2
- 1.764 neurônios, com taxa de regularização de abandono de 0,4 (probabilidade de 0,4 de qualquer elemento cair durante o treinamento)
- Camada Densa (Camada Logits): 10 neurônios, um para cada classe de dígito alvo (0-9).
Existem três módulos importantes para usar 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_pool2d (). Constrói uma camada de pooling bidimensional usando o algoritmo de pooling máximo.
- 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 agrupar tudo 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 a ser remodelado e a forma do tensor. O primeiro argumento são os recursos dos dados, que são definidos no argumento da função.
Uma imagem tem altura, largura e canal. O conjunto de dados MNIST é uma imagem monocromática com tamanho 28x28. Definimos o tamanho do lote como -1 no argumento de forma para que tome a forma dos recursos ["x"]. A vantagem é fazer com que os hiperparâmetros do tamanho do lote sejam ajustados. Se o tamanho do lote for definido como 7, o tensor alimentará 5.488 valores (28 * 28 * 7).
Step 3: Convolutional layer
# first Convolutional Layerconv1 = 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 5x5 com o mesmo preenchimento. O mesmo preenchimento significa que o tensor de saída e 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].
Etapa 4: camada de pooling
A próxima etapa após a convolução é o cálculo do pool. O cálculo de pooling reduzirá a dimensionalidade dos dados. Você pode usar o módulo max_pool2d com um tamanho de 2x2 e passo de 2. Você usa a camada anterior como entrada. O tamanho da saída será [batch_size, 14, 14, 14]
# first Pooling Layerpool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Etapa 5: segunda camada convolucional e camada de pooling
A segunda camada convolucional tem 32 filtros, com um tamanho de saída de [batch_size, 14, 14, 32]. A camada de pooling tem o mesmo tamanho de antes e o formato de saída é [batch_size, 14, 14, 18].
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 feições deve ser achatado antes de ser conectado à camada densa. Você pode usar a remodelagem do módulo com um tamanho de 7 * 7 * 36.
A camada densa conectará 1764 neurônios. Você adiciona uma função de ativação Relu. Além disso, você adiciona um termo de regularização do abandono com uma taxa de 0,3, o que significa que 30 por cento dos pesos serão definidos como 0. Observe que o abandono ocorre apenas durante a fase de treinamento. A função cnn_model_fn possui um modo de argumento para declarar se o modelo precisa ser treinado ou para avaliar.
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
Finalmente, você pode definir a última camada com a previsão do modelo. A forma de saída é igual ao tamanho do lote e 10, o número total de imagens.
# Logits Layerlogits = tf.layers.dense(inputs=dropout, units=10)
Você pode criar um dicionário contendo as classes e a probabilidade de cada classe. O módulo tf.argmax () com retorna o valor mais alto se as camadas logit. 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 a previsão de dicionário quando o modo estiver definido como previsão. Você adiciona estes códigos para exibir as previsões
if mode == tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
A próxima etapa 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 é otimizar o modelo, ou seja, encontrar os melhores valores dos pesos. Para isso, você usa um otimizador de descida 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ê terminou com a CNN. No entanto, você deseja exibir as métricas de desempenho durante o modo de avaliação. A métrica de desempenho para um modelo multiclasse é a métrica de precisão. O Tensorflow é equipado com um módulo de precisão com 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 Layerinput_layer = tf.reshape(features["x"], [-1, 28, 28, 1])# Convolutional Layerconv1 = tf.layers.conv2d(inputs=input_layer,filters=32,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)# Pooling Layerpool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)# Convolutional Layer #2 and Pooling Layerconv2 = 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 Layerpool2_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 Layerlogits = 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 Lossloss = 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 modeeval_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)
As etapas abaixo são iguais aos tutoriais anteriores.
Em primeiro lugar, você define um estimador com o modelo CNN.
# Create the Estimatormnist_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")
Um CNN leva muitas vezes para treinar, portanto, você cria um gancho Logging para armazenar os valores das camadas softmax a cada 50 iterações.
# Set up logging for predictionstensors_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. Você define um tamanho de lote de 100 e embaralha os dados. Observe que definimos etapas de treinamento de 16.000, pode levar muito tempo para treinar. Ser paciente.
# Train the modeltrain_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á pronto, você pode avaliá-lo e imprimir os resultados
# Evaluate the model and print resultseval_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)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56INFO: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, você obtém uma precisão de 97%. Você pode alterar a arquitetura, o tamanho do lote e o número de iterações para melhorar a precisão. A rede neural CNN teve um desempenho muito melhor do que a RNA ou a regressão logística. No tutorial sobre rede neural artificial, você obteve uma precisão de 96%, que é menor do que o CNN. Os desempenhos da CNN são impressionantes com um conjunto de imagens maior , tanto em termos de computação de velocidade quanto de precisão.
Resumo
Uma rede neural convolucional funciona muito bem para avaliar a imagem. Este tipo de arquitetura é dominante para reconhecer objetos de uma imagem ou vídeo.
Para construir uma CNN, você precisa seguir seis etapas:
Etapa 1: camada de entrada:
Esta etapa remodela os dados. A forma é igual à raiz quadrada do número de pixels. Por exemplo, se uma imagem tem 156 pixels, a forma é 26x26. Você precisa especificar se a imagem tem cor ou não. Se sim, então você tinha 3 para a forma- 3 para RGB-, caso contrário, 1.
input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Etapa 2: camada convolucional
Em seguida, você precisa criar as camadas convolucionais. Você aplica filtros diferentes para permitir que a rede aprenda recursos importantes. Você especifica o tamanho do kernel e a quantidade de filtros.
conv1 = tf.layers.conv2d(inputs=input_layer,filters=14,kernel_size=[5, 5],padding="same",activation=tf.nn.relu)
Etapa 3: camada de pooling
Na terceira etapa, você adiciona uma camada de pool. Esta camada diminui o tamanho da entrada. Ele faz isso tomando o valor máximo da submatriz a. Por exemplo, se a submatriz for [3,1,3,2], o agrupamento retornará o máximo, que é 3.
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Etapa 4: adicionar camada convolucional e camada de pooling
Nesta etapa, você pode adicionar o quanto quiser, camadas conv e camadas de pool. O Google usa arquitetura com mais de 20 camadas conv.
Etapa 5: camada densa
O passo 5 aplainar o anterior para criar camadas totalmente conectadas. Nesta etapa, você pode usar uma função de ativação diferente e adicionar um efeito de dropout.
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 6: Camada Logit
A etapa final é a previsão.
logits = tf.layers.dense(inputs=dropout, units=10)