1、官方文档推荐的定义类,调用call函数
通过继承tf.keras.Model并定义自己的前向传递来构建完全可自定义的模型。 在init方法中创建图层并将它们设置为类实例的属性。 在call方法中定义正向传递。
直接返回 numpy向量
class MyModel(keras.Model): def __init__(self, num_classes=10): super(MyModel, self).__init__(name='my_model') self.num_classes = num_classes # Define your layers here. self.dense_1 = keras.layers.Dense(32, activation='relu') self.dense_2 = keras.layers.Dense(num_classes, activation='sigmoid') def call(self, inputs): # Define your forward pass here, # using layers you previously defined (in `__init__`). x = self.dense_1(inputs) return self.dense_2(x)
2、调用接口写函数类
每个block都是一个网络层定义函数
def get_model(hyper_params): detections_per_layer = hyper_params["detections_per_layer"] img_size = hyper_params["img_size"] total_reg_points = hyper_params["total_landmarks"] * 2 + 4 input = Input(shape=(None, None, 3)) first_conv = Conv2D(24, (5,5), strides=2, padding="same", activation="relu")(input) single_1 = blaze_block(first_conv, 24) single_2 = blaze_block(single_1, 24) single_3 = blaze_block(single_2, 48, 2) single_4 = blaze_block(single_3, 48) single_5 = blaze_block(single_4, 48) double_1 = double_blaze_block(single_5, [24, 96], 2) double_2 = double_blaze_block(double_1, [24, 96]) double_3 = double_blaze_block(double_2, [24, 96]) double_4 = double_blaze_block(double_3, [24, 96], 2) double_5 = double_blaze_block(double_4, [24, 96]) double_6 = double_blaze_block(double_5, [24, 96]) double_3_labels = Conv2D(detections_per_layer[0], (3, 3), padding="same")(double_3) double_6_labels = Conv2D(detections_per_layer[1], (3, 3), padding="same")(double_6) double_3_boxes = Conv2D(detections_per_layer[0] * total_reg_points, (3, 3), padding="same")(double_3) double_6_boxes = Conv2D(detections_per_layer[1] * total_reg_points, (3, 3), padding="same")(double_6) pred_labels = HeadWrapper(1, name="conf_head")([double_3_labels, double_6_labels]) pred_labels = Activation("sigmoid", name="conf")(pred_labels) pred_deltas = HeadWrapper(total_reg_points, name="loc")([double_3_boxes, double_6_boxes]) return Model(inputs=input, outputs=[pred_deltas, pred_labels])其中:HeadWrapper是个类,继承了keras的Layer方法 。
class HeadWrapper(keras.layers.Layer): def __init__(self, last_dimension, **kwargs): super(HeadWrapper, self).__init__(**kwargs) self.last_dimension = last_dimension def get_config(self): config = super(HeadWrapper, self).get_config() config.update({"last_dimension": self.last_dimension}) return config def call(self, inputs): last_dimension = self.last_dimension batch_size = tf.shape(inputs[0])[0] outputs = [] for conv_layer in inputs: outputs.append(tf.reshape(conv_layer, (batch_size, -1, last_dimension))) # return tf.concat(outputs, axis=1)该方法类似与下列方法写成函数而已
inputs = tf.keras.Input(shape=(3,)) x = tf.keras.layers.Dense(4, activation=tf.nn.relu)(inputs) outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x) model = tf.keras.Model(inputs=inputs, outputs=outputs)