Camada de saída extra em uma rede neural (decimal a binária)

17

Estou trabalhando com uma pergunta do livro on-line:

http://neuralnetworksanddeeplearning.com/chap1.html

Eu posso entender que, se a camada de saída adicional for de 5 neurônios de saída, provavelmente poderia definir um viés de 0,5 e um peso de 0,5 cada para a camada anterior. Mas a pergunta agora pede uma nova camada de quatro neurônios de saída - o que é mais do que suficiente para representar 10 saídas possíveis em .24

Alguém pode me orientar nas etapas envolvidas na compreensão e solução desse problema?

A questão do exercício:

Existe uma maneira de determinar a representação bit a bit de um dígito adicionando uma camada extra à rede de três camadas acima. A camada extra converte a saída da camada anterior em uma representação binária, conforme ilustrado na figura abaixo. Encontre um conjunto de pesos e desvios para a nova camada de saída. Suponha que as 3 primeiras camadas de neurônios sejam tais que a saída correta na terceira camada (ou seja, a camada de saída antiga) tenha ativação pelo menos 0,99 e saídas incorretas tenham ativação menor que 0,01.

insira a descrição da imagem aqui

Victor Yip
fonte

Respostas:

16

A pergunta está solicitando que você faça o seguinte mapeamento entre a representação antiga e a nova representação:

Represent    Old                     New
0            1 0 0 0 0 0 0 0 0 0     0 0 0 0 
1            0 1 0 0 0 0 0 0 0 0     0 0 0 1 
2            0 0 1 0 0 0 0 0 0 0     0 0 1 0 

3            0 0 0 1 0 0 0 0 0 0     0 0 1 1 
4            0 0 0 0 1 0 0 0 0 0     0 1 0 0 
5            0 0 0 0 0 1 0 0 0 0     0 1 0 1 

6            0 0 0 0 0 0 1 0 0 0     0 1 1 0 
7            0 0 0 0 0 0 0 1 0 0     0 1 1 1 
8            0 0 0 0 0 0 0 0 1 0     1 0 0 0 

9            0 0 0 0 0 0 0 0 0 1     1 0 0 1

Como a camada de saída antiga possui uma forma simples, é muito fácil de obter. Cada neurônio de saída deve ter um peso positivo entre si e os neurônios de saída que devem estar representados, e um peso negativo entre ele e os neurônios de saída que devem estar desligados. Os valores devem ser combinados para serem grandes o suficiente para ligar ou desligar de forma limpa, para que eu usasse pesos maiores, como +10 e -10.

Se você tiver ativações sigmóides aqui, o viés não é tão relevante. Você só quer saturar cada neurônio para ativar ou desativar. A pergunta permitiu assumir sinais muito claros na camada de saída antiga.

i=3A3OldZjNewZjNew=Σi=0i=9WijAiOld

W3,0=10
W3,1=10
W3,2=+10
W3,3=+10

Isso deve produzir claramente perto da 0 0 1 1saída quando apenas o neurônio da camada de saída antiga representando um "3" estiver ativo. Na questão, você pode assumir a ativação de 0,99 de um neurônio e <0,01 para os concorrentes na camada antiga. Portanto, se você usar a mesma magnitude de pesos, valores relativamente pequenos provenientes de + -0,1 (0,01 * 10) dos outros valores de ativação da camada antiga não afetarão seriamente o valor + -9,9 e as saídas na nova camada será saturado muito próximo de 0 ou 1.

Neil Slater
fonte
Obrigado. Eu não consegui seguir essa parte, você se importaria de elaborar mais, por favor? - "Eu posso ter pesos que vão da ativação da saída antiga i = 3, AOld3 ao logit das novas saídas ZNewj, onde ZNewj = Σi = 9i = 0Wij ∗ AOldi da seguinte forma: W3,0 = −10 W3,1 = −10 W3 , 2 = + 10 W3,3 = + 10 "
Victor Yip
Ai=f(Zi)f
@ NeilSlater - seus pesos de exemplo funcionarão para saídas que não sejam 3? Eu não vejo que eles vão. Por favor elabore. Obrigado.
FullStack
A3old
1
@ Rrz0: Como estou assumindo uma camada sigmóide na saída, por ser uma classificação binária - o bit está ativado ou desativado. Então, no seu exemplo, você obtém sigmoid((0 * 10) * 1)0,5. Ao escolher números adequadamente grandes, você garante uma saída muito alta ou baixa antes do sigmóide, que produzirá muito próximo de 0 ou 1. Isso é IMO mais robusto do que a saída linear assumida na resposta do FullStack, mas ignorando isso, essencialmente nossa duas respostas são iguais.
Neil Slater
4

O código abaixo do SaturnAPI responde a esta pergunta. Veja e execute o código em https://saturnapi.com/artitw/neural-network-decimal-digits-to-binary-bitwise-conversion

