如何在fit / partial_fit之后操纵skflow模型的权重?

时间:2016-06-14 09:54:18

标签: variables copy tensorflow shared skflow

我正在构建基于Tensorflow的skflow库的多个DNN模型。我将数据分区为minibatches并使用partial_fit进行拟合。在partial_fit的每个循环之后,我想将TensorFlowDNNC分类器模型的第一个n隐藏层的权重复制到另一个TensorFlowDNNC分类器模型。然后使用partial_fit继续学习/复制。 (两个模型的前n个隐藏层的拓扑结构相同。)

我知道如何从classifier1中检索权重:

classifier.get_tensor_value( 'DNN /层0 /线性/矩阵:0')

但我不知道如何将其值复制到分类器2中!

用例:

我正在尝试基于skflow的TensorFlowDNNClassifier / TensorFlowDNNRegressor构建一个M DNN模型的集合。我希望这些M模型能够在彼此之间共享前n层。也就是说,相同的输入,体系结构和。我想通过对skflow原始代码的最小改动来做到这一点。为此,我想把我的数据划分为小批量,并在当时训练模型一个小批量。在每个步骤(使用小批量)中,我在一个模型上应用partial_fit,并将其第一个n隐藏层的权重复制到整体中的下一个模型。然后我使用相同的minibatch对第二个模型进行partial_fit,然后将权重的新值复制到下一个模型。我重复这个训练/复制,直到我到达整体中的最后一个模型。在训练Mth模型之后,我将其第一个n隐藏层的权重复制到所有先前的(M-1)模型。然后我用下一个小批量重复这个,直到所有M型号的重量收敛。

编辑:感谢@Ismael和@ilblackdragon(通过其他论坛)提供的宝贵意见。他们建议的解决方案最适合模型创建。我不得不为TensorFlowEstimator添加额外的功能,这样我就可以在训练时轻松地将权重从一个模型复制到另一个模型(在微型计算机上进行多步训练)。我将以下函数添加到类 TensorFlowEstimator (在文件estimators / base.py中定义)

def extract_num_hidden_layers(self,graph_ops):
    nhl = 0
    are_there_more_layers = True
    while are_there_more_layers:
        are_there_more_layers = False 
        layerName = 'dnn/layer' + str(nhl) + '/Linear/Matrix'
        for op in graph_ops:
            if(op.name == layerName):
                nhl+=1
                are_there_more_layers = True
                break
    return nhl

def create_updaters(self):
    self.weight_updaters = []
    self.bias_updaters = []
    for h in range(0,self.num_hidden_layers):
        with tf.variable_scope('', reuse=True):
            wName = 'dnn/layer' + str(h) + '/Linear/Matrix'
            wUpOp = tf.assign(tf.get_variable(wName), self.nValues)
            self.weight_updaters.append(wUpOp)
            bName = 'dnn/layer' + str(h) + '/Linear/Bias'
            bUpOp = tf.assign(tf.get_variable(bName), self.nValues)
            self.bias_updaters.append(bUpOp)

def get_layer_weights(self, layer_num):
    layer_name = 'dnn/layer' + str(layer_num) + '/Linear/Matrix:0'
    return self.get_tensor_value(layer_name)

def get_layer_biases(self, layer_num):
    layer_name = 'dnn/layer' + str(layer_num) + '/Linear/Bias:0'
    return self.get_tensor_value(layer_name)

def get_layer_params(self, layer_num):
    return [self.get_layer_weights(layer_num), self.get_layer_biases(layer_num)]

def set_layer_weights(self, layer_num, weights_values):
    self._session.run(self.weight_updaters[layer_num], 
                                feed_dict = {self.nValues: weights_values})

def set_layer_biases(self, layer_num, biases_values):
    self._session.run(self.bias_updaters[layer_num], 
                                feed_dict = {self.nValues: biases_values})

def set_layer_params(self, layer_num, params_values):
    self.set_layer_weights(layer_num, params_values[0])
    self.set_layer_biases(layer_num, params_values[1])

然后我使用self.model_fn(self._inp,self._out)创建模型图后,将以下行添加到函数 _setup_training

        graph_ops = self._graph.get_operations()
        self.num_hidden_layers = self.extract_num_hidden_layers(graph_ops)
        self.nValues = tf.placeholder(tf.float32)

        #self.weight_updaters & self.bias_updaters
        self.create_updaters()

这里有如何使用getter和setter函数:

iris = datasets.load_iris()
classifier = skflow.TensorFlowDNNClassifier(hidden_units=[10,5,4], n_classes=3,continue_training=True)
classifier.fit(iris.data, iris.target)
l1b = classifier.get_layer_biases(1)
l1b[3] = 2 # here I manually change the value for demo
classifier.set_layer_biases(1,l1b)

1 个答案:

答案 0 :(得分:0)

您应该使用TensorFlowEstimator,您可以在其中定义自定义模型,基本上您可以将任何TensorFlow代码插入到自定义模型中。

因此,如果您知道如何检索权重,则可以使用tf.Variable并将权重传递给新的dnn作为其初始值,因为:

  

.Variable可以将Tensor或Python对象转换为   张量为初始值

。所以我认为权重的转移应该是这样的:

weights_i = classifier_i.get_tensor_value('dnn/layer0/Linear/Matrix:0')

def my_model_i_plus_1(X, y):
    W = tf.Variable(weights_i)
    b = tf.Variable(tf.zeros([biases_size]))

    layer = tf.nn.relu(tf.matmul(X, W) + b)

    return skflow.models.logistic_regression(layer, y)


classifier_i_plus_1 = skflow.TensorFlowEstimator(model_fn=my_model_i_plus_1,
                                    n_classes=3,
                                    optimizer="SGD")