|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +""" |
| 5 | +Performs an error analysis, showing the intances that were missclassified |
| 6 | +""" |
| 7 | + |
| 8 | +import pickle |
| 9 | +import keras |
| 10 | +import numpy as np |
| 11 | +from configuration import PICKLE_FILE_NAMES_400M |
| 12 | + |
| 13 | +MODEL_FILE_NAME = "models/RNN-432180483-batch_size_2048-n_rnn_layers_8-drop_out_0-n_neurons_hidden_dense_layer_classifier_512-n_class_layers_2-learning_rate_0.0001-n_neurons_lstm_out_256-embedding_dim_32-activation_relu-lstm_True-" |
| 14 | +LANGUAGE_LABELS = ["Assembly", "C", "C++", "C#", "CSS", "Go", "HTML", "Java", "JavaScript", "Kotlin", |
| 15 | + "Matlab", "Perl", "PHP", "Python", "R", "Ruby", "Scala", "SQL", "Swift", "TypeScript", |
| 16 | + "Unix Shell"] |
| 17 | +NUMBER_INSTANCES_TO_PROCESS = 100_000 |
| 18 | + |
| 19 | + |
| 20 | +def load_dataset(x_file_name: str, y_file_name: str): |
| 21 | + print("Loading X for validation...") |
| 22 | + with open(x_file_name, 'rb') as handle: |
| 23 | + x_test = pickle.load(handle) |
| 24 | + print("Loading Y validation...") |
| 25 | + with open(y_file_name, 'rb') as handle: |
| 26 | + y_test = pickle.load(handle) |
| 27 | + # Convert from one-hot to integer values |
| 28 | + y_test = np.argmax(y_test, axis=1) |
| 29 | + print(x_test.shape) |
| 30 | + print(y_test.shape) |
| 31 | + return x_test, y_test |
| 32 | + |
| 33 | + |
| 34 | +def shuffle_dataset(x_data, y_data): |
| 35 | + print("Shuffling dataset...") |
| 36 | + assert len(x_data) == len(y_data) |
| 37 | + indices = np.random.permutation(len(x_data)) |
| 38 | + return x_data[indices], y_data[indices] |
| 39 | + |
| 40 | + |
| 41 | +def get_erroneous_predictions(y_test, predicted_y, actual_lang: str, predicted_lang: str): |
| 42 | + assert len(y_test) == len(predicted_y) |
| 43 | + actual_lang_index, predicted_lang_index = LANGUAGE_LABELS.index(actual_lang), LANGUAGE_LABELS.index(predicted_lang) |
| 44 | + wrong_classification_indexes = [i for i in range(len(y_test)) if y_test[i] == actual_lang_index and |
| 45 | + np.argmax(predicted_y[i]) == predicted_lang_index] |
| 46 | + return wrong_classification_indexes |
| 47 | + |
| 48 | + |
| 49 | +def convert_vector_to_code(vector) -> str: |
| 50 | + return "".join(map(lambda integer: chr(integer - 2 + 32), vector)) |
| 51 | + |
| 52 | + |
| 53 | +def show_error_instances(wrong_classification_indexes, x_test): |
| 54 | + for index in wrong_classification_indexes: |
| 55 | + print(f'Source code line: "{convert_vector_to_code(x_test[index])}".') |
| 56 | + |
| 57 | + |
| 58 | +def show_miss_classifications(actual_lang: str, predicted_lang: str): |
| 59 | + # Load dataset |
| 60 | + x_test, y_test = load_dataset(PICKLE_FILE_NAMES_400M['x_test'], PICKLE_FILE_NAMES_400M['y_test']) |
| 61 | + x_test, y_test = shuffle_dataset(x_test, y_test) |
| 62 | + x_test, y_test = x_test[:NUMBER_INSTANCES_TO_PROCESS], y_test[:NUMBER_INSTANCES_TO_PROCESS] |
| 63 | + # Load model |
| 64 | + print(f"Loading the model from {MODEL_FILE_NAME} ...") |
| 65 | + model = keras.models.load_model(MODEL_FILE_NAME) |
| 66 | + # Predict the languages |
| 67 | + predicted_y = model.predict(x_test) |
| 68 | + wrong_classification_indexes = get_erroneous_predictions(y_test, predicted_y, actual_lang, predicted_lang) |
| 69 | + print(f"Miss classifications of {actual_lang} (actual) as {predicted_lang} (predicted):") |
| 70 | + show_error_instances(wrong_classification_indexes, x_test) |
| 71 | + |
| 72 | + |
| 73 | +def main(): |
| 74 | + show_miss_classifications("Swift", "Kotlin") |
| 75 | + |
| 76 | + |
| 77 | +if __name__ == "__main__": |
| 78 | + main() |
0 commit comments