% Welcome to Saturn's MATLAB-Octave API.
% Delete the sample code below these comments and write your own!

% Exercise from http://neuralnetworksanddeeplearning.com/chap1.html
% There is a way of determining the bitwise representation of a digit by adding an extra layer to the three-layer network above. The extra layer converts the output from the previous layer into a binary representation, as illustrated in the figure below. Find a set of weights and biases for the new output layer. Assume that the first 3 layers of neurons are such that the correct output in the third layer (i.e., the old output layer) has activation at least 0.99, and incorrect outputs have activation less than 0.01.

% Inputs from 3rd layer
xj = eye(10,10)

% Weights matrix
wj = [0 0 0 0 0 0 0 0 1 1 ;
      0 0 0 0 1 1 1 1 0 0 ;
      0 0 1 1 0 0 1 1 0 0 ;
      0 1 0 1 0 1 0 1 0 1 ]';

% Results
wj*xj


% Confirm results
integers = 0:9;
dec2bin(integers)
Pilha completa
fonte
Observe que isso implementa um conjunto de pesos para uma camada de saída linear. Por outro lado, minha resposta pressupõe a ativação sigmóide na camada de saída. Caso contrário, as duas respostas são equivalentes.
Neil Slater
O que se entende por entradas eye(10,10)?
precisa saber é o seguinte
sim, na verdade, funciona como um encanto, apenas tentei em Octave online e confirmou, thanks !! ... PS: Um pouco o explicação também seria bom, se alguém ser preso :)
Anaximandro Andrade
1
@ Rrz0 é uma função Matlab / Octave para a criação de matriz de identidade (com os apenas na diagonal principal)
Anaximandro Andrade
0

Prova pitônica para o exercício acima:

"""
NEURAL NETWORKS AND DEEP LEARNING by Michael Nielsen

Chapter 1

http://neuralnetworksanddeeplearning.com/chap1.html#exercise_513527

Exercise:

There is a way of determining the bitwise representation of a digit by adding an extra layer to the three-layer network above. The extra layer converts the output from the previous layer into a binary representation, as illustrated in the figure below. Find a set of weights and biases for the new output layer. Assume that the first 3 layers of neurons are such that the correct output in the third layer (i.e., the old output layer) has activation at least 0.99, and incorrect outputs have activation less than 0.01.

"""
import numpy as np


def sigmoid(x):
    return(1/(1+np.exp(-x)))


def new_representation(activation_vector):
    a_0 = np.sum(w_0 * activation_vector)
    a_1 = np.sum(w_1 * activation_vector)
    a_2 = np.sum(w_2 * activation_vector)
    a_3 = np.sum(w_3 * activation_vector)

    return a_3, a_2, a_1, a_0


def new_repr_binary_vec(new_representation_vec):
    sigmoid_op = np.apply_along_axis(sigmoid, 0, new_representation_vec)
    return (sigmoid_op > 0.5).astype(int)


w_0 = np.full(10, -1, dtype=np.int8)
w_0[[1, 3, 5, 7, 9]] = 1
w_1 = np.full(10, -1, dtype=np.int8)
w_1[[2, 3, 6, 7]] = 1
w_2 = np.full(10, -1, dtype=np.int8)
w_2[[4, 5, 6, 7]] = 1
w_3 = np.full(10, -1, dtype=np.int8)
w_3[[8, 9]] = 1

activation_vec = np.full(10, 0.01, dtype=np.float)
# correct number is 5
activation_vec[3] = 0.99

new_representation_vec = new_representation(activation_vec)
print(new_representation_vec)
# (-1.04, 0.96, -1.0, 0.98)
print(new_repr_binary_vec(new_representation_vec))
# [0 1 0 1]

# if you wish to convert binary vector to int
b = new_repr_binary_vec(new_representation_vec)
print(b.dot(2**np.arange(b.size)[::-1]))
# 5
NpnSaddy
fonte
0

Uma pequena modificação na resposta do FullStack sobre os comentários de Neil Slater usando o Octave:

% gzanellato
% Octave

% 3rd layer:
A = eye(10,10);

% Weights matrix:

fprintf('\nSet of weights:\n\n')

wij = [-10 -10 -10 -10 -10 -10 -10 -10 10 10;
       -10 -10 -10 -10 10 10 10 10 -10 -10;
       -10 -10 10 10 -10 -10 10 10 -10 -10;
       -10 10 -10 10 -10 10 -10 10 -10 10]

% Any bias between -9.999.. and +9.999.. runs ok

bias=5

Z=wij*A+bias;

% Sigmoid function:

for j=1:10;
  for i=1:4;
    Sigma(i,j)=int32(1/(1+exp(-Z(i,j))));
  end
end

fprintf('\nBitwise representation of digits:\n\n')

disp(Sigma')
gzanellato
fonte