Пользовательский слой Keras с некоторыми нетренируемыми весами

#python #tensorflow #machine-learning #keras #custom-training

Вопрос:

Я хотел бы иметь слой в последовательной модели, который имеет некоторые фиксированные, не поддающиеся обучению веса, редко распределенные внутри слоя.

Например: я создаю модель с несколькими слоями

 model = Sequential()
model.add(Dense(units=n_nodes, activation=activation, kernel_initializer='glorot_uniform'), input_shape=(n_nodes,))
model.add(Dense(....
 

затем я компилирую и подгоняю модель и получаю два слоя с обученными весами.

Затем я хотел бы, например model.layer[0] , изменить и исправить некоторые веса, а затем выполнить переподготовку сети.

Обученный слой, например, является

 a b c
d e f
g h i
 

и я хочу, чтобы все было так:

 A* b  c
d  e  F*
g  H* I*
 

с помощью A*, F*, H* и I* отредактированные веса и набор не поддаются обучению, так что после очередного раунда обучения слой приводит к чему-то вроде этого

 A*  b2  c2
d2  e2  F*
g2  H*  I*
 

Моя сеть построена в Керасе, и я не нашел способа осуществить эту трансформацию. Возможно ли это вообще? Я думал о создании пользовательского слоя, но не могу понять, как сделать необучаемыми только некоторые значения.

Комментарии:

1. Вы можете добавить ограничения к весам, например, как показано здесь

2. @JE_Muc Спасибо, я рассмотрю ограничения, но на данный момент я не смог установить, чтобы отдельные веса были нетренируемыми

3. Просто создайте класс ограничений и назначьте фиксированные значения необучаемым ячейкам тензора, например, вместо return w * tf.cast(tf.math.greater_equal(w, 0.), w.dtype) того , чтобы в примере , Попробуйте что-то вроде w[0, 0] = A и w[1, 2] = F т. Д., А затем . return w

Ответ №1:

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

Чтобы исправить конкретные веса, используйте пользовательский класс ограничений (спасибо @Artem Glukhov за упоминание tf.keras.backend.set_value ):

 class FixWeights(tf.keras.constraints.Constraint):

    def __call__(self, w):
        tf.keras.backend.set_value(w[0, 0], A)
        tf.keras.backend.set_value(w[1, 2], F)
        tf.keras.backend.set_value(w[2, 1], H)
        tf.keras.backend.set_value(w[2, 2], I)
 
        return w
 

и добавьте это в свой слой с:

 tf.keras.layers.Dense(..., kernel_constraint=FixWeights())
 

Комментарии:

1. Спасибо за ответ, но это приводит к тому,что w[x, y] являются объектами, изменяемыми ресурсами, и, следовательно, они не поддерживают назначение элементов

2. Я решил проблему, используя keras.backend.set_value(w[0,0], a) и вернув w, как это сделали вы. Большое спасибо!

3. Добро пожаловать и спасибо с моей стороны за то, что указали правильный способ присвоения значений тензору веса! Я добавил это к своему ответу.