Perceptron multi-camada usando Tensorflow

Aayush Agrawal Blocked Unblock Seguir Seguindo 11 de setembro de 2018

Neste blog, vamos construir uma rede neural (perceptron multicamada) usando TensorFlow e treiná-la com sucesso para reconhecer dígitos na imagem. O Tensorflow é um framework de aprendizado profundo muito popular lançado, e este notebook irá guiar a construção de uma rede neural com esta biblioteca. Se você quer entender o que é um perceptron multicamada, você pode olhar para o meu blog anterior, onde eu construí um perceptron multicamada a partir do zero usando o Numpy.

Vamos começar importando nossos dados. Como Keras, uma biblioteca de aprendizagem profunda de alto nível já possui dados MNIST como parte de seus dados padrão, vamos apenas importar o conjunto de dados de lá e dividi-lo em conjunto de treinamento e teste.

 ## Carregando o conjunto de dados MNIST de keras 
importar keras
de sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot como plt
% matplotlib inline
 def load_dataset (flatten = False ): 
(X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data ()
 # normalize x 
X_train = X_train.astype (float) / 255.
X_test = X_test.astype (float) / 255.
 # reservamos os últimos 10000 exemplos de treinamento para validação 
X_train, X_val = X_train [: - 10000], X_train [-10000:]
y_train, y_val = y_train [: - 10000], y_train [-10000:]
 se achatar: 
X_train = X_train.reshape ([X_train.shape [0], -1])
X_val = X_val.reshape ([X_val.shape [0], -1])
X_test = X_test.reshape ([X_test.shape [0], -1])
 voltar X_train, y_train, X_val, y_val, X_test, y_test 
 X_train, y_train, X_val, y_val, X_test, y_test = load_dataset () 
## Dimensões de impressão
print (X_train.shape, y_train.shape)
## Visualizando o primeiro dígito
plt.imshow (X_train [0], cmap = "Grays");

Como podemos ver que nossos dados atuais têm a dimensão N 28 * 28, começaremos por achatar a imagem em N * 784 e codificar um a quente nossa variável de destino.

 ## Alterando a dimensão das imagens de entrada de N * 28 * 28 para N * 784 
X_train = X_train.reshape ((X_train.shape [0], X_train.shape [1] * X_train.shape [2]))
X_test = X_test.reshape ((X_test.shape [0], X_test.shape [1] * X_test.shape [2]))
 print ('Dimensão do trem:'); print (X_train.shape) 
print ('Dimensão do teste:'); print (X_test.shape)
 ## Alterando os rótulos para um vetor codificado para uma quente 
lb = LabelBinarizer ()
y_train = lb.fit_transform (y_train)
y_test = lb.transform (y_test)
print ('Treinar a dimensão das etiquetas:'); print (y_train.shape)
print ('Dimensão das etiquetas de teste:'); print (y_test.shape)

Agora nós processamos os dados, vamos começar a construir nosso perceptron multicamada usando o tensorflow. Começaremos importando as bibliotecas necessárias.

 ## Importando bibliotecas necessárias 
import numpy como np
importar tensorflow como tf
de sklearn.metrics import roc_auc_score, accuracy_score
s = tf.InteractiveSession ()

tf.InteractiveSession () é uma maneira de executar o modelo tensorflow diretamente sem instanciar um gráfico sempre que quisermos executar um modelo. Nós estaremos construindo 784 (Entrada) -512 (camada oculta 1) -256 (camada oculta 2) -10 (saída) modelo de rede neural. Vamos começar nossa construção de modelo definindo variáveis de inicialização.

 ## Definindo vários parâmetros de inicialização para o modelo 784-512-256-10 MLP 
num_classes = y_train.shape [1]
num_features = X_train.shape [1]
num_output = y_train.shape [1]
num_layers_0 = 512
num_layers_1 = 256
starter_learning_rate = 0,001
regularizer_rate = 0.1

Em tensorflow, definimos um espaço reservado para nossas variáveis de entrada e variáveis de saída e quaisquer variáveis que desejamos acompanhar.

 # Espaços reservados para os dados de entrada 
input_X = tf.placeholder ('float32', forma = ( Nenhum , num_features), nome = "input_X")
input_y = tf.placeholder ('float32', forma = ( Nenhum , num_classes), nome = 'input_Y')
## para a camada de dropout
keep_prob = tf.placeholder (tf.float32)

Como camadas densas requerem pesos e vieses e elas precisam ser inicializadas com uma distribuição normal aleatória com média zero e pequena variância (1 / raiz quadrada do número de características).

 ## Pesos inicializados pela função normal aleatória com std_dev = 1 / sqrt (número de recursos de entrada) 
weights_0 = tf.Variavel (tf.random_normal ([num_features, num_layers_0], stddev = (1 / tf.sqrt (float (num_features)))))
bias_0 = tf.Variable (tf.random_normal ([num_layers_0]))
 weights_1 = tf.Variavel (tf.random_normal ([num_layers_0, num_layers_1], stddev = (1 / tf.sqrt (flutuante (num_layers_0))))) 
bias_1 = tf.Variable (tf.random_normal ([num_layers_1]))
 pesos_2 = tf.Variavel (tf.random_normal ([num_layers_1, num_output], stddev = (1 / tf.sqrt (float (num_layers_1))))) 
bias_2 = tf.Variable (tf.random_normal ([num_output]))

Agora vamos começar a escrever o cálculo do gráfico para desenvolver o nosso modelo 784 (Entrada) -512 (camada oculta 1) -256 (camada oculta 2) -10 (saída) . Vamos multiplicar a entrada para cada camada com seus respectivos pesos e adicionar um termo de polarização. Depois de pesos e preconceitos, precisamos adicionar uma ativação; usaremos a ativação de ReLU para camadas ocultas e softmax para a camada de saída final para obter o escore de probabilidade de classe. Também para evitar overfitting; Vamos adicionar alguns drop out após cada camada oculta. O abandono é um conceito essencial na criação de redundâncias na nossa rede, o que leva a uma melhor generalização.

 ## Inicializando pesagens e vieses 
hidden_output_0 = tf.nn.relu (tf.matmul (input_X, pesos_0) + bias_0)
hidden_output_0_0 = tf.nn.dropout (hidden_output_0, keep_prob)
 hidden_output_1 = tf.nn.relu (tf.matmul (hidden_output_0_0, weights_1) + bias_1) 
hidden_output_1_1 = tf.nn.dropout (hidden_output_1, keep_prob)
 predicted_y = tf.sigmoid (tf.matmul (hidden_output_1_1, weights_2) + bias_2) 

Agora precisamos definir uma função de perda para otimizar nossos pesos e vieses, e usaremos a entropia cruzada softmax com logits para o rótulo previsto e correto. Também adicionaremos alguma regularização L2 à nossa rede.

 ## Definindo a função de perda 
loss = tf.reduce_mean (tf.nn.softmax_cross_entropy_with_logits_v2 (logits = predicted_y, labels = input_y))
+ regularizer_rate * (tf.reduce_sum (tf.square (bias_0)) + tf.reduce_sum (tf.square (bias_1)))

Agora precisamos definir um otimizador e uma taxa de aprendizado para nossa rede para otimizar pesos e vieses em nossa função de perda. Usaremos decaimento exponencial em nossa taxa de aprendizado a cada cinco épocas para reduzir o aprendizado em 15%. Para o otimizador, vamos usar o otimizador Adam.

 ## Taxa de aprendizagem variável 
learning_rate = tf.train.exponential_decay (starter_learning_rate, 0, 5, 0.85, staircase = True )
## Adam otimizador para encontrar o peso certo
optimizer = tf.train.AdamOptimizer (learning_rate) .minimize (perda, var_list = [pesos_0, pesos_1, pesos_2,
bias_0, bias_1, bias_2])

Nós terminamos com a construção do nosso modelo. Vamos definir a métrica de precisão para avaliar o desempenho do nosso modelo, pois a função de perda não é intuitiva.

 ## Definição de métricas 
predição correta = tf.equal (tf.argmax (y_train, 1), tf.argmax (predicted_y, 1))
exatidão = tf.reduce_mean (tf.cast (correct_prediction, tf.float32))

Agora começaremos a treinar nossa rede em dados de treinamento e avaliaremos nossa rede no conjunto de dados de teste simultaneamente. Nós estaremos usando otimização de lote com tamanho 128 e treiná-lo por 14 épocas para obter uma precisão de 98% +.

 ## Parâmetros de treinamento 
batch_size = 128
épocas = 14
dropout_prob = 0,6
 training_accuracy = [] 
training_loss = []
testing_accuracy = []
 s.run (tf.global_variables_initializer ()) 
para época no intervalo (épocas):
arr = np.arange (X_train.shape [0])
np.random.shuffle (arr)
para o índice no intervalo (0, X_train.shape [0], batch_size):
s.run (otimizador, {input_X: X_train [arr [índice: index + batch_size]],
input_y: y_train [arr [índice: index + batch_size]],
keep_prob: dropout_prob})
training_accuracy.append (s.run (precisão, feed_dict = {input_X: X_train,
input_y: y_train, keep_prob: 1}))
training_loss.append (s.run (perda, {input_X: X_train,
input_y: y_train, keep_prob: 1}))

## Avaliação do modelo
testing_accuracy.append (accuracy_score (y_test.argmax (1),
s.run (predicted_y, {input_X: X_test, keep_prob: 1}). argmax (1)))
print ("Epoch: {0} , Train loss: {1: .2f} Treinar acc: {2:, 3f} , Testar acc: {3:, 3f} " .format (época,
training_loss [epoch],
training_accuracy [época],
testing_accuracy [epoch]))

Vamos treinar a visualização e testar a precisão como uma função do número de épocas.

 ## Gráfico de plotagem de treinamento e precisão de testes em função de iterações 
iterações = lista (intervalo (épocas))
plt.plot (iterações, training_accuracy, label = 'Train')
plt.plot (iterações, testing_accuracy, label = 'Test')
plt.ylabel ('Precisão')
plt.xlabel ('iterações')
plt.show ()
print ("Precisão do Trem: {0: .2f} " .format (training_accuracy [-1]))
print ("Precisão do teste: {0: .2f} " .format (testing_accuracy [-1]))

Como podemos ver, nós treinamos com sucesso um perceptron Multi-Layer que foi escrito em tensorflow com alta precisão de validação!

Espero que você tenha gostado de ler e sinta-se à vontade para usar meu código (também disponível no Jupyter Notebook ) para testá-lo para seus propósitos. Além disso, se houver algum comentário sobre o código ou apenas a postagem do blog, sinta-se à vontade para entrar em contato com o LinkedIn ou enviar um e-mail para aayushmnit@gmail.com. Por favor, deixe um comentário ou uma palmada se você gosta do conteúdo e quer que eu escreva esses blogs com mais frequência.