在给定的DL模型中研究特征的重要性和权重演变

时间:2019-01-16 11:18:30

标签: python tensorflow keras deep-learning feature-selection

我向您道歉的时间比平时长,但是对于该问题来说很重要:

我最近被分配从事一个现有项目的工作,该项目使用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 :(得分:0)

这种推论并不完全正确。特征之间的组合不是线性的。的确,严格地说,如果为0并不重要,但是可能是以另一种方式在另一个深层将其重新组合。

如果模型是线性的,那将是正确的。实际上,这就是PCA分析的工作方式,它通过协方差矩阵搜索线性关系。特征值将指示每个功能的重要性。

我认为有几种方法可以证实您的怀疑:

  1. 消除您认为不重要的功能,以便再次训练并查看结果。如果相似,则您的怀疑是正确的。

  2. 应用当前模型,以一个示例(我们称其为枢轴)为例,以评估并显着更改您认为不相关的功能并创建许多示例。这适用于几个枢轴。如果结果相似,则该字段无关紧要。示例(我认为第一个功能不相关):

    assets/images/logo-sticky.png