问题
I'm trying to build an Autoencoder neural network for finding outliers in a single column list of text. My input have 138 lines and they look like this:
amaze_header_2.png
amaze_header.png
circle_shape.xml
disableable_ic_edit_24dp.xml
fab_label_background.xml
fab_shadow_black.9.png
fab_shadow_dark.9.png
I've built an autoencoder network using Keras, and I use a python function to convert my text input into an array with the ascii representation of each character, padded by zeroes so they all have the same size.
And my full code is like this:
import sys
from keras import Input, Model
import matplotlib.pyplot as plt
from keras.layers import Dense
import numpy as np
from pprint import pprint
from google.colab import drive
# Monta o arquivo do Google Drive
drive.mount('/content/drive')
with open('/content/drive/My Drive/Colab Notebooks/drawables.txt', 'r') as arquivo:
dados = arquivo.read().splitlines()
# Define uma função para pegar uma lista e retornar um inteiro com o tamanho do
# maior elemento
def tamanho_maior_elemento(lista):
maior = 0
for elemento in lista:
tamanho_elemento = len(elemento)
if tamanho_elemento > maior:
maior = tamanho_elemento
return maior
# Define uma função para pegar uma lista e o tamanho do maior elemento e
# retornar uma lista contendo uma outra lista com cada caractere convertido para
# ascii, antes de converter são adicionados zeros a direita para eles ficarem
# com o mesmo tamanho do maior elemento.
def texto_para_ascii(lista, tamanho_maior_elemento):
#para cada linha
lista_ascii = list()
for elemento in lista:
elemento_ascii_lista = list()
#coloca zeros do lado da string
elemento_com_zeros = elemento.ljust(tamanho_maior_elemento, "0")
for caractere in elemento_com_zeros:
elemento_ascii_lista.append(ord(caractere))
lista_ascii.append(elemento_ascii_lista)
return lista_ascii
def ascii_para_texto(lista):
#para cada linha
lista_ascii = list()
for elemento in lista:
elemento_ascii_lista = list()
for caractere in elemento:
elemento_ascii_lista.append(chr(caractere))
elemento_ascii_string = "".join(elemento_ascii_lista)
lista_ascii.append(elemento_ascii_string)
return lista_ascii
# Pega o tamanho do maior elemento
tamanho_maior_elemento = tamanho_maior_elemento(dados)
# Pega o tamanho da lista
tamanho_lista = len(dados)
# Converte os dados para ascii
dados_ascii = texto_para_ascii(dados, tamanho_maior_elemento)
# Converte a linha de dados em ascii para um array numpy
np_dados_ascii = np.array(dados_ascii)
# Define o tamanho da camada comprimida
tamanho_comprimido = int(tamanho_maior_elemento/5)
# Cria a camada de Input com o tamanho do maior elemento
dados_input = Input(shape=(tamanho_maior_elemento,))
# Cria uma camada escondida com o tamanho da camada comprimida
hidden = Dense(tamanho_comprimido, activation='relu')(dados_input)
# Cria a camada de saida com o tamanho do maior elemento
output = Dense(tamanho_maior_elemento, activation='relu')(hidden)
#resultado = Dense(tamanho_maior_elemento, activation='sigmoid')(output)
resultado = Dense(tamanho_maior_elemento)(output)
# Cria o modelo
autoencoder = Model(input=dados_input, output=resultado)
# Compila o modelo
autoencoder.compile(optimizer='adam', loss='mse')
# Faz o fit com os dados
history = autoencoder.fit(np_dados_ascii, np_dados_ascii, epochs=10)
# Plota o gráfico das epochs
plt.plot(history.history["loss"])
plt.ylabel("Loss")
plt.xlabel("Epoch")
plt.show()
# Pega a saída do predict
predict = autoencoder.predict(np_dados_ascii)
# Pega os índices do array que foram classificados
indices = np.argmax(predict, axis=0)
# Converte a saída do predict de array numpy para array normal
indices_list = indices.tolist()
identificados = list()
for indice in indices_list:
identificados.append(dados[indice])
pprint(identificados)
My np.argmax(predict, axis=0)
function returns a list of numbers, which none of them are higher than my array size, so I presumed that they are the positions in my input array that were outliers.
But I'm super unsure on how to interpret the predict data, my "indices" variable looks like this:
array([116, 116, 74, 74, 97, 115, 34, 116, 39, 39, 116, 116, 115,
116, 34, 74, 74, 34, 115, 116, 115, 74, 116, 39, 84, 116,
39, 34, 34, 84, 115, 115, 34, 39, 34, 116, 116, 10])
Have I done the correct interpretation? I mean, what are these numbers being returned? They look nothing like my input. So I assumed that they are the positions on my input data array. Am I right?
EDIT: if at the end of the script I do:
print("--------------")
pprint(np_dados_ascii)
print("--------------")
pprint(predict)
I get the following data:
--------------
array([[ 97, 98, 111, ..., 48, 48, 48],
[ 97, 109, 97, ..., 48, 48, 48],
[ 97, 109, 97, ..., 48, 48, 48],
...,
[115, 97, 102, ..., 48, 48, 48],
[115, 100, 95, ..., 48, 48, 48],
[115, 101, 97, ..., 48, 48, 48]])
--------------
array([[86.44533 , 80.48006 , 13.409852, ..., 60.649754, 21.34232 ,
24.23074 ],
[98.18514 , 87.98954 , 14.873579, ..., 65.382866, 22.747816,
23.74556 ],
[85.682945, 79.46511 , 13.117042, ..., 60.182964, 21.096725,
22.625275],
...,
[86.989494, 77.36661 , 14.291222, ..., 53.586407, 18.540628,
26.212025],
[76.0646 , 70.029236, 11.804929, ..., 52.506832, 18.65119 ,
21.961123],
[93.25003 , 82.855354, 15.329873, ..., 56.992035, 19.869513,
28.3672 ]], dtype=float32)
What do the predict output mean? I don't get why there are floats being returned if my input is an integer array.
Shouldn't it be an array with a different shape (in my result, they are equal) containing just the ascii text of the outliers?
回答1:
Autoencoders are a type of NN used to map higher dimensional input to a lower dimensional representation. The architecture of an autoencoder is quite easy to understand and implement.
This article explains in a simple way what they do and how you should interpret your data.
For your specific case, first of all, I would try a different representation of the input, splitting each word after any '_' or '.' and encode it as a vector using the Keras Embedding layer: here a tutorial on how to use Embedding Layers
Then, what you really want is to look at the output of your middle hidden layer, that is the one that encodes your input into a lower dimensional space. From this lower dimensional space, you can then either train a classifier to detect outliers if you have ground truth or use other unsupervised learning techniques to perform anomaly detection or simply visualization and clustering.
来源:https://stackoverflow.com/questions/55794234/unsure-about-the-result-my-autoencoder-neural-network-is-giving-me-from-keras-pr