TensorFlow学习笔记(1)—— TensorFlow.Keras基本工作流

本文介绍使用TensorFlow2构建神经网络模型的过程,涵盖Sequential模型、函数式API及自定义模型等多种方式,并详细讲解模型编译、训练、评估及预测的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总览

最近在学习TensorFlow 2的API,官方教程一开始就介绍了整合进TensorFlow中的Keras。学习了一些基本API之后发现Keras的API较为友善,并且非常具有结构性,基本工作流也有较为固定的模式。一图胜千言,在此先总结出tensorflow.keras的基本工作流程:
tf.keras Basic Pipeline
接下来再把其中一些关键步骤的具体用法简单记录一下。

模型创建

第一步自然就是要定义出神经网络模型,Keras模型的基类为tensorflow.keras.Model,模型中的基本组件就是层结构tensorflow.keras.layers.Layer)。神经网络可以看做就是层的有向无环图(DAG)。模型创建就是定义出模型中各层的具体结构是什么、层与层之间的关系是什么。下面简述几种常用的模型构建方式。

Sequential

Keras提供了tensorflow.keras.Sequential类可以更方便地直接使用。正如其名,Sequential表示一组顺序层结构组成的神经网络,适用于一个输入对应一个输出的情况。可以在创建模型实例时直接将层实例列表作为参数,一步构建完成:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10)
])

也可以先不用参数创建实例,之后再使用Sequential的add方法按顺序向模型实例中逐个添加层实例:

model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10))

add对应,还有pop方法,就是从层结构列表的末尾移出一个层实例。

函数式调用

上述Sequential模型仅适用于一个输入对应一个输出的简单神经网络。而目前有很多更复杂的、非线性神经网络结构。即可能单一输入会产生分支,也有可能多个分支共享一个层结构。因此Keras也提供了函数式API,可以更灵活地实现更复杂的神经网络。

所谓函数式API,即每个层对象都可以被直接函数式地调用,这种调用就指明了这个层的一个输入与输出关系。如:

inputs = keras.Input(shape=(784,))
dense = layers.Dense(64, activation="relu")
x = dense(inputs)

首先定义了一个Dense层,之后直接函数式地调用层实例,以inputs作为输入参数,赋值给变量x。这样也就定义了从inputs经过densex的输入输出关系。这样就可以灵活地定义不同层与各种输出输出之间的关系,最后再通过inputsoutputs参数初始化model类,也就可以将连接inputsoutputs的所有层打包成一个模型:

encoder_input = keras.Input(shape=(28, 28, 1), name="original_img")
x = layers.Conv2D(16, 3, activation="relu")(encoder_input)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.Conv2D(16, 3, activation="relu")(x)
encoder_output = layers.GlobalMaxPooling2D()(x)

encoder = keras.Model(encoder_input, encoder_output, name="encoder")

decoder_input = keras.Input(shape=(16,), name="encoded_img")
x = layers.Reshape((4, 4, 1))(decoder_input)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
x = layers.Conv2DTranspose(32, 3, activation="relu")(x)
x = layers.UpSampling2D(3)(x)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
decoder_output = layers.Conv2DTranspose(1, 3, activation="relu")(x)

decoder = keras.Model(decoder_input, decoder_output, name="decoder")

autoencoder_input = keras.Input(shape=(28, 28, 1), name="img")
encoded_img = encoder(autoencoder_input)
decoded_img = decoder(encoded_img)
autoencoder = keras.Model(autoencoder_input, decoded_img, name="autoencoder")

由于Model类就是Layer的子类,因此也可以对模型进行函数式调用,从输入产生输出。如上例就独立地定义了encoderdecoder两个模型,之后再通过两步对模型的函数式调用,将两个模型连接起来形成更复杂的autoencoder模型。

小结

此外还有更高级的创建模型的方法,就是通过自定义Model类的子类来根据需求灵活自定义模型。这些官方指南——“编写自定义层和模型”中有详述,以后深入学习。

模型中的层也就都是tensorflow.keras.layers.Layer的具体子类,可以自己实现。Keras当然也准备了很多常用到的神经网络结构,均放在tensorflow.keras.layers包下,这些会在以后学习深挖。

个人总结构建模型这一步,也就是定义正向传播Forward Propagation)的过程,强调如何从Input -> Output。

Model常用属性和方法

在此简单记录一些tensorflow.keras.Model中常用的属性和方法备忘:

  • model.layers:该属性即为构建模型时加入的层结构列表
  • model.weights:该属性即为模型中的所有参数,虽然属性名叫weights,实际上包括偏置bias参数;
  • model.metrics_names:该属性为模型训练或测试之后输出对应的标签,往往就是损失(loss)和各种监控指标(metrics)。注意只有在模型经过实际数据的训练(fit)或测试(evaluate)之后,该属性才会有值;
  • model.summary():该方法比较常用,就是把模型的总结打印出来,可以快速概览模型的层级结构参数数量,如:
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    keras_layer (KerasLayer)     (None, 20)                400020    
    _________________________________________________________________
    dense (Dense)                (None, 16)                336       
    _________________________________________________________________
    dense_1 (Dense)              (None, 1)                 17        
    =================================================================
    Total params: 400,373
    Trainable params: 400,373
    Non-trainable params: 0
    _________________________________________________________________
    
  • model.save_weights(filepath)model.load_weights(filepath):这一对方法就是用于存储和读取模型所有参数的方法,注意仅仅是存储参数,并没有存储模型的结构;
  • model.save(filepath):该方法就是完整存储模型的方法,存储了模型的结构、参数以及优化器的状态。

其他方法就是模型训练、评估等关键流程的方法了,将会在下文中继续介绍。

模型编译

该步骤即为调用tensorflow.keras.Model.compile方法,其主要目的在于定义模型的损失函数优化器和训练或测试过程中想要监控的指标,对应地就是方法中lossoptimizermetrics三个参数:

这三个参数既可以是某个具体实例,也可以使用代表该类的字符串。如下例就是设置模型使用二分类交叉熵作为损失函数、使用Adam优化器来更新参数、监控指标为正确率:

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

个人总结模型编译这一步,也就是定义反向传播Backward Propagation)的过程,强调了模型的目标和更新参数的方式。

模型训练

该步骤即为调用tensorflow.keras.Model.fit方法,该方法就是用于定义模型的具体训练过程中的各种设置,参数较多,下面按重要性从大到小的方式列出这些参数:

  • x:训练集的输入,可以是Numpy的ndarray、TensorFlow的tensor,此时每一行代表一个数据。也可以是tensorflow.data.Datasettensorflow.keras.utils.Sequence
  • yx对应的真实值,需要与x类型一致(ndarray或tensor)。但若xtensorflow.data.Datasettensorflow.keras.utils.Sequence,则不需要y,因为这两种类型中已经包含了输入值和真实值了;
  • batch_size:每一次参数更新输入的数据量,默认值为32。若xDatasetSequence时,也不需要该参数;
  • epochs:全部完整遍历训练集多少次;
  • verbose:输出模式。0 = silent, 1 = progress bar, 2 = one line per epoch。默认为1。非0时,均会打印出loss和compile时设置的metrics;
  • validation_data:验证集,一个二元组,分别为验证集的输入和输出;
  • validation_split:0-1的小数,即从训练集中分割出多少比例作为验证集;
  • callbacks:一个列表,其中元素均为tf.keras.callbacks.Callback或其子类的实例。该类中包含了各种训练过程中的回调函数,如on_batch_beginon_batch_endon_epoch_beginon_epoch_end等。这些函数也都见名知意,就是在对应的训练过程的某个阶段开始或结束后的回调函数。如下例就是在每个epoch结束的时候打印一个“.”:
    class PrintDot(keras.callbacks.Callback):
      def on_epoch_end(self, epoch, logs):
        print('.', end='')
    
    history = model.fit(
      normed_train_data, train_labels,
      epochs=1000, validation_split = 0.2, verbose=0,
      callbacks=[PrintDot()])
    

训练记录

fit函数的返回值是一个tensorflow.python.keras.callbacks.History对象,其中记录了训练过程中的一些细节:

  • history:一个字典,其中包括了每个epoch训练集和验证集的损失和监控指标,带有前缀"val_"的key对应的就是验证集的记录。如:{'accuracy': [0.62166667, 0.6613333, 0.6961333], 'loss': [0.6447853596051534, 0.5929351980527242, 0.5533953377087911], 'val_accuracy': [0.6462, 0.6841, 0.7026], 'val_loss': [0.6143643766641617, 0.5779335916042327, 0.542848551273346]}
  • params:一个字典,记录的就是训练的各种参数,如:{'batch_size': None, 'epochs': 20, 'steps': 30, 'samples': None, 'verbose': 0, 'do_validation': True, 'metrics': ['loss', 'accuracy', 'val_loss', 'val_accuracy']}
  • epoch:一个整数数组,记录epoch的序数,长度与history中每个value的长度一致。往往以epoch为x,history中某个value作为y,绘制出训练过程中某个监控指标的变化情况。

模型评估

该步骤即为调用tensorflow.keras.Model.evaluate方法,该方法即为通过测试集数据来评估训练后的模型。该方法有一个参数return_dict决定了返回值类型:默认为False,表示返回值是一个列表,其中包括测试集的损失(loss)和监控指标(metrics);为True时,则返回值是一个字典,字典的key就是损失和监控指标的name属性,可以通过model.metrics_names获取当前模型中所有监控指标的名称。

该方法中很多参数与训练模型的fit函数类似:

  • xy:即为测试集的输入和输出;
  • batch_size:批次大小;
  • verbose:输出模式;
  • callbacks:回调函列表;

模型使用

该步骤即为调用tensorflow.keras.Model.predict方法,使用已经训练后的模型对未知输入数据进行推断。由于是对未知数据进行推断,因此该方法中也就只需要x参数设置输入值,输入数据按行(第一个维度)排列。返回值即为推断结果,是numpy的ndarray类型,同样按行排列。其他参数,如batch_sizeverbose等与fitevaluate方法中一样。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值