Как инвертировать одно горячее кодирование для выходного вектора из модели AutoEncoder? - PullRequest
0 голосов
/ 22 мая 2018

У меня есть список токенов в качестве входных данных.Я использовал одну горячую кодировку для преобразования текстового списка в двоичную кодированную матрицу.Эта матрица затем подается в простую архитектуру автоэнкодера.Архитектура состоит из 2 полностью связанных слоев, за которыми следует первая часть этой ссылки .

Чтобы сравнить / понять результат этой архитектуры, нам нужно инвертировать одно горячее кодированиепреобразование.Этот шаг блокируется этой ошибкой:

ValueError: y содержит новые метки: [121]

def getTokens(xml_string):
firstTagMatches = re.findall('(\<\w+\>)', xml_string, re.DOTALL)
closedTagMatches = re.findall('(\<\/\w+\>)', xml_string, re.DOTALL)
betweenTagMatches = re.findall(r'>(.*?)<', xml_string)
xmlTokens = firstTagMatches + betweenTagMatches + closedTagMatches
return xmlTokens
def oneHotEncoding(data):
values = array(data)
# integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
# binary encode
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
return onehot_encoded
def invertOneHotEncoding(data,decoded_imgs):
values = array(data)
print('values', values)
print('type', type(values))
 # integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
print('integer_encoded', integer_encoded)
print('decoded images 1', decoded_imgs)
    # invert 
#final_decoded = np.zeros(shape= decoded_imgs.shape)
#for (x,y), value in np.ndenumerate(decoded_imgs):
#    if value > 0:
#        final_decoded[x,y] = 1
#print('decoded images 2', final_decoded)
inverted = [label_encoder.inverse_transform([argmax(decoded_imgs[i, :])]) for i in range(len(decoded_imgs))] 
#inverted = label_encoder.inverse_transform([argmax(final_decoded[0, :])])
return inverted
def getEncodedTrainingData(directoryPath):
#path = '/some/path/to/file'
encodedXML = np.zeros(shape=(0,166)) #because we know that the first file will give us a numpy array of shape=(166,166)
for filename in os.listdir(directoryPath):
    print('filename', filename)
    pretty_xml_as_string = ''
    trainingTokens = []
    xmlObject = xml.dom.minidom.parse(directoryPath+'/'+filename) 
    pretty_xml_as_string = xmlObject.toprettyxml()
    trainingTokens = getTokens(pretty_xml_as_string)
    transformedMatrice = oneHotEncoding(trainingTokens)
    dimensions = transformedMatrice.shape[0] * transformedMatrice.shape[1]
    onehotEncodedArray = np.resize(transformedMatrice, (int(dimensions/166),166)) #it may loose some information !! need a better solution
    print('onehotEncodedArray shape', onehotEncodedArray.shape)
    encodedXML = np.concatenate((encodedXML, onehotEncodedArray), axis=0)
print('before deleting shape', encodedXML.shape)
#encodedXML = np.delete(encodedXML,np.s_[0:166], axis=0) #remove the first initialized line
return encodedXML

encodedXML = getEncodedTrainingData('./trainingData/')
encodedXML_test = getEncodedTrainingData('./testingData/')

Часть машинного обучения:

#make the AutoEncoder Model
# this is the size of our encoded representations
encoding_dim = 32  
# this is our input placeholder
input_vector = Input(shape=(166,))
# "encoded" is the encoded representation of the input
encoded = Dense(encoding_dim, activation='relu', 
activity_regularizer=regularizers.l1(10e-5))(input_vector)
# "decoded" is the lossy reconstruction of the input
decoded = Dense(166, activation='relu')(encoded)
# this model maps an input to its reconstruction
autoencoder = Model(input_vector, decoded)
 encoder = Model(input_vector, encoded)
 encoded_input = Input(shape=(encoding_dim,))
 # retrieve the last layer of the autoencoder model
 decoder_layer = autoencoder.layers[-1]
 # create the decoder model
 decoder = Model(encoded_input, decoder_layer(encoded_input))
  autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy', metrics=['binary_accuracy', 'categorical_accuracy'])
 x_train = encodedXML
 x_test = encodedXML_test
 autoencoder.fit(x_train, x_train,
            epochs=50,
            batch_size=256,
            shuffle=False,
            validation_data=(x_test, x_test))
 # encode and decode some digits
 # note that we take them from the *test* set
 encoded_imgs = encoder.predict(x_test)
 decoded_imgs = decoder.predict(encoded_imgs)
 invertedSentence = invertOneHotEncoding(testDataTokens,decoded_imgs)

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

На самом деле код работает отлично.Дело в том, что когда я натренировал autoEncoder на моих реальных данных, данных было недостаточно.Поэтому, когда я тестировал автоэнкодер, предсказанный вектор не был точно тестовым вектором.Вот почему я получил исключение ValueError.Чтобы получить окончательный декодированный вывод, я изменил 'invertOneHotEncoding', чтобы он имел:

def invertOneHotEncoding(label_encoder,decoded_imgs):
inverted = []
for i in range(len(decoded_imgs)):
    try:
        print('decoded', label_encoder.inverse_transform([argmax(decoded_imgs[i, :])]))
        inverted.append(label_encoder.inverse_transform([argmax(decoded_imgs[i, :])]))
    except ValueError:
        inverted.append('<>')
return inverted

Так что теперь я думаю, имеет смысл, почему я получил эту ошибку.

0 голосов
/ 22 мая 2018

Вы путаете входы и выходы.Давайте упростим это, предположим, что есть 4 метки, затем ваша x_train = [[0,1,0,0], [0,0,0,1]], поэтому у вас уже есть две точки данных, одна из которых имеет горячее кодирование.Теперь вы можете построить свой автоматический кодер как:

in = Input(shape=(num_classes,))
enc = Dense(encoding_dim, activation='relu')(in)
out = Dense(num_classes, activation='softmax')(enc)

Ваша сеть должна будет предсказать один из классов как распределение на основе закодированного вектора.Учитывая, что это все еще проблема классификации, у вас будет categorical_crossentropy в качестве вашей потери при тренировках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...