Como posso fazer minha rede tratar rotações da entrada igualmente?


11

Estou tentando programar meu próprio sistema para executar uma rede neural. Para reduzir o número de nós necessários, foi sugerido que ele tratasse as rotações da entrada igualmente.

Minha rede tem como objetivo aprender e prever o Jogo da Vida de Conway, olhando para cada quadrado e seus quadrados ao redor em uma grade e fornecendo a saída para esse quadrado. Sua entrada é uma sequência de 9 bits:

Planador

O acima é representado como 010 001 111.

No entanto, existem outras três rotações dessa forma e todas produzem a mesma saída:

Rotações do planador

Minha topologia de rede é de 9 nós de entrada e 1 nó de saída para o próximo estado do quadrado central na entrada. Como posso construir a (s) camada (s) oculta (s) para que elas tomem cada uma dessas rotações da mesma forma, reduzindo o número de entradas possíveis em um quarto da original?

Editar:

Há também um giro de cada rotação que produz um resultado idêntico. Incorporar esses itens reduzirá minhas entradas em 1/8. Com o planador, meu objetivo é que todas essas entradas sejam tratadas exatamente da mesma forma. Isso precisa ser feito com pré-processamento ou posso incorporá-lo à rede?


Excelente questão! Tenho um problema semelhante e impeditivo em meu próprio projeto e ficarei muito interessado em aprender sobre as técnicas mais eficientes para reduzir a simetria.
DukeZhou

@DukeZhou Eu tenho a impressão de que levará um tempo para obter uma resposta, no entanto. Eu estou preparado para usar a minha escassa oferta de rep para configurar uma recompensa se necessário ...
Aric

Outra solução é pré-processar a entrada, de modo que todas as 4 rotações sejam convertidas na mesma imagem antes de serem alimentadas à rede.
precisa saber é o seguinte

Respostas:


4

Se bem entendi, seu único nó de saída será o próximo status do quadrado no meio. Você não precisa se preocupar com o número de nós nas camadas ocultas enquanto tiver recursos suficientes para treinar o modelo. Esse problema é muito fácil de aprender para uma rede neural, portanto, não há preocupação com o tamanho.

Você precisa fazer um treinamento supervisionado, o que significa que precisa alimentar os dados de entrada e a saída esperada correspondente. Você precisa ter certeza de que nos dados de treinamento todas as 4 rotações são atribuídas à mesma saída. Dessa forma, sua rede deve aprender a tratar tudo isso da mesma maneira.

Você me deixou curioso, então eu me tentei. Minha solução pode aprender 100% de correção em cerca de 20 épocas em execução em alguns segundos no meu laptop antigo. Alterei apenas ligeiramente a saída para ser categórica [0,1] ou [1,0], mas isso dá o mesmo resultado que você está procurando. Apenas para referência, aqui está o código escrito em python:

from keras.models import Sequential
from keras.layers import Input, Dense
from keras.models import Model
from keras import optimizers
from keras.utils.np_utils import to_categorical
import helper

x_,y_ = helper.fnn_csv_toXY("conway.csv","output",False)
y_binary = to_categorical(y_)

model = Sequential()
model.add(Dense(100, activation='relu', kernel_initializer='glorot_uniform',input_shape =(9,)))
model.add(Dense(20, activation='relu', kernel_initializer='glorot_uniform'))
model.add(Dense(2, activation='softmax'))
adam=optimizers.Adam()
model.compile(optimizer=adam,
              loss='categorical_crossentropy',
              metrics=['acc'])
model.fit(x_, y_binary, epochs=100)

A rede que utilizarei será simulada por uma classe escrita por mim, daí a memória se preocupar.
Aric

Se você deseja reduzir o uso de memória pela rede, a redução do número de entradas possíveis (girando) ajudará a ter uma rede menor. Quanto mais fácil a tarefa de aprendizado é a menor rede necessária. Nesse caso, o pré-processamento seria melhor. No entanto, NN é para aprendizado de conceitos e, para aprender o conceito de Jogo da Vida, você deve alimentar todos os padrões. Se seu objetivo é minimizar absolutamente a pegada de memória, resolva o problema de maneira linear.
Manngo 8/08/19

Se a memória não for uma preocupação, prefiro que a rede execute essa operação pelos mesmos motivos que você declarou. O pré-processamento remove parte da tarefa da rede, simplificando-a.
Aric

Correto, então vá para o pré-processamento. Eu acho que com isso a pergunta é respondida. Você pode optar por implementá-lo se tiver problemas com a memória. Dica: use float para os pesos que levam apenas 32 bits em vez do dobro que leva 64. Isso usará menos memória.
Manngo 08/08/19

4

Você identificou uma otimização no espaço do problema e deseja incorporar isso na sua rede neural. Sugiro pré-processamento: componha sua otimização com uma rede neural que faça um subconjunto do que você deseja.

Em outras palavras, normalize sua entrada codificando manualmente um algoritmo de rotação que gira entradas para capturar a equivalência destacada em sua postagem. Em seguida, alimente o resultado dessa transformação à sua rede neural, para treinamento e todos os outros usos. Isso significa que você está treinando a rede neural para resolver o subproblema identificado - as rotações são redundantes.

Teste seu normalizador gerando entrada aleatória, girando-o para todas as quatro transformações em potencial, execute o normalizador em cada uma e verifique se todas são equivalentes.


1

Para ser mais purista, comece considerando a entrada de maneira diferente, como uma matriz circular de tamanho quatro, cada item contendo um par de bits e, adicionalmente, um bit central:

... 01, 01, 11, 10 ...

0 0

Em todo o design da rede, continue essa estrutura circular e o paradigma do ponto central.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.