tensorflow2.x:构建tf.keras.Model实例的几种方式
说明
我以前是tensorflow1.x的用户,当时tensorflow还没合并keras,很多接口比较原始,还有session和napescope等概念。最近接触了下tf2.9, 发现写法都变了,作为一个tf2.x的初学者,记录下自己刚开始的一些心得。
我看到tf2.9的接口已经很接近pytorch了,但是还是没有pytorch好用。我看到教程里搭建模型主要就是实例化一个tf.keras.Model并对它进行各种设置,实例化一个tf.keras.Model对象竟然同时存在多种方式,这也不是“灵活”能解释的通的,感觉还是没有实现一种好用的方式达到“一招鲜”,多种方式并存的原因可能还是设计不够简单。
使用tf.keras.Sequential
tf.keras.models.Sequential继承自tf.keras.Model,所以实例化一个Sequential对象也可以。Sequential主要用于结构简单的层级网络,无法构建结构复杂的网络,这点从名字里也可看出来。
接口定义:
tf.keras.Sequential( layers=None, name=None )
初始化的时候可以传图两个参数,第一个是网络层的列表,第二个是名字。 同时tf.keras.models.Sequential也是它的别名。
方法1: 构造传参初始化
教程里的例子:
import tensorflow as tf model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation=relu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation=softmax) ])
这里传入了多个layers对象,组成了这个模型。这是比较简单的一种方式。
方法2:使用add()增加layers
构造时不传参,构造后可以使用add接口一层层往上加
model = tf.keras.Sequential() model.add(tf.keras.Input(shape=(16,))) model.add(tf.keras.layers.Dense(8)) model.add(tf.keras.layers.Dense(4))
这里构造了一个两层全连接的网络。
构造一个tf.keras.Model实例
Sequential只能搭建简单的网络,如果内部有复杂的结构,就需要直接使用tf.keras.Model构造。
方法3:继承tf.keras.Model类
这也是最像pytorch的方式。主要就是实现call()函数,其原型:
call( inputs, training=None, mask=None )
教程里的例子:
class MyModel(tf.keras.Model): def __init__(self): super(MyModel, self).__init__() self.conv1 = Conv2D(32, 3, activation=relu) self.flatten = Flatten() self.d1 = Dense(128, activation=relu) self.d2 = Dense(10, activation=softmax) def call(self, x): x = self.conv1(x) x = self.flatten(x) x = self.d1(x) return self.d2(x) model = MyModel()
如果是多输入输出的话,输入用[inoput1, input2]这样的方式来传入就可以,输出用[out1,out2]的方式来返回。
方法4:直接构造tf.keras.Model实例
最简单的方式构造一个单输入输出的网络:
inputs = tf.keras.layers.Input(shape=(3,)) outputs = tf.keras.layers.Dense(2)(inputs) model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
也可构建多输入输出的网络。这里是一个两个输出的例子:
inputs = tf.keras.layers.Input(shape=(3,)) d = tf.keras.layers.Dense(2, name=out) output_1 = d(inputs) output_2 = d(inputs) model = tf.keras.models.Model( inputs=inputs, outputs=[output_1, output_2])