TensorFlow 2.0 —— 模型训练

article/2025/10/29 18:27:04

目录

  • 1、Keras版本模型训练
    • 1.1 构造模型(顺序模型、函数式模型、子类模型)
    • 1.2 模型训练:model.fit()
    • 1.3 模型验证:model.evaluate()
    • 1.4 模型预测:model.predict()
    • 1.5 使用样本加权和类别加权
    • 1.6 回调函数
      • 1.6.1 EarlyStopping(早停)
      • 1.6.2 checkpoint模型
      • 1.6.3 使用回调实现动态学习率调整
    • 1.7 将数据传递到多输入、多输出模型
      • 1.7.1 损失函数
      • 1.7.2 指标函数
      • 1.7.3 完整运行
  • 2、自动求导方法
    • 2.1 tf.GradientTape详解
  • 3、自定义模型训练
    • 3.1 模型自动求导
    • 3.2 用GradientTape自定义训练模型
      • 3.2.1 模型构建
      • 3.2.2 创建数据
      • 3.2.3 定义损失函数和优化器
      • 3.2.4 模型训练
    • 3.3 使用GradientTape自定义训练模型进阶(加入评估函数)
      • 3.3.1 模型构建
      • 3.3.2 构造数据集、优化器、损失函数
      • 3.3.3 模型训练

1、Keras版本模型训练

1.1 构造模型(顺序模型、函数式模型、子类模型)

import numpy as np
import tensorflow as tfinputs = tf.keras.Input(shape=(32,))  # 数据维度为32
x = tf.keras.layers.Dense(64, activation='relu')(inputs)  # 64个隐藏神经元
x = tf.keras.layers.Dense(64, activation='relu')(x)  # 64个隐藏神经元
predictions = tf.keras.layers.Dense(10)(x)  # 输出10分类结果# - inputs:模型的输入
# - outputs:模型的输出model = tf.keras.Model(inputs=inputs, outputs=predictions)# 指定损失函数(loss) tf.keras.optimizers.RMSprop
# 优化器(optimizer) tf.keras.SparseCategoricalCrossentropy
# 指标(metrics) ['accuracy']model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])# 构造训练集、验证集、测试集
x_train = np.random.random((1000,32))  # 1000条数据,维度为32
y_train = np.random.randint(10, size=(1000,))x_val = np.random.random((200, 32))  # 200条数据,维度为32
y_val = np.random.randint(10, size=(200,))x_test = np.random.random((200, 32))  # 200条数据,维度为32
y_te t = np.random.randint(10, size=(200,))

tf2.0提供了许多内置的优化器,损失函数和评价指标。通常不需要从头开始创建自己的损失函数、评价指标或者优化器,因为所需的可能已经是Keras API的一部分。

1.2 模型训练:model.fit()

构造模型后,通过将数据切成大小为"batch_size"的"批"来训练模型,并针对给定数量的"epoch"重复遍历整个数据集。

# help(model.fit)  查看model.fit()的各项功能
model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_val, y_val))

上面代码中使用validation_data=(x_val, y_val)表示验证集,其中(x_val, y_val)是一个元组。参数validation_data将Numpy的元组传递(x_val, y_val)给模型,以在每个时期结束时评估验证损失和验证指标。

除了使用参数validation_data传递验证集以外,还可以使用参数validation_split,validation_split允许自动保留部分训练数据以供验证,参数值表示要保留用于验证的数据的一部分,因此应将其设置为大于0小于1的数字。例如,validation_split=0.2表示“使用20%的训练数据作为验证集”,而validation_split=0.6表示“使用60%的数据用于验证”。

验证的计算方法是在进行任何改组之前,对fit调用接收到的数组进行最后x%的采样。

注意,validation_split只能在使用Numpy进行训练时使用。

1.3 模型验证:model.evaluate()

results = model.evaluate(x_test, y_test, batch_size=128)

1.4 模型预测:model.predict()

predictions = model.predict(x_test[:3])

1.5 使用样本加权和类别加权

在模型训练的时候,除了输入数据和目标数据外,还可以在使用时将样本权重或类别权重传递给模型fit。

从Numpy数据进行训练时,通过sample_weight和class_weight参数设置样本权重或者累呗权重。

