Как манипулировать весами модели skflow после подгонки /part_fit?

Я строю несколько моделей DNN на основе библиотеки skflow Tensorflow. Я делю свои данные на мини-пакеты и использую для подгонки part_fit. После каждого цикла part_fit я хотел бы скопировать веса первых n-скрытых слоев модели TensorFlowDNNClassifier в другую модель TensorFlowDNNClassifier. А затем продолжайте изучение / копирование с использованием part_fit. (Топология первых n-скрытых слоев для обеих моделей идентична.)

Я знаю, как получить вес из классификатора1:

classifier.get_tensor_value ('DNN /layer0/ Линейный / Матрица:0')

Но я не знаю, как скопировать их значения в классификатор2!

Случай использования:

Я пытаюсь создать ансамбль из моделей M DNN, основанных на TensorFlowDNNClassifier/TensorFlowDNNRegressor skflow. Я хотел бы, чтобы эти M модели разделяли первые n слоев друг с другом. То есть одни и те же входные данные, архитектура и значения. Я хотел сделать это с минимальным изменением исходного кода skflow. Чтобы сделать это, я подумал о том, чтобы разделить свои данные на мини-пакеты и обучить модели по одной мини-партии за раз. На каждом этапе (с использованием мини-пакета) я применяю частичное_применение к одной модели и копирую веса ее первых n-скрытых слоев на следующую модель в ансамбле. Затем я частично подгоняю вторую модель, используя тот же мини-пакет, а затем копирую новые значения весов в следующую модель. Я повторяю эту тренировку / копирование, пока не достигну последней модели в ансамбле. После обучения M-ой модели я копирую веса первых n-скрытых слоев для всех предыдущих (M-1) моделей. Затем я повторяю это со следующей мини-партией, пока веса всех моделей М не сойдутся.

РЕДАКТИРОВАТЬ: Спасибо @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])

Затем я добавил следующие строки в функцию _setup_training сразу после создания графа модели с помощью self.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()

А вот как использовать функции получения и установки:

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 ответ

Решение

Вы должны использовать TensorFlowEstimator, в котором вы можете определить свои пользовательские модели, в основном вы можете вставить любой код TensorFlow в пользовательскую модель.

Поэтому, если вы знаете, как получить вес, вы можете использовать tf.Variable и передать веса новому dnn в качестве его начального значения, поскольку:

tf.Variable может иметь объект Tensor или Python, конвертируемый в Tensor в качестве начального значения.

, Поэтому я думаю, что передача весов должна выглядеть примерно так:

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")
Другие вопросы по тегам