Uma exploração de dados de estado de modelo na detecção de anomalias |  por Sara Nóbrega |  abril de 2024

Os dados

Dados de pixel MNIST

O primeiro conjunto de dados empregado aqui são os dados usuais de pixel MNIST, compostos por números escritos à mão. Aqui, o fundo é preto e os dígitos são brancos.

Figura 1: Dados de pixel MNIST | Imagem do autor

Anômalo Dados de pixel MNIST

Para testar o novo procedimento e compará-lo com o usual, criei quatro tipos simples de dados anômalos.

O objetivo era testar as capacidades de detecção de cada método em um pequeno espectro de variações de ruído, intensificadas gradativamente de um tipo de anomalia para outro.

A taxa de ruído aumenta do primeiro para o quarto tipo de dados anômalos. Como você pode ver na figura abaixo, no primeiro e no segundo tipos de dados o ruído não é detectável nem a olho nu, enquanto no terceiro tipo já é possível detectar alguns pixels brancos.

Figura 2: Quatro tipos de dados anômalos | Imagem do autor

Dados de estado do modelo

Embora os dados de pixels do MNIST, com seus dígitos escritos à mão em um cenário nítido, forneçam uma base clássica para detecção de anomalias, estamos tentando outra coisa. É um pequeno salto, levando-nos direto ao núcleo da RNA treinada para ver o que os neurônios estão fazendo. Isso poderia nos dar um ângulo totalmente novo para detectar anomalias.

Conforme mencionado, os dados de estado deste modelo são compostos por o estado dos neurônios em uma RNA quando treinados com dados MNIST. Assim, para gerar esses dados, começamos treinando uma RNA simples com dados de pixel MNIST, tanto com dados normais quanto anômalos (os anômalos são compostos pelos dados ruidosos mostrados anteriormente na Figura 2).

Em seguida, realizamos o usual: dividimos os dados em treinamento e teste, e então ajustamos o modelo RNA:

model.fit(X_train,Y_cat_train,epochs=8, validation_data=(X_test, y_cat_test))

Depois disso, queremos recuperar os nomes das camadas em modelo e armazene-os em uma lista:

list(map(lambda x: x.name, model.layers))

Finalmente, criamos um novo modelo que recebe a mesma entrada que o original modelo mas produz saída de uma camada específica chamada “densa”:

intermediate_layer_model=Model(inputs=model.input, outputs=model.get_layer("dense").output)

Isto é útil para extrair informações de camadas intermediárias de uma rede neural.

Vamos dar uma olhada nisso dados de estado do modelo:

model_state_data_layer1=pd.read_csv("first_layer_dense.csv",header=None)
model_state_data_layer2=pd.read_csv("second_layer_dense.csv",header=None)

model_state_data_layer1.head(4)

Figura 3: Instantâneo dos dados do estado do modelo (primeira camada). | Imagem do autor

Os dados do estado do modelo da primeira camada neural são compostos por 32 colunas e 4 linhas.

Com apenas algumas linhas de código, conseguimos extrair dados das camadas intermediárias de uma rede neural.

Para estudar a eficácia do novo método, usarei dados tanto do primeira e segunda camadas da rede neural.

Fuente