在数据集训练时,通过使数据集返回一个元组(input_batch, target_batch, sample_weight_batch)。“样本权重”数组是一个数字数组,用于指定批次中每个样本在计算总损失时应具有的权重,它通常用于不平衡的分类问题中(这种想法是为很少见的类别赋予更多的权重)。当使用的权重为1和0时,该数组可以作为损失函数的掩码(完全丢弃某些样本对总损失的贡献)。

“类别权重”字典是同一个概念的一个更具体的实例,它将类别索引映射到应该属于该类别的样本的样本权重。例如,如果在数据中类“0”的表示量比类“1”的表示量少两倍,则可以使用class_weight={0:1,1:0.5}。

下面列举一个Numpy示例,其中使用类权重或样本权重来更加重视第5类的正确分类。

构建模型

import tensorflow as tfdef get_uncompiled_model():inputs = tf.keras.Input(shape=(32,), name='digits')x = tf.keras.layers.Dense(64, activation='relu', name="dense_1")(inputs)x = tf.keras.layers.Dense(64, activation='relu', name='dense_2')(x)outputs = tf.keras.layers.Dense(10, name="predictions")(x)model = tf.keras.Model(inputs=inputs,outputs=outputs)return modeldef get_compiled_model():model = get_uncompiled_model()model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-3),loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['sparse_categorical_accuracy'])return model

类别加权

import numpy as np# 构造训练集、验证集、测试集
x_train = np.random.random((1000,32))  # 1000条数据,维度为32
y_train = np.random.randint(10, size=(1000,))x_val = np.random.random((200, 32))  # 200条数据,维度为32
y_val = np.random.randint(10, size=(200,))x_test = np.random.random((200, 32))  # 200条数据,维度为32
y_test = np.random.randint(10, size=(200,))# 类别5:加权
class_weight = {0:1, 1:1, 2:1, 3:1, 4:1, 5:2, 6:1, 7:1, 8:1, 9:1}model = get_compiled_model()
model.fit(x_train, y_train, class_weight=class_weight, batch_size=64, epoch=4)

样本加权

# 样本加权
import numpy as np# 构造训练集、验证集、测试集
x_train = np.random.random((1000,32))  # 1000条数据,维度为32
y_train = np.random.randint(10, size=(1000,))x_val = np.random.random((200, 32))  # 200条数据,维度为32
y_val = np.random.randint(10, size=(200,))x_test = np.random.random((200, 32))  # 200条数据,维度为32
y_test = np.random.randint(10, size=(200,))sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train==5] = 2model = get_compiled_model()
model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epoch=4)

1.6 回调函数

Keras中的回调是在训练期间(在某个时期开始,在批处理结束时,在某个时期结束时等)在不同时间点调用的对象,这些对象可用于实现以下行为:

  • 在训练过程中的不同时间点进行验证(除了内置的按时间段验证);
  • 定期或在超过特定精度阈值时对模型进行检查;
  • 当训练似乎停滞不前时,更改模型的学习率;
  • 当训练似乎停滞不前时,对顶层进行微调;
  • 当训练结束或超出特定性能阈值时发送电子邮件或在即时消息通知等等;
  • 回调可以作为列表传递给model.fit;

1.6.1 EarlyStopping(早停)

  • monitor:被监测的数据;
  • min_delta:在被监测的数据中被认为是提升的最小变化。例如,小于min_delta的绝对变化会被认为没有提升;
  • patience:没有进步的训练轮数,在这之后训练就会被停止;
  • verbose:详细信息模式;
  • mode:{auto,min,max}其中之一。在min模式中,当被监测的数据停止下降时,训练就会停止;在max模式中,当被监测的数据停止上升,训练就会停止;在auto模式中,方向会自动从被监测的数据的名字中判断出来。
# 早停的应用示例
model = get_compiled_model()# callbacks相当于list
callbacks = [tf.keras.callbacks.EarlyStopping(# 当“val_loss”不再下降时停止训练,'val_loss'为监控的指标monitor='val_loss',# “不再下降”被定义为“减少不超过1e-2”min_delta=1e-2,# “不再改善”进一步定义为“至少2个epoch”patience=2,verbose=1)
]
model.fit(x_train, y_train, epoch=20, batch_size=64,callbacks=callbacks,validation_split=0.2)

1.6.2 checkpoint模型

在相对较大的数据集上训练模型时,至关重要的是要定期保存模型的checkpoint,最简单的方法是使用ModelCheckpoint回调。

# 模型保存checkpoint示例
model = get_compiled_model()callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='mymodel_{epoch}',  # 模型保存路径save_best_only=True,  monitor='val_loss',save_weights_only=True,  # 保存模型权重verbose=1)
]
model.fit(x_train, y_train,epoch=20,batch_size=64,callbacks=callbacks,validation_split=0.2)

1.6.3 使用回调实现动态学习率调整

由于优化程序无法访问验证指标,因此无法使用这些计划对象来实现动态学习率计划(例如当验证损失不再改善的时候降低学习率);

但是回调确实可以访问所有指标,包括验证指标!因此可以通过使用回调函数来修改优化程序上的当前学习率,从而实现此模式。实际上,它是作为ReduceLROnPlateau回调内置的。

ReduceLROnPlateau参数:

  • monitor:被监测的指标;
  • factor:学习速率被降低的因数。新的学习速率=学习速率*因数;
  • patience:没有进步的训练轮数,在这之后训练速率会被降低;
  • verbose:整数,是否显示信息,0或者1;
  • mode:{auto,min,max}其中之一。如果是min模式,如果被监测的数据已经停止下降则学习速率会被降低;如果是max模式,如果被监测的数据已经停止上升则学习速率会被降低;如果是auto模式,方向会被从监测的数据中自动推断处理;
  • min_delta:衡量新的最佳阈值,仅关注重大变化;
  • cooldown:在学习速率被降低后,重新恢复正常操作之前等待的训练轮数量;
  • min_lr:学习速率的下边界;
# 动态调整学习率示例
model = get_compiled_model()callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='mymodel_{epoch}',  # 模型保存路径save_best_only=True,monitor='val_loss',save_weights_only=True,  # 保存模型权重verbose=1),tf.keras.callbacks.ReduceLROnPlateau(monitor="val_sparse_categorical_accuracy",verbose=1,mode='max',factor=0.5,patience=3)
]
model.fit(x_train, y_train,epoch=20,batch_size=64,callbacks=callbacks,validation_split=0.2)

许多内置的回调函数可用:

  • TensorBoard:定期编写可在TensorBoard中可视化的模型日志
  • CSVLogger:将损失和指标数据流式传输到CSV文件;

1.7 将数据传递到多输入、多输出模型

在前面的示例中,我们考虑一个具有单个输入(shape的张量(32,))和单个输出(shape的预测张量(10,))的模型,但是具有多个输入或输出的模型呢?

考虑以下模型,该模型具有形状的图像输入(32,32,3),即(height,width,channels)和形状的时间序列输入(None,10),即(timesteps,features)。我们的模型将具有根据这些输入的组合计算出的两个输出:“得分”(形状为(1,))和五类(形状为(5,))的概率分布。

image_input = tf.keras.Input(shape=(32,32,3), name='img_input')
timeseries_input = tf.keras.Input(shape=(20,10), name='ts_input')x1 = tf.keras.layers.Conv2D(3, 3)(image_input)
x1 = tf.keras.layers.GlobalAveragePooling2D()(x1)x2 = tf.keras.layers.Conv1D(3, 3)(timeseries_input)
x2 = tf.keras.layers.GlobalAveragePooling1D()(x2)x = tf.keras.layers.concatenate([x1,x2])score_output = tf.keras.layers.Dense(1, name='score_output')(x)
class_output = tf.keras.layers.Dense(5, name='class_output')(x)model = tf.keras.Model(inputs=[image_input, timeseries_input], outputs=[score_output, class_output])

下面绘制这个模型,以便可以清楚知道我们在这里做什么(请注意,图中显示的形状是批处理形状,而不是按样本的形状)。

我们通过tf.keras.utils.plot_model进行可视化操作,在window中直接使用该方法可能会出现一些问题,我们可以通过博客尝试解决这个问题。
在这里插入图片描述

1.7.1 损失函数

在编译时,通过将损失函数作为列表传递,我们可以为不同的输出指定不同的损失:

model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss=[tf.keras.losses.MeanSquaredError(),tf.keras.losses.CategoricalCrossentropy(from_logits=True)]
)

如果我们仅使用单个损失函数传递给模型,则将相同的损失函数应用于每个输出,这在此处不合适。

1.7.2 指标函数

model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss=[tf.keras.losses.MeanSquaredError(),tf.keras.losses.CategoricalCrossentropy(from_logits=True)],metrics = [[tf.keras.metrics.MeanAbsolutePercentageError(),tf.keras.metrics.MeanAbsoluteError()],[tf.keras.metrics.CategoricalAccuracy()]]
)

由于我们为输出层命名,因此还可以通过dict指定每个输出的损失和指标:

model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss={'score_output':tf.keras.losses.MeanSquaredError(),'class_output':tf.keras.losses.CategoricalCrossentropy(from_logits=True)},metrics={'score_output':[tf.keras.metrics.MeanAbsolutePercentageError(),tf.keras.metrics.MeanAbsoluteError()],'class_output':[tf.keras.metrics.CategoricalAccuracy()]})

如果有两个以上的输出,建议使用显式名称和字典。

可以使用以下参数对不同的特定于输出的损失赋予不同的权重(例如在我们的示例中,我们可能希望给某类损失函数赋予更高的权重)

model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss={'score_output':tf.keras.losses.MeanSquaredError(),'class_output':tf.keras.losses.CategoricalCrossentropy(from_logits=True)},metrics={'score_output':[tf.keras.metrics.MeanAbsolutePercentageError(),tf.keras.metrics.MeanAbsoluteError()],'class_output':[tf.keras.metrics.CategoricalAccuracy()]},loss_weight={'score_output':2.,'class_output':1.})

如果某些输出仅用于预测而不是训练,我们可以选择不为某些输出计算损失。

model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss=[None, tf.keras.losses.CategoricalCrossentropy(from_logits=True)])model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss={'class_output':tf.keras.losses.CategoricalCrossentropy(from_logits=True)})

1.7.3 完整运行

import tensorflow as tf
import numpy as npimage_input = tf.keras.Input(shape=(32,32,3), name='img_input')
timeseries_input = tf.keras.Input(shape=(20,10), name='ts_input')x1 = tf.keras.layers.Conv2D(3, 3)(image_input)
x1 = tf.keras.layers.GlobalAveragePooling2D()(x1)x2 = tf.keras.layers.Conv1D(3, 3)(timeseries_input)
x2 = tf.keras.layers.GlobalAveragePooling1D()(x2)x = tf.keras.layers.concatenate([x1,x2])score_output = tf.keras.layers.Dense(1, name='score_output')(x)
class_output = tf.keras.layers.Dense(5, name='class_output')(x)model = tf.keras.Model(inputs=[image_input, timeseries_input], outputs=[score_output, class_output])img_data = np.random.random_sample(size=(100, 32, 32, 3))
ts_data = np.random.random_sample(size=(100, 20, 10))
score_targets = np.random.random_sample(size=(100, 1))
class_targets = np.random.random_sample(size=(100, 5))model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3),loss=[tf.keras.losses.MeanSquaredError(),tf.keras.losses.CategoricalCrossentropy(from_logits=True)],metrics = [[tf.keras.metrics.MeanAbsolutePercentageError(),tf.keras.metrics.MeanAbsoluteError()],[tf.keras.metrics.CategoricalAccuracy()]]
)# 两种训练方式
model.fit([img_data, ts_data], [score_targets, class_targets], batch_size=32, epochs=3)model.fit({'img_input':img_data, 'ts_input':ts_data},{'score_output':score_targets, 'class_output':class_targets},batch_size=32,epochs=3)

2、自动求导方法

tensorflow中的梯度求解利器:tf.GradientTape

GradientTape是eager模式下计算梯度用的,而eager模式是TensorFlow 2.0的默认模式。

举个例子,计算 y = x 2 y=x^2 y=x2 x = 3 x=3 x=3时的导数:

import tensorflow as tfx = tf.constant(3.0)
with tf.GradientTape() as g:g.watch(x)  # watch的作用:确保某个tensor被tape追踪y = x * x
dy_dx = g.gradient(y,x)  # gradient的作用:根据tape上面的上下文来计算某个或者某些tensor的梯度

2.1 tf.GradientTape详解

tf.GradientTape(persistent=False,watch_accessed_variables=True)
  • persistent:用来指定新创建的gradient tape是否是可持续性,默认是False,意味着只能够调用一次gradient()函数。
  • watch_accessed_variables:表明这个GradientTape是不是会自动追踪任何能被训练(trainable)的变量。默认是True,要是False的话,意味着需要手动去指定想追踪的那些变量。
gradient(target,sources)
  • 作用:根据tape上面的上下文来计算某个或者某些tensor的梯度参数。
  • target:被微分的Tensor,可以理解为loss值(针对深度学习训练来说),就像上面代码中的y。
  • sources:Tensor或者Variable列表(当然可以只有一个值)。
  • 返回:一个列表表示各个变量的梯度值,和source中的变量列表一一对应,表明这个变量的梯度。
watch(tensor)
  • 作用:确保某个tensor被tape追踪;
  • 参数:一个Tensor或者一个Tensor列表;
  • 一般在网络中使用时,不需要显式调用watch函数,使用默认设置。GradientTape会监控可训练变量;
apply_gradients(grads_and_vars, name=None)
  • 作用:把计算出来的梯度更新到变量上;
  • grads_and_vars:(gradient,variable)对的列表形式;
  • name:操作名;

大概的使用方法如下面代码所示:

loss_object = tf.keras.losses.CategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adam()with tf.GradientTape() as tape:predictions = model(data)loss = loss_object(labels, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))

3、自定义模型训练

3.1 模型自动求导

  1. 构建模型(神经网络的前向传播);
  2. 定义损失函数;
  3. 定义优化函数;
  4. 定义tape;
  5. 模型得到预测值;
  6. 前向传播得到loss;
  7. 反向传播;
  8. 用优化函数将计算出来的梯度更新到变量上面;
import numpy as np
import tensorflow as tfclass MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classes# 定义自己需要的层self.dense_1 = tf.keras.layers.Dense(32, activation='relu')self.dense_2 = tf.keras.layers.Dense(self.num_classes)def call(self, inputs):# 定义前向传播x = self.dense_1(inputs)return self.dense_2(x)data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))model = MyModel(num_classes=10)loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()with tf.GradientTape() as tape:predictions = model(data)loss = loss_object(labels, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))

3.2 用GradientTape自定义训练模型

3.2.1 模型构建

import tensorflow as tfclass MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classes# 定义自己需要的层self.dense_1 = tf.keras.layers.Dense(32, activation='relu')self.dense_2 = tf.keras.layers.Dense(self.num_classes)def call(self, inputs):# 定义前向传播x = self.dense_1(inputs)return self.dense_2(x)

3.2.2 创建数据

import numpy as npdata = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

3.2.3 定义损失函数和优化器

model = MyModel(num_classes=10)# 优化器
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
# 损失函数
loss_fn = tf.keras.losses.CategoricalCrossentropy()# 训练数据集准备(准备dataset并且打乱数据)
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((data, labels))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)

3.2.4 模型训练

import numpy as np
import tensorflow as tfclass MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classes# 定义自己需要的层self.dense_1 = tf.keras.layers.Dense(32, activation='relu')self.dense_2 = tf.keras.layers.Dense(num_classes)def call(self, inputs):#定义前向传播# 使用在 (in `__init__`)定义的层x = self.dense_1(inputs)return self.dense_2(x)data = np.random.random((100, 32))
labels = np.random.random((100, 10))model = MyModel(num_classes=10)# Instantiate an optimizer.
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
# Instantiate a loss function.
loss_fn = tf.keras.losses.CategoricalCrossentropy()# Prepare the training dataset.
batch_size = 16
train_dataset = tf.data.Dataset.from_tensor_slices((data, labels))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)epochs = 3
for epoch in range(epochs):print('Start of epoch %d' % (epoch,))# 遍历数据集的batch_sizefor step, (x_batch_train, y_batch_train) in enumerate(train_dataset):# 打开GradientTape以记录正向传递期间运行的操作,这将启用自动区分。with tf.GradientTape() as tape:# 运行该模型的前向传播。 模型应用于其输入的操作将记录在GradientTape上。logits = model(x_batch_train, training=True)  # 这个minibatch的预测值# 计算这个minibatch的损失值loss_value = loss_fn(y_batch_train, logits)# 使用GradientTape自动获取可训练变量相对于损失的梯度。grads = tape.gradient(loss_value, model.trainable_weights)# 通过更新变量的值来最大程度地减少损失,从而执行梯度下降的一步。optimizer.apply_gradients(zip(grads, model.trainable_weights))# 每200 batches打印一次.if step % 200 == 0:print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))print('Seen so far: %s samples' % ((step + 1) * 64))

3.3 使用GradientTape自定义训练模型进阶(加入评估函数)

让我们将metric添加到组合中。下面可以在从头开始编写的训练循环中随时使用内置指标(或编写的自定义指标)。流程如下:

  • 在循环开始时初始化metrics
  • metric.update_state():每batch之后更新
  • metric.result():需要显示metrics的当前值时调用
  • metric.reset_states():需要清除metrics状态时重置(通常在每个epoch的结尾)

3.3.1 模型构建

class MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classes# 定义自己需要的层self.dense_1 = tf.keras.layers.Dense(32, activation='relu')self.dense_2 = tf.keras.layers.Dense(num_classes)def call(self, inputs):#定义前向传播# 使用在 (in `__init__`)定义的层x = self.dense_1(inputs)return self.dense_2(x)

3.3.2 构造数据集、优化器、损失函数

import numpy as np
x_train = np.random.random((1000, 32))
y_train = np.random.random((1000, 10))
x_val = np.random.random((200, 32))
y_val = np.random.random((200, 10))
x_test = np.random.random((200, 32))
y_test = np.random.random((200, 10))# 优化器
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
# 损失函数
loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)# 准备metrics函数
train_acc_metric = tf.keras.metrics.CategoricalAccuracy()
val_acc_metric = tf.keras.metrics.CategoricalAccuracy()# 准备训练数据集
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)# 准备测试数据集
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

3.3.3 模型训练

model = MyModel(num_classes=10)
epochs = 3
for epoch in range(epochs):print('Start of epoch %d' % (epoch,))# 遍历数据集的batch_sizefor step, (x_batch_train, y_batch_train) in enumerate(train_dataset):#一个batchwith tf.GradientTape() as tape:logits = model(x_batch_train)loss_value = loss_fn(y_batch_train, logits)grads = tape.gradient(loss_value, model.trainable_weights)optimizer.apply_gradients(zip(grads, model.trainable_weights))# 更新训练集的metricstrain_acc_metric(y_batch_train, logits)     # 在每个epoch结束时显示metrics。train_acc = train_acc_metric.result()print('Training acc over epoch: %s' % (float(train_acc),))# 在每个epoch结束时重置训练指标train_acc_metric.reset_states()#!!!!!!!!!!!!!!!# 在每个epoch结束时运行一个验证集。for x_batch_val, y_batch_val in val_dataset:val_logits = model(x_batch_val)# 更新验证集mericsval_acc_metric(y_batch_val, val_logits)val_acc = val_acc_metric.result()print('Validation acc: %s' % (float(val_acc),))val_acc_metric.reset_states()#显示测试集

http://chatgpt.dhexx.cn/article/yvNp7ifQ.shtml

相关文章

如何在jupyter上运行Java代码(适用LINUX)

如何在jupyter上运行Java代码 1.下载必须软件 下载JDK且JDK版本必须 ≥ 9 ≥9 ≥9从github上下载ijava 附 : ijava下载链接.装有jupyter,我在LINUX上是直接装的anaconda 安装过程 将下载的ijava压缩包解压出来,并在此路径用该命令 : sudo…

Java单元测试介绍

文章目录 单元测试单元测试基本介绍单元测试快速入门单元测试常用注解 单元测试 单元测试基本介绍 单元测试: 单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,…

Jupyter 配置 Java环境,写Java代码,测试成功

本次简单诉说下怎么通过jupyter安装iJava,写Java代码。 安装Java的不说了 我使用的是Java15 然后去:https://github.com/SpencerPark/IJava/releases 下载zip,不要下载其他的 得到就是一个py文件 下面就是一个 python install.py 我这里就…

java调用python执行脚本,附代码

最近有个功能需要java调用python脚本实现一些功能,前期需要做好的准备:配置好python环境,如下: 以下展示的为两种,一种为生成图片,另一种为生成字符串。 package com.msdw.tms.common.utils.py;import ja…

Selenium Java自动化测试环境搭建

IDE用的是Eclipse。 步骤1:因为是基于Java,所以首先要下载与安装JDK(Java Development Kit) 下载: 点击这里下载JDK 安装:按照默认安装一路点next就可以了。 验证:安装完成后,在命…

java单元测试(Junit)

相关代码下载链接: http://download.csdn.net/detail/stevenhu_223/4884357 在有些时候,我们需要对我们自己编写的代码进行单元测试(好处是,减少后期维护的精力和费用),这是一些最基本的模块测试。当然&…

Java单元测试工具:JUnit4(一)——概述及简单例子

(一)JUnit概述及一个简单例子 看了慕课网的JUnit视频教程: http://www.imooc.com/learn/356,总结笔记。 这篇笔记记录JUnit的概述,以及一个快速入门的例子。 1.概述 1.1 什么是JUnit ①JUnit是用于编写可复用测试集的…

Linux下执行Python脚本

1.Linux Python环境 Linux系统一般集成Python,如果没有安装,可以手动安装,联网状态下可直接安装。Fedora下使用yum install,Ubuntu下使用apt-get install,前提都是root权限。安装完毕,可将Python加入环境变…

python pytest脚本执行工具

pytest脚本执行工具 支持获取当前路径下所有.py脚本 添加多个脚本,一起执行 import tkinter as tk from tkinter import filedialog import subprocess import os from datetime import datetimedef select_script():script_path filedialog.askopenfilename(fil…

linux上运行python(简单版)

linux上运行python(简单版) 一、前提准备1.centOS72.挂载yum源[http://t.csdn.cn/Isf0i](http://t.csdn.cn/Isf0i) 二、安装python3三、运行程序 一、前提准备 1.centOS7 2.挂载yum源http://t.csdn.cn/Isf0i 在终端进行安装python3 二、安装python3 …

linux怎么运行python脚本?

linux运行python脚本的方法: 1、命令行执行: 建立一个test.py文档,在其中书写python代码。之后,在命令行执行:python test.py 说明:其中python可以写成python的绝对路径。使用which python进行查询。 注…

java实现远程执行Linux下的shell脚本

java实现远程执行Linux下的shell脚本 背景导入Jar包第一步:远程连接第二步:开启Session第三步:新建测试脚本文件结果报错 背景 最近有个项目,需要在Linux下的服务器内写了一部分Python脚本,业务处理却是在Java内&…

Java运行Python脚本

前段时间遇到了在JavaWeb项目中嵌入运行Python脚本的功能的需求。想到的方案有两种,一种是使用Java技术(Jython或Runtime.exec)运行Python脚本,另一种是搭建一个Python工程对外提供相应http或webservice接口。两种方案我都有实现&…

Java项目分层

MVC模式 在实际的开发中有一种项目的程序组织架构方案叫做MVC模式,按照程序 的功能将他们分成三个层,如下图:Modle层(模型层)、View层(显示层)、Controller层(控制层)。…

java项目收获总结_java开发项目收获心得

1 java开发项目收获心得 it行业现在的发展如日中天,很多人都纷纷走进这个行业,而java作为跨平台的编程语言更是受欢迎。java其实相对其他语言来说的确很有优势,但是也有点缺陷,但是以后发展到什么程度,谁都不知道。那么下面小编给大家说说java开发项目收获心得,希望能对你…

java查看jar包依赖_java项目开发中如何查找到项目依赖的jar包?

不管是java普通工程,还是java web项目,甚至是android项目,依赖包的管理有2种: 1.直接依赖jar包 这种方式简单直白,项目下载后在正确的ide或者稍微做转换就可以运行起来。比如java web工程的WEB-INF/lib下 只要按这个步骤Java Build Path=>Add Libraty=>Web App Libr…

Java小白必看:开发一个编程项目的完整流程(附100套Java编程项目源码+视频)

我相信很多Java新手都会遇到这样一个问题:跟着教材敲代码,很容易;但是让他完整的实现一个应用项目,却不会;不知道从哪里开始,不知道实现一个项目的完整流程是怎样的,看似很简单的一个问题&#…

分享67套基于Java开发的Java毕业设计实战项目(含源码+毕业论文)【新星计划】

【新星计划】分享67套基于Java开发的Java毕业设计实战项目(含源码毕业论文) 基于Java开发的Java毕业设计实战项目 本文中的所有主题都来自互联网。如果您侵犯您的权利,请及时联系Blogger,博主将及时处理。 投诉邮箱:1919101926qq.com (没事…

分享一些我的学习方法

赖勇浩(http://laiyonghao.com ) 经常听到和看到一些前辈提起搞编程这一行最大的痛苦在于知识的更新太频繁,如同逆水行舟,不进则退,稍一松懈,就跟不上潮流。的确如此,既然身在 IT 界&#xff0c…

规划之路:SLAM学习经验分享

针对想学SLAM的提问,我觉得我还是有一定的发言权。 作为一个刚入坑SLAM一年多的初学者,首先想说的就是这个研究方向比较广,大方向按搭载传感器分为激光SLAM和视觉SLAM两种,激光SLAM搭载激光雷达,视觉SLAM搭载单目、双目…