keras自定義層


一、基本定義方法

當然,Lambda層僅僅適用於不需要增加訓練參數的情形,如果想要實現的功能需要往模型新增參數,那么就必須要用到自定義Layer了。其實這也不復雜,相比於Lambda層只不過代碼多了幾行,官方文章已經寫得很清楚了:
https://keras.io/layers/writing-your-own-keras-layers/

這里把它頁面上的例子搬過來:

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim # 可以自定義一些屬性,方便調用
        super(MyLayer, self).__init__(**kwargs) # 必須

    def build(self, input_shape):
        # 添加可訓練參數
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(input_shape[1], self.output_dim),
                                      initializer='uniform',
                                      trainable=True)

    def call(self, x):
        # 定義功能,相當於Lambda層的功能函數
        return K.dot(x, self.kernel)

    def compute_output_shape(self, input_shape):
        # 計算輸出形狀,如果輸入和輸出形狀一致,那么可以省略,否則最好加上
        return (input_shape[0], self.output_dim)

參考鏈接:https://spaces.ac.cn/archives/5765

如上所示, 其中有三個函數需要我們自己實現:

  • build() 用來初始化定義weights, 這里可以用父類的self.add_weight() 函數來初始化數據, 該函數必須將 self.built 設置為True, 以保證該 Layer 已經成功 build , 通常如上所示, 使用 super(MyLayer, self).build(input_shape) 來完成。
  • call() 用來執行 Layer 的職能, x就是該層的輸入,x與權重kernel做點積,生成新的節點層,即當前 Layer 所有的計算過程均在該函數中完成。
  • compute_output_shape() 用來計算輸出張量的 shape。

例如輸入input=【5,128】,5是batch_size,128是embedding向量的維度,input_shape[0]=5,input_shape[1]=128,假如output_dim=256,所以self.kernel的維度就是【128,256】,最后compute_output_shape的輸出維度就是【5,256】。調用方式:Mylayer(256)(input)

 

二、add_weight源碼

def add_weight(self,
                   name,
                   shape,
                   dtype=None,
                   initializer=None,
                   regularizer=None,
                   trainable=True,
                   constraint=None):
        """Adds a weight variable to the layer.
        # Arguments
            name: String, the name for the weight variable.
            shape: The shape tuple of the weight.
            dtype: The dtype of the weight.
            initializer: An Initializer instance (callable).
            regularizer: An optional Regularizer instance.
            trainable: A boolean, whether the weight should
                be trained via backprop or not (assuming
                that the layer itself is also trainable).
            constraint: An optional Constraint instance.
        # Returns
            The created weight variable.
        """
        initializer = initializers.get(initializer)
        if dtype is None:
            dtype = K.floatx()
        weight = K.variable(initializer(shape),
                            dtype=dtype,
                            name=name,
                            constraint=constraint)
        if regularizer is not None:
            self.add_loss(regularizer(weight))
        if trainable:
            self._trainable_weights.append(weight)
        else:
            self._non_trainable_weights.append(weight)
        return weight
從上述代碼來看通過 add_weight 創建的參數, trainable 設置 True ,自動納入訓練參數中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM