自定義層的主要數據結構是layer,實現自定義層的最佳方法是拓展 tf.keras.layers.Layer類,分爲三個部分:
__init__ 進行與輸入無關的初始化,定義相關的層
build 知道輸入張量的形狀,並進行其餘初始化
call 定義前向傳播
通過iris數據集進行實驗
import tensorflow as tf
print(tf.__version__) # 查看tf版本
tf.test.is_gpu_available() # 看GPU是否可用,不支持則不用
import tensorflow as tf
class MyDense(tf.keras.layers.Layer):
def __init__(self, units=32, **kwargs):
self.units = units
super(MyDense, self).__init__(**kwargs)
#build方法一般定義Layer需要被訓練的參數。
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=True,
name='w')
self.b = self.add_weight(shape=(self.units,),
initializer='random_normal',
trainable=True,
name='b')
super(MyDense,self).build(input_shape) # 相當於設置self.built = True
#call方法一般定義正向傳播運算邏輯,__call__方法調用了它。
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
#如果要讓自定義的Layer通過Functional API 組合成模型時可以序列化,需要自定義get_config方法,保存模型不寫這部分會報錯
def get_config(self):
config = super(MyDense, self).get_config()
config.update({'units': self.units})
return config
from sklearn import datasets
iris = datasets.load_iris()
data = iris.data
labels = iris.target
print(data[:5])
print(labels)
#網絡 函數式構建的網絡
inputs = tf.keras.Input(shape=(4,))
x = MyDense(units=16)(inputs)
x = tf.nn.tanh(x)
x = MyDense(units=3)(x) #0,1,2
# x= tf.keras.layers.Dense(16)(x)
predictions = tf.nn.softmax(x)
model = tf.keras.Model(inputs=inputs, outputs=predictions)
import numpy as np
data = np.concatenate((data,labels.reshape(150,1)),axis=-1)
np.random.shuffle(data)
labels = data[:,-1]
data = data[:,:4]
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])
#keras
model.fit(data, labels, batch_size=32, epochs=100,shuffle=True)
model.summary()
model.save('keras_model_tf_version.h5') # 保存模型
_custom_objects = {"MyDense" : MyDense,} # 讀取保存的模型不加這一行會報錯
new_model = tf.keras.models.load_model("keras_model_tf_version.h5",custom_objects=_custom_objects)
y_pred = new_model.predict(data)
np.argmax(y_pred,axis=1)
print(labels)
模型訓練結果:
32/150 [=====>........................] - ETA: 0s - loss: 0.6379 - sparse_categorical_accuracy: 1.0000
150/150 [==============================] - 0s 124us/sample - loss: 0.6732 - sparse_categorical_accuracy: 0.9733
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 4)] 0
_________________________________________________________________
my_dense (MyDense) (None, 16) 80
_________________________________________________________________
tf_op_layer_Tanh (TensorFlow [(None, 16)] 0
_________________________________________________________________
my_dense_1 (MyDense) (None, 3) 51
_________________________________________________________________
tf_op_layer_Softmax (TensorF [(None, 3)] 0
=================================================================
Total params: 131
Trainable params: 131
Non-trainable params: 0