camada oculta

Construindo uma rede neural com uma única camada oculta usando Numpy

Compartilhe!

Construindo uma rede neural com uma única camada oculta usando Numpy

Implementar uma rede neural de classificação de 2 classes com uma única camada oculta usando Numpy

No post anterior , discutimos como fazer uma rede neural simples usando NumPy. Neste post, vamos falar sobre como fazer uma rede neural profunda com uma camada oculta.

  1. Bibliotecas de importação

Iremos importar algumas bibliotecas python básicas como numpy, matplotlib (para gráficos de plotagem), sklearn (para mineração de dados e ferramenta de análise), etc. que precisaremos.

import numpy as np 
import matplotlib.pyplot as plt
de sklearn.model_selection import train_test_split

2. Conjunto de dados

Nós vamos usar o Banknote Da t Aset que envolve prever se uma determinada nota é autênticos dadas várias medidas tomadas a partir de uma fotografia. É um problema de classificação binária (2 classes). Existem 1.372 observações com 4 variáveis ​​de entrada e 1 variável de saída. Para mais detalhes veja o link.

data = np.genfromtxt ('data_banknote_authentication.txt', delimiter = ',') 
X = data [:,: 4]
y = data [:, 4]

Podemos visualizar o conjunto de dados usando um gráfico de dispersão. Podemos ver que duas classes (autênticas e não autênticas) são separáveis. Nosso objetivo é construir um modelo que se ajuste a esses dados, ou seja, queremos construir um modelo de rede neural que defina as regiões como autênticas ou não autênticas.

plt.scatter (X [:, 0], X [:, 1], alpha = 0.2, 
c = y, cmap = 'viridis')
plt.xlabel ('variância da wavelet')
plt.ylabel ('skewness of wavelet ');
Imagem para postagem

Agora, vamos dividir os dados em um conjunto de treinamento e um conjunto de teste. Isso pode ser feito usando a função sklearn train_test_split () . 20% dos dados são selecionados para teste e 80% para trem. Além disso, verificaremos o tamanho do conjunto de treinamento e do conjunto de teste. Isso será útil posteriormente para projetar nosso modelo de rede neural.

X_train, X_test, y_train, y_test = train_test_split (X, y, test_size = 0,2, random_state = 42)X_train = X_train.T 
y_train = y_train.reshape (1, y_train.shape [0])X_test = X_test.T
y_test = y_test.reshape (1, y_test.shape [0])print ('Train X Shape:', X_train.shape)
print ('Train Y Shape:', y_train.shape)
print ('Eu tenho m =% d exemplos de treinamento!'% (X_train.shape [1]))

print ('\ nTeste forma X:', X_teste.shape)
Imagem para postagem

3. Modelo de rede neural

A metodologia geral para construir uma rede neural é:

1. Defina a estrutura da rede neural (nº de unidades de entrada, nº de unidades ocultas, etc.). 
2. Inicialize os parâmetros do modelo
3. Loop:
- Implementar propagação direta
- Computar perda
- Implementar propagação reversa para obter os gradientes
- Atualizar parâmetros (gradiente descendente)

Vamos construir uma rede neural com uma única camada oculta, conforme mostrado na figura a seguir:

Imagem para postagem

3.1 Definir estrutura

Precisamos definir o número de unidades de entrada, o número de unidades ocultas e a camada de saída. As unidades de entrada são iguais ao número de recursos no conjunto de dados (4), a camada oculta é definida como 4 (para esse propósito), e o problema é a classificação binária, usaremos uma saída de camada única.

def define_structure (X, Y): 
input_unit = X.shape [0] # tamanho da camada de entrada
hidden_unit = 4 # camada oculta de tamanho 4
output_unit = Y.shape [0] # tamanho do
retorno da camada de saída (input_unit, hidden_unit, output_unit )(input_unit, hidden_unit, output_unit) = define_structure (X_train, y_train)
print ("O tamanho da camada de entrada é: =" + str (input_unit))
print ("O tamanho da camada oculta é: =" + str (hidden_unit) ))
print ("O tamanho da camada de saída é: =" + str (output_unit))
Imagem para postagem

3.2 Inicializar o parâmetro do modelo

Precisamos inicializar as matrizes de peso e vetores de polarização. O peso é inicializado aleatoriamente enquanto o bias é definido como zeros. Isso pode ser feito usando a seguinte função.

def parameters_initialization (input_unit, hidden_unit, output_unit): 
np.random.seed (2)
W1 = np.random.randn (oculto_unit, input_unit) * 0,01
b1 = np.zeros ((hidden_unit, 1))
W2 = np.random. randn (output_unit, hidden_unit) * 0.01
b2 = np.zeros ((output_unit, 1))
parameters = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2}

parâmetros de retorno

3.3.1 Propagação direta

Para a propagação direta, dado o conjunto de recursos de entrada (X), precisamos calcular a função de ativação para cada camada. Para a camada oculta, estamos usando a função de ativação tanh :

Imagem para postagem
Imagem para postagem

Da mesma forma, para a camada de saída, estamos usando a função de ativação sigmóide.

Imagem para postagem
Imagem para postagem

Podemos usar o código a seguir para implementar a propagação direta.

def sigmóide (z): 
retornar 1 / (1 + np.exp (-z))def forward_propagation (X, parâmetros):
W1 = parâmetros ['W1']
b1 = parâmetros ['b1']
W2 = parâmetros ['W2']
b2 = parâmetros ['b2']

Z1 = np.dot (W1, X) + b1
A1 = np.tanh (Z1)
Z2 = np.dot (W2, A1) + b2
A2 = sigmóide (Z2)
cache = {"Z1": Z1, "A1": A1, "Z2": Z2, " A2 ": A2}

retorna A2, cache

3.3.2 Cálculo de Custo

Vamos calcular o custo de entropia cruzada. Na seção acima, calculamos A2. Usando A2, podemos calcular o custo de entropia cruzada usando a seguinte fórmula.

Imagem para postagem
def cross_entropy_cost (A2, Y, parâmetros): 
# número do exemplo de treinamento
m = Y.shape [1]
# Calcula o custo de entropia cruzada
logprobs = np.multiply (np.log (A2), Y) + np.multiply ( (1-Y), np.log (1 - A2))
custo = - np.sum (logprobs) / m
custo = float (np.squeeze (custo))

custo de retorno

3.3.3 Retropropagação

Precisamos calcular o gradiente em relação a diferentes parâmetros, conforme mostrado abaixo.

Imagem para postagem
Cortesia da foto: Andrew Ng
def backward_propagation (parâmetros, cache, X, Y): 
# número do exemplo de treinamento
m = X.shape [1]

W1 = parâmetros ['W1']
W2 = parâmetros ['W2']
A1 = cache ['A1']
A2 = cache ['A2']

dZ2 = A2-Y
dW2 = (1 / m) * np.dot (dZ2, A1.T)
db2 = (1 / m) * np.sum (dZ2, eixo = 1, keepdims = Verdadeiro)
dZ1 = np.multiply (np.dot (W2.T, dZ2), 1 - np.power (A1, 2))
dW1 = (1 / m) * np.dot (dZ1, XT)
db1 = (1 /m)*np.sum(dZ1, axis = 1, keepdims = True)

grads = {"dW1": dW1, "db1": db1, "dW2": dW2, "db2": db2}

retornar grads

3.3.4 Gradiente descendente (parâmetros de atualização)

Precisamos atualizar os parâmetros usando a regra de descida gradiente, ou seja

Imagem para postagem

onde 𝛼 é a taxa de aprendizagem e 𝜃 é o parâmetro.

def gradiente_descent (parâmetros, grads, learning_rate = 0,01): 
W1 = parâmetros ['W1']
b1 = parâmetros ['b1']
W2 = parâmetros ['W2']
b2 = parâmetros ['b2']

dW1 = grads ['dW1 ']
db1 = grads [' db1 ']
dW2 = grads [' dW2 ']
db2 = grads [' db2 '] W1 = W1 - learning_rate * dW1
b1 = b1 - learning_rate * db1
W2 = W2 - learning_rate * dW2
b2 = b2 - learning_rate * db2

parâmetros = {"W1": W1, "b1": b1, "W2": W2, " b2 ": b2}

parâmetros de retorno

4. Modelo de rede neural

Finalmente, juntando todas as funções, podemos construir um modelo de rede neural com uma única camada oculta.

def neural_network_model (X, Y, hidden_unit, num_iterations = 1000): 
np.random.seed (3)
input_unit = define_structure (X, Y) [0]
output_unit = define_structure (X, Y) [2]

parameters = parameters_initialization (input_unit, unidade_oculta, unidade_saída)

W1 = parâmetros ['W1']
b1 = parâmetros ['b1']
W2 = parâmetros ['W2']
b2 = parâmetros ['b2']

para i no intervalo (0, num_iterações):
A2, cache = forward_propagation (X, parâmetros)
cost = cross_entropy_cost (A2, Y, parâmetros)
grads =backward_propagation (parameters, cache, X, Y)
parameters = gradient_descent (parameters, grads)
if i% 5 == 0:
print ("Custo após iteração% i:% f"% (i, custo)) parâmetros de retornoparâmetros = neural_network_model (X_train, y_train, 4, num_iterations = 1000)
Imagem para postagem

5. Predição

Usando o parâmetro aprendido, podemos prever a classe para cada exemplo usando a propagação direta.

prediction de def (parâmetros, X): 
A2, cache = forward_propagation (X, parâmetros)
predictions = np.round (A2)

retornar previsões

Se a ativação> 0,5, a previsão é 1, caso contrário, 0.

predictions = prediction (parameters, X_train) 
print ('Accuracy Train:% d'% float ((np.dot (y_train, predictions.T) + np.dot (1 - y_train, 1 - predictions.T)) / float ( y_train.size) * 100) + '%')predictions = prediction (parameters, X_test)
print ('Accuracy Test:% d'% float ((np.dot (y_test, predictions.T) + np.dot (1 - y_test, 1 - predictions.T)) / float ( y_test.size) * 100) + '%')
Imagem para postagem

Como podemos ver, a precisão do treinamento está em torno de 97%, o que significa que nosso modelo está funcionando e ajustou os dados de treinamento com alta probabilidade. A precisão do teste é de cerca de 96%. Dado o modelo simples e o pequeno conjunto de dados, podemos considerá-lo um bom modelo.

Créditos: https://towardsdatascience.com/building-a-neural-network-with-a-single-hidden-layer-using-numpy-923be1180dbf

Compartilhe!