Изучение важности характеристик и эволюции весов в данной модели DL - PullRequest
0 голосов
/ 16 января 2019

Я прошу прощения за более длинное, чем обычно, вступление, но это важно для вопроса:

Недавно я был назначен для работы над существующим проектом, который использует Keras + Tensorflow для создания полностью подключенной сети.

В целом модель имеет 3 полностью связанных слоя с 500 нейронами и имеет 2 выходных класса.Первый слой имеет 500 нейронов, которые связаны с 82 входными объектами.Модель используется в производстве и переобучается еженедельно, используя информацию этой недели, сгенерированную из внешнего источника.

Инженер, который разработал модель, здесь больше не работает, и я пытаюсь провести обратный инжиниринг и понятьПоведение модели.

Пара целей, которые я определил для себя:

  1. Понимание процесса выбора функции и важности функции.
  2. Понимание и контроль за еженедельникомпроцесс переобучения.

Чтобы попытаться ответить на оба вопроса, я провел эксперимент, в котором я наполняю свой код двумя моделями: одна с предыдущей недели, а другая с текущейнеделя:

import pickle
import numpy as np
import matplotlib.pyplot as plt
from keras.models import model_from_json

path1 = 'C:/Model/20190114/'
path2 = 'C:/Model/20190107/'
model_name1 = '0_10.1'
model_name2 = '0_10.2'

models = [path1 + model_name1, path2 + model_name2]
features_cum_weight = {}

Затем я беру каждую функцию и пытаюсь суммировать все веса (их абсолютное значение), которые связывают его с первым скрытым слоем.Таким образом, я создаю два вектора 82 значений:

for model_name in models:
    structure_filename = model_name + "_structure.json"
    weights_filename = model_name + "_weights.h5"

    with open(structure_filename, 'r') as model_json:
        model = model_from_json(model_json.read())
        model.load_weights(weights_filename)

    in_layer_weights = model.layers[0].get_weights()[0]
    in_layer_weights = abs(in_layer_weights)
    features_cum_weight[model_name] = in_layer_weights.sum(axis=1)

Затем я строю их, используя MatplotLib:

# Plot the Evolvement of Input Neuron Weights:
keys = list(features_cum_weight.keys())
weights_1 = features_cum_weight[keys[0]]
weights_2 = features_cum_weight[keys[1]]

fig, ax = plt.subplots(nrows=2, ncols=2)
width = 0.35  # the width of the bars

n_plots = 4
batch = int(np.ceil(len(weights_1)/n_plots))

for i in range(n_plots):
    start = i*(batch+1)
    stop  = min(len(weights_1), start + batch + 1)
    cur_w1 = weights_1[start:stop]
    cur_w2 = weights_2[start:stop]

    ind = np.arange(len(cur_w1))
    cur_ax = ax[i//2][i%2]

    cur_ax.bar(ind - width/2, cur_w1, width, color='SkyBlue', label='Current Model')
    cur_ax.bar(ind + width/2, cur_w2, width, color='IndianRed', label='Previous Model')

    cur_ax.set_ylabel('Sum of Weights')
    cur_ax.set_title('Sum of all weights connected by feature')
    cur_ax.set_xticks(ind)
    cur_ax.legend()
    cur_ax.set_ylim(0, 30)

plt.show()

В результате получается следующий график:

MatPlotLib plot

Затем я пытаюсь сравнить векторы, чтобы вывести:

  1. Если векторы были радикально изменены - могут быть некоторые серьезные изменения в данных обучения илиНекоторая проблема при переподготовке модели.
  2. Если какое-либо значение близко к нулю, модель могла бы распознать эту функцию как несущественную.

Мне нужно ваше мнение и идеи о следующем:

  1. Общий подход к этому эксперименту.
  2. Советы по другим идеям по обратному проектированию наданная модель.
  3. Информация о выводе, который я привожу здесь.

Спасибо всем, я открыт для любых предложений и критиков!

1 Ответ

0 голосов
/ 16 января 2019

Этот тип вывода не совсем верно. Сочетание функций не является линейным. Это правда, что если строго 0, то это не имеет значения, но может случиться так, что он затем рекомбинируется другим способом и в другом глубоком слое.

Было бы верно, если бы ваша модель была линейной. Фактически, именно так работает анализ PCA, где он ищет линейные отношения через ковариационную матрицу. Собственное значение будет указывать на важность каждого признака.

Я думаю, что есть несколько способов подтвердить ваши подозрения:

  1. Исключите функции, которые, по вашему мнению, не важны для повторной тренировки и просмотра результата. Если это похоже, ваши подозрения верны.

  2. Примените текущую модель, возьмите пример (мы будем называть его опорным), чтобы оценить и значительно изменить функции, которые вы считаете не относящимися к делу, и создать множество примеров. Это относится к нескольким пивотам. Если результат похож, это поле не должно иметь значения. Пример (я считаю, что первая особенность не имеет значения):

    data = np.array([[0.5, 1, 0.5], [1, 2, 5]])
    range_values = 50
    
    new_data = []
    for i in range(data.shape[0]):
        sample = data[i]
        # We create new samples 
        for i in range (1000):
            noise = np.random.rand () * range_values
            new_sample = sample.copy()
            new_sample[0] += noise
            new_data.append(new_sample)
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...