Keras - 自定義層



Keras允許我們建立自己的自定義層。建立新層後,可以在任何模型中無限制地使用它。讓我們學習如何在本章中建立新層。

Keras提供了一個基礎的類Layer,可以對其進行子類化以建立我們自己的自定義層。讓我們建立一個簡單的層,它將根據正態分佈查詢權重,然後在訓練期間進行基本計算,即查詢輸入與其權重的乘積之和。

步驟1:匯入必要的模組

首先,讓我們匯入必要的模組:

from keras import backend as K 
from keras.layers import Layer

這裡:

  • backend用於訪問dot函式。

  • Layer是基類,我們將對其進行子類化以建立我們的層。

步驟2:定義層類

讓我們透過對Layer類進行子類化來建立一個新類MyCustomLayer

class MyCustomLayer(Layer): 
   ...

步驟3:初始化層類

讓我們按照如下所示初始化我們的新類:

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

這裡:

  • 第2行設定輸出維度。

  • 第3行呼叫基類或超類的init函式。

步驟4:實現build方法

build是主要方法,其唯一目的是正確構建層。它可以執行與層內部工作相關的任何操作。完成自定義功能後,我們可以呼叫基類的build函式。我們的自定義build函式如下:

def build(self, input_shape): 
   self.kernel = self.add_weight(name = 'kernel', 
      shape = (input_shape[1], self.output_dim), 
      initializer = 'normal', trainable = True) 
   super(MyCustomLayer, self).build(input_shape)

這裡:

  • 第1行定義了帶有一個引數input_shapebuild方法。輸入資料的形狀由input_shape表示。

  • 第2行建立與輸入形狀對應的權重,並將其設定為核心。這是層的自定義功能。它使用'normal'初始化器建立權重。

  • 第6行呼叫基類的build方法。

步驟5:實現call方法

call方法在訓練過程中執行層的精確工作。

我們的自定義call方法如下:

def call(self, input_data): 
   return K.dot(input_data, self.kernel)

這裡:

  • 第1行定義了帶有一個引數input_datacall方法。input_data是我們的層的輸入資料。

  • 第2行返回輸入資料input_data和我們層的核心self.kernel的點積。

步驟6:實現compute_output_shape方法

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

這裡:

  • 第1行定義了帶有一個引數input_shapecompute_output_shape方法。

  • 第2行使用輸入資料的形狀和初始化層時設定的輸出維度來計算輸出形狀。

實現build、callcompute_output_shape完成了建立自定義層。最終完整的程式碼如下所示:

from keras import backend as K from keras.layers import Layer
class MyCustomLayer(Layer): 
   def __init__(self, output_dim, **kwargs): 
      self.output_dim = output_dim 
      super(MyCustomLayer, self).__init__(**kwargs) 
   def build(self, input_shape): self.kernel = 
      self.add_weight(name = 'kernel', 
      shape = (input_shape[1], self.output_dim), 
      initializer = 'normal', trainable = True) 
      super(MyCustomLayer, self).build(input_shape) # 
      Be sure to call this at the end 
   def call(self, input_data): return K.dot(input_data, self.kernel) 
   def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)

使用我們的自定義層

讓我們使用我們的自定義層建立一個簡單的模型,如下所示:

from keras.models import Sequential 
from keras.layers import Dense 

model = Sequential() 
model.add(MyCustomLayer(32, input_shape = (16,))) 
model.add(Dense(8, activation = 'softmax')) model.summary()

這裡:

  • 我們的MyCustomLayer使用32個單元和(16,)作為輸入形狀新增到模型中。

執行應用程式將列印如下所示的模型摘要:

Model: "sequential_1" 
_________________________________________________________________ 
Layer (type) Output Shape Param 
#================================================================ 
my_custom_layer_1 (MyCustomL (None, 32) 512 
_________________________________________________________________
dense_1 (Dense) (None, 8) 264 
================================================================= 
Total params: 776 
Trainable params: 776 
Non-trainable params: 0 
_________________________________________________________________
廣告