# List of metrics to monitor
metrics=[keras.metrics.SparseCategoricalAccuracy()],
)
**我们调用 fit(),它将把数据切成大小为 batch\_size 的 "批次",并在给定的时间内反复迭代整个数据集,从而训练模型**。
print(“Fit model on training data”)
history = model.fit(
x_train,
y_train,
batch_size=64,
epochs=2,
# We pass some validation for
# monitoring validation loss and metrics
# at the end of each epoch
validation_data=(x_val, y_val),
)
**咱们将要训练时,按照刚才提到的,将Kaggle的环境从CPU改为GPU**。
**接下来继续我们的训练**。
![](https://img-blog.csdnimg.cn/direct/1a61b2c0fdeb4220b3309dfea978f616.png)
**返回的历史对象记录了训练过程中的损失值和度量值:**
![](https://img-blog.csdnimg.cn/direct/d268a11f6e9b41d3a73b6dde1c47f32e.png)
**我们通过 evaluate() 在测试数据上对模型进行评估**:
Evaluate the model on the test data using evaluate
print(“Evaluate on test data”)
results = model.evaluate(x_test, y_test, batch_size=128)
print(“test loss, test acc:”, results)
Generate predictions (probabilities – the output of the last layer)
on new data using predict
print(“Generate predictions for 3 samples”)
predictions = model.predict(x_test[:3])
print(“predictions shape:”, predictions.shape)
**演绎如下**:
![](https://img-blog.csdnimg.cn/direct/bb32d2dfe11544488a6b69d085a849b5.png)
**现在,让我们来详细回顾一下这个工作流程的各个部分:**
## 编译()方法:指定损失、度量和优化器
**要使用 fit() 训练一个模型,需要指定一个损失函数、一个优化器,还可以选择一些监控指标**。
**您可以将这些参数作为编译()方法的参数传递给模型**:
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=[keras.metrics.SparseCategoricalAccuracy()],
)
**度量参数应该是一个列表--你的模型可以有任意数量的度量参数**。
**如果模型有多个输出,可以为每个输出指定不同的损耗和度量,还可以调节每个输出对模型总损耗的贡献。**
**请注意,如果您对默认设置感到满意,在许多情况下,可以通过字符串标识符来指定优化器、损耗和度量作为快捷方式**:
model.compile(
optimizer=“rmsprop”,
loss=“sparse_categorical_crossentropy”,
metrics=[“sparse_categorical_accuracy”],
)
**为便于以后重用,让我们把模型定义和编译步骤放在函数中;我们将在本文的不同示例中多次调用它们。**
def get_uncompiled_model():
inputs = keras.Input(shape=(784,), name=“digits”)
x = layers.Dense(64, activation=“relu”, name=“dense_1”)(inputs)
x = layers.Dense(64, activation=“relu”, name=“dense_2”)(x)
outputs = layers.Dense(10, activation=“softmax”, name=“predictions”)(x)
model = keras.Model(inputs=inputs, outputs=outputs)
return model
def get_compiled_model():
model = get_uncompiled_model()
model.compile(
optimizer=“rmsprop”,
loss=“sparse_categorical_crossentropy”,
metrics=[“sparse_categorical_accuracy”],
)
return model
## Keras提供许多内置优化器、损耗和指标
**一般来说,****您不必从头开始创建自己的损失、度量或优化器,因为您需要的东西很可能已经是 Keras API 的一部分**:
**优化器:**
* `SGD()` (with or without momentum)
* `RMSprop()`
* `Adam()`
* etc.
**损失:**
* `MeanSquaredError()`
* `KLDivergence()`
* `CosineSimilarity()`
* etc.
**度量:**
* `AUC()`
* `Precision()`
* `Recall()`
* etc.
### **定制损失**
如果需要创建自定义损失,Keras 提供了三种方法。
**第一种方法是创建一个接受输入 y\_true 和 y\_pred 的函数。下面的示例显示了一个计算真实数据与预测之间均方误差的损失函数**:
def custom_mean_squared_error(y_true, y_pred):
return ops.mean(ops.square(y_true - y_pred), axis=-1)
model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=custom_mean_squared_error)
We need to one-hot encode the labels to use MSE
y_train_one_hot = ops.one_hot(y_train, num_classes=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
**结果如下**:
![](https://img-blog.csdnimg.cn/direct/efeca36b9cdb43e287882a89e9b7d0db.png)
**如果需要一个除了 y\_true 和 y\_pred 之外还能接收其他参数的损失函数,可以子类化 keras.losses.Loss 类并实现以下两个方法:**
>
> \_\_init\_\_(self):**在调用损失函数时接受要传递的参数**
> call(self,y\_true,y\_pred):**使用目标(y\_true)和模型预测(y\_pred)计算模型的损失**
>
>
>
比方说,您想使用均方误差,但要加上一个项,以抑制预测值偏离 0.5(我们假设分类目标是单击编码的,取值在 0 和 1 之间)。
**这将激励模型不要过于自信,从而有助于减少过度拟合(不试试怎么知道行不行!)。**
**具体做法如下:**
class CustomMSE(keras.losses.Loss):
def init(self, regularization_factor=0.1, name=“custom_mse”):
super().init(name=name)
self.regularization_factor = regularization_factor
def call(self, y_true, y_pred):
mse = ops.mean(ops.square(y_true - y_pred), axis=-1)
reg = ops.mean(ops.square(0.5 - y_pred), axis=-1)
return mse + reg * self.regularization_factor
model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=CustomMSE())
y_train_one_hot = ops.one_hot(y_train, num_classes=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
**结果如下:**
![](https://img-blog.csdnimg.cn/direct/d1c6b96e4188455283f89ee8ca1ddaa7.png)
### 自定义指标
如果您需要的度量指标不是 API 的一部分,您可以通过子类化 keras.metrics.Metric 类轻松创建自定义度量指标。您需要实现 4 个方法:
>
> \_\_init\_\_(self),您将在其中为度量创建状态变量。
> update\_state(self,y\_true,y\_pred,sample\_weight=None),使用目标 y\_true 和模型预测 y\_pred 更新状态变量。
> result(self),使用状态变量计算最终结果。
> reset\_state(self),用于重新初始化度量器的状态。
>
>
>
状态更新和结果计算是分开的(分别在 update\_state() 和 result() 中),因为在某些情况下,结果计算可能非常昂贵,而且只能定期进行。
**下面是一个简单的示例,展示了如何实现 CategoricalTruePositives 指标,该指标用于计算有多少样本被正确分类为属于给定类别:**
class CategoricalTruePositives(keras.metrics.Metric):
def init(self, name=“categorical_true_positives”, **kwargs):
super().init(name=name, **kwargs)
self.true_positives = self.add_variable(
shape=(), name=“ctp”, initializer=“zeros”
)
def update_state(self, y_true, y_pred, sample_weight=None):
y_pred = ops.reshape(ops.argmax(y_pred, axis=1), (-1, 1))
values = ops.cast(y_true, "int32") == ops.cast(y_pred, "int32")
values = ops.cast(values, "float32")
if sample_weight is not None:
sample_weight = ops.cast(sample_weight, "float32")
values = ops.multiply(values, sample_weight)
self.true_positives.assign_add(ops.sum(values))
def result(self):
return self.true_positives.value
def reset_state(self):
# The state of the metric will be reset at the start of each epoch.
self.true_positives.assign(0.0)
model = get_uncompiled_model()
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
结果如下:
![](https://img-blog.csdnimg.cn/direct/7624f65759fa4ad6a79a1fac3466449b.png)
## 处理不符合标准特征的损失和指标
绝大多数损失和度量指标都可以通过 y\_true 和 y\_pred 计算得出,其中 y\_pred 是模型的输出,但并非所有损失和度量指标都可以通过 y\_true 和 y\_pred 计算得出。例如,正则化损失可能只需要激活一层(在这种情况下没有目标),而这种激活可能不是模型的输出。
在这种情况下,可以在自定义层的调用方法中调用 self.add\_loss(loss\_value)。以这种方式添加的损失会被添加到训练过程中的 "主 "损失(传递给 compile() 的损失)中。
**下面是一个添加活动正则化的简单示例(请注意,所有 Keras 层都内置了活动正则化,本层只是为了提供一个具体示例):**
class ActivityRegularizationLayer(layers.Layer):
def call(self, inputs):
self.add_loss(ops.sum(inputs) * 0.1)
return inputs # Pass-through layer.
inputs = keras.Input(shape=(784,), name=“digits”)
x = layers.Dense(64, activation=“relu”, name=“dense_1”)(inputs)
Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)
x = layers.Dense(64, activation=“relu”, name=“dense_2”)(x)
outputs = layers.Dense(10, name=“predictions”)(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
The displayed loss will be much higher than before
due to the regularization component.
model.fit(x_train, y_train, batch_size=64, epochs=1)
结果如下:
![](https://img-blog.csdnimg.cn/direct/6e688dd01c994edc9fd1bb7271dfe489.png)
请注意,当通过 add\_loss() 传递损失时,调用 compile() 时就可以不使用损失函数了,因为模型已经有了要最小化的损失。
请看下面的 LogisticEndpoint 层:**它将 targets 和 logits 作为输入,并通过 add\_loss() 跟踪交叉熵损失。**
class LogisticEndpoint(keras.layers.Layer):
def init(self, name=None):
super().init(name=name)
self.loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
def call(self, targets, logits, sample_weights=None):
# Compute the training-time loss value and add it
# to the layer using `self.add_loss()`.
loss = self.loss_fn(targets, logits, sample_weights)
self.add_loss(loss)
# Return the inference-time prediction tensor (for `.predict()`).
return ops.softmax(logits)
**您可以在有两个输入(输入数据和目标)的模型中使用它,编译时不需要损失参数,就像这样**:
inputs = keras.Input(shape=(3,), name=“inputs”)
targets = keras.Input(shape=(10,), name=“targets”)
logits = keras.layers.Dense(10)(inputs)
predictions = LogisticEndpoint(name=“predictions”)(targets, logits)
model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer=“adam”) # No loss argument!
data = {
“inputs”: np.random.random((3, 3)),
“targets”: np.random.random((3, 10)),
}
model.fit(data)
**演绎结果如下**:
![](https://img-blog.csdnimg.cn/direct/416bd11820d743bc8c3ae0cdf62d2c75.png)
## 自动分隔验证暂留集
在你看到的第一个端到端示例中,我们使用 validation\_data 参数将 NumPy 数组(x\_val、y\_val)的元组传递给模型,以便在每个历时结束时评估验证损失和验证指标。
这里还有一个选项:参数 validation\_split 可以自动保留部分训练数据用于验证。
>
> 例如,validation\_split=0.2 表示 "使用 20% 的数据进行验证",validation\_split=0.6 表示 "使用 60% 的数据进行验证"。
>
>
>
计算验证的方法是,在任何洗牌之前,从 fit() 调用收到的数组中提取最后 x% 的样本。
请注意,只有在使用 NumPy 数据训练时才能使用 validation\_split。
model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
演绎结果如下:
![](https://img-blog.csdnimg.cn/direct/aaa77ea8b6034b0ebb6a91d1f5592103.png)
## 使用 tf.data 数据集进行培训和评估
在过去的几段中,我们已经了解了如何处理损失、度量值和优化器,还了解了当数据以 NumPy 数组形式传递时,如何在 fit() 中使用 validation\_data 和 validation\_split 参数。
另一种方法是使用类似迭代器的东西,比如 tf.data.Dataset、PyTorch DataLoader 或 Keras PyDataset。
**tf.data API 是 TensorFlow 2.0 中的一组实用工具,用于以快速、可扩展的方式加载和预处理数据。**
无论您使用的后端是 JAX、PyTorch 还是 TensorFlow,您都可以使用 tf.data 训练您的 Keras 模型。
**您可以将 Dataset 实例直接传递给 fit()、evaluate() 和 predict() 方法**:
model = get_compiled_model()
First, let’s create a training Dataset instance.
For the sake of our example, we’ll use the same MNIST data as before.
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
Now we get a test dataset.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)
Since the dataset already takes care of batching,
we don’t pass a batch_size
argument.
model.fit(train_dataset, epochs=3)
You can also evaluate or predict on a dataset.
print(“Evaluate”)
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
**演绎结果如下**:
![](https://img-blog.csdnimg.cn/direct/04f9249cc7e74c25b5877e41e4b11d49.png)
**请注意,数据集会在每个轮次结束时重置,因此可以在下一个轮次重复使用。**
如果只想在该数据集的特定批次上运行训练,可以传递 steps\_per\_epoch 参数,指定在进入下一个 epoch 之前,模型应使用该数据集运行多少训练步骤。
model = get_compiled_model()
Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
Only use the 100 batches per epoch (that’s 64 * 100 samples)
model.fit(train_dataset, epochs=3, steps_per_epoch=100)
**结果如下**:
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/aaa85b2f7048b5447f119d0128a807dc.png)
![img](https://img-blog.csdnimg.cn/img_convert/7abc188205c6760c2b711682282a76b4.png)
![img](https://img-blog.csdnimg.cn/img_convert/c44a1e516f99e1b761aaafd9ae757c30.png)
![img](https://img-blog.csdnimg.cn/img_convert/d7554249b8b624165e279c02bf411853.png)
![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**
989383)]
[外链图片转存中...(img-n18Z5AuV-1713789989384)]
[外链图片转存中...(img-4KUsfI3q-1713789989384)]
[外链图片转存中...(img-5P7Iq2c1-1713789989385)]
![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**
![](https://img-blog.csdnimg.cn/img_convert/d7e9c8328c00715b0643043a515c7683.jpeg)