Как я могу сделать обучаемый параметр в керасе?

1

спасибо за то, что посмотрел мой вопрос.

Например.

Конечным результатом является сумма двух матриц A и B, например:

output = keras.layers.add([A, B])

Теперь я хочу создать новый параметр x для изменения вывода.

Я хочу сделать newoutput = Ax + B (1-x)

и x - это обучаемый параметр в моей сети.

что я должен делать? пожалуйста, помогите мне ~ спасибо!

редактировать (часть кода):

conv1 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(input)
drop1 = Dropout(0.5)(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(drop1)

conv2 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)
conv2 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)
drop2 = Dropout(0.5)(conv2)

up1 = Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop2))

#the line I want to change:
merge = add([drop2,up1])
#this layer is simply add drop2 and up1 layer.now I want to add a trainable parameter x to adjust the weight of thoese two layers.

Я пытался использовать коды, но все же возникал ряд вопросов:

1. Как я могу использовать свой собственный слой?

merge = Mylayer()(drop2,up1)

или иначе?

2. В чем смысл out_dim? эти параметры - все 3-мерная матрица. Каково мнение out_dim?

спасибо... TT

edit2 (решена)

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

from keras.layers import add

class MyLayer(Layer):

def __init__(self, **kwargs):
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):

    self._x = K.variable(0.5)
    self.trainable_weights = [self._x]

    super(MyLayer, self).build(input_shape)  # Be sure to call this at the end

def call(self, x):
    A, B = x
    result = add([self._x*A ,(1-self._x)*B])
    return result

def compute_output_shape(self, input_shape):
    return input_shape[0]
Теги:
tensorflow
keras
deep-learning

1 ответ

1
Лучший ответ

Вы должны создать пользовательский класс, который наследует от Layer и создает обучаемый параметр, используя self.add_weight(...). Вы можете найти пример этого здесь и там.

Для вашего примера слой будет выглядеть примерно так:

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self._A = self.add_weight(name='A', 
                                    shape=(input_shape[1], self.output_dim),
                                    initializer='uniform',
                                    trainable=True)
        self._B = self.add_weight(name='B', 
                                    shape=(input_shape[1], self.output_dim),
                                    initializer='uniform',
                                    trainable=True)
        super(MyLayer, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        return K.dot(x, self._A) + K.dot(1-x, self._B)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)

Редактирование: только на основе имен я (ошибочно) предполагается, что x является входными слоями, и вы хотите оптимизировать A и B Но, как вы сказали, вы хотите оптимизировать x. Для этого вы можете сделать что-то вроде этого:

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):

    def __init__(self, **kwargs):
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self._x = self.add_weight(name='x', 
                                    shape=(1,),
                                    initializer='uniform',
                                    trainable=True)
        super(MyLayer, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        A, B = x
        return K.dot(self._x, A) + K.dot(1-self._x, B)

    def compute_output_shape(self, input_shape):
        return input_shape[0]

Edit2: вы можете вызвать этот слой, используя

merge = Mylayer()([drop2,up1])
  • 0
    У меня возник вопрос: для моего примера x - это обучаемый параметр, A / B-матрица - входной параметр. почему бы не добавить х в функцию сборки?
  • 0
    @Lomo Смотрите мои изменения.
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню