2016-06-14 39 views
1

我正在構建基於Tensorflow的skflow庫的多個DNN模型。我將我的數據分成小型文件,並使用partial_fit進行擬合。在partial_fit的每個循環之後,我想將TensorFlowDNNClassifier模型的第一個隱藏層的權重複制到另一個TensorFlowDNNClassifier模型中。然後繼續使用partial_fit進行學習/複製。 (兩個模型的第一n隱藏層的拓撲結構是相同的。)如何在fit/partial_fit之後處理skflow模型的權重?

我知道如何檢索來自classifier1權重:

classifier.get_tensor_value('DNN /層0 /線性/矩陣:0 「)

但我不知道如何將他們的值複製到classifier2!

的用例:

我試圖建立一個基於skflow的TensorFlowDNNClassifier/TensorFlowDNNRegressor中號DNN模型的集合。我希望這些M模型分享彼此之間的前n層。也就是說,相同的輸入,體系結構和。我想通過對skflow的原始代碼進行最小限度的更改來完成此操作。爲了做到這一點,我想到了將我的數據分成小型文件,並在當時訓練模型中的一個小型文件。在每個步驟(使用minibatch)期間,我將partial_fit應用於一個模型,並將其第一個隱藏層的權重複制到合奏中的下一個模型。然後我使用相同的小批次partial_fit第二個模型,然後將權重的新值複製到下一個模型。我重複這個訓練/複製,直到我到達合奏中的最後一個模型。訓練完第M個模型後,我將其第一個隱藏層的權重複制到所有以前的(M-1)模型中。然後我用下一個小批次重複這個過程,直到所有M個模型的權重收斂。

編輯:感謝@Ismael和@ilblackdragon(通過另一個論壇)提供寶貴意見。他們建議的解決方案最適合模型創建。我不得不爲TensorFlowEstimator添加額外的功能,這樣我就可以輕鬆地將權重從一個模型複製到另一個模型中(在minibatches上進行多個步驟的訓練)。我添加以下功能到類TensorFlowEstimator(在文件估計/ 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]) 

然後添加以下行到使用自創建模型的圖表之後_setup_training功能。 model_fn(self._inp,self._out)

 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) 

回答

0

您應該使用TensorFlowEstimator,您可以在其中定義自定義模型,基本上可以將任何TensorFlow代碼插入到自定義模型中。

所以如果你知道如何檢索您可以使用tf.Variable的權重,並通過權重到一個新的DNN作爲其初始值,因爲:

TF。變量可以具有可作爲初始值轉換爲 張量的張量或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")