[深度之眼]TensorFlow2.0項目班-自定義層

自定義層的主要數據結構是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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章