Как я могу использовать инициализированные веса слоев в настраиваемом регуляризаторе keras? - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь создать собственный регуляризатор Keras, который использует расстояние от веса слоя до его первоначального веса, но то, что я использовал, похоже, не работает.Кажется, что этот регуляризатор никак не влияет на тренировку и функцию потери.

Не могли бы вы помочь мне понять, что я делаю не так?

class NormReg():
    def __init__(self, coeff):
        self._coeff = coeff
        self._original_weights = None

    def _norm(self, weight_matrix):
        return K.sum(K.square(weight_matrix))

    def __call__(self, weight_matrix):
        if self._original_weights is None:
            self._original_weights = weight_matrix

        diff_matrix = weight_matrix - self._original_weights
        return self._coeff * self._norm(diff_matrix)

(я использую тензор потока в качестве бэкэнда)

Редактировать: Немного поиграв с этим классом, я заметил кое-что странное: как будто объект регуляризатора создается снова и снова в процессе обучения в каждой партии, что объясняет, почему я получаю нули.Я пришел к такому выводу, изменив класс на -

class NormReg():
    def __init__(self, coeff):
        self._ugly_check = 1
        self._coeff = coeff
        self._original_weights = None

    def _norm(self, weight_matrix):
        return K.sum(K.square(weight_matrix))

    def __call__(self, weight_matrix):
        if self._original_weights is None:
            self._original_weights = weight_matrix
        if self._ugly_check == 1:
            self._ugly_check = 0
            return 10000
        diff_matrix = weight_matrix - self._original_weights
        return self._coeff * self._norm(diff_matrix)

И, увидев, что потеря действительно понесет штраф, вытекающий из того, что _ugly_check равен 1 на протяжении всего обучения.

1 Ответ

0 голосов
/ 17 апреля 2019

Я до сих пор не до конца понимаю все гайки и болты, стоящие за ним, но вот где я ошибся:

Я предположил, что регуляризатор используется моделью во время обучения, но он находится вЭтот факт используется только один раз при построении вычислительного графа, который будет использовать модель.Итак, что Керас научил делать в своем вычислительном графе, это «взять веса, вычесть их из себя и вернуть коэффициент, умноженный на норму».После моего редактирования он научился делать «взвешивание и возврат 10000».

Таким образом, все это исправляется путем изменения функции __call__ на:

def __call__(self, weight_matrix):
        diff_matrix = weight_matrix - K.eval(weight_matrix)
        return self._coeff * self._norm(diff_matrix)

. Это означает, что теперь он вычитает конкретный массив из заданных весов и затем вычисляет разницу.Это ndarray, конечно, начальные веса, так как это первые веса, с которыми сталкивается этот объект.

Не стесняйтесь поправлять меня и давать более точный ответ.Как я уже сказал, я до сих пор не понимаю этого в полной мере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...