最近在用tensorflow2.0搭建一個簡單的神經網絡,雖然結構簡單但是由於對自定義有要求,官方提供的layer和model不能滿足要求,因此需要自行對layer、model、loss function進行自定義。由於tensorflow2.0發布不久,國內相關文章較少,我便決定寫上這一系列文章。本文討論tensorflow2.0中如何自定義layer。
(一)tensorflow2.0 - 自定義layer
(二)tensorflow2.0 - 自定義Model
(三)tensorflow2.0 - 自定義loss function(損失函數)
(四)tensorflow2.0 - 實戰稀疏自動編碼器SAE
本文不討論tensorflow1和2在版本上自定義layer的區別,只講述2.0版本下如何自定義layer。
本文架構上不做長篇大論,直接根據代碼來解釋如何自定義模型。
首先引入相應的庫函數
import tensorflow as tf
from tensorflow.keras import *
然后自定義Layer類,這里命名為SAELayer,繼承自tensorflow.keras.layers.Layer
,由於上面引入的庫函數為from tensorflow.keras import *
,所以寫起來就比較清爽,可以直接簡寫為layers.Layer
,之后的都如此,寫法上tensorflow.keras
都省略了,就不做多解釋。
需要注意,Layer類中涉及到了三個重要的方法,分別是__init__()
,build()
,call()
,關於他們的關系與作用請看我的另一篇文章(tensorflow2.0中Layer的__init__(),build(), call()函數)。這里只簡單說明,__init__()
函數在創建Layer
對象時調用,build
在第一次調用call
前調用(只調用一次),往后使用Layer
的方法都是使用call()
的方法。
需要注意build()
方法的參數,該方法是被自動調用的,所以其參數是固定的(當然改形參名稱沒關系),但是不能添加或者刪除參數。而call()
方法的官方定義為Layer.call(inputs, **kwargs)
,因此它至少需要一個input
作為參數(輸入該層的數據),其他參數可以按需自定義
下例為進行一個簡單的sigmoid(w*x + b)
的功能的自定義層,當然這是一次對一批數據進行操作,所以需要用矩陣(張量)的方式來思考。
class SAELayer(layers.Layer):
# 初始化num_outputs,即當前層輸出元素的個數
def __init__(self, num_outputs):
super(SAELayer, self).__init__()
self.num_outputs = num_outputs
# 在第一次調用該Layer的call方法前(自動)調用該函數,可以知道輸入數據的shape
# 根據輸入數據的shape可以初始化權值、bias的矩陣
def build(self, input_shape):
self.kernel = self.add_variable("kernel",
shape=[int(input_shape[-1]),
self.num_outputs])
self.bias = self.add_variable("bias",
shape=[self.num_outputs])
def call(self, input):
output = tf.matmul(input, self.kernel) + self.bias
# sigmoid激活函數
output = tf.nn.sigmoid(output)
return output
到此Layer
就定義好了,大家可以根據需要對其各部分進行修改,比如在build()
中增刪參數、在call()
中更改計算方式、激活函數等等。
Layer定義好了,如何使用呢?
大可以按照正常使用其他Layer的方式來調用,如果想看具體實例,可以看下一篇文章,里面將Layer放入了一個簡單的自定義Model中進行使用。
(二)tensorflow2.0 - 自定義Model
參考文獻: