├── 08_Accelerators ├── 08_03_TPU.ipynb ├── 08_02_GPU.ipynb └── 08_01_Distributed_training.ipynb ├── 05_Customization ├── 05_01_Create_an_op.ipynb └── 05_02_Extension_types.ipynb ├── 03_Build_with_Core ├── 03_05_Custom_optimizers.ipynb ├── 03_03_Multilayer_perceptrons.ipynb ├── 03_04_Matrix_approximation.ipynb ├── 03_06_DTensor_with_core_APIS.ipynb └── 03_00_Introduce.ipynb ├── 04_TensorFlow_in_depth ├── 04_06_Numpy_API.ipynb ├── 04_02_Advanced_autodiff.ipynb ├── 04_08_DTensor_concepts.ipynb ├── 04_07_Numpy_API_type_promotion.ipynb ├── 04_05_Random_number_generation.ipynb ├── 04_01_Tensor_slicing.ipynb ├── 04_03_Ragged_tensor.ipynb └── 04_09_Thinking_in_tensorflow2.ipynb ├── 10_TensorFlow_Serving ├── 10_02_Installation.ipynb ├── 10_03_Serving_a_tensorFlow_model.ipynb ├── 10_01_Tensorflow_serving_with_docker.ipynb └── 10_04_Advanced_model_server_configration.ipynb ├── .gitattributes ├── 09_Performance ├── 09_02_Profile_tensorflow_performance.ipynb ├── 09_01_Better_performance_with_tffunction.ipynb ├── 09_05_Mixed_precision.ipynb ├── 09_04_Graph_optimization.ipynb └── 09_03_Opimize_GPU_performance.ipynb ├── 06_Data_input_pipelines ├── 06_03_Analyze_pipeline_performance.ipynb └── 06_02_Optimize_pipeline_performance.ipynb ├── .gitignore ├── 02_Keras ├── mini_resnet.png ├── my_first_model.png ├── multi_input_and_output_model.png ├── my_first_model_with_shape_info.png ├── 02_10_Working_with_RNNS.ipynb ├── 02_06_Customizing_Saving.ipynb ├── 02_04_Making_new_layers_and_models_via_subclassing.ipynb ├── 02_12_Writing_your_own_callbacks.ipynb ├── 02_13_Transfer_learning_and_finetuning.ipynb ├── 02_14_MultiGPU_and_distributed_triaining.ipynb ├── 02_05_Serialization_and_saving.ipynb ├── 02_01_The_sequential_model.ipynb ├── 02_11_Understading_masking_and_padding.ipynb ├── 02_07_Working_with_preprocessing_layers.ipynb ├── 02_08_Customizing_what_happens_in_fit.ipynb └── 02_09_Writing_a_training_loop_from_scratch.ipynb ├── 01_TensorFlow_basics ├── __Checkpoint │ ├── keras │ │ ├── checkpoint │ │ ├── my_checkpoint.index │ │ └── my_checkpoint.data-00000-of-00001 │ ├── my_checkpoint.index │ └── my_checkpoint.data-00000-of-00001 ├── __KerasModel │ └── exname_of_file │ │ ├── fingerprint.pb │ │ ├── saved_model.pb │ │ ├── keras_metadata.pb │ │ └── variables │ │ ├── variables.index │ │ └── variables.data-00000-of-00001 ├── __SaveModel │ └── the_saved_model │ │ ├── fingerprint.pb │ │ ├── saved_model.pb │ │ └── variables │ │ ├── variables.index │ │ └── variables.data-00000-of-00001 ├── 01_04_Graph_ands_functions.ipynb ├── 01_02_Variables.ipynb └── 01_05_Modules_layers_and_models.ipynb ├── 07_Import_and_export ├── res │ ├── grace_hopper.jpg │ └── ImageNetLabels.txt ├── multi_input_and_output_model.png └── 07_01_Checkpoint.ipynb ├── README.md └── LICENSE /08_Accelerators/08_03_TPU.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /05_Customization/05_01_Create_an_op.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Build_with_Core/03_05_Custom_optimizers.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_06_Numpy_API.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /05_Customization/05_02_Extension_types.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_TensorFlow_Serving/10_02_Installation.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Build_with_Core/03_03_Multilayer_perceptrons.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Build_with_Core/03_04_Matrix_approximation.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Build_with_Core/03_06_DTensor_with_core_APIS.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_02_Advanced_autodiff.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_08_DTensor_concepts.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | . filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /09_Performance/09_02_Profile_tensorflow_performance.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_07_Numpy_API_type_promotion.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /09_Performance/09_01_Better_performance_with_tffunction.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_TensorFlow_Serving/10_03_Serving_a_tensorFlow_model.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /06_Data_input_pipelines/06_03_Analyze_pipeline_performance.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_TensorFlow_Serving/10_01_Tensorflow_serving_with_docker.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_TensorFlow_Serving/10_04_Advanced_model_server_configration.ipynb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | REFER.MD 2 | **/__SavedModel/ 3 | **/__Checkpoint/ 4 | **/__KerasModel/ 5 | **/__TFRecord/ 6 | **/__MobileNet/ -------------------------------------------------------------------------------- /02_Keras/mini_resnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/02_Keras/mini_resnet.png -------------------------------------------------------------------------------- /02_Keras/my_first_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/02_Keras/my_first_model.png -------------------------------------------------------------------------------- /01_TensorFlow_basics/__Checkpoint/keras/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "my_checkpoint" 2 | all_model_checkpoint_paths: "my_checkpoint" 3 | -------------------------------------------------------------------------------- /02_Keras/multi_input_and_output_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/02_Keras/multi_input_and_output_model.png -------------------------------------------------------------------------------- /07_Import_and_export/res/grace_hopper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/07_Import_and_export/res/grace_hopper.jpg -------------------------------------------------------------------------------- /02_Keras/my_first_model_with_shape_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/02_Keras/my_first_model_with_shape_info.png -------------------------------------------------------------------------------- /01_TensorFlow_basics/__Checkpoint/my_checkpoint.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__Checkpoint/my_checkpoint.index -------------------------------------------------------------------------------- /07_Import_and_export/multi_input_and_output_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/07_Import_and_export/multi_input_and_output_model.png -------------------------------------------------------------------------------- /01_TensorFlow_basics/__Checkpoint/keras/my_checkpoint.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__Checkpoint/keras/my_checkpoint.index -------------------------------------------------------------------------------- /01_TensorFlow_basics/__KerasModel/exname_of_file/fingerprint.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__KerasModel/exname_of_file/fingerprint.pb -------------------------------------------------------------------------------- /01_TensorFlow_basics/__KerasModel/exname_of_file/saved_model.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__KerasModel/exname_of_file/saved_model.pb -------------------------------------------------------------------------------- /01_TensorFlow_basics/__SaveModel/the_saved_model/fingerprint.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__SaveModel/the_saved_model/fingerprint.pb -------------------------------------------------------------------------------- /01_TensorFlow_basics/__SaveModel/the_saved_model/saved_model.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__SaveModel/the_saved_model/saved_model.pb -------------------------------------------------------------------------------- /01_TensorFlow_basics/__KerasModel/exname_of_file/keras_metadata.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__KerasModel/exname_of_file/keras_metadata.pb -------------------------------------------------------------------------------- /01_TensorFlow_basics/__Checkpoint/my_checkpoint.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__Checkpoint/my_checkpoint.data-00000-of-00001 -------------------------------------------------------------------------------- /01_TensorFlow_basics/__Checkpoint/keras/my_checkpoint.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__Checkpoint/keras/my_checkpoint.data-00000-of-00001 -------------------------------------------------------------------------------- /01_TensorFlow_basics/__KerasModel/exname_of_file/variables/variables.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__KerasModel/exname_of_file/variables/variables.index -------------------------------------------------------------------------------- /01_TensorFlow_basics/__SaveModel/the_saved_model/variables/variables.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__SaveModel/the_saved_model/variables/variables.index -------------------------------------------------------------------------------- /01_TensorFlow_basics/__KerasModel/exname_of_file/variables/variables.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__KerasModel/exname_of_file/variables/variables.data-00000-of-00001 -------------------------------------------------------------------------------- /01_TensorFlow_basics/__SaveModel/the_saved_model/variables/variables.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidglue/Deep_Learning_TensorFlow2_Examples/HEAD/01_TensorFlow_basics/__SaveModel/the_saved_model/variables/variables.data-00000-of-00001 -------------------------------------------------------------------------------- /02_Keras/02_10_Working_with_RNNS.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /02_Keras/02_06_Customizing_Saving.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#" 10 | ] 11 | } 12 | ], 13 | "metadata": { 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "nbformat": 4, 19 | "nbformat_minor": 2 20 | } 21 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_05_Random_number_generation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /02_Keras/02_04_Making_new_layers_and_models_via_subclassing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /08_Accelerators/08_02_GPU.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /09_Performance/09_05_Mixed_precision.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /02_Keras/02_12_Writing_your_own_callbacks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /09_Performance/09_04_Graph_optimization.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_01_Tensor_slicing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_03_Ragged_tensor.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /08_Accelerators/08_01_Distributed_training.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /09_Performance/09_03_Opimize_GPU_performance.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /02_Keras/02_13_Transfer_learning_and_finetuning.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /02_Keras/02_14_MultiGPU_and_distributed_triaining.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /04_TensorFlow_in_depth/04_09_Thinking_in_tensorflow2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /06_Data_input_pipelines/06_02_Optimize_pipeline_performance.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#Advanced\n", 10 | "#TODO " 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "nbformat": 4, 20 | "nbformat_minor": 2 21 | } 22 | -------------------------------------------------------------------------------- /01_TensorFlow_basics/01_04_Graph_ands_functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "### 1.4 计算图和 tf.function 简介" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "### 总结\n", 19 | "\n", 20 | "#1.tf.function 是 TensorFlow 2.x 中引入的一个装饰器,用于将 Python 函数转换为 TensorFlow 图函数(Graph Function)。\n", 21 | "#这样做的好处是可以提高函数的执行效率,并允许 TensorFlow 使用自动微分(Automatic Differentiation)来计算梯度。\n", 22 | "\n", 23 | "#2.当你将一个函数用 tf.function 装饰时,TensorFlow 会在第一次调用该函数时将其转换为一个计算图,并在后续调用中重复使用这个计算图,\n", 24 | "#而不是每次都重新构建计算图。这可以显著减少 CPU 和 GPU 的计算开销,尤其是在执行大量迭代或需要重复调用同一个函数的场景中。\n", 25 | "\n", 26 | "#3.需要注意的是,虽然 tf.function 提供了很多便利,但它并不总是必需的。对于简单的函数或一次性任务,直接使用 TensorFlow 的原生 Python API \n", 27 | "#可能更加直观和简单。然而,对于需要高性能和可重复执行的任务,使用 tf.function 可以显著提高效率和可靠性。" 28 | ] 29 | } 30 | ], 31 | "metadata": { 32 | "language_info": { 33 | "name": "python" 34 | } 35 | }, 36 | "nbformat": 4, 37 | "nbformat_minor": 2 38 | } 39 | -------------------------------------------------------------------------------- /02_Keras/02_05_Serialization_and_saving.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from tensorflow import keras\n", 10 | "\n", 11 | "\n", 12 | "\n", 13 | "##Keras 模型由多个组件组成:\n", 14 | "\n", 15 | "#架构或配置,指定模型包含的层及其连接方式。\n", 16 | "# 优化器(通过编译模型来定义)。\n", 17 | "# 一组损失和指标(通过编译模型或调用 add_loss() 或 add_metric() 定义)。\n", 18 | "# 您可以通过 Keras API 将这些片段一次性保存到磁盘,或仅选择性地保存其中一些片段:\n", 19 | "\n", 20 | "#将所有内容以 TensorFlow SavedModel 格式(或较早的 Keras H5 格式)保存到单个存档。这是标准做法。\n", 21 | "# 仅保存架构/配置,通常保存为 JSON 文件。\n", 22 | "# 仅保存权重值。通常在训练模型时使用。\n", 23 | "# 我们来看看每个选项。什么时候使用哪个选项?它们是如何工作的?\n" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "### 2.5.1 如何保存和加载模型\n", 33 | "\n", 34 | "## 保存 Keras 模型\n", 35 | "model = ... # Get model (Sequential, Functional Model, or Model subclass)\n", 36 | "model.save('path/to/location')\n" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "##重新加载模型:\n", 46 | "model = keras.models.load_model('path/to/location')" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "### 更多功能\n", 56 | "#全模型保存和加载、保存架构、只需使用模型进行推断\n", 57 | "# (在这种情况下,您无需重新开始训练,因此不需要编译信息或优化器状态)等更多功能,\n", 58 | "#参考:https://tensorflow.google.cn/guide/keras/save_and_serialize?hl=zh-cn#%E7%AE%80%E4%BB%8B\n", 59 | "# 或参考1.5节。" 60 | ] 61 | } 62 | ], 63 | "metadata": { 64 | "kernelspec": { 65 | "display_name": "Python 3", 66 | "language": "python", 67 | "name": "python3" 68 | }, 69 | "language_info": { 70 | "codemirror_mode": { 71 | "name": "ipython", 72 | "version": 3 73 | }, 74 | "file_extension": ".py", 75 | "mimetype": "text/x-python", 76 | "name": "python", 77 | "nbconvert_exporter": "python", 78 | "pygments_lexer": "ipython3", 79 | "version": "3.11.8" 80 | } 81 | }, 82 | "nbformat": 4, 83 | "nbformat_minor": 2 84 | } 85 | -------------------------------------------------------------------------------- /03_Build_with_Core/03_00_Introduce.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "\n", 10 | "\n", 11 | "#TensorFlow Core API 提供了一组全面的、可组合的和 可扩展的低级 API,实现高性能(分布式和加速) 计算,\n", 12 | "#主要用于构建机器学习 (ML) 模型以及 在 TensorFlow 平台中创作 ML 工作流工具和框架。这些 API 为创建高度可配置的模型奠定了基础 从头开始的细粒度控制和新框架。\n", 13 | "\n", 14 | "#核心 API 可用作高级机器学习 API 的替代方法 就像Keras一样。这些高级 API 最适合常规机器学习 需要。\n", 15 | "#它们提供了各种模块,可以抽象出 ML 的复杂性 同时还提供通过子类进行自定义的功能。\n", 16 | "\n", 17 | "\n", 18 | "\n" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "### 1 谁应该使用核心 API\n", 28 | "\n", 29 | "#TensorFlow Core 低级 API 由以下 ML 开发人员设计 在考虑:\n", 30 | "# 研究人员构建具有高度可配置性的复杂模型\n", 31 | "# 有兴趣将 TensorFlow 用作高性能科学的开发人员 计算平台\n", 32 | "# 框架作者在 TensorFlow 平台之上构建工具\n", 33 | "# 对以下内容感兴趣的高级 API 用户:\n", 34 | "# 向机器学习工作流添加其他功能 例如自定义层、损失、模型和优化器\n", 35 | "# 详细了解其模型的内部工作原理" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "### 2 核心 API 应用\n", 45 | "\n", 46 | "## 1)构建模型和工作流\n", 47 | "#核心 API 最常用于构建高度可定制和优化的 机器学习模型和工作流。以下是一些方式 TensorFlow Core API 可以改进您的机器学习模型和工作流程 发展:\n", 48 | "# 构建不完全适合 高级 API 支持的结构\n", 49 | "# 在 Keras 中构建自定义层、损失、模型和优化器\n", 50 | "# 实施新的优化技术以加快收敛 训练\n", 51 | "# 创建用于评估的自定义指标\n", 52 | "# 设计高度可配置的训练循环,支持以下功能 批处理、交叉验证和分发策略\n" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "## 2)构建框架和工具\n", 62 | "#TensorFlow Core API 还可以作为新 高级框架。以下是一些工具和框架的示例: 使用低级 API 创建:\n", 63 | "# Keras:人类的深度学习\n", 64 | "# TensorFlow 模型优化工具包: 一套工具,用于优化 ML 模型以进行部署和执行\n", 65 | "# TensorFlow Graphics:一个用于 使有用的图形功能广泛可访问" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "## 3)专为科学计算而构建\n", 75 | "#TensorFlow Core API 也可以在机器领域之外应用 学习。以下是 TensorFlow 的一些通用用例,用于科学 计算机科学:\n", 76 | "# 固体力学和流体动力学问题的物理模拟\n", 77 | "# 图形渲染应用程序,如光线追踪\n", 78 | "# 求解约束优化问题" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "## 4)核心 API 组件\n", 88 | "#以下是构成 TensorFlow Core 低 级别 API。请注意,这不是一个包罗万象的列表:\n", 89 | "# Data structures : tf.Tensor, tf.Variable, tf.TensorArray\n", 90 | "# Primitive APIs: tf.shape, slicing, tf.concat, tf.bitwise\n", 91 | "# Numerical: tf.math, tf.linalg, tf.random\n", 92 | "# Functional components: tf.function, tf.GradientTape\n", 93 | "# Distribution: DTensor\n", 94 | "# Export: tf.saved_model" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "### 总结\n", 104 | "#实际生产中为了兼顾快捷性和灵活性,可以Core API + Keras结合开发,例如构建模型、损失等用CORE API,多输入输出、embedding共享、多目标训练时用keras。" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "language_info": { 110 | "name": "python" 111 | } 112 | }, 113 | "nbformat": 4, 114 | "nbformat_minor": 2 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 深度学习入门指南 2 | 基于TensorFlow2 + Keras讲解深度学习入门指南。 3 | 4 | ## 注意 5 | 如果通过Github站内超链接打开Jupyter Notebook文件发生错误,可以点击根据 https://nbviewer.org 生成的“备用链接”间接访问对应文件。 6 | 或者通过以下链接访问整个项目的站外备用链接,注意点击站外备用链接里的非Jupyter Notebook格式文件会跳转回到Github仓库内: 7 | ● [**Deep_Learning_TensorFlow2_Examples**](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/tree/master/) 8 | 9 | 10 | ## 张量 11 | ● [**张量**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/01_TensorFlow_basics/01_01_Tensors.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/01_TensorFlow_basics/01_01_Tensors.ipynb)] 12 | ● [**变量**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/01_TensorFlow_basics/01_02_Variables.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/01_TensorFlow_basics/01_02_Variables.ipynb)] 13 | ● [**自动微分**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/01_TensorFlow_basics/01_03_Automatic_differentiation.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/01_TensorFlow_basics/01_03_Automatic_differentiation.ipynb)] 14 | ● 图和函数简介 15 | ● [**模块、层和模型简介**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/01_TensorFlow_basics/01_05_Modules_layers_and_models.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/01_TensorFlow_basics/01_05_Modules_layers_and_models.ipynb)] 16 | ● [**训练循环**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/01_TensorFlow_basics/01_06_Training_loops.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/01_TensorFlow_basics/01_06_Training_loops.ipynb)] 17 | ● 高级自动微分 18 | ● 不规则张量 19 | ● [**稀疏张量**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/04_TensorFlow_in_depth/04_04_Sparse_tensor.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/04_TensorFlow_in_depth/04_04_Sparse_tensor.ipynb)] 20 | ● Numpy API 21 | ● Tensor切片 22 | 23 | ## Keras 24 | ● [**Sequential模型**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_01_The_sequential_model.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_01_The_sequential_model.ipynb)] 25 | ● [**Functional API**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_02_The_functional_API.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_02_The_functional_API.ipynb)] 26 | ● [**使用内置方法进行训练和评估**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_03_Training_evaluation_with_the_built_in_methods.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_03_Training_evaluation_with_the_built_in_methods.ipynb)] 27 | ● 通过子类化构建新层和模型 28 | ● [**保存并加载Keras模型**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_05_Serialization_and_saving.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_05_Serialization_and_saving.ipynb)] 29 | ● [**使用预处理层**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_07_Working_with_preprocessing_layers.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_07_Working_with_preprocessing_layers.ipynb)] 30 | ● [**自定义Model.fit的操作流程**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_08_Customizing_what_happens_in_fit.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_08_Customizing_what_happens_in_fit.ipynb)] 31 | ● [**从头开始编写训练循环**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_09_Writing_a_training_loop_from_scratch.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_09_Writing_a_training_loop_from_scratch.ipynb)] 32 | ● 采用Keras的循环神经网络(RNN) 33 | ● [**采用Keras进行遮盖和填充**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/02_Keras/02_11_Understading_masking_and_padding.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/02_Keras/02_11_Understading_masking_and_padding.ipynb)] 34 | ● 自动编写回调 35 | ● 迁移学习和微调 36 | ● 使用TensorFlow Cloud训练Keras模型 37 | 38 | ## TensorFlow Core 39 | ● [**TensorFlow Core API 快速入门**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/03_Build_with_Core/03_01_Quickstart_for_core.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/03_Build_with_Core/03_01_Quickstart_for_core.ipynb)] 40 | ● [**使用 Core API 进行二元分类的逻辑回归**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/03_Build_with_Core/03_02_Logistic_regression.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/03_Build_with_Core/03_02_Logistic_regression.ipynb)] 41 | 42 | ## 自定义 43 | ● 创建操作 44 | ● 生成随机数字 45 | 46 | ## 数据输入流水线 47 | ● [**tf.data**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/06_Data_input_pipelines/06_01_tfdata.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/06_Data_input_pipelines/06_01_tfdata.ipynb)] 48 | ● 优化流水线性能 49 | ● 分析流水线性能 50 | 51 | ## 保存模型 52 | ● [**Checkpoint**](https://github.com/solidglue/TensorFlow2_Keras_Guide_API_Jupyter_Demo/blob/master/07_Import_and_export/07_01_Checkpoint.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/07_Import_and_export/07_01_Checkpoint.ipynb)] 53 | ● [**SavedModel**](https://github.com/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/07_Import_and_export/07_02_SaveModel.ipynb)     [~~*(备用链接)*~~](https://nbviewer.org/github/solidglue/Deep_Learning_TensorFlow2_Examples/blob/master/07_Import_and_export/07_02_SaveModel.ipynb)] 54 | 55 | ## 加速器 56 | ● 分布式训练 57 | ● GPU 58 | ● TPU 59 | 60 | ## 性能 61 | ● 使用tf.function提升性能 62 | ● 分析TensorFlow的性能 63 | ● 优化GPU性能 64 | ● 图优化 65 | ● 混合精度 66 | 67 | ## TensorFlow Serving(服务) 68 | ● TensorFlow Serving和Docker 69 | ● 安装 70 | ● 提供TensorFlow模型 71 | ● 高级模型服务器配置 72 | 73 | 74 | ## *扩展 75 | 76 | 1.**推荐系统** 77 | 王树森推荐系统公开课 - 基于小红书的场景讲解工业界真实的推荐系统。 78 | ● [**Recommender_System**](https://github.com/solidglue/Recommender_System) 79 | 80 | 2.**YouTuBe推荐系统排序模型** 81 | 以"DNN_for_YouTube_Recommendations"模型和电影评分数据集(ml-1m)为基础,详尽的展示了如何基于TensorFlow2实现推荐系统排序模型。 82 | ● [**YouTube深度排序模型(多值embedding、多目标学习)**](https://github.com/solidglue/DNN_for_YouTube_Recommendations) 83 | 84 | 3.**推荐系统推理服务** 85 | 基于Goalng、Docker和微服务思想实现了高并发、高性能和高可用的推荐系统推理微服务,包括多种召回/排序服务,并提供多种接口访问方式(REST、gRPC和Dubbo)等,每日可处理上千万次推理请求。 86 | ● [**推荐系统推理微服务Golang**](https://github.com/solidglue/Recommender_System_Inference_Services) 87 | 88 | 4.**机器学习 Sklearn入门教程** 89 | ● [**机器学习Sklearn入门教程**](https://github.com/solidglue/Machine_Learning_Sklearn_Examples) 90 | -------------------------------------------------------------------------------- /07_Import_and_export/07_01_Checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "\n", 20 | "#“保存 TensorFlow 模型”这一短语通常表示保存以下两种元素之一:\n", 21 | "\n", 22 | "#检查点,或\n", 23 | "#SavedModel。\n", 24 | "#检查点可以捕获模型使用的所有参数(tf.Variable 对象)的确切值。\n", 25 | "#检查点不包含对模型所定义计算的任何描述,因此通常仅在将使用保存参数值的源代码可用时才有用。\n", 26 | "\n", 27 | "#另一方面,除了参数值(检查点)之外,SavedModel 格式还包括对模型所定义计算的序列化描述。\n", 28 | "#这种格式的模型独立于创建模型的源代码。因此,它们适合通过 TensorFlow Serving、TensorFlow Lite、TensorFlow.js \n", 29 | "#或者使用其他编程语言(C、C++、Java、Go、Rust、C# 等 TensorFlow API)编写的程序进行部署。\n", 30 | "\n", 31 | "#本文介绍用于编写和读取检查点的 API。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 5, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "### 7.1.1 从 tf.keras 训练 API 保存\n", 41 | "\n", 42 | "class Net(tf.keras.Model):\n", 43 | " \"\"\"A simple linear model.\"\"\"\n", 44 | "\n", 45 | " def __init__(self):\n", 46 | " super(Net, self).__init__()\n", 47 | " self.l1 = tf.keras.layers.Dense(5)\n", 48 | "\n", 49 | " def call(self, x):\n", 50 | " return self.l1(x)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 6, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "net = Net()\n", 60 | "net.save_weights('__Checkpoint/easy_checkpoint')" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 7, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "### 7.1.2 编写检查点\n", 70 | "#为了帮助演示 tf.train.Checkpoint 的所有功能, 下面定义了一个玩具 (toy) 数据集和优化步骤:\n", 71 | "\n", 72 | "##1.设置\n", 73 | "def toy_dataset():\n", 74 | " inputs = tf.range(10.)[:, None]\n", 75 | " labels = inputs * 5. + tf.range(5.)[None, :]\n", 76 | " return tf.data.Dataset.from_tensor_slices(\n", 77 | " dict(x=inputs, y=labels)).repeat().batch(2)\n", 78 | "\n" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 8, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "def train_step(net, example, optimizer):\n", 88 | " \"\"\"Trains `net` on `example` using `optimizer`.\"\"\"\n", 89 | " with tf.GradientTape() as tape:\n", 90 | " output = net(example['x'])\n", 91 | " loss = tf.reduce_mean(tf.abs(output - example['y']))\n", 92 | " variables = net.trainable_variables\n", 93 | " gradients = tape.gradient(loss, variables)\n", 94 | " optimizer.apply_gradients(zip(gradients, variables))\n", 95 | " return loss" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 9, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "##2.创建检查点对象\n", 105 | "#使用 tf.train.Checkpoint 对象手动创建一个检查点,其中要检查的对象设置为对象的特性。\n", 106 | "#tf.train.CheckpointManager 也有助于管理多个检查点。\n", 107 | "opt = tf.keras.optimizers.Adam(0.1)\n", 108 | "dataset = toy_dataset()\n", 109 | "iterator = iter(dataset)\n", 110 | "ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator)\n", 111 | "manager = tf.train.CheckpointManager(ckpt, '__Checkpoint/tf_ckpts', max_to_keep=3)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 10, 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "##3.训练模型并为模型设置检查点\n", 121 | "#以下训练循环可创建模型和优化器的实例,然后将它们收集到 tf.train.Checkpoint 对象中。\n", 122 | "#它在每批数据上循环调用训练步骤,并定期将检查点写入磁盘。\n", 123 | "\n", 124 | "def train_and_checkpoint(net, manager):\n", 125 | " ckpt.restore(manager.latest_checkpoint)\n", 126 | " if manager.latest_checkpoint:\n", 127 | " print(\"Restored from {}\".format(manager.latest_checkpoint))\n", 128 | " else:\n", 129 | " print(\"Initializing from scratch.\")\n", 130 | "\n", 131 | " for _ in range(50):\n", 132 | " example = next(iterator)\n", 133 | " loss = train_step(net, example, opt)\n", 134 | " ckpt.step.assign_add(1)\n", 135 | " if int(ckpt.step) % 10 == 0:\n", 136 | " save_path = manager.save()\n", 137 | " print(\"Saved checkpoint for step {}: {}\".format(int(ckpt.step), save_path))\n", 138 | " print(\"loss {:1.2f}\".format(loss.numpy()))" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 11, 144 | "metadata": {}, 145 | "outputs": [ 146 | { 147 | "name": "stdout", 148 | "output_type": "stream", 149 | "text": [ 150 | "Initializing from scratch.\n", 151 | "Saved checkpoint for step 10: __Checkpoint/tf_ckpts\\ckpt-1\n", 152 | "loss 27.70\n", 153 | "Saved checkpoint for step 20: __Checkpoint/tf_ckpts\\ckpt-2\n", 154 | "loss 21.12\n", 155 | "Saved checkpoint for step 30: __Checkpoint/tf_ckpts\\ckpt-3\n", 156 | "loss 14.57\n", 157 | "Saved checkpoint for step 40: __Checkpoint/tf_ckpts\\ckpt-4\n", 158 | "loss 8.15\n", 159 | "Saved checkpoint for step 50: __Checkpoint/tf_ckpts\\ckpt-5\n", 160 | "loss 3.02\n" 161 | ] 162 | } 163 | ], 164 | "source": [ 165 | "train_and_checkpoint(net, manager)" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 12, 171 | "metadata": {}, 172 | "outputs": [ 173 | { 174 | "name": "stdout", 175 | "output_type": "stream", 176 | "text": [ 177 | "Restored from __Checkpoint/tf_ckpts\\ckpt-5\n", 178 | "Saved checkpoint for step 60: __Checkpoint/tf_ckpts\\ckpt-6\n", 179 | "loss 0.62\n", 180 | "Saved checkpoint for step 70: __Checkpoint/tf_ckpts\\ckpt-7\n", 181 | "loss 0.50\n", 182 | "Saved checkpoint for step 80: __Checkpoint/tf_ckpts\\ckpt-8\n", 183 | "loss 0.65\n", 184 | "Saved checkpoint for step 90: __Checkpoint/tf_ckpts\\ckpt-9\n", 185 | "loss 0.26\n", 186 | "Saved checkpoint for step 100: __Checkpoint/tf_ckpts\\ckpt-10\n", 187 | "loss 0.19\n" 188 | ] 189 | } 190 | ], 191 | "source": [ 192 | "##4.恢复和继续训练\n", 193 | "#在第一个训练周期结束后,您可以传递一个新的模型和管理器,但在您中断的地方继续训练:\n", 194 | "opt = tf.keras.optimizers.Adam(0.1)\n", 195 | "net = Net()\n", 196 | "dataset = toy_dataset()\n", 197 | "iterator = iter(dataset)\n", 198 | "ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator)\n", 199 | "manager = tf.train.CheckpointManager(ckpt, '__Checkpoint/tf_ckpts', max_to_keep=3)\n", 200 | "\n", 201 | "train_and_checkpoint(net, manager)" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 13, 207 | "metadata": {}, 208 | "outputs": [ 209 | { 210 | "data": { 211 | "text/plain": [ 212 | "['__Checkpoint/tf_ckpts\\\\ckpt-8',\n", 213 | " '__Checkpoint/tf_ckpts\\\\ckpt-9',\n", 214 | " '__Checkpoint/tf_ckpts\\\\ckpt-10']" 215 | ] 216 | }, 217 | "execution_count": 13, 218 | "metadata": {}, 219 | "output_type": "execute_result" 220 | } 221 | ], 222 | "source": [ 223 | "#tf.train.CheckpointManager 对象会删除旧的检查点。上面配置为仅保留最近的三个检查点。\n", 224 | "manager.checkpoints" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": {}, 231 | "outputs": [], 232 | "source": [ 233 | "#这些路径(如 './tf_ckpts/ckpt-10')不是磁盘上的文件,而是一个 index 文件和一个或多个包含变量值的数据文件的前缀。\n", 234 | "#这些前缀被分组到一个单独的 checkpoint 文件 ('./tf_ckpts/checkpoint') 中,其中 CheckpointManager 保存其状态。" 235 | ] 236 | } 237 | ], 238 | "metadata": { 239 | "kernelspec": { 240 | "display_name": "Python 3", 241 | "language": "python", 242 | "name": "python3" 243 | }, 244 | "language_info": { 245 | "codemirror_mode": { 246 | "name": "ipython", 247 | "version": 3 248 | }, 249 | "file_extension": ".py", 250 | "mimetype": "text/x-python", 251 | "name": "python", 252 | "nbconvert_exporter": "python", 253 | "pygments_lexer": "ipython3", 254 | "version": "3.11.8" 255 | } 256 | }, 257 | "nbformat": 4, 258 | "nbformat_minor": 2 259 | } 260 | -------------------------------------------------------------------------------- /02_Keras/02_01_The_sequential_model.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import keras\n", 20 | "from keras import layers\n", 21 | "\n", 22 | "### Sequential模型" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", 35 | "\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | "### 2.1.1 何时使用顺序模型\n", 41 | "#序列模型适用于每个层恰好有一个输入张量和一个输出张量的普通层堆栈。\n", 42 | "\n", 43 | "#示意性地,以下模型:Sequential\n", 44 | "# Define Sequential model with 3 layers\n", 45 | "model = keras.Sequential(\n", 46 | " [\n", 47 | " layers.Dense(2, activation=\"relu\", name=\"layer1\"),\n", 48 | " layers.Dense(3, activation=\"relu\", name=\"layer2\"),\n", 49 | " layers.Dense(4, name=\"layer3\"),\n", 50 | " ]\n", 51 | ")\n", 52 | "# Call model on a test input\n", 53 | "x = tf.ones((3, 3))\n", 54 | "y = model(x)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "#等效于此函数:\n", 64 | "# Create 3 layers\n", 65 | "layer1 = layers.Dense(2, activation=\"relu\", name=\"layer1\")\n", 66 | "layer2 = layers.Dense(3, activation=\"relu\", name=\"layer2\")\n", 67 | "layer3 = layers.Dense(4, name=\"layer3\")\n", 68 | "\n", 69 | "# Call layers on a test input\n", 70 | "x = tf.ones((3, 3))\n", 71 | "y = layer3(layer2(layer1(x)))" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "## 在以下情况下,顺序模型不适用:\n", 81 | "# 您的模型具有多个输入或多个输出\n", 82 | "# 任何图层都具有多个输入或多个输出\n", 83 | "# 您需要进行图层共享\n", 84 | "# 您需要非线性拓扑(例如残差连接、多分支 模型)\n", 85 | "\n" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 5, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "### 2.1.2 创建顺序模型\n", 95 | "#您可以通过将层列表传递给 Sequentiald的构造函数来创建 Sequential模型:\n", 96 | "model = keras.Sequential(\n", 97 | " [\n", 98 | " layers.Dense(2, activation=\"relu\"),\n", 99 | " layers.Dense(3, activation=\"relu\"),\n", 100 | " layers.Dense(4),\n", 101 | " ]\n", 102 | ")" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 6, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "[,\n", 114 | " ,\n", 115 | " ]" 116 | ] 117 | }, 118 | "execution_count": 6, 119 | "metadata": {}, 120 | "output_type": "execute_result" 121 | } 122 | ], 123 | "source": [ 124 | "#其图层可通过以下属性访问:layers\n", 125 | "model.layers" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 8, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "#您还可以通过以下方法以增量方式创建顺序模型:add()\n", 135 | "model = keras.Sequential()\n", 136 | "model.add(layers.Dense(2, activation=\"relu\"))\n", 137 | "model.add(layers.Dense(3, activation=\"relu\"))\n", 138 | "model.add(layers.Dense(4))" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 9, 144 | "metadata": {}, 145 | "outputs": [ 146 | { 147 | "name": "stdout", 148 | "output_type": "stream", 149 | "text": [ 150 | "2\n" 151 | ] 152 | } 153 | ], 154 | "source": [ 155 | "#请注意,还有一种相应的方法可以删除图层: 顺序模型的行为非常类似于层列表。pop()\n", 156 | "model.pop()\n", 157 | "print(len(model.layers)) # 2" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 10, 163 | "metadata": {}, 164 | "outputs": [], 165 | "source": [ 166 | "#另请注意,Sequential 构造函数接受一个参数,就像 Keras 中的任何图层或模型。\n", 167 | "#这对于注释 TensorBoard 图形很有用 具有语义上有意义的名称。name\n", 168 | "\n", 169 | "model = keras.Sequential(name=\"my_sequential\")\n", 170 | "model.add(layers.Dense(2, activation=\"relu\", name=\"layer1\"))\n", 171 | "model.add(layers.Dense(3, activation=\"relu\", name=\"layer2\"))\n", 172 | "model.add(layers.Dense(4, name=\"layer3\"))" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 11, 178 | "metadata": {}, 179 | "outputs": [ 180 | { 181 | "data": { 182 | "text/plain": [ 183 | "[]" 184 | ] 185 | }, 186 | "execution_count": 11, 187 | "metadata": {}, 188 | "output_type": "execute_result" 189 | } 190 | ], 191 | "source": [ 192 | "### 2.1.3 提前指定输入形状\n", 193 | "#通常,Keras中的所有层都需要知道其输入的形状,以便能够创建其权重。\n", 194 | "#因此,当您创建这样的层时,最初它没有权重:\n", 195 | "layer = layers.Dense(3)\n", 196 | "layer.weights # Empty" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 12, 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "data": { 206 | "text/plain": [ 207 | "[,\n", 212 | " ]" 213 | ] 214 | }, 215 | "execution_count": 12, 216 | "metadata": {}, 217 | "output_type": "execute_result" 218 | } 219 | ], 220 | "source": [ 221 | "#它在第一次调用输入时创建其权重,因为形状 权重取决于输入的形状:\n", 222 | "# Call layer on a test input\n", 223 | "x = tf.ones((1, 4))\n", 224 | "y = layer(x)\n", 225 | "layer.weights # Now it has weights, of shape (4, 3) and (3,)" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 13, 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "Number of weights after calling the model: 6\n" 238 | ] 239 | } 240 | ], 241 | "source": [ 242 | "#当然,这也适用于Sequential模型。当您实例化一个没有输入形状的Sequential模型时,\n", 243 | "#它不是“构建”的:它没有权重(调用model.weights会导致一个错误,说明这一点)。\n", 244 | "#权重是在模型第一次看到一些输入数据时创建的:\n", 245 | "model = keras.Sequential(\n", 246 | " [\n", 247 | " layers.Dense(2, activation=\"relu\"),\n", 248 | " layers.Dense(3, activation=\"relu\"),\n", 249 | " layers.Dense(4),\n", 250 | " ]\n", 251 | ") # No weights at this stage!\n", 252 | "\n", 253 | "# At this point, you can't do this:\n", 254 | "# model.weights\n", 255 | "\n", 256 | "# You also can't do this:\n", 257 | "# model.summary()\n", 258 | "\n", 259 | "# Call the model on a test input\n", 260 | "x = tf.ones((1, 4))\n", 261 | "y = model(x)\n", 262 | "print(\"Number of weights after calling the model:\", len(model.weights)) # 6" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 14, 268 | "metadata": {}, 269 | "outputs": [ 270 | { 271 | "name": "stdout", 272 | "output_type": "stream", 273 | "text": [ 274 | "Model: \"sequential_3\"\n", 275 | "_________________________________________________________________\n", 276 | " Layer (type) Output Shape Param # \n", 277 | "=================================================================\n", 278 | " dense_7 (Dense) (1, 2) 10 \n", 279 | " \n", 280 | " dense_8 (Dense) (1, 3) 9 \n", 281 | " \n", 282 | " dense_9 (Dense) (1, 4) 16 \n", 283 | " \n", 284 | "=================================================================\n", 285 | "Total params: 35 (140.00 Byte)\n", 286 | "Trainable params: 35 (140.00 Byte)\n", 287 | "Non-trainable params: 0 (0.00 Byte)\n", 288 | "_________________________________________________________________\n" 289 | ] 290 | } 291 | ], 292 | "source": [ 293 | "#“构建”模型后,可以调用其方法来显示其 内容:summary()\n", 294 | "model.summary()" 295 | ] 296 | } 297 | ], 298 | "metadata": { 299 | "kernelspec": { 300 | "display_name": "Python 3", 301 | "language": "python", 302 | "name": "python3" 303 | }, 304 | "language_info": { 305 | "codemirror_mode": { 306 | "name": "ipython", 307 | "version": 3 308 | }, 309 | "file_extension": ".py", 310 | "mimetype": "text/x-python", 311 | "name": "python", 312 | "nbconvert_exporter": "python", 313 | "pygments_lexer": "ipython3", 314 | "version": "3.11.8" 315 | } 316 | }, 317 | "nbformat": 4, 318 | "nbformat_minor": 2 319 | } 320 | -------------------------------------------------------------------------------- /02_Keras/02_11_Understading_masking_and_padding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import tensorflow as tf\n", 20 | "from tensorflow import keras\n", 21 | "from tensorflow.keras import layers\n", 22 | "\n", 23 | "#INFO:序列特征等长度不一致,需要补全。比不规则张量更灵活。\n", 24 | "\n", 25 | "#遮盖的作用是告知序列处理层输入中有某些时间步骤丢失,因此在处理数据时应将其跳过。\n", 26 | "#填充是遮盖的一种特殊形式,其中被遮盖的步骤位于序列的起点或开头。\n", 27 | "# 填充是出于将序列数据编码成连续批次的需要:为了使批次中的所有序列适合给定的标准长度,有必要填充或截断某些序列。" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "[['Hello', 'world', '!'],\n", 39 | " ['How', 'are', 'you', 'doing', 'today'],\n", 40 | " ['The', 'weather', 'will', 'be', 'nice', 'tomorrow']]" 41 | ] 42 | }, 43 | "execution_count": 2, 44 | "metadata": {}, 45 | "output_type": "execute_result" 46 | } 47 | ], 48 | "source": [ 49 | "### 2.11.1 填充序列数据\n", 50 | "#在处理序列数据时,各个样本常常具有不同长度。请考虑以下示例(文本被切分为单词):\n", 51 | "[\n", 52 | " [\"Hello\", \"world\", \"!\"],\n", 53 | " [\"How\", \"are\", \"you\", \"doing\", \"today\"],\n", 54 | " [\"The\", \"weather\", \"will\", \"be\", \"nice\", \"tomorrow\"],\n", 55 | "]" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 4, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "text/plain": [ 66 | "[[71, 1331, 4231], [73, 8, 3215, 55, 927], [83, 91, 1, 645, 1253, 927]]" 67 | ] 68 | }, 69 | "execution_count": 4, 70 | "metadata": {}, 71 | "output_type": "execute_result" 72 | } 73 | ], 74 | "source": [ 75 | "#进行词汇查询后,数据可能会被向量化为整数,例如:\n", 76 | "[\n", 77 | " [71, 1331, 4231],\n", 78 | " [73, 8, 3215, 55, 927],\n", 79 | " [83, 91, 1, 645, 1253, 927],\n", 80 | "]" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 5, 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/plain": [ 91 | "array([[ 711, 632, 71, 0, 0, 0],\n", 92 | " [ 73, 8, 3215, 55, 927, 0],\n", 93 | " [ 83, 91, 1, 645, 1253, 927]])" 94 | ] 95 | }, 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "#此数据是一个嵌套列表,其中各个样本的长度分别为 3、5 和 6。由于深度学习模型的输入数据必须为单一张量\n", 103 | "# (例如在此例中形状为 (batch_size, 6, vocab_size)),短于最长条目的样本需要用占位符值进行填充\n", 104 | "# (或者,也可以在填充短样本前截断长样本)。\n", 105 | "\n", 106 | "#Keras 提供了一个效用函数来截断和填充 Python 列表,\n", 107 | "# 使其具有相同长度:tf.keras.preprocessing.sequence.pad_sequences。\n", 108 | "raw_inputs = [\n", 109 | " [711, 632, 71],\n", 110 | " [73, 8, 3215, 55, 927],\n", 111 | " [83, 91, 1, 645, 1253, 927],\n", 112 | "]\n", 113 | "\n", 114 | "# By default, this will pad using 0s; it is configurable via the\n", 115 | "# \"value\" parameter.\n", 116 | "# Note that you could \"pre\" padding (at the beginning) or\n", 117 | "# \"post\" padding (at the end).\n", 118 | "# We recommend using \"post\" padding when working with RNN layers\n", 119 | "# (in order to be able to use the\n", 120 | "# CuDNN implementation of the layers).\n", 121 | "padded_inputs = tf.keras.preprocessing.sequence.pad_sequences(\n", 122 | " raw_inputs, padding=\"post\"\n", 123 | ")\n", 124 | "padded_inputs\n" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [ 133 | "### 2.11.2 遮盖\n", 134 | "#既然所有样本现在都具有了统一长度,那就必须告知模型,数据的某些部分实际上是填充,应该忽略。这种机制就是遮盖。\n", 135 | "\n", 136 | "#在 Keras 模型中引入输入掩码有三种方式:\n", 137 | "# 添加一个 keras.layers.Masking 层。\n", 138 | "# 使用 mask_zero=True 配置一个 keras.layers.Embedding 层。\n", 139 | "# 在调用支持 mask 参数的层(如 RNN 层)时,手动传递此参数。\n" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 6, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "name": "stdout", 149 | "output_type": "stream", 150 | "text": [ 151 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", 152 | "\n" 153 | ] 154 | }, 155 | { 156 | "data": { 157 | "text/plain": [ 158 | "" 162 | ] 163 | }, 164 | "execution_count": 6, 165 | "metadata": {}, 166 | "output_type": "execute_result" 167 | } 168 | ], 169 | "source": [ 170 | "### 2.11.3 掩码生成层:Embedding 和 Masking\n", 171 | "#这些层将在后台创建一个掩码张量(形状为 (batch, sequence_length) 的二维张量),\n", 172 | "# 并将其附加到由 Masking 或 Embedding 层返回的张量输出上。\n", 173 | "\n", 174 | "embedding = layers.Embedding(input_dim=5000, output_dim=16, mask_zero=True)\n", 175 | "masked_output = embedding(padded_inputs)\n", 176 | "masked_output._keras_mask\n", 177 | "\n" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 16, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/plain": [ 188 | "TensorShape([3, 6, 16])" 189 | ] 190 | }, 191 | "execution_count": 16, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "masked_output.shape" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 12, 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/plain": [ 208 | "" 212 | ] 213 | }, 214 | "execution_count": 12, 215 | "metadata": {}, 216 | "output_type": "execute_result" 217 | } 218 | ], 219 | "source": [ 220 | "masking_layer = layers.Masking()\n", 221 | "# Simulate the embedding lookup by expanding the 2D input to 3D,\n", 222 | "# with embedding dimension of 10.\n", 223 | "unmasked_embedding = tf.cast(\n", 224 | " tf.tile(tf.expand_dims(padded_inputs, axis=-1), [1, 1, 10]), tf.float32\n", 225 | ")\n", 226 | "masked_embedding = masking_layer(unmasked_embedding)\n", 227 | "masked_embedding._keras_mask #您可以在输出结果中看到,该掩码是一个形状为 (batch_size, sequence_length) 的二维布尔张量,\n", 228 | " # 其中每个 False 条目表示对应的时间步骤应在处理时忽略。" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 14, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "data": { 238 | "text/plain": [ 239 | "TensorShape([3, 6, 10])" 240 | ] 241 | }, 242 | "execution_count": 14, 243 | "metadata": {}, 244 | "output_type": "execute_result" 245 | } 246 | ], 247 | "source": [ 248 | "unmasked_embedding.shape" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 15, 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "data": { 258 | "text/plain": [ 259 | "TensorShape([3, 6, 10])" 260 | ] 261 | }, 262 | "execution_count": 15, 263 | "metadata": {}, 264 | "output_type": "execute_result" 265 | } 266 | ], 267 | "source": [ 268 | "masked_embedding.shape" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 18, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "### 2.11.4 函数式 API 和序列式 API 中的掩码传播\n", 278 | "#在使用函数式 API 或序列式 API 时,由 Embedding 或 Masking 层生成的掩码将通过网络传播给任何能够使用它们的层(如 RNN 层)。\n", 279 | "#Keras 将自动提取与输入相对应的掩码,并将其传递给任何知道该掩码使用方法的层。\n", 280 | "\n", 281 | "#例如,在下面的序贯模型中,LSTM 层将自动接收掩码,这意味着它将忽略填充的值:\n", 282 | "model = keras.Sequential(\n", 283 | " [layers.Embedding(input_dim=5000, output_dim=16, mask_zero=True), layers.LSTM(32),]\n", 284 | ")\n" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 19, 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "#对以下函数式 API 的情况也是如此:\n", 294 | "inputs = keras.Input(shape=(None,), dtype=\"int32\")\n", 295 | "x = layers.Embedding(input_dim=5000, output_dim=16, mask_zero=True)(inputs)\n", 296 | "outputs = layers.LSTM(32)(x)\n", 297 | "\n", 298 | "model = keras.Model(inputs, outputs)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": null, 304 | "metadata": {}, 305 | "outputs": [], 306 | "source": [ 307 | "### 2.11.5 更多功能\n", 308 | "#将掩码张量直接传递给层、在自定义层中支持遮盖、在兼容层上选择启用掩码传播更多功能,\n", 309 | "#可参考:https://tensorflow.google.cn/guide/keras/masking_and_padding?hl=zh-cn#%E5%B0%86%E6%8E%A9%E7%A0%81%E5%BC%A0%E9%87%8F%E7%9B%B4%E6%8E%A5%E4%BC%A0%E9%80%92%E7%BB%99%E5%B1%82" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "### 2.11.6 tf.data的padding\n", 319 | "#dataset.padded_batch \n", 320 | "#可参考6.1.3节" 321 | ] 322 | } 323 | ], 324 | "metadata": { 325 | "kernelspec": { 326 | "display_name": "Python 3", 327 | "language": "python", 328 | "name": "python3" 329 | }, 330 | "language_info": { 331 | "codemirror_mode": { 332 | "name": "ipython", 333 | "version": 3 334 | }, 335 | "file_extension": ".py", 336 | "mimetype": "text/x-python", 337 | "name": "python", 338 | "nbconvert_exporter": "python", 339 | "pygments_lexer": "ipython3", 340 | "version": "3.11.8" 341 | } 342 | }, 343 | "nbformat": 4, 344 | "nbformat_minor": 2 345 | } 346 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /01_TensorFlow_basics/01_02_Variables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "\n", 20 | "# Uncomment to see where your variables get placed (see below)\n", 21 | "# tf.debugging.set_log_device_placement(True)" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 5, 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "data": { 31 | "text/plain": [ 32 | "" 35 | ] 36 | }, 37 | "execution_count": 5, 38 | "metadata": {}, 39 | "output_type": "execute_result" 40 | } 41 | ], 42 | "source": [ 43 | "\n", 44 | "### 1.2 变量\n", 45 | "\n", 46 | "### 1.2.1 创建变量\n", 47 | "#变量通过 tf.Variable 类进行创建和跟踪。tf.Variable 表示张量,对它执行运算可以改变其值。\n", 48 | "#要创建变量,请提供一个初始值。tf.Variable 与初始值的 dtype 相同。\n", 49 | "\n", 50 | "my_tensor = tf.constant([[1,2,3],[4,5,6]])\n", 51 | "my_variable = tf.Variable(my_tensor)\n", 52 | "my_variable" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "" 64 | ] 65 | }, 66 | "execution_count": 3, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "# Variables can be all kinds of types, just like tensors\n", 73 | "bool_variable = tf.Variable([False, False, False, True])\n", 74 | "bool_variable" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "" 86 | ] 87 | }, 88 | "execution_count": 4, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "complex_variable = tf.Variable([5 + 4j, 6 + 1j])\n", 95 | "complex_variable" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 6, 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "name": "stdout", 105 | "output_type": "stream", 106 | "text": [ 107 | "Shape: (2, 3)\n", 108 | "DType: \n", 109 | "As NumPy: [[1 2 3]\n", 110 | " [4 5 6]]\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "##变量与张量的定义方式和操作行为都十分相似,实际上,它们都是 tf.Tensor 支持的一种数据结构。\n", 116 | "#与张量类似,变量也有 dtype 和形状,并且可以导出至 NumPy。\n", 117 | "print(\"Shape: \", my_variable.shape)\n", 118 | "print(\"DType: \", my_variable.dtype)\n", 119 | "print(\"As NumPy: \", my_variable.numpy())" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 7, 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "data": { 129 | "text/plain": [ 130 | "" 133 | ] 134 | }, 135 | "execution_count": 7, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "##大部分张量运算在变量上也可以按预期运行,不过变量无法重构形状。\n", 142 | "tf.convert_to_tensor(my_variable)" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 13, 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "data": { 152 | "text/plain": [ 153 | "" 154 | ] 155 | }, 156 | "execution_count": 13, 157 | "metadata": {}, 158 | "output_type": "execute_result" 159 | } 160 | ], 161 | "source": [ 162 | "tf.math.argmax(my_variable)" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 15, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "" 177 | ] 178 | }, 179 | "execution_count": 15, 180 | "metadata": {}, 181 | "output_type": "execute_result" 182 | } 183 | ], 184 | "source": [ 185 | "tf.reshape(my_variable,[3,2])" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 16, 191 | "metadata": {}, 192 | "outputs": [ 193 | { 194 | "data": { 195 | "text/plain": [ 196 | "" 199 | ] 200 | }, 201 | "execution_count": 16, 202 | "metadata": {}, 203 | "output_type": "execute_result" 204 | } 205 | ], 206 | "source": [ 207 | "my_variable #my_variable本身并没有改变。Copying and reshaping" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 20, 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "data": { 217 | "text/plain": [ 218 | "" 219 | ] 220 | }, 221 | "execution_count": 20, 222 | "metadata": {}, 223 | "output_type": "execute_result" 224 | } 225 | ], 226 | "source": [ 227 | "##可以使用 tf.Variable.assign 重新分配张量。调用 assign(通常)不会分配新张量,而会重用现有张量的内存。\n", 228 | "#用于更新 TensorFlow 变量的值。它将新的值赋给变量或其部分数值。\n", 229 | "a = tf.Variable([2.0, 3.0])\n", 230 | "a.assign([4,5])" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 21, 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "data": { 240 | "text/plain": [ 241 | "" 242 | ] 243 | }, 244 | "execution_count": 21, 245 | "metadata": {}, 246 | "output_type": "execute_result" 247 | } 248 | ], 249 | "source": [ 250 | "a #a的值已经被更新\n" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 22, 256 | "metadata": {}, 257 | "outputs": [ 258 | { 259 | "name": "stdout", 260 | "output_type": "stream", 261 | "text": [ 262 | "[5. 6.]\n", 263 | "[2. 3.]\n", 264 | "[7. 9.]\n", 265 | "[0. 0.]\n" 266 | ] 267 | } 268 | ], 269 | "source": [ 270 | "##如果在运算中像使用张量一样使用变量,那么通常会对支持张量执行运算。\n", 271 | "##从现有变量创建新变量会复制支持张量。两个变量不能共享同一内存空间。\n", 272 | "a = tf.Variable([2.0, 3.0])\n", 273 | "# Create b based on the value of a\n", 274 | "b = tf.Variable(a)\n", 275 | "a.assign([5, 6])\n", 276 | "\n", 277 | "# a and b are different\n", 278 | "print(a.numpy())\n", 279 | "print(b.numpy())\n", 280 | "\n", 281 | "# There are other versions of assign\n", 282 | "print(a.assign_add([2,3]).numpy()) # [7. 9.] #用于将一个给定的增量值加到变量上,并将结果赋给该变量。\n", 283 | "print(a.assign_sub([7,9]).numpy()) # [0. 0.]\n", 284 | "\n" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 27, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "name": "stdout", 294 | "output_type": "stream", 295 | "text": [ 296 | " \n", 299 | "\n", 300 | " \n", 303 | "\n", 304 | " \n", 307 | "\n", 308 | "tf.Tensor(\n", 309 | "[[False False False]\n", 310 | " [False False False]], shape=(2, 3), dtype=bool)\n" 311 | ] 312 | } 313 | ], 314 | "source": [ 315 | "### 1.2.2 生命周期、命名和监视\n", 316 | "## 变量命名\n", 317 | "#tf.Variable 实例与其他 Python 对象的生命周期相同。如果没有对变量的引用,则会自动将其解除分配。\n", 318 | "#为了便于跟踪和调试,您还可以为变量命名。两个变量可以使用相同的名称。\n", 319 | "# Create a and b; they will have the same name but will be backed by\n", 320 | "# different tensors.\n", 321 | "a = tf.Variable(my_tensor, name=\"Mark\")\n", 322 | "# A new variable with the same name, but different value\n", 323 | "# Note that the scalar add is broadcast\n", 324 | "b = tf.Variable(my_tensor + 1, name=\"Mark\")\n", 325 | "\n", 326 | "# These are elementwise-unequal, despite having the same name\n", 327 | "print(my_variable,'\\n')\n", 328 | "print(a,'\\n')\n", 329 | "print(b,'\\n')\n", 330 | "print(a == b)" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 29, 336 | "metadata": {}, 337 | "outputs": [ 338 | { 339 | "data": { 340 | "text/plain": [ 341 | "" 342 | ] 343 | }, 344 | "execution_count": 29, 345 | "metadata": {}, 346 | "output_type": "execute_result" 347 | } 348 | ], 349 | "source": [ 350 | "##变量名唯一性\n", 351 | "#保存和加载模型时会保留变量名。默认情况下,模型中的变量会自动获得唯一变量名,\n", 352 | "#所以除非您希望自行命名,否则不必多此一举。\n", 353 | "\n", 354 | "#虽然变量对微分很重要,但某些变量不需要进行微分。在创建时,通过将 trainable 设置为 False \n", 355 | "#可以关闭梯度。例如,训练计步器就是一个不需要梯度的变量。\n", 356 | "step_counter = tf.Variable(1, trainable=False)\n", 357 | "step_counter" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 32, 363 | "metadata": {}, 364 | "outputs": [ 365 | { 366 | "name": "stdout", 367 | "output_type": "stream", 368 | "text": [ 369 | "tf.Tensor(\n", 370 | "[[22. 28.]\n", 371 | " [49. 64.]], shape=(2, 2), dtype=float32)\n" 372 | ] 373 | } 374 | ], 375 | "source": [ 376 | "### 1.2.3 放置变量和张量\n", 377 | "#为了提高性能,TensorFlow 会尝试将张量和变量放在与其 dtype 兼容的最快设备上。\n", 378 | "#这意味着如果有 GPU,那么大部分变量都会放置在 GPU 上。\n", 379 | "#不过,您可以对此进行重写。在此代码段中,即使存在可用的 GPU,我们也可以在 CPU 上放置一个浮点张量和一个变量。\n", 380 | "with tf.device(\"CPU:0\"):\n", 381 | " # Create some tensors\n", 382 | " a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", 383 | " b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])\n", 384 | " c = tf.matmul(a, b)\n", 385 | " print(c)" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": 33, 391 | "metadata": {}, 392 | "outputs": [ 393 | { 394 | "name": "stdout", 395 | "output_type": "stream", 396 | "text": [ 397 | "tf.Tensor(\n", 398 | "[[ 1. 4. 9.]\n", 399 | " [ 4. 10. 18.]], shape=(2, 3), dtype=float32)\n" 400 | ] 401 | } 402 | ], 403 | "source": [ 404 | "#您可以将变量或张量的位置设置在一个设备上,然后在另一个设备上执行计算。\n", 405 | "#但这样会产生延迟,因为需要在两个设备之间复制数据。\n", 406 | "#不过,如果您有多个 GPU 工作进程,但希望变量只有一个副本,则可以这样做。\n", 407 | "with tf.device('CPU:0'):\n", 408 | " a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", 409 | " b = tf.Variable([[1.0, 2.0, 3.0]])\n", 410 | "\n", 411 | "with tf.device('GPU:0'):\n", 412 | " # Element-wise multiply\n", 413 | " k = a * b\n", 414 | "\n", 415 | "print(k)" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "metadata": {}, 422 | "outputs": [], 423 | "source": [ 424 | "### 总结\n", 425 | "\n", 426 | "#有时候特征空间较大,无法用一张GPU完成参数更新,需要多行卡完成计算,\n", 427 | "#则可以考虑把参数拆分放在不同卡上。例如用户id单独放一张卡做embedding。" 428 | ] 429 | } 430 | ], 431 | "metadata": { 432 | "kernelspec": { 433 | "display_name": "Python 3", 434 | "language": "python", 435 | "name": "python3" 436 | }, 437 | "language_info": { 438 | "codemirror_mode": { 439 | "name": "ipython", 440 | "version": 3 441 | }, 442 | "file_extension": ".py", 443 | "mimetype": "text/x-python", 444 | "name": "python", 445 | "nbconvert_exporter": "python", 446 | "pygments_lexer": "ipython3", 447 | "version": "3.11.8" 448 | } 449 | }, 450 | "nbformat": 4, 451 | "nbformat_minor": 2 452 | } 453 | -------------------------------------------------------------------------------- /07_Import_and_export/res/ImageNetLabels.txt: -------------------------------------------------------------------------------- 1 | background 2 | tench 3 | goldfish 4 | great white shark 5 | tiger shark 6 | hammerhead 7 | electric ray 8 | stingray 9 | cock 10 | hen 11 | ostrich 12 | brambling 13 | goldfinch 14 | house finch 15 | junco 16 | indigo bunting 17 | robin 18 | bulbul 19 | jay 20 | magpie 21 | chickadee 22 | water ouzel 23 | kite 24 | bald eagle 25 | vulture 26 | great grey owl 27 | European fire salamander 28 | common newt 29 | eft 30 | spotted salamander 31 | axolotl 32 | bullfrog 33 | tree frog 34 | tailed frog 35 | loggerhead 36 | leatherback turtle 37 | mud turtle 38 | terrapin 39 | box turtle 40 | banded gecko 41 | common iguana 42 | American chameleon 43 | whiptail 44 | agama 45 | frilled lizard 46 | alligator lizard 47 | Gila monster 48 | green lizard 49 | African chameleon 50 | Komodo dragon 51 | African crocodile 52 | American alligator 53 | triceratops 54 | thunder snake 55 | ringneck snake 56 | hognose snake 57 | green snake 58 | king snake 59 | garter snake 60 | water snake 61 | vine snake 62 | night snake 63 | boa constrictor 64 | rock python 65 | Indian cobra 66 | green mamba 67 | sea snake 68 | horned viper 69 | diamondback 70 | sidewinder 71 | trilobite 72 | harvestman 73 | scorpion 74 | black and gold garden spider 75 | barn spider 76 | garden spider 77 | black widow 78 | tarantula 79 | wolf spider 80 | tick 81 | centipede 82 | black grouse 83 | ptarmigan 84 | ruffed grouse 85 | prairie chicken 86 | peacock 87 | quail 88 | partridge 89 | African grey 90 | macaw 91 | sulphur-crested cockatoo 92 | lorikeet 93 | coucal 94 | bee eater 95 | hornbill 96 | hummingbird 97 | jacamar 98 | toucan 99 | drake 100 | red-breasted merganser 101 | goose 102 | black swan 103 | tusker 104 | echidna 105 | platypus 106 | wallaby 107 | koala 108 | wombat 109 | jellyfish 110 | sea anemone 111 | brain coral 112 | flatworm 113 | nematode 114 | conch 115 | snail 116 | slug 117 | sea slug 118 | chiton 119 | chambered nautilus 120 | Dungeness crab 121 | rock crab 122 | fiddler crab 123 | king crab 124 | American lobster 125 | spiny lobster 126 | crayfish 127 | hermit crab 128 | isopod 129 | white stork 130 | black stork 131 | spoonbill 132 | flamingo 133 | little blue heron 134 | American egret 135 | bittern 136 | crane 137 | limpkin 138 | European gallinule 139 | American coot 140 | bustard 141 | ruddy turnstone 142 | red-backed sandpiper 143 | redshank 144 | dowitcher 145 | oystercatcher 146 | pelican 147 | king penguin 148 | albatross 149 | grey whale 150 | killer whale 151 | dugong 152 | sea lion 153 | Chihuahua 154 | Japanese spaniel 155 | Maltese dog 156 | Pekinese 157 | Shih-Tzu 158 | Blenheim spaniel 159 | papillon 160 | toy terrier 161 | Rhodesian ridgeback 162 | Afghan hound 163 | basset 164 | beagle 165 | bloodhound 166 | bluetick 167 | black-and-tan coonhound 168 | Walker hound 169 | English foxhound 170 | redbone 171 | borzoi 172 | Irish wolfhound 173 | Italian greyhound 174 | whippet 175 | Ibizan hound 176 | Norwegian elkhound 177 | otterhound 178 | Saluki 179 | Scottish deerhound 180 | Weimaraner 181 | Staffordshire bullterrier 182 | American Staffordshire terrier 183 | Bedlington terrier 184 | Border terrier 185 | Kerry blue terrier 186 | Irish terrier 187 | Norfolk terrier 188 | Norwich terrier 189 | Yorkshire terrier 190 | wire-haired fox terrier 191 | Lakeland terrier 192 | Sealyham terrier 193 | Airedale 194 | cairn 195 | Australian terrier 196 | Dandie Dinmont 197 | Boston bull 198 | miniature schnauzer 199 | giant schnauzer 200 | standard schnauzer 201 | Scotch terrier 202 | Tibetan terrier 203 | silky terrier 204 | soft-coated wheaten terrier 205 | West Highland white terrier 206 | Lhasa 207 | flat-coated retriever 208 | curly-coated retriever 209 | golden retriever 210 | Labrador retriever 211 | Chesapeake Bay retriever 212 | German short-haired pointer 213 | vizsla 214 | English setter 215 | Irish setter 216 | Gordon setter 217 | Brittany spaniel 218 | clumber 219 | English springer 220 | Welsh springer spaniel 221 | cocker spaniel 222 | Sussex spaniel 223 | Irish water spaniel 224 | kuvasz 225 | schipperke 226 | groenendael 227 | malinois 228 | briard 229 | kelpie 230 | komondor 231 | Old English sheepdog 232 | Shetland sheepdog 233 | collie 234 | Border collie 235 | Bouvier des Flandres 236 | Rottweiler 237 | German shepherd 238 | Doberman 239 | miniature pinscher 240 | Greater Swiss Mountain dog 241 | Bernese mountain dog 242 | Appenzeller 243 | EntleBucher 244 | boxer 245 | bull mastiff 246 | Tibetan mastiff 247 | French bulldog 248 | Great Dane 249 | Saint Bernard 250 | Eskimo dog 251 | malamute 252 | Siberian husky 253 | dalmatian 254 | affenpinscher 255 | basenji 256 | pug 257 | Leonberg 258 | Newfoundland 259 | Great Pyrenees 260 | Samoyed 261 | Pomeranian 262 | chow 263 | keeshond 264 | Brabancon griffon 265 | Pembroke 266 | Cardigan 267 | toy poodle 268 | miniature poodle 269 | standard poodle 270 | Mexican hairless 271 | timber wolf 272 | white wolf 273 | red wolf 274 | coyote 275 | dingo 276 | dhole 277 | African hunting dog 278 | hyena 279 | red fox 280 | kit fox 281 | Arctic fox 282 | grey fox 283 | tabby 284 | tiger cat 285 | Persian cat 286 | Siamese cat 287 | Egyptian cat 288 | cougar 289 | lynx 290 | leopard 291 | snow leopard 292 | jaguar 293 | lion 294 | tiger 295 | cheetah 296 | brown bear 297 | American black bear 298 | ice bear 299 | sloth bear 300 | mongoose 301 | meerkat 302 | tiger beetle 303 | ladybug 304 | ground beetle 305 | long-horned beetle 306 | leaf beetle 307 | dung beetle 308 | rhinoceros beetle 309 | weevil 310 | fly 311 | bee 312 | ant 313 | grasshopper 314 | cricket 315 | walking stick 316 | cockroach 317 | mantis 318 | cicada 319 | leafhopper 320 | lacewing 321 | dragonfly 322 | damselfly 323 | admiral 324 | ringlet 325 | monarch 326 | cabbage butterfly 327 | sulphur butterfly 328 | lycaenid 329 | starfish 330 | sea urchin 331 | sea cucumber 332 | wood rabbit 333 | hare 334 | Angora 335 | hamster 336 | porcupine 337 | fox squirrel 338 | marmot 339 | beaver 340 | guinea pig 341 | sorrel 342 | zebra 343 | hog 344 | wild boar 345 | warthog 346 | hippopotamus 347 | ox 348 | water buffalo 349 | bison 350 | ram 351 | bighorn 352 | ibex 353 | hartebeest 354 | impala 355 | gazelle 356 | Arabian camel 357 | llama 358 | weasel 359 | mink 360 | polecat 361 | black-footed ferret 362 | otter 363 | skunk 364 | badger 365 | armadillo 366 | three-toed sloth 367 | orangutan 368 | gorilla 369 | chimpanzee 370 | gibbon 371 | siamang 372 | guenon 373 | patas 374 | baboon 375 | macaque 376 | langur 377 | colobus 378 | proboscis monkey 379 | marmoset 380 | capuchin 381 | howler monkey 382 | titi 383 | spider monkey 384 | squirrel monkey 385 | Madagascar cat 386 | indri 387 | Indian elephant 388 | African elephant 389 | lesser panda 390 | giant panda 391 | barracouta 392 | eel 393 | coho 394 | rock beauty 395 | anemone fish 396 | sturgeon 397 | gar 398 | lionfish 399 | puffer 400 | abacus 401 | abaya 402 | academic gown 403 | accordion 404 | acoustic guitar 405 | aircraft carrier 406 | airliner 407 | airship 408 | altar 409 | ambulance 410 | amphibian 411 | analog clock 412 | apiary 413 | apron 414 | ashcan 415 | assault rifle 416 | backpack 417 | bakery 418 | balance beam 419 | balloon 420 | ballpoint 421 | Band Aid 422 | banjo 423 | bannister 424 | barbell 425 | barber chair 426 | barbershop 427 | barn 428 | barometer 429 | barrel 430 | barrow 431 | baseball 432 | basketball 433 | bassinet 434 | bassoon 435 | bathing cap 436 | bath towel 437 | bathtub 438 | beach wagon 439 | beacon 440 | beaker 441 | bearskin 442 | beer bottle 443 | beer glass 444 | bell cote 445 | bib 446 | bicycle-built-for-two 447 | bikini 448 | binder 449 | binoculars 450 | birdhouse 451 | boathouse 452 | bobsled 453 | bolo tie 454 | bonnet 455 | bookcase 456 | bookshop 457 | bottlecap 458 | bow 459 | bow tie 460 | brass 461 | brassiere 462 | breakwater 463 | breastplate 464 | broom 465 | bucket 466 | buckle 467 | bulletproof vest 468 | bullet train 469 | butcher shop 470 | cab 471 | caldron 472 | candle 473 | cannon 474 | canoe 475 | can opener 476 | cardigan 477 | car mirror 478 | carousel 479 | carpenter's kit 480 | carton 481 | car wheel 482 | cash machine 483 | cassette 484 | cassette player 485 | castle 486 | catamaran 487 | CD player 488 | cello 489 | cellular telephone 490 | chain 491 | chainlink fence 492 | chain mail 493 | chain saw 494 | chest 495 | chiffonier 496 | chime 497 | china cabinet 498 | Christmas stocking 499 | church 500 | cinema 501 | cleaver 502 | cliff dwelling 503 | cloak 504 | clog 505 | cocktail shaker 506 | coffee mug 507 | coffeepot 508 | coil 509 | combination lock 510 | computer keyboard 511 | confectionery 512 | container ship 513 | convertible 514 | corkscrew 515 | cornet 516 | cowboy boot 517 | cowboy hat 518 | cradle 519 | crane 520 | crash helmet 521 | crate 522 | crib 523 | Crock Pot 524 | croquet ball 525 | crutch 526 | cuirass 527 | dam 528 | desk 529 | desktop computer 530 | dial telephone 531 | diaper 532 | digital clock 533 | digital watch 534 | dining table 535 | dishrag 536 | dishwasher 537 | disk brake 538 | dock 539 | dogsled 540 | dome 541 | doormat 542 | drilling platform 543 | drum 544 | drumstick 545 | dumbbell 546 | Dutch oven 547 | electric fan 548 | electric guitar 549 | electric locomotive 550 | entertainment center 551 | envelope 552 | espresso maker 553 | face powder 554 | feather boa 555 | file 556 | fireboat 557 | fire engine 558 | fire screen 559 | flagpole 560 | flute 561 | folding chair 562 | football helmet 563 | forklift 564 | fountain 565 | fountain pen 566 | four-poster 567 | freight car 568 | French horn 569 | frying pan 570 | fur coat 571 | garbage truck 572 | gasmask 573 | gas pump 574 | goblet 575 | go-kart 576 | golf ball 577 | golfcart 578 | gondola 579 | gong 580 | gown 581 | grand piano 582 | greenhouse 583 | grille 584 | grocery store 585 | guillotine 586 | hair slide 587 | hair spray 588 | half track 589 | hammer 590 | hamper 591 | hand blower 592 | hand-held computer 593 | handkerchief 594 | hard disc 595 | harmonica 596 | harp 597 | harvester 598 | hatchet 599 | holster 600 | home theater 601 | honeycomb 602 | hook 603 | hoopskirt 604 | horizontal bar 605 | horse cart 606 | hourglass 607 | iPod 608 | iron 609 | jack-o'-lantern 610 | jean 611 | jeep 612 | jersey 613 | jigsaw puzzle 614 | jinrikisha 615 | joystick 616 | kimono 617 | knee pad 618 | knot 619 | lab coat 620 | ladle 621 | lampshade 622 | laptop 623 | lawn mower 624 | lens cap 625 | letter opener 626 | library 627 | lifeboat 628 | lighter 629 | limousine 630 | liner 631 | lipstick 632 | Loafer 633 | lotion 634 | loudspeaker 635 | loupe 636 | lumbermill 637 | magnetic compass 638 | mailbag 639 | mailbox 640 | maillot 641 | maillot 642 | manhole cover 643 | maraca 644 | marimba 645 | mask 646 | matchstick 647 | maypole 648 | maze 649 | measuring cup 650 | medicine chest 651 | megalith 652 | microphone 653 | microwave 654 | military uniform 655 | milk can 656 | minibus 657 | miniskirt 658 | minivan 659 | missile 660 | mitten 661 | mixing bowl 662 | mobile home 663 | Model T 664 | modem 665 | monastery 666 | monitor 667 | moped 668 | mortar 669 | mortarboard 670 | mosque 671 | mosquito net 672 | motor scooter 673 | mountain bike 674 | mountain tent 675 | mouse 676 | mousetrap 677 | moving van 678 | muzzle 679 | nail 680 | neck brace 681 | necklace 682 | nipple 683 | notebook 684 | obelisk 685 | oboe 686 | ocarina 687 | odometer 688 | oil filter 689 | organ 690 | oscilloscope 691 | overskirt 692 | oxcart 693 | oxygen mask 694 | packet 695 | paddle 696 | paddlewheel 697 | padlock 698 | paintbrush 699 | pajama 700 | palace 701 | panpipe 702 | paper towel 703 | parachute 704 | parallel bars 705 | park bench 706 | parking meter 707 | passenger car 708 | patio 709 | pay-phone 710 | pedestal 711 | pencil box 712 | pencil sharpener 713 | perfume 714 | Petri dish 715 | photocopier 716 | pick 717 | pickelhaube 718 | picket fence 719 | pickup 720 | pier 721 | piggy bank 722 | pill bottle 723 | pillow 724 | ping-pong ball 725 | pinwheel 726 | pirate 727 | pitcher 728 | plane 729 | planetarium 730 | plastic bag 731 | plate rack 732 | plow 733 | plunger 734 | Polaroid camera 735 | pole 736 | police van 737 | poncho 738 | pool table 739 | pop bottle 740 | pot 741 | potter's wheel 742 | power drill 743 | prayer rug 744 | printer 745 | prison 746 | projectile 747 | projector 748 | puck 749 | punching bag 750 | purse 751 | quill 752 | quilt 753 | racer 754 | racket 755 | radiator 756 | radio 757 | radio telescope 758 | rain barrel 759 | recreational vehicle 760 | reel 761 | reflex camera 762 | refrigerator 763 | remote control 764 | restaurant 765 | revolver 766 | rifle 767 | rocking chair 768 | rotisserie 769 | rubber eraser 770 | rugby ball 771 | rule 772 | running shoe 773 | safe 774 | safety pin 775 | saltshaker 776 | sandal 777 | sarong 778 | sax 779 | scabbard 780 | scale 781 | school bus 782 | schooner 783 | scoreboard 784 | screen 785 | screw 786 | screwdriver 787 | seat belt 788 | sewing machine 789 | shield 790 | shoe shop 791 | shoji 792 | shopping basket 793 | shopping cart 794 | shovel 795 | shower cap 796 | shower curtain 797 | ski 798 | ski mask 799 | sleeping bag 800 | slide rule 801 | sliding door 802 | slot 803 | snorkel 804 | snowmobile 805 | snowplow 806 | soap dispenser 807 | soccer ball 808 | sock 809 | solar dish 810 | sombrero 811 | soup bowl 812 | space bar 813 | space heater 814 | space shuttle 815 | spatula 816 | speedboat 817 | spider web 818 | spindle 819 | sports car 820 | spotlight 821 | stage 822 | steam locomotive 823 | steel arch bridge 824 | steel drum 825 | stethoscope 826 | stole 827 | stone wall 828 | stopwatch 829 | stove 830 | strainer 831 | streetcar 832 | stretcher 833 | studio couch 834 | stupa 835 | submarine 836 | suit 837 | sundial 838 | sunglass 839 | sunglasses 840 | sunscreen 841 | suspension bridge 842 | swab 843 | sweatshirt 844 | swimming trunks 845 | swing 846 | switch 847 | syringe 848 | table lamp 849 | tank 850 | tape player 851 | teapot 852 | teddy 853 | television 854 | tennis ball 855 | thatch 856 | theater curtain 857 | thimble 858 | thresher 859 | throne 860 | tile roof 861 | toaster 862 | tobacco shop 863 | toilet seat 864 | torch 865 | totem pole 866 | tow truck 867 | toyshop 868 | tractor 869 | trailer truck 870 | tray 871 | trench coat 872 | tricycle 873 | trimaran 874 | tripod 875 | triumphal arch 876 | trolleybus 877 | trombone 878 | tub 879 | turnstile 880 | typewriter keyboard 881 | umbrella 882 | unicycle 883 | upright 884 | vacuum 885 | vase 886 | vault 887 | velvet 888 | vending machine 889 | vestment 890 | viaduct 891 | violin 892 | volleyball 893 | waffle iron 894 | wall clock 895 | wallet 896 | wardrobe 897 | warplane 898 | washbasin 899 | washer 900 | water bottle 901 | water jug 902 | water tower 903 | whiskey jug 904 | whistle 905 | wig 906 | window screen 907 | window shade 908 | Windsor tie 909 | wine bottle 910 | wing 911 | wok 912 | wooden spoon 913 | wool 914 | worm fence 915 | wreck 916 | yawl 917 | yurt 918 | web site 919 | comic book 920 | crossword puzzle 921 | street sign 922 | traffic light 923 | book jacket 924 | menu 925 | plate 926 | guacamole 927 | consomme 928 | hot pot 929 | trifle 930 | ice cream 931 | ice lolly 932 | French loaf 933 | bagel 934 | pretzel 935 | cheeseburger 936 | hotdog 937 | mashed potato 938 | head cabbage 939 | broccoli 940 | cauliflower 941 | zucchini 942 | spaghetti squash 943 | acorn squash 944 | butternut squash 945 | cucumber 946 | artichoke 947 | bell pepper 948 | cardoon 949 | mushroom 950 | Granny Smith 951 | strawberry 952 | orange 953 | lemon 954 | fig 955 | pineapple 956 | banana 957 | jackfruit 958 | custard apple 959 | pomegranate 960 | hay 961 | carbonara 962 | chocolate sauce 963 | dough 964 | meat loaf 965 | pizza 966 | potpie 967 | burrito 968 | red wine 969 | espresso 970 | cup 971 | eggnog 972 | alp 973 | bubble 974 | cliff 975 | coral reef 976 | geyser 977 | lakeside 978 | promontory 979 | sandbar 980 | seashore 981 | valley 982 | volcano 983 | ballplayer 984 | groom 985 | scuba diver 986 | rapeseed 987 | daisy 988 | yellow lady's slipper 989 | corn 990 | acorn 991 | hip 992 | buckeye 993 | coral fungus 994 | agaric 995 | gyromitra 996 | stinkhorn 997 | earthstar 998 | hen-of-the-woods 999 | bolete 1000 | ear 1001 | toilet tissue -------------------------------------------------------------------------------- /02_Keras/02_07_Working_with_preprocessing_layers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 20, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import tensorflow as tf\n", 10 | "from tensorflow import keras\n", 11 | "from tensorflow.keras import layers\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": {}, 19 | "outputs": [ 20 | { 21 | "name": "stdout", 22 | "output_type": "stream", 23 | "text": [ 24 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", 25 | "\n", 26 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\optimizers\\__init__.py:309: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n", 27 | "\n", 28 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\utils\\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.\n", 29 | "\n", 30 | "1563/1563 [==============================] - 6s 3ms/step - loss: 2.1259\n" 31 | ] 32 | }, 33 | { 34 | "data": { 35 | "text/plain": [ 36 | "" 37 | ] 38 | }, 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "output_type": "execute_result" 42 | } 43 | ], 44 | "source": [ 45 | "###2.7.1 标准化数值特征\n", 46 | "# Load some data\n", 47 | "(x_train, y_train), _ = keras.datasets.cifar10.load_data()\n", 48 | "x_train = x_train.reshape((len(x_train), -1))\n", 49 | "input_shape = x_train.shape[1:]\n", 50 | "classes = 10\n", 51 | "\n", 52 | "# Create a Normalization layer and set its internal state using the training data\n", 53 | "normalizer = layers.Normalization()\n", 54 | "normalizer.adapt(x_train)\n", 55 | "\n", 56 | "# Create a model that include the normalization layer\n", 57 | "inputs = keras.Input(shape=input_shape)\n", 58 | "x = normalizer(inputs)\n", 59 | "outputs = layers.Dense(classes, activation=\"softmax\")(x)\n", 60 | "model = keras.Model(inputs, outputs)\n", 61 | "\n", 62 | "# Train the model\n", 63 | "model.compile(optimizer=\"adam\", loss=\"sparse_categorical_crossentropy\")\n", 64 | "model.fit(x_train, y_train)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 7, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "array([ 72, 144, 84, ..., 50, 171, 161], dtype=uint8)" 76 | ] 77 | }, 78 | "execution_count": 7, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "x_train[:,-1]" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 11, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "" 98 | ] 99 | }, 100 | "execution_count": 11, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "normalizer(x_train)[:,-1]" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 12, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD/CAYAAAA+CADKAAAABmJLR0QA/wD/AP+gvaeTAAASuUlEQVR4nO3dX2hb5RsH8O+xrYgKm2NrL1x3IVjtNqmgwjZ0sjlwCCcyXbt1WzsHbqTghcxdprSwXabOC2HaeCEOlrT1qgH/sfaioJ38FCI0nR3epKsXiSDJvHPrnt/FPGcnyWmbtGneNM/3A2HLe07OefKefHPe86ZtLBEREJE6j5gugIjMYPiJlGL4iZRi+ImUajRdgJ/z58/j9u3bpssgqpjLly9j+/btpsvIU5Nn/u+++w6zs7Omy9hQZmdn8cMPP5gugwrcuXMHX3/9NXK5nOlSitTkmR8AOjs7MTg4aLqMDWNwcBCjo6MYGxszXQp5JJNJ7N6923QZvmryzE9E64/hJ1KK4SdSiuEnUorhJ1KK4SdSiuEnUorhJ1KK4SdSiuEnUorhJ1KK4SdSiuEnUorhJ1KK4SdSiuEnUqpuwt/f34/+/n7TZRBtGHUTfpNyuRwsy1r1Y2/cuIFIJIJAIFDhypZmWZbvzYTC/qul2upZzf4Zr3JdvHjR2L6npqZW/dhwOAwAuHTpUqXKKYmIIJfLYfPmzQCAbDaLTZs2VbUGR2H/iQgymQxaWloAmK2tntVN+E3J5XKIRCKrfrzzplXt8APIC5SpcC3Vf83Nze7/Gfz1URfD/kwmg1gs5g6bC+/H43FYloVAIID5+Xl3nXg87q4TiURgWRb6+vpw69YtAPAdcha2hcNhxOPxvGUbWaX6Dqhe/zlvIM7j+/v7kclkMDQ0lLe/oaEh9zHeZd7n5bQHAgFMTk4WPd9cLoe+vr76mF+SGtTe3i4DAwMlr2/btgAQ5+l4709PT4uISCqVEgASDAZFRNzl3nWy2awEg0EBIHNzc5JOp/O2692Ot63w/mqsdRsDAwPS3t6+5v1Wqu9EZM39V2qfOPtNp9NFtU5PT+fd97JtW9LptFurbdsSjUZFRGRiYkIASCKRKOqTRCLhuz0/MzMzAkBmZmZKWr+a6iL8IsUvFL8XTinrJBIJASDhcHhN2ylXrYS/1LZS+m4t21quvVAoFMoLY+HjwuGwAJBUKpVXqxN0EZFoNOpbZygUyttmNptdsR6vWg5/XQz7K6mjowMAcOHCBcOVbDym+u7ixYu4cuUK5ufn84b2jkOHDgEAvv/+e7ft+vXr2Ldvn3v/2rVrAIovSwrnYupp/oHhp7oQiUTwwQcfwLbtomUdHR0IBoM4d+4ccrkccrkc/vjjD+zYscNdx5l3kAej4bxbvWL4lxAMBk2XsGFVq+/6+voAALFYDOfOncOnn36Ktra2ZWv69ttvMTU1hdOnT/uu552wrHcMfwHn4L/11luGK9l4qtl3N27cwOuvvw4A6O7uBoC8M3kh5+zf3d2NSCSCPXv25C0fHh4GAFy9etX9Xj1n9r9e1UX4M5lM3v+9950D6f2iRO9y4MGZw1nn6tWrsG3bHT46ZwznhX3jxg33cc6Zx1l3tS8Wb23V/EJHv/1Wsu+A1fdf4X68bty4gb1796K9vT3v8fPz83ln7sJtOGd7v0uDt99+G8CDa/zNmzfDsiy0tLSgs7Nz2Vo2NKPTjUsod7Yfno+e/G5+63jbvB/nDA8P583oplIpd9n4+LiIiPuRkPMxkTPLHQqF3La11l6ucmf7V+qzSvSdyOr6r9TanH0VPt6Z/ffO7jts23Y/iiyUSqUkFAq5Hw06j/fu07btkvtYpLZn++si/Ku12qDVotV+1LdaG7HvnJ9FqKZaDn9dDPuJSjE6OorOzk7TZdQMteEvnCeg0m2kvuvv78/7Md6DBw+aLqlmqP3FHuc3xpz/SwU/zy3159Mruc9qWs++qzTnE4Dh4WGcPXvWcDW1RW341/MFW8thqISN9PzOnj3L0C9B7bCfSDuGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0ipmv3Z/rGxMSSTSdNlbBizs7P4888/+SurNebOnTumS1iSJTX4Wxrnz5/H7du3TZdR96amptDe3o5t27aZLqXuXb58Gdu3bzddRp6aDD9Vh2VZGBkZQVdXl+lSyABe8xMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpxfATKcXwEynF8BMpZYmImC6C1l8wGMTvv/+e1/bjjz/iueeew9atW922hoYGfPXVV3j66aerXSJVWaPpAqg6mpub8fnnnxe1J5PJvPvPPPMMg68Eh/1KnDhxYsV1mpqa8N57761/MVQTOOxX5IUXXkAymcRyh/zWrVt49tlnq1gVmcIzvyK9vb1oaGjwXWZZFl588UUGXxGGX5Hjx49jcXHRd1lDQwNOnz5d5YrIJA77ldm3bx9+/vln3L9/P6/dsizcvn2bk32K8MyvTE9PDyzLymt75JFH8OqrrzL4yjD8yhw7dqwo/JZlobe311BFZArDr8yWLVvwxhtvoLHx4Y94WJaFd955x2BVZALDr9CpU6fca/7GxkYcPnwYW7ZsMVwVVRvDr9CRI0fw6KOPAgAWFxdx6tQpwxWRCQy/Qk888QRs2wYAPPbYY+7/SReGX6mTJ08CeDAKePzxxw1XQyYw/EodPnwYTz31VEk/80/1qei3+hYWFvDTTz+ZqIWq7LXXXkMul8Po6KjpUmidtba2Yu/evfmNUmBkZEQA8MYbb3V0O3r0aGHUZcnf5+dP/dYvy7IwMjKCrq4u06VQFXR2dvq285qfSCmGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0gphp9IKYafSCmGn0gp1eHPZDKIxWIIBAJuW39/P/r7+9d1v9XYBxXj8c6nOvwDAwPo7u5GPB5ft33kcrmi78bbKCYnJ2FZFizLWvLF6yz33moVj3eBpf6Apxb47w8crpfx8fGa608AMjIyUtK62WxWotGoAJBQKOS7TjqdFgCSTqcrWea60Hi8jx496vsHPFWf+ddbLpdDJBIxXcaabNq0CcePHwcAXLp0CbFYrGid5ubmvH+12mjHe83hL7yOisfjsCwLgUAA8/PzeevmcjnEYjF3eBiJRJDJZPK2FY/HEQgEkMvl0NfXh/7+/iX30dfX5+7D2a63zdlnJBLJG75697nccwH8h7XO81tp++Fw2B1iOsv99lFq35Taz+slHA6ju7vb9w3AD493jR/vwqFAucN+27bdodT09LSIiKRSKQEgwWCwaN3h4WEReTBUtG1bbNuWbDbru61EIiHBYDCvPZFIiIjI9PS0u4/l9hsMBt0hqd9yeIaB3v14l3uHs86wLpVKlb39pfaxmr5Zrp9XgjKG/d7HiIiEQqG841C4fC3Picd7fY73UsP+ilzz+z25wraJiYmijnUOaDQaLXqc0wnl7MOvLRQKLXtwVrrvNTc3JwBkYmJi1dv3ayu3b1bqg5WsJfzZbNZ9Yc7NzRUtd/B4L11jtY+38fA775he2WxWAIht28tuq9R9LPf4VCol4XB41S8G5905HA4XLStn+35ta+mbaodf5OEEn23b7gu4sAYe76VrrPbxNh7+Ug/yerwYhoeHxbZt9518NS+GUCiUd2BWu/21POdaCb+ISCKRcF+szgu3lLp4vKt/vI2H3xkqFn4cBCx/zVTOPvzanI+pnGu21bwYhoeH87bhVe72/drW0jemwi/y8HrYmQfw4vFeusZqH2/j4Xc6zZm8EHk41PFeU1X6xbDW+861mLfGtezPr20tfWMy/CIPay9czuO99GOqfbzXLfzO9R/wcNLGeSLedzdnosh7nRiNRvPe6bzbWmkf3jZne35tzrtsKpXKG6al0+mi9QvvO7Orhdd9znorbd+7PJ1OSzgc9q2x3L5Zrp9LUW74V/ohHr8zP4937RzvdQu/U4z3IPq1OU/IGVIBD2Y2vbO83sf4TXystA+/NufaNBQKSTqddmdrnQO93M37cYvfbaXt+y2vRN+s1M+lHLNSw7/U8y7kd33M410bx3up8Fv/bdQ1OjqKY8eOoaCZ6gi/olsX5yu6x8bG8tr5471ESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REo1LrVgdHS0mnVQlU1PT5sugapkYWEB27dvL15Q+Av+zh/z4I033urnVtIf8yA9+Ec9dOM1P5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSDD+RUgw/kVIMP5FSjaYLoOqIRqP4559/itqvX7+ObDab13bkyBFs27atWqWRIZaIiOkiaP2dOXMGX375JZqamty2+/fvw7IsWJYFAFhcXMSTTz6Jv/76C48++qipUqlKOOxXoru7GwBw9+5d97a4uIh79+659xsaGtDV1cXgK8EzvxKLi4tobm7G33//vex6k5OTOHDgQJWqIpN45leioaEBJ06cWPasvnXrVuzfv7+KVZFJDL8i3d3d+Pfff32XNTU1obe3Fw0NDVWuikzhsF8REcGOHTuwsLDgu/x///sfXn755SpXRabwzK+IZVno6enJm/F3tLa24qWXXjJQFZnC8Ctz6tQp3L17N6+tqakJZ86ccT/yIx047Ffo+eefx9zcXF5bMpnEzp07DVVEJvDMr1Bvb6879LcsC7t372bwFWL4FTp58iTu3bsHAGhsbERvb6/hisgEDvuVeuWVV/DLL7/AsiykUim0traaLomqjGd+pZyz/Z49exh8pRh+pbq6utDQ0ICenh7TpZAhDL9SLS0tePPNN/Huu++aLoUMUXnNv3PnTty8edN0GVRDZmZmsGvXLtNlVJXaP+Zx9OhRdHZ2mi7DiLGxMUxPT+Pjjz82XYpxCwsL+Oijj0yXYYTa8O/atQtdXV2myzBidnYWyWRS7fP3SiaTasPPa34ipRh+IqUYfiKlGH4ipRh+IqUYfiKlGH4ipRh+IqUYfiKlGH4ipRh+IqUYfiKlGH4ipRh+IqUYfiKlGH4ipRj+NchkMojFYggEAqZLISqb2r/kUwkDAwP47LPPTJex7pb7Dr9wOIy2tjbs378fmzZtqmJVtFY886/BlStXTJdQFSKCdDrt3s9msxARiAgOHTqESCSCnp4eZDIZg1VSuRh+Kklzc7P7f+8ZvqOjA1988QUA4P3330cul6t6bbQ6DH8ZcrkcYrEYLMtCIBDArVu3fNfLZDIYGhpy15ucnHTbvXME8XjcXWd+fj5vG87jI5EIMplM0dB7qX2Y0NzcjA8//BDxeBxTU1N5y7T1xYYiCrW3t8vAwEDZj7NtW4LBoGSzWRERiUajAkC83ZhOp8W2bYlGoyIiMjExIQAkkUiIbdvu+tPT0yIikkqlBIAEg0F3G+FwWFKplIiIZLNZCYVCJe+jFAMDA9Le3l728y98rl7ZbLboeWyEvpiZmREAMjMzU0ZP1AeGv0Tj4+MCQObm5tw25wXvfTE6bwheACQUCrn/91vubQMg6XTavZ9Op8vax0rWI/x+yzdCX2gOP4f9Jfrmm28AAG1tbW6b3+z2tWvXADyYIXduAHDp0qWS9xUMBtHS0oJYLIZcLofm5maI54uVKrGPamBf1DjT7z4mrObMjyXOeoXtS6233PLCtrm5ubxhcTgcLqmWUq3nsN97xt0IfcEzP1XcUpOBpWhra8P4+DgSiQSCwSAuXLiAoaGhiu6j0n799VcAwIEDB4qWaeuLjYLhL9Hw8DAA4LfffitpvatXr7ofezmz0aWyLAu5XA4dHR24cuUKEokELly4UNF9VFImk8Enn3wC27Zx8ODBita50fpiQzE99DBhNcN+Zybatm139tmZWYZnhtqZkCq8pVKpvGXOJwbeSUNnYgv/DZ+d/aRSqbzh7nL7KMVqhv3eOp3aRcSdubdtO29ibqP0heZhP8NfhlQqJcFg0A2792Mm7ws/lUq5H0kFg0H3hVj4Al2uLZ1OSzgc9r3OXW4fpSg3/H7hcm7hcNj9qM5PrfeF5vBbIp6pUyV27tyJrq4uDA4Omi7FiMHBQYyOjmJ2dtZ0KcYlk0ns3r0bMzMz2LVrl+lyqorX/ERKMfxESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REox/ERKMfxESjH8REqp/X3+mzdvmi6DaojG3+dX+UWdly9f5tdKUZ7W1lbTJVSdyjM/EfGan0gthp9IKYafSKlGAGOmiyCi6vs/kAjIjpYnu7UAAAAASUVORK5CYII=", 117 | "text/plain": [ 118 | "" 119 | ] 120 | }, 121 | "execution_count": 12, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "#您还可以将模型绘制为计算图:\n", 128 | "keras.utils.plot_model(model, \"my_first_model.png\") #normalizer也是网络的一层" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 16, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "data": { 138 | "text/plain": [ 139 | "" 146 | ] 147 | }, 148 | "execution_count": 16, 149 | "metadata": {}, 150 | "output_type": "execute_result" 151 | } 152 | ], 153 | "source": [ 154 | "### 2.7.2 通过单热编码对字符串分类特征进行编码\n", 155 | "# Define some toy data\n", 156 | "data = tf.constant([[\"a\"], [\"b\"], [\"c\"], [\"b\"], [\"c\"], [\"a\"]])\n", 157 | "\n", 158 | "# Use StringLookup to build an index of the feature values and encode output.\n", 159 | "lookup = layers.StringLookup(output_mode=\"one_hot\")\n", 160 | "lookup.adapt(data)\n", 161 | "\n", 162 | "# Convert new test data (which includes unknown feature values)\n", 163 | "test_data = tf.constant([[\"a\"], [\"b\"], [\"c\"], [\"d\"], [\"e\"], [\"\"]])\n", 164 | "encoded_data = lookup(test_data) #请注意,此处的索引 0 保留用于词汇表外值(adapt()期间未看到的值)。\n", 165 | "encoded_data" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 19, 171 | "metadata": {}, 172 | "outputs": [ 173 | { 174 | "data": { 175 | "text/plain": [ 176 | "" 183 | ] 184 | }, 185 | "execution_count": 19, 186 | "metadata": {}, 187 | "output_type": "execute_result" 188 | } 189 | ], 190 | "source": [ 191 | "### 2.7.3 通过单热编码对整数分类特征进行编码 - 重要\n", 192 | "# Define some toy data\n", 193 | "data = tf.constant([[10], [20], [20], [10], [30], [0]])\n", 194 | "\n", 195 | "# Use IntegerLookup to build an index of the feature values and encode output.\n", 196 | "lookup = layers.IntegerLookup(output_mode=\"one_hot\")\n", 197 | "lookup.adapt(data)\n", 198 | "\n", 199 | "# Convert new test data (which includes unknown feature values)\n", 200 | "test_data = tf.constant([[10], [10], [20], [50], [60], [0]])\n", 201 | "encoded_data = lookup(test_data) #请注意,索引 0 是为缺失值(应将其指定为值)保留的 0),索引 1 保留用于词汇表外值(adapt()期间未看到的值))。\n", 202 | "encoded_data" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 21, 208 | "metadata": {}, 209 | "outputs": [ 210 | { 211 | "data": { 212 | "text/plain": [ 213 | "TensorShape([10000, 64])" 214 | ] 215 | }, 216 | "execution_count": 21, 217 | "metadata": {}, 218 | "output_type": "execute_result" 219 | } 220 | ], 221 | "source": [ 222 | "### 2.7.4 将哈希技巧应用于整数分类特征\n", 223 | "#如果您有一个可以采用许多不同值的分类特征(按 1e4 或更高),其中每个值在数据中仅出现几次, 对特征值进行索引和单热编码变得不切实际且无效。\n", 224 | "# 相反,应用“哈希技巧”可能是一个好主意:将值哈希到向量 固定大小。这样可以使功能空间的大小保持可管理,并消除了需求 用于显式索引。\n", 225 | "# Sample data: 10,000 random integers with values between 0 and 100,000\n", 226 | "data = np.random.randint(0, 100000, size=(10000, 1))\n", 227 | "\n", 228 | "# Use the Hashing layer to hash the values to the range [0, 64]\n", 229 | "hasher = layers.Hashing(num_bins=64, salt=1337)\n", 230 | "\n", 231 | "# Use the CategoryEncoding layer to multi-hot encode the hashed values\n", 232 | "encoder = layers.CategoryEncoding(num_tokens=64, output_mode=\"multi_hot\")\n", 233 | "encoded_data = encoder(hasher(data))\n", 234 | "encoded_data.shape" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": 23, 240 | "metadata": {}, 241 | "outputs": [ 242 | { 243 | "data": { 244 | "text/plain": [ 245 | "" 250 | ] 251 | }, 252 | "execution_count": 23, 253 | "metadata": {}, 254 | "output_type": "execute_result" 255 | } 256 | ], 257 | "source": [ 258 | "encoded_data[-1]" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": 25, 264 | "metadata": {}, 265 | "outputs": [ 266 | { 267 | "data": { 268 | "text/plain": [ 269 | "" 270 | ] 271 | }, 272 | "execution_count": 25, 273 | "metadata": {}, 274 | "output_type": "execute_result" 275 | } 276 | ], 277 | "source": [ 278 | "###<补充> 2.7.5 将hash技巧用于字符串分类特征\n", 279 | "import tensorflow as tf \n", 280 | " \n", 281 | "# 创建一个字符串张量 \n", 282 | "string_tensor = tf.constant([\"apple\", \"banana\", \"cherry\"]) \n", 283 | " \n", 284 | "# 设置哈希桶的数量 \n", 285 | "num_buckets = 10 \n", 286 | " \n", 287 | "# 对字符串进行哈希 \n", 288 | "hashed_tensor = tf.strings.to_hash_bucket(string_tensor, num_buckets) \n", 289 | " \n", 290 | "# 输出哈希值 \n", 291 | "hashed_tensor" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": null, 297 | "metadata": {}, 298 | "outputs": [], 299 | "source": [ 300 | "### 总结\n", 301 | "#1. 是单独在tf中进行特征处理,还是用hadoop等预处理好,根据实际数据决定,数据量较大时推荐hadoop预处理好再训练;\n", 302 | "#2. 特征hash可用MurmurHash,是一种非加密型哈希函数,适用于一般的哈希检索操作,具有较高的运算性能和较低的碰撞率。" 303 | ] 304 | } 305 | ], 306 | "metadata": { 307 | "kernelspec": { 308 | "display_name": "Python 3", 309 | "language": "python", 310 | "name": "python3" 311 | }, 312 | "language_info": { 313 | "codemirror_mode": { 314 | "name": "ipython", 315 | "version": 3 316 | }, 317 | "file_extension": ".py", 318 | "mimetype": "text/x-python", 319 | "name": "python", 320 | "nbconvert_exporter": "python", 321 | "pygments_lexer": "ipython3", 322 | "version": "3.11.8" 323 | } 324 | }, 325 | "nbformat": 4, 326 | "nbformat_minor": 2 327 | } 328 | -------------------------------------------------------------------------------- /02_Keras/02_08_Customizing_what_happens_in_fit.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 12, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import tensorflow as tf\n", 10 | "from tensorflow import keras\n", 11 | "\n", 12 | "\n", 13 | "###自定义 Model.fit 的内容\n", 14 | "\n", 15 | "##您在进行监督学习时可以使用 fit(),一切都可以顺利完成。\n", 16 | "#需要从头开始编写自己的训练循环时,您可以使用 GradientTape 并控制每个微小的细节。\n", 17 | "#但如果您需要自定义训练算法,又想从 fit() 的便捷功能(例如回调、内置分布支持或步骤融合)中受益,那么该怎么做?\n", 18 | "#Keras 的核心原则是渐进式呈现复杂性。您应当始终能够以渐进的方式习惯较低级别的工作流。如果高级功能并不完全符合您的用例,那么您就不应深陷其中。您应当能够从容地控制微小的细节,同时保留与之相称的高级便利性。\n", 19 | "#需要自定义 fit() 的功能时,您应重写 Model 类的训练步骤函数。此函数是 fit() 会针对每批次数据调用的函数。然后,您将能够像往常一样调用 fit(),它将运行您自己的学习算法。\n", 20 | "#请注意,此模式不会妨碍您使用函数式 API 构建模型。无论是构建 Sequential 模型、函数式 API 模型还是子类模型,均可采用这种模式。\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 4, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "### 2.8.1 第一个简单的示例\n", 30 | "\"\"\"\n", 31 | "让我们从一个简单的示例开始:\n", 32 | "\n", 33 | "创建一个将 keras.Model 子类化的新类。\n", 34 | "仅重写 train_step(self, data) 方法。\n", 35 | "返回一个将指标名称(包括损失)映射到其当前值的字典。\n", 36 | "输入参数 data 是传递以拟合训练数据的数据:\n", 37 | "\n", 38 | "如果通过调用 fit(x, y, ...) 传递 Numpy 数组,则 data 将为元祖 (x, y)。\n", 39 | "如果通过调用 fit(dataset, ...) 传递 tf.data.Dataset,则 data 将为每批次 dataset 产生的数据。\n", 40 | "我们在 train_step 方法的主体中实现了定期的训练更新,类似于您已经熟悉的内容。重要的是,我们通过 self.compiled_loss 计算损失,它会封装传递给 compile() 的损失函数。\n", 41 | "\n", 42 | "同样,我们调用 self.compiled_metrics.update_state(y, y_pred) 来更新在 compile() 中传递的指标的状态,并在最后从 self.metrics 中查询结果以检索其当前值。\n", 43 | "\"\"\"\n", 44 | "\n", 45 | "class CustomModel(keras.Model):\n", 46 | " def train_step(self, data):\n", 47 | " # Unpack the data. Its structure depends on your model and\n", 48 | " # on what you pass to `fit()`.\n", 49 | " x, y = data\n", 50 | "\n", 51 | " with tf.GradientTape() as tape:\n", 52 | " y_pred = self(x, training=True)\n", 53 | " # Compute the loss value\n", 54 | " # (the loss function is configured in `compile()`)\n", 55 | "\n", 56 | " loss = self.compiled_loss(y, y_pred, regularization_losses=self.losses) \n", 57 | "\n", 58 | " # Compute gradients\n", 59 | " trainable_vars = self.trainable_variables\n", 60 | " gradients = tape.gradient(loss,trainable_vars)\n", 61 | "\n", 62 | " # Update weights\n", 63 | " self.optimizer.apply_gradients(zip(gradients, trainable_vars))\n", 64 | "\n", 65 | " # Update metrics (includes the metric that tracks the loss)\n", 66 | " self.compiled_metrics.update_state(y, y_pred)\n", 67 | "\n", 68 | " # Return a dict mapping metric names to current value\n", 69 | " return {m.name: m.result() for m in self.metrics}\n", 70 | " \n" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 5, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "Epoch 1/3\n", 83 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\utils\\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.\n", 84 | "\n", 85 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\engine\\base_layer_utils.py:384: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.\n", 86 | "\n", 87 | "32/32 [==============================] - 1s 3ms/step - loss: 1.4951 - mae: 1.1202\n", 88 | "Epoch 2/3\n", 89 | "32/32 [==============================] - 0s 3ms/step - loss: 0.6545 - mae: 0.6848\n", 90 | "Epoch 3/3\n", 91 | "32/32 [==============================] - 0s 2ms/step - loss: 0.3335 - mae: 0.4640\n" 92 | ] 93 | }, 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "" 98 | ] 99 | }, 100 | "execution_count": 5, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "#我们来试一下:\n", 107 | "import numpy as np\n", 108 | "\n", 109 | "# Construct and compile an instance of CustomModel\n", 110 | "inputs = keras.Input(shape=(32,))\n", 111 | "outputs = keras.layers.Dense(1)(inputs)\n", 112 | "model = CustomModel(inputs, outputs)\n", 113 | "model.compile(optimizer=\"adam\", loss=\"mse\", metrics=[\"mae\"])\n", 114 | "\n", 115 | "# Just use `fit` as usual\n", 116 | "x = np.random.random((1000, 32))\n", 117 | "y = np.random.random((1000, 1))\n", 118 | "model.fit(x, y, epochs=3)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 6, 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "Epoch 1/5\n", 131 | "32/32 [==============================] - 0s 1ms/step - loss: 0.9252 - mae: 0.8349\n", 132 | "Epoch 2/5\n", 133 | "32/32 [==============================] - 0s 2ms/step - loss: 0.3931 - mae: 0.5085\n", 134 | "Epoch 3/5\n", 135 | "32/32 [==============================] - 0s 2ms/step - loss: 0.2541 - mae: 0.4007\n", 136 | "Epoch 4/5\n", 137 | "32/32 [==============================] - 0s 2ms/step - loss: 0.2340 - mae: 0.3851\n", 138 | "Epoch 5/5\n", 139 | "32/32 [==============================] - 0s 2ms/step - loss: 0.2294 - mae: 0.3813\n" 140 | ] 141 | }, 142 | { 143 | "data": { 144 | "text/plain": [ 145 | "" 146 | ] 147 | }, 148 | "execution_count": 6, 149 | "metadata": {}, 150 | "output_type": "execute_result" 151 | } 152 | ], 153 | "source": [ 154 | "### 2.8.2 在更低级别上操作\n", 155 | "\"\"\"\n", 156 | "当然,您可以直接跳过在 compile() 中传递损失函数,而在 train_step 中手动完成所有内容。指标也是如此。\n", 157 | "\n", 158 | "以下是一个较低级别的示例,仅使用 compile() 配置优化器:\n", 159 | "\n", 160 | " ·我们从创建 Metric 实例以跟踪我们的损失和 MAE 得分开始。\n", 161 | " ·我们实现可更新这些指标状态(通过对指标调用 update_state())的自定义 train_step() ,然后对其进行查询(通过 result())以返回其当前平均值,由进度条显示并传递给任何回调。\n", 162 | " ·请注意,需要在每个周期之间对指标调用 reset_states()!否则,调用 result() 会返回自训练开始以来的平均值,但我们通常要使用的是每个周期的平均值。幸运的是,该框架可以帮助\n", 163 | " 我们实现:只需在模型的 metrics 属性中列出要重置的任何指标。模型将在每个 fit() 周期开始时或在开始调用 evaluate() 时对其中列出的任何对象调用 reset_states()。\n", 164 | "\"\"\"\n", 165 | "loss_tracker = keras.metrics.Mean(name=\"loss\")\n", 166 | "mae_metric = keras.metrics.MeanAbsoluteError(name=\"mae\")\n", 167 | "\n", 168 | "\n", 169 | "class CustomModel(keras.Model):\n", 170 | " def train_step(self, data):\n", 171 | " x, y = data\n", 172 | "\n", 173 | " with tf.GradientTape() as tape:\n", 174 | " y_pred = self(x, training=True) # Forward pass\n", 175 | " # Compute our own loss\n", 176 | " loss = keras.losses.mean_squared_error(y, y_pred)\n", 177 | "\n", 178 | " # Compute gradients\n", 179 | " trainable_vars = self.trainable_variables\n", 180 | " gradients = tape.gradient(loss, trainable_vars)\n", 181 | "\n", 182 | " # Update weights\n", 183 | " self.optimizer.apply_gradients(zip(gradients, trainable_vars))\n", 184 | "\n", 185 | " # Compute our own metrics\n", 186 | " loss_tracker.update_state(loss)\n", 187 | " mae_metric.update_state(y, y_pred)\n", 188 | " return {\"loss\": loss_tracker.result(), \"mae\": mae_metric.result()}\n", 189 | "\n", 190 | " @property\n", 191 | " def metrics(self):\n", 192 | " # We list our `Metric` objects here so that `reset_states()` can be\n", 193 | " # called automatically at the start of each epoch\n", 194 | " # or at the start of `evaluate()`.\n", 195 | " # If you don't implement this property, you have to call\n", 196 | " # `reset_states()` yourself at the time of your choosing.\n", 197 | " return [loss_tracker, mae_metric]\n", 198 | "\n", 199 | "\n", 200 | "# Construct an instance of CustomModel\n", 201 | "inputs = keras.Input(shape=(32,))\n", 202 | "outputs = keras.layers.Dense(1)(inputs)\n", 203 | "model = CustomModel(inputs, outputs)\n", 204 | "\n", 205 | "# We don't passs a loss or metrics here.\n", 206 | "model.compile(optimizer=\"adam\")\n", 207 | "\n", 208 | "# Just use `fit` as usual -- you can use callbacks, etc.\n", 209 | "x = np.random.random((1000, 32))\n", 210 | "y = np.random.random((1000, 1))\n", 211 | "model.fit(x, y, epochs=5)" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 7, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "name": "stdout", 221 | "output_type": "stream", 222 | "text": [ 223 | "Epoch 1/3\n", 224 | "32/32 [==============================] - 0s 1ms/step - loss: 0.8096 - mae: 1.1755\n", 225 | "Epoch 2/3\n", 226 | "32/32 [==============================] - 0s 2ms/step - loss: 0.3579 - mae: 0.7392\n", 227 | "Epoch 3/3\n", 228 | "32/32 [==============================] - 0s 2ms/step - loss: 0.1694 - mae: 0.4798\n" 229 | ] 230 | }, 231 | { 232 | "data": { 233 | "text/plain": [ 234 | "" 235 | ] 236 | }, 237 | "execution_count": 7, 238 | "metadata": {}, 239 | "output_type": "execute_result" 240 | } 241 | ], 242 | "source": [ 243 | "### 2.8.3 支持 sample_weight 和 class_weight\n", 244 | "\"\"\"\n", 245 | "您可能已经注意到,我们的第一个基本示例并没有提及样本加权。如果要支持 fit() 参数 sample_weight 和 class_weight,只需执行以下操作:\n", 246 | "\n", 247 | "从 data 参数中解包 sample_weight\n", 248 | "将其传递给 compiled_loss 和 compiled_metrics(当然,如果您不依赖 compile() 来获取损失和指标,也可以手动应用)\n", 249 | "就是这么简单。\n", 250 | "\"\"\"\n", 251 | "class CustomModel(keras.Model):\n", 252 | " def train_step(self, data):\n", 253 | " # Unpack the data. Its structure depends on your model and\n", 254 | " # on what you pass to `fit()`.\n", 255 | " if len(data) == 3:\n", 256 | " x, y, sample_weight = data\n", 257 | " else:\n", 258 | " sample_weight = None\n", 259 | " x, y = data\n", 260 | "\n", 261 | " with tf.GradientTape() as tape:\n", 262 | " y_pred = self(x, training=True) # Forward pass\n", 263 | " # Compute the loss value.\n", 264 | " # The loss function is configured in `compile()`.\n", 265 | " loss = self.compiled_loss(\n", 266 | " y,\n", 267 | " y_pred,\n", 268 | " sample_weight=sample_weight,\n", 269 | " regularization_losses=self.losses,\n", 270 | " )\n", 271 | "\n", 272 | " # Compute gradients\n", 273 | " trainable_vars = self.trainable_variables\n", 274 | " gradients = tape.gradient(loss, trainable_vars)\n", 275 | "\n", 276 | " # Update weights\n", 277 | " self.optimizer.apply_gradients(zip(gradients, trainable_vars))\n", 278 | "\n", 279 | " # Update the metrics.\n", 280 | " # Metrics are configured in `compile()`.\n", 281 | " self.compiled_metrics.update_state(y, y_pred, sample_weight=sample_weight)\n", 282 | "\n", 283 | " # Return a dict mapping metric names to current value.\n", 284 | " # Note that it will include the loss (tracked in self.metrics).\n", 285 | " return {m.name: m.result() for m in self.metrics}\n", 286 | "\n", 287 | "\n", 288 | "# Construct and compile an instance of CustomModel\n", 289 | "inputs = keras.Input(shape=(32,))\n", 290 | "outputs = keras.layers.Dense(1)(inputs)\n", 291 | "model = CustomModel(inputs, outputs)\n", 292 | "model.compile(optimizer=\"adam\", loss=\"mse\", metrics=[\"mae\"])\n", 293 | "\n", 294 | "# You can now use sample_weight argument\n", 295 | "x = np.random.random((1000, 32))\n", 296 | "y = np.random.random((1000, 1))\n", 297 | "sw = np.random.random((1000, 1))\n", 298 | "model.fit(x, y, sample_weight=sw, epochs=3)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 8, 304 | "metadata": {}, 305 | "outputs": [ 306 | { 307 | "name": "stdout", 308 | "output_type": "stream", 309 | "text": [ 310 | "32/32 [==============================] - 0s 2ms/step - loss: 0.2208 - mae: 0.3802\n" 311 | ] 312 | }, 313 | { 314 | "data": { 315 | "text/plain": [ 316 | "[0.22083483636379242, 0.3802275061607361]" 317 | ] 318 | }, 319 | "execution_count": 8, 320 | "metadata": {}, 321 | "output_type": "execute_result" 322 | } 323 | ], 324 | "source": [ 325 | "### 2.8.5 提供您自己的评估步骤\n", 326 | "#如何对调用 model.evaluate() 进行相同的处理?您需要以完全相同的方式重写 test_step。如下所示:\n", 327 | "class CustomModel(keras.Model):\n", 328 | " def test_step(self, data):\n", 329 | " # Unpack the data\n", 330 | " x, y = data\n", 331 | " # Compute predictions\n", 332 | " y_pred = self(x, training=False)\n", 333 | " # Updates the metrics tracking the loss\n", 334 | " self.compiled_loss(y, y_pred, regularization_losses=self.losses)\n", 335 | " # Update the metrics.\n", 336 | " self.compiled_metrics.update_state(y, y_pred)\n", 337 | " # Return a dict mapping metric names to current value.\n", 338 | " # Note that it will include the loss (tracked in self.metrics).\n", 339 | " return {m.name: m.result() for m in self.metrics}\n", 340 | "\n", 341 | "\n", 342 | "# Construct an instance of CustomModel\n", 343 | "inputs = keras.Input(shape=(32,))\n", 344 | "outputs = keras.layers.Dense(1)(inputs)\n", 345 | "model = CustomModel(inputs, outputs)\n", 346 | "model.compile(loss=\"mse\", metrics=[\"mae\"])\n", 347 | "\n", 348 | "# Evaluate with our custom test_step\n", 349 | "x = np.random.random((1000, 32))\n", 350 | "y = np.random.random((1000, 1))\n", 351 | "model.evaluate(x, y)" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 9, 357 | "metadata": {}, 358 | "outputs": [], 359 | "source": [ 360 | "### 2.8.6 总结:端到端 GAN 示例\n", 361 | "\"\"\"\n", 362 | "让我们看一个利用您刚刚所学全部内容的端到端示例。\n", 363 | "\n", 364 | "请考虑:\n", 365 | "\n", 366 | "旨在生成 28x28x1 图像的生成器网络。\n", 367 | "旨在将 28x28x1 图像分为两类(“fake”和“real”)的鉴别器网络。\n", 368 | "分别用于两个网络的优化器。\n", 369 | "训练鉴别器的损失函数。\n", 370 | "\"\"\"\n", 371 | "from tensorflow.keras import layers\n", 372 | "\n", 373 | "# Create the discriminator\n", 374 | "discriminator = keras.Sequential(\n", 375 | " [\n", 376 | " keras.Input(shape=(28, 28, 1)),\n", 377 | " layers.Conv2D(64, (3, 3), strides=(2, 2), padding=\"same\"),\n", 378 | " layers.LeakyReLU(alpha=0.2),\n", 379 | " layers.Conv2D(128, (3, 3), strides=(2, 2), padding=\"same\"),\n", 380 | " layers.LeakyReLU(alpha=0.2),\n", 381 | " layers.GlobalMaxPooling2D(),\n", 382 | " layers.Dense(1),\n", 383 | " ],\n", 384 | " name=\"discriminator\",\n", 385 | ")\n", 386 | "\n", 387 | "# Create the generator\n", 388 | "latent_dim = 128\n", 389 | "generator = keras.Sequential(\n", 390 | " [\n", 391 | " keras.Input(shape=(latent_dim,)),\n", 392 | " # We want to generate 128 coefficients to reshape into a 7x7x128 map\n", 393 | " layers.Dense(7 * 7 * 128),\n", 394 | " layers.LeakyReLU(alpha=0.2),\n", 395 | " layers.Reshape((7, 7, 128)),\n", 396 | " layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding=\"same\"),\n", 397 | " layers.LeakyReLU(alpha=0.2),\n", 398 | " layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding=\"same\"),\n", 399 | " layers.LeakyReLU(alpha=0.2),\n", 400 | " layers.Conv2D(1, (7, 7), padding=\"same\", activation=\"sigmoid\"),\n", 401 | " ],\n", 402 | " name=\"generator\",\n", 403 | ")\n" 404 | ] 405 | }, 406 | { 407 | "cell_type": "code", 408 | "execution_count": 10, 409 | "metadata": {}, 410 | "outputs": [], 411 | "source": [ 412 | "#这是特征齐全的 GAN 类,重写了 compile() 以使用其自己的签名,并在 train_step 的 17 行中实现了整个 GAN 算法:\n", 413 | "class GAN(keras.Model):\n", 414 | " def __init__(self, discriminator, generator, latent_dim):\n", 415 | " super(GAN, self).__init__()\n", 416 | " self.discriminator = discriminator\n", 417 | " self.generator = generator\n", 418 | " self.latent_dim = latent_dim\n", 419 | "\n", 420 | " def compile(self, d_optimizer, g_optimizer, loss_fn):\n", 421 | " super(GAN, self).compile()\n", 422 | " self.d_optimizer = d_optimizer\n", 423 | " self.g_optimizer = g_optimizer\n", 424 | " self.loss_fn = loss_fn\n", 425 | "\n", 426 | " def train_step(self, real_images):\n", 427 | " if isinstance(real_images, tuple):\n", 428 | " real_images = real_images[0]\n", 429 | " # Sample random points in the latent space\n", 430 | " batch_size = tf.shape(real_images)[0]\n", 431 | " random_latent_vectors = tf.random.normal(shape=(batch_size, self.latent_dim))\n", 432 | "\n", 433 | " # Decode them to fake images\n", 434 | " generated_images = self.generator(random_latent_vectors)\n", 435 | "\n", 436 | " # Combine them with real images\n", 437 | " combined_images = tf.concat([generated_images, real_images], axis=0)\n", 438 | "\n", 439 | " # Assemble labels discriminating real from fake images\n", 440 | " labels = tf.concat(\n", 441 | " [tf.ones((batch_size, 1)), tf.zeros((batch_size, 1))], axis=0\n", 442 | " )\n", 443 | " # Add random noise to the labels - important trick!\n", 444 | " labels += 0.05 * tf.random.uniform(tf.shape(labels))\n", 445 | "\n", 446 | " # Train the discriminator\n", 447 | " with tf.GradientTape() as tape:\n", 448 | " predictions = self.discriminator(combined_images)\n", 449 | " d_loss = self.loss_fn(labels, predictions)\n", 450 | " grads = tape.gradient(d_loss, self.discriminator.trainable_weights)\n", 451 | " self.d_optimizer.apply_gradients(\n", 452 | " zip(grads, self.discriminator.trainable_weights)\n", 453 | " )\n", 454 | "\n", 455 | " # Sample random points in the latent space\n", 456 | " random_latent_vectors = tf.random.normal(shape=(batch_size, self.latent_dim))\n", 457 | "\n", 458 | " # Assemble labels that say \"all real images\"\n", 459 | " misleading_labels = tf.zeros((batch_size, 1))\n", 460 | "\n", 461 | " # Train the generator (note that we should *not* update the weights\n", 462 | " # of the discriminator)!\n", 463 | " with tf.GradientTape() as tape:\n", 464 | " predictions = self.discriminator(self.generator(random_latent_vectors))\n", 465 | " g_loss = self.loss_fn(misleading_labels, predictions)\n", 466 | " grads = tape.gradient(g_loss, self.generator.trainable_weights)\n", 467 | " self.g_optimizer.apply_gradients(zip(grads, self.generator.trainable_weights))\n", 468 | " return {\"d_loss\": d_loss, \"g_loss\": g_loss}" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": null, 474 | "metadata": {}, 475 | "outputs": [], 476 | "source": [ 477 | "#让我们对其进行测试: - 网络故障,未运行\n", 478 | "# Prepare the dataset. We use both the training & test MNIST digits.\n", 479 | "batch_size = 64\n", 480 | "(x_train, _), (x_test, _) = keras.datasets.mnist.load_data()\n", 481 | "all_digits = np.concatenate([x_train, x_test])\n", 482 | "all_digits = all_digits.astype(\"float32\") / 255.0\n", 483 | "all_digits = np.reshape(all_digits, (-1, 28, 28, 1))\n", 484 | "dataset = tf.data.Dataset.from_tensor_slices(all_digits)\n", 485 | "dataset = dataset.shuffle(buffer_size=1024).batch(batch_size)\n", 486 | "\n", 487 | "gan = GAN(discriminator=discriminator, generator=generator, latent_dim=latent_dim)\n", 488 | "gan.compile(\n", 489 | " d_optimizer=keras.optimizers.Adam(learning_rate=0.0003),\n", 490 | " g_optimizer=keras.optimizers.Adam(learning_rate=0.0003),\n", 491 | " loss_fn=keras.losses.BinaryCrossentropy(from_logits=True),\n", 492 | ")\n", 493 | "\n", 494 | "# To limit the execution time, we only train on 100 batches. You can train on\n", 495 | "# the entire dataset. You will need about 20 epochs to get nice results.\n", 496 | "gan.fit(dataset.take(100), epochs=1)" 497 | ] 498 | } 499 | ], 500 | "metadata": { 501 | "kernelspec": { 502 | "display_name": "Python 3", 503 | "language": "python", 504 | "name": "python3" 505 | }, 506 | "language_info": { 507 | "codemirror_mode": { 508 | "name": "ipython", 509 | "version": 3 510 | }, 511 | "file_extension": ".py", 512 | "mimetype": "text/x-python", 513 | "name": "python", 514 | "nbconvert_exporter": "python", 515 | "pygments_lexer": "ipython3", 516 | "version": "3.11.8" 517 | } 518 | }, 519 | "nbformat": 4, 520 | "nbformat_minor": 2 521 | } 522 | -------------------------------------------------------------------------------- /02_Keras/02_09_Writing_a_training_loop_from_scratch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "\n", 19 | "import tensorflow as tf\n", 20 | "from tensorflow import keras\n", 21 | "from tensorflow.keras import layers\n", 22 | "import numpy as np\n", 23 | "\n", 24 | "### 从头编写训练循环\n", 25 | "#Keras 提供了默认的训练与评估循环 fit() 和 evaluate()。使用内置方法进行训练和评估指南中介绍了它们的用法。\n", 26 | "#如果想要自定义模型的学习算法,同时又能利用 fit() 的便利性(例如,使用 fit() 训练 GAN),\n", 27 | "# 则可以将 Model 类子类化并实现自己的 train_step() 方法,此方法可在 fit() 中重复调用。自定义 fit() 的功能指南对此进行了介绍。\n", 28 | "#现在,如果您想对训练和评估进行低级别控制,则应当从头开始编写自己的训练和评估循环。这正是本指南要介绍的内容。" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:1398: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.\n", 41 | "\n" 42 | ] 43 | } 44 | ], 45 | "source": [ 46 | "### 2.9.1 使用 GradientTape:第一个端到端示例\n", 47 | "#在 GradientTape 作用域内调用模型使您可以检索层的可训练权重相对于损失值的梯度。利用优化器实例,您可以使用上述梯度来更新这些变量(可以使用 model.trainable_weights 检索这些变量)。\n", 48 | "\n", 49 | "#我们考虑一个简单的 MNIST 模型:\n", 50 | "inputs = keras.Input(shape=(784,), name=\"digits\")\n", 51 | "x1 = layers.Dense(64, activation=\"relu\")(inputs)\n", 52 | "x2 = layers.Dense(64, activation=\"relu\")(x1)\n", 53 | "outputs = layers.Dense(10, name=\"predictions\")(x2)\n", 54 | "model = keras.Model(inputs=inputs, outputs=outputs)\n" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "#我们使用带自定义训练循环的 mini-batch 梯度对其进行训练。 - 网络故障,未运行\n", 64 | "\n", 65 | "#首先,我们需要优化器、损失函数和数据集:\n", 66 | "# Instantiate an optimizer.\n", 67 | "optimizer = keras.optimizers.SGD(learning_rate=1e-3)\n", 68 | "# Instantiate a loss function.\n", 69 | "loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)\n", 70 | "\n", 71 | "# Prepare the training dataset.\n", 72 | "batch_size = 64\n", 73 | "(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()\n", 74 | "x_train = np.reshape(x_train, (-1, 784))\n", 75 | "x_test = np.reshape(x_test, (-1, 784))\n", 76 | "\n", 77 | "# Reserve 10,000 samples for validation.\n", 78 | "x_val = x_train[-10000:]\n", 79 | "y_val = y_train[-10000:]\n", 80 | "x_train = x_train[:-10000]\n", 81 | "y_train = y_train[:-10000]\n", 82 | "\n", 83 | "# Prepare the training dataset.\n", 84 | "train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))\n", 85 | "train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)\n", 86 | "\n", 87 | "# Prepare the validation dataset.\n", 88 | "val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))\n", 89 | "val_dataset = val_dataset.batch(batch_size)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "\"\"\"\n", 99 | "下面是我们的训练循环:\n", 100 | "\n", 101 | "我们打开一个遍历各周期的 for 循环\n", 102 | "对于每个周期,我们打开一个分批遍历数据集的 for 循环\n", 103 | "对于每个批次,我们打开一个 GradientTape() 作用域\n", 104 | "在此作用域内,我们调用模型(前向传递)并计算损失\n", 105 | "在作用域之外,我们检索模型权重相对于损失的梯度\n", 106 | "最后,我们根据梯度使用优化器来更新模型的权重\n", 107 | "\"\"\"\n", 108 | "epochs = 2\n", 109 | "for epoch in range(epochs):\n", 110 | " print(\"\\nStart of epoch %d\" % (epoch,))\n", 111 | "\n", 112 | " # Iterate over the batches of the dataset.\n", 113 | " for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):\n", 114 | "\n", 115 | " # Open a GradientTape to record the operations run\n", 116 | " # during the forward pass, which enables auto-differentiation.\n", 117 | " with tf.GradientTape() as tape:\n", 118 | "\n", 119 | " # Run the forward pass of the layer.\n", 120 | " # The operations that the layer applies\n", 121 | " # to its inputs are going to be recorded\n", 122 | " # on the GradientTape.\n", 123 | " logits = model(x_batch_train, training=True) # Logits for this minibatch\n", 124 | "\n", 125 | " # Compute the loss value for this minibatch.\n", 126 | " loss_value = loss_fn(y_batch_train, logits)\n", 127 | "\n", 128 | " # Use the gradient tape to automatically retrieve\n", 129 | " # the gradients of the trainable variables with respect to the loss.\n", 130 | " grads = tape.gradient(loss_value, model.trainable_weights)\n", 131 | "\n", 132 | " # Run one step of gradient descent by updating\n", 133 | " # the value of the variables to minimize the loss.\n", 134 | " optimizer.apply_gradients(zip(grads, model.trainable_weights))\n", 135 | "\n", 136 | " # Log every 200 batches.\n", 137 | " if step % 200 == 0:\n", 138 | " print(\n", 139 | " \"Training loss (for one batch) at step %d: %.4f\"\n", 140 | " % (step, float(loss_value))\n", 141 | " )\n", 142 | " print(\"Seen so far: %s samples\" % ((step + 1) * batch_size))" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "### 2.9.2 指标的低级处理\n", 152 | "\"\"\"\n", 153 | "在这种从头开始编写的训练循环中,您可以轻松重用内置指标(或编写的自定义指标)。下面列出了具体流程:\n", 154 | " 在循环开始时实例化指标\n", 155 | " 在每个批次后调用 metric.update_state()\n", 156 | " 当您需要显示指标的当前值时,调用 metric.result()\n", 157 | " 当您需要清除指标的状态(通常在周期结束)时,调用 metric.reset_states()\n", 158 | "我们利用这些知识在每个周期结束时基于验证数据计算 SparseCategoricalAccuracy\n", 159 | "\"\"\"\n", 160 | "# Get model\n", 161 | "inputs = keras.Input(shape=(784,), name=\"digits\")\n", 162 | "x = layers.Dense(64, activation=\"relu\", name=\"dense_1\")(inputs)\n", 163 | "x = layers.Dense(64, activation=\"relu\", name=\"dense_2\")(x)\n", 164 | "outputs = layers.Dense(10, name=\"predictions\")(x)\n", 165 | "model = keras.Model(inputs=inputs, outputs=outputs)\n", 166 | "\n", 167 | "# Instantiate an optimizer to train the model.\n", 168 | "optimizer = keras.optimizers.SGD(learning_rate=1e-3)\n", 169 | "# Instantiate a loss function.\n", 170 | "loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)\n", 171 | "\n", 172 | "# Prepare the metrics.\n", 173 | "train_acc_metric = keras.metrics.SparseCategoricalAccuracy()\n", 174 | "val_acc_metric = keras.metrics.SparseCategoricalAccuracy()\n" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "#下面是我们的训练和评估循环:\n", 184 | "import time\n", 185 | "\n", 186 | "epochs = 2\n", 187 | "for epoch in range(epochs):\n", 188 | " print(\"\\nStart of epoch %d\" % (epoch,))\n", 189 | " start_time = time.time()\n", 190 | "\n", 191 | " # Iterate over the batches of the dataset.\n", 192 | " for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):\n", 193 | " with tf.GradientTape() as tape:\n", 194 | " logits = model(x_batch_train, training=True)\n", 195 | " loss_value = loss_fn(y_batch_train, logits)\n", 196 | " grads = tape.gradient(loss_value, model.trainable_weights)\n", 197 | " optimizer.apply_gradients(zip(grads, model.trainable_weights))\n", 198 | "\n", 199 | " # Update training metric.\n", 200 | " train_acc_metric.update_state(y_batch_train, logits)\n", 201 | "\n", 202 | " # Log every 200 batches.\n", 203 | " if step % 200 == 0:\n", 204 | " print(\n", 205 | " \"Training loss (for one batch) at step %d: %.4f\"\n", 206 | " % (step, float(loss_value))\n", 207 | " )\n", 208 | " print(\"Seen so far: %d samples\" % ((step + 1) * batch_size))\n", 209 | "\n", 210 | " # Display metrics at the end of each epoch.\n", 211 | " train_acc = train_acc_metric.result()\n", 212 | " print(\"Training acc over epoch: %.4f\" % (float(train_acc),))\n", 213 | "\n", 214 | " # Reset training metrics at the end of each epoch\n", 215 | " train_acc_metric.reset_states()\n", 216 | "\n", 217 | " # Run a validation loop at the end of each epoch.\n", 218 | " for x_batch_val, y_batch_val in val_dataset:\n", 219 | " val_logits = model(x_batch_val, training=False)\n", 220 | " # Update val metrics\n", 221 | " val_acc_metric.update_state(y_batch_val, val_logits)\n", 222 | " val_acc = val_acc_metric.result()\n", 223 | " val_acc_metric.reset_states()\n", 224 | " print(\"Validation acc: %.4f\" % (float(val_acc),))\n", 225 | " print(\"Time taken: %.2fs\" % (time.time() - start_time))" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": {}, 232 | "outputs": [], 233 | "source": [ 234 | "### 2.9.3 使用 tf.function 加快训练步骤速度\n", 235 | "\"\"\"\n", 236 | "TensorFlow 2 中的默认运行时为 Eager Execution。因此,上述训练循环以 Eager 模式执行。\n", 237 | "\n", 238 | "这非常适合调试,但计算图编译具有无限性能优势。将您的计算描述为静态计算图可以让框架应用全局性能优化。\n", 239 | " 当框架在不了解后续运算的情况下被限制为以贪婪方式依次执行运算时,全局性能优化无法实现。\n", 240 | "\n", 241 | "您可以编译成任何函数均将张量作为输入的静态计算图。只需在上面添加一个 @tf.function 装饰器,如下所示:\n", 242 | "\"\"\"\n", 243 | "\n", 244 | "@tf.function\n", 245 | "def train_step(x, y):\n", 246 | " with tf.GradientTape() as tape:\n", 247 | " logits = model(x, training=True)\n", 248 | " loss_value = loss_fn(y, logits)\n", 249 | " grads = tape.gradient(loss_value, model.trainable_weights)\n", 250 | " optimizer.apply_gradients(zip(grads, model.trainable_weights))\n", 251 | " train_acc_metric.update_state(y, logits)\n", 252 | " return loss_value\n", 253 | "\n" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": null, 259 | "metadata": {}, 260 | "outputs": [], 261 | "source": [ 262 | "#我们对评估步骤执行相同的操作:\n", 263 | "@tf.function\n", 264 | "def test_step(x, y):\n", 265 | " val_logits = model(x, training=False)\n", 266 | " val_acc_metric.update_state(y, val_logits)" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "metadata": {}, 273 | "outputs": [], 274 | "source": [ 275 | "#现在,我们使用编译后的训练步骤重新运行训练循环:\n", 276 | "import time\n", 277 | "\n", 278 | "epochs = 2\n", 279 | "for epoch in range(epochs):\n", 280 | " print(\"\\nStart of epoch %d\" % (epoch,))\n", 281 | " start_time = time.time()\n", 282 | "\n", 283 | " # Iterate over the batches of the dataset.\n", 284 | " for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):\n", 285 | " loss_value = train_step(x_batch_train, y_batch_train)\n", 286 | "\n", 287 | " # Log every 200 batches.\n", 288 | " if step % 200 == 0:\n", 289 | " print(\n", 290 | " \"Training loss (for one batch) at step %d: %.4f\"\n", 291 | " % (step, float(loss_value))\n", 292 | " )\n", 293 | " print(\"Seen so far: %d samples\" % ((step + 1) * batch_size))\n", 294 | "\n", 295 | " # Display metrics at the end of each epoch.\n", 296 | " train_acc = train_acc_metric.result()\n", 297 | " print(\"Training acc over epoch: %.4f\" % (float(train_acc),))\n", 298 | "\n", 299 | " # Reset training metrics at the end of each epoch\n", 300 | " train_acc_metric.reset_states()\n", 301 | "\n", 302 | " # Run a validation loop at the end of each epoch.\n", 303 | " for x_batch_val, y_batch_val in val_dataset:\n", 304 | " test_step(x_batch_val, y_batch_val)\n", 305 | "\n", 306 | " val_acc = val_acc_metric.result()\n", 307 | " val_acc_metric.reset_states()\n", 308 | " print(\"Validation acc: %.4f\" % (float(val_acc),))\n", 309 | " print(\"Time taken: %.2fs\" % (time.time() - start_time))" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "### 2.9.4 对模型跟踪的损失进行低级处理\n", 319 | "\"\"\"\n", 320 | "层和模型以递归方式跟踪调用 self.add_loss(value) 的层在前向传递过程中创建的任何损失。可在前向传递结束时通过属性 model.losses 获得标量损失值的结果列表。\n", 321 | "\n", 322 | "如果要使用这些损失分量,应将它们求和并添加到训练步骤的主要损失中。\n", 323 | "\n", 324 | "考虑下面这个层,它会产生活动正则化损失:\n", 325 | "\"\"\"\n", 326 | "class ActivityRegularizationLayer(layers.Layer):\n", 327 | " def call(self, inputs):\n", 328 | " self.add_loss(1e-2 * tf.reduce_sum(inputs))\n", 329 | " return inputs\n" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": null, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "#我们构建一个使用它的超简单模型:\n", 339 | "inputs = keras.Input(shape=(784,), name=\"digits\")\n", 340 | "x = layers.Dense(64, activation=\"relu\")(inputs)\n", 341 | "# Insert activity regularization as a layer\n", 342 | "x = ActivityRegularizationLayer()(x)\n", 343 | "x = layers.Dense(64, activation=\"relu\")(x)\n", 344 | "outputs = layers.Dense(10, name=\"predictions\")(x)\n", 345 | "\n", 346 | "model = keras.Model(inputs=inputs, outputs=outputs)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": null, 352 | "metadata": {}, 353 | "outputs": [], 354 | "source": [ 355 | "#我们的训练步骤现在应当如下所示:\n", 356 | "@tf.function\n", 357 | "def train_step(x, y):\n", 358 | " with tf.GradientTape() as tape:\n", 359 | " logits = model(x, training=True)\n", 360 | " loss_value = loss_fn(y, logits)\n", 361 | " # Add any extra losses created during the forward pass.\n", 362 | " loss_value += sum(model.losses)\n", 363 | " grads = tape.gradient(loss_value, model.trainable_weights)\n", 364 | " optimizer.apply_gradients(zip(grads, model.trainable_weights))\n", 365 | " train_acc_metric.update_state(y, logits)\n", 366 | " return loss_value" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [ 375 | "### 2.9.5 端到端示例:从头开始的 GAN 训练循环\n", 376 | "#我们来实现这个训练循环。首先,创建用于区分虚假数字和真实数字的判别器:\n", 377 | "discriminator = keras.Sequential(\n", 378 | " [\n", 379 | " keras.Input(shape=(28, 28, 1)),\n", 380 | " layers.Conv2D(64, (3, 3), strides=(2, 2), padding=\"same\"),\n", 381 | " layers.LeakyReLU(alpha=0.2),\n", 382 | " layers.Conv2D(128, (3, 3), strides=(2, 2), padding=\"same\"),\n", 383 | " layers.LeakyReLU(alpha=0.2),\n", 384 | " layers.GlobalMaxPooling2D(),\n", 385 | " layers.Dense(1),\n", 386 | " ],\n", 387 | " name=\"discriminator\",\n", 388 | ")\n", 389 | "discriminator.summary()" 390 | ] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "execution_count": null, 395 | "metadata": {}, 396 | "outputs": [], 397 | "source": [ 398 | "#接着,我们创建一个生成器网络,它可以将隐向量转换成形状为 (28, 28, 1)(表示 MNIST 数字)的输出:\n", 399 | "latent_dim = 128\n", 400 | "\n", 401 | "generator = keras.Sequential(\n", 402 | " [\n", 403 | " keras.Input(shape=(latent_dim,)),\n", 404 | " # We want to generate 128 coefficients to reshape into a 7x7x128 map\n", 405 | " layers.Dense(7 * 7 * 128),\n", 406 | " layers.LeakyReLU(alpha=0.2),\n", 407 | " layers.Reshape((7, 7, 128)),\n", 408 | " layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding=\"same\"),\n", 409 | " layers.LeakyReLU(alpha=0.2),\n", 410 | " layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding=\"same\"),\n", 411 | " layers.LeakyReLU(alpha=0.2),\n", 412 | " layers.Conv2D(1, (7, 7), padding=\"same\", activation=\"sigmoid\"),\n", 413 | " ],\n", 414 | " name=\"generator\",\n", 415 | ")" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "metadata": {}, 422 | "outputs": [], 423 | "source": [ 424 | "#这是关键部分:训练循环。如您所见,训练非常简单。训练步骤函数仅有 17 行代码。\n", 425 | "# Instantiate one optimizer for the discriminator and another for the generator.\n", 426 | "d_optimizer = keras.optimizers.Adam(learning_rate=0.0003)\n", 427 | "g_optimizer = keras.optimizers.Adam(learning_rate=0.0004)\n", 428 | "\n", 429 | "# Instantiate a loss function.\n", 430 | "loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)\n", 431 | "\n", 432 | "\n", 433 | "@tf.function\n", 434 | "def train_step(real_images):\n", 435 | " # Sample random points in the latent space\n", 436 | " random_latent_vectors = tf.random.normal(shape=(batch_size, latent_dim))\n", 437 | " # Decode them to fake images\n", 438 | " generated_images = generator(random_latent_vectors)\n", 439 | " # Combine them with real images\n", 440 | " combined_images = tf.concat([generated_images, real_images], axis=0)\n", 441 | "\n", 442 | " # Assemble labels discriminating real from fake images\n", 443 | " labels = tf.concat(\n", 444 | " [tf.ones((batch_size, 1)), tf.zeros((real_images.shape[0], 1))], axis=0\n", 445 | " )\n", 446 | " # Add random noise to the labels - important trick!\n", 447 | " labels += 0.05 * tf.random.uniform(labels.shape)\n", 448 | "\n", 449 | " # Train the discriminator\n", 450 | " with tf.GradientTape() as tape:\n", 451 | " predictions = discriminator(combined_images)\n", 452 | " d_loss = loss_fn(labels, predictions)\n", 453 | " grads = tape.gradient(d_loss, discriminator.trainable_weights)\n", 454 | " d_optimizer.apply_gradients(zip(grads, discriminator.trainable_weights))\n", 455 | "\n", 456 | " # Sample random points in the latent space\n", 457 | " random_latent_vectors = tf.random.normal(shape=(batch_size, latent_dim))\n", 458 | " # Assemble labels that say \"all real images\"\n", 459 | " misleading_labels = tf.zeros((batch_size, 1))\n", 460 | "\n", 461 | " # Train the generator (note that we should *not* update the weights\n", 462 | " # of the discriminator)!\n", 463 | " with tf.GradientTape() as tape:\n", 464 | " predictions = discriminator(generator(random_latent_vectors))\n", 465 | " g_loss = loss_fn(misleading_labels, predictions)\n", 466 | " grads = tape.gradient(g_loss, generator.trainable_weights)\n", 467 | " g_optimizer.apply_gradients(zip(grads, generator.trainable_weights))\n", 468 | " return d_loss, g_loss, generated_images" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": null, 474 | "metadata": {}, 475 | "outputs": [], 476 | "source": [ 477 | "#我们通过在各个图像批次上重复调用 train_step 来训练 GAN。\n", 478 | "\n", 479 | "#由于我们的判别器和生成器是卷积神经网络,因此您将在 GPU 上运行此代码。\n", 480 | "import os\n", 481 | "\n", 482 | "# Prepare the dataset. We use both the training & test MNIST digits.\n", 483 | "batch_size = 64\n", 484 | "(x_train, _), (x_test, _) = keras.datasets.mnist.load_data()\n", 485 | "all_digits = np.concatenate([x_train, x_test])\n", 486 | "all_digits = all_digits.astype(\"float32\") / 255.0\n", 487 | "all_digits = np.reshape(all_digits, (-1, 28, 28, 1))\n", 488 | "dataset = tf.data.Dataset.from_tensor_slices(all_digits)\n", 489 | "dataset = dataset.shuffle(buffer_size=1024).batch(batch_size)\n", 490 | "\n", 491 | "epochs = 1 # In practice you need at least 20 epochs to generate nice digits.\n", 492 | "save_dir = \"./\"\n", 493 | "\n", 494 | "for epoch in range(epochs):\n", 495 | " print(\"\\nStart epoch\", epoch)\n", 496 | "\n", 497 | " for step, real_images in enumerate(dataset):\n", 498 | " # Train the discriminator & generator on one batch of real images.\n", 499 | " d_loss, g_loss, generated_images = train_step(real_images)\n", 500 | "\n", 501 | " # Logging.\n", 502 | " if step % 200 == 0:\n", 503 | " # Print metrics\n", 504 | " print(\"discriminator loss at step %d: %.2f\" % (step, d_loss))\n", 505 | " print(\"adversarial loss at step %d: %.2f\" % (step, g_loss))\n", 506 | "\n", 507 | " # Save one generated image\n", 508 | " img = tf.keras.preprocessing.image.array_to_img(\n", 509 | " generated_images[0] * 255.0, scale=False\n", 510 | " )\n", 511 | " img.save(os.path.join(save_dir, \"generated_img\" + str(step) + \".png\"))\n", 512 | "\n", 513 | " # To limit execution time we stop after 10 steps.\n", 514 | " # Remove the lines below to actually train the model!\n", 515 | " if step > 10:\n", 516 | " break" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [ 525 | "### 总结:对比1.6节的training_loop。" 526 | ] 527 | } 528 | ], 529 | "metadata": { 530 | "kernelspec": { 531 | "display_name": "Python 3", 532 | "language": "python", 533 | "name": "python3" 534 | }, 535 | "language_info": { 536 | "codemirror_mode": { 537 | "name": "ipython", 538 | "version": 3 539 | }, 540 | "file_extension": ".py", 541 | "mimetype": "text/x-python", 542 | "name": "python", 543 | "nbconvert_exporter": "python", 544 | "pygments_lexer": "ipython3", 545 | "version": "3.11.8" 546 | } 547 | }, 548 | "nbformat": 4, 549 | "nbformat_minor": 2 550 | } 551 | -------------------------------------------------------------------------------- /01_TensorFlow_basics/01_05_Modules_layers_and_models.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n", 13 | "\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "from datetime import datetime\n", 20 | "\n", 21 | "%load_ext tensorboard\n", 22 | "\n", 23 | "### 1.5 模块、层和模型简介\n", 24 | "#要进行 TensorFlow 机器学习,您可能需要定义、保存和恢复模型。\n", 25 | "\n", 26 | "#抽象地说,模型是:\n", 27 | "# 一个在张量上进行某些计算的函数(前向传递)\n", 28 | "# 一些可以更新以响应训练的变量" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 4, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "data": { 38 | "text/plain": [ 39 | "" 40 | ] 41 | }, 42 | "execution_count": 4, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "### 1.5.1 在 TensorFlow 中定义模型和层\n", 49 | "#大多数模型都由层组成。层是具有已知数学结构的函数,可以重复使用并具有可训练的变量。\n", 50 | "#在 TensorFlow 中,层和模型的大多数高级实现(例如 Keras 或 Sonnet)都在以下同一个基础类上构建:tf.Module。\n", 51 | "\n", 52 | "#下面是一个在标量张量上运行的非常简单的 tf.Module 示例:\n", 53 | "\n", 54 | "class SimpleModel(tf.Module): #SimpleModel 类继承自 tf.Module\n", 55 | " def __init__(self,name=None):\n", 56 | " super().__init__(name=name)\n", 57 | " self.a_variable = tf.Variable(5.0, name=\"train_me\")\n", 58 | " self.non_trainable_variable = tf.Variable(5.0, trainable=False, name=\"do_not_train_me\")\n", 59 | " def __call__(self,x):\n", 60 | " return self.a_variable * x + self.non_trainable_variable \n", 61 | " \n", 62 | "simple_module = SimpleModel(name=\"simple\")\n", 63 | "simple_module(tf.constant(5.))" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "trainable variables: (,)\n", 76 | "all variables: (, )\n" 77 | ] 78 | } 79 | ], 80 | "source": [ 81 | "#您可以出于任何原因开启和关闭变量的可训练性,包括在微调过程中冻结层和变量。\n", 82 | "\n", 83 | "#注:tf.Module 是 tf.keras.layers.Layer 和 tf.keras.Model 的基类,因此您在此处看到的一切内容也适用于 Keras。\n", 84 | "#出于历史兼容性原因,Keras 层不会从模块收集变量,因此您的模型应仅使用模块或仅使用 Keras 层。不过,下面给出的用于检查变量的方法在这两种情况下相同。\n", 85 | "\n", 86 | "#通过将 tf.Module 子类化,将自动收集分配给该对象属性的任何 tf.Variable 或 tf.Module 实例。这样,您可以保存和加载变量,还可以创建 tf.Module 的集合。\n", 87 | "# All trainable variables\n", 88 | "print(\"trainable variables:\", simple_module.trainable_variables)\n", 89 | "# Every variable\n", 90 | "print(\"all variables:\", simple_module.variables)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 13, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "##下面是一个由模块组成的两层线性层模型的示例。\n", 100 | "\n", 101 | "#首先是一个密集(线性)层:\n", 102 | "class Dense(tf.Module):\n", 103 | " def __init__(self, in_features, out_features, name=None):\n", 104 | " super().__init__(name = name)\n", 105 | "\n", 106 | " self.w = tf.Variable(\n", 107 | " tf.random.normal([in_features, out_features]), name='w'\n", 108 | " )\n", 109 | " self.b = tf.Variable(tf.zeros([out_features]),name='b')\n", 110 | "\n", 111 | " def __call__(self, x):\n", 112 | " y = tf.matmul(x,self.w) + self.b\n", 113 | " return tf.nn.relu(y) \n" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 14, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "Model results: tf.Tensor([[0. 0.]], shape=(1, 2), dtype=float32)\n" 126 | ] 127 | } 128 | ], 129 | "source": [ 130 | "#随后是完整的模型,此模型将创建并应用两个层实例:\n", 131 | "class SequentialModule(tf.Module):\n", 132 | " def __init__(self, name=None):\n", 133 | " super().__init__(name=name)\n", 134 | "\n", 135 | " self.dense_1 = Dense(in_features=3,out_features=3)\n", 136 | " self.dense_2 = Dense(in_features=3,out_features=2)\n", 137 | "\n", 138 | " def __call__(self, x):\n", 139 | " x = self.dense_1(x)\n", 140 | " return self.dense_2(x)\n", 141 | "\n", 142 | "# You have made a model!\n", 143 | "my_model = SequentialModule(name=\"the_model\")\n", 144 | "\n", 145 | "#call it, with random results\n", 146 | "print(\"Model results:\", my_model(tf.constant([[2.0, 2.0, 2.0]])))" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 15, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "Submodules: (<__main__.Dense object at 0x00000216FA14B4D0>, <__main__.Dense object at 0x00000216FA181E90>)\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "#tf.Module 实例将以递归方式自动收集分配给它的任何 tf.Variable 或 tf.Module 实例。这样,您可以使用单个模型实例管理 tf.Module 的集合,并保存和加载整个模型。\n", 164 | "print(\"Submodules:\", my_model.submodules)" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 16, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | " \n", 177 | "\n", 178 | " \n", 182 | "\n", 183 | " \n", 184 | "\n", 185 | " \n", 189 | "\n" 190 | ] 191 | } 192 | ], 193 | "source": [ 194 | "for var in my_model.variables:\n", 195 | " print(var, \"\\n\")" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 17, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "## 等待创建变量\n", 205 | "#您在这里可能已经注意到,必须定义层的输入和输出大小。这样,w 变量才会具有已知的形状并且可被分配。\n", 206 | "#通过将变量创建推迟到第一次使用特定输入形状调用模块时,您将无需预先指定输入大小。\n", 207 | "\n", 208 | "class FlexibleDenseModule(tf.Module):\n", 209 | " # Note: No need for `in_features`\n", 210 | " def __init__(self, out_features, name=None):\n", 211 | " super().__init__(name=name)\n", 212 | " self.is_built = False\n", 213 | " self.out_features = out_features\n", 214 | "\n", 215 | " def __call__(self, x):\n", 216 | " # Create variables on first call.\n", 217 | " if not self.is_built:\n", 218 | " self.w = tf.Variable(\n", 219 | " tf.random.normal([x.shape[-1], self.out_features]), name='w')\n", 220 | " self.b = tf.Variable(tf.zeros([self.out_features]), name='b')\n", 221 | " self.is_built = True\n", 222 | "\n", 223 | " y = tf.matmul(x, self.w) + self.b\n", 224 | " return tf.nn.relu(y)\n" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": 19, 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "name": "stdout", 234 | "output_type": "stream", 235 | "text": [ 236 | "Model results: tf.Tensor([[0. 0.]], shape=(1, 2), dtype=float32)\n" 237 | ] 238 | } 239 | ], 240 | "source": [ 241 | "# Used in a module\n", 242 | "class MySequentialModule(tf.Module):\n", 243 | " def __init__(self, name=None):\n", 244 | " super().__init__(name=name)\n", 245 | "\n", 246 | " self.dense_1 = FlexibleDenseModule(out_features=3)\n", 247 | " self.dense_2 = FlexibleDenseModule(out_features=2)\n", 248 | "\n", 249 | " def __call__(self, x):\n", 250 | " x = self.dense_1(x)\n", 251 | " return self.dense_2(x)\n", 252 | "\n", 253 | "my_model = MySequentialModule(name=\"the_model\")\n", 254 | "print(\"Model results:\", my_model(tf.constant([[2.0, 2.0, 2.0]])))\n", 255 | "\n", 256 | "#这种灵活性是 TensorFlow 层通常仅需要指定其输出的形状(例如在 tf.keras.layers.Dense 中),而无需指定输入和输出大小的原因。" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 21, 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "data": { 266 | "text/plain": [ 267 | "'__Checkpoint/my_checkpoint'" 268 | ] 269 | }, 270 | "execution_count": 21, 271 | "metadata": {}, 272 | "output_type": "execute_result" 273 | } 274 | ], 275 | "source": [ 276 | "###1.5.2 保存权重\n", 277 | "\n", 278 | "#您可以将 tf.Module 保存为检查点和 SavedModel。\n", 279 | "#检查点即是权重(即模块及其子模块内部的变量集的值)。\n", 280 | "\n", 281 | "chkp_path = \"__Checkpoint/my_checkpoint\" ##检查点由两种文件组成---数据本身以及元数据的索引文件。\n", 282 | " #索引文件跟踪实际保存的内容和检查点的编号,而检查点数据包含变量值及其特性查找路径。\n", 283 | "checkpoint = tf.train.Checkpoint(model=my_model)\n", 284 | "checkpoint.write(chkp_path)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 23, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "[('_CHECKPOINTABLE_OBJECT_GRAPH', []),\n", 296 | " ('model/dense_1/b/.ATTRIBUTES/VARIABLE_VALUE', [3]),\n", 297 | " ('model/dense_1/w/.ATTRIBUTES/VARIABLE_VALUE', [3, 3]),\n", 298 | " ('model/dense_2/b/.ATTRIBUTES/VARIABLE_VALUE', [2]),\n", 299 | " ('model/dense_2/w/.ATTRIBUTES/VARIABLE_VALUE', [3, 2])]" 300 | ] 301 | }, 302 | "execution_count": 23, 303 | "metadata": {}, 304 | "output_type": "execute_result" 305 | } 306 | ], 307 | "source": [ 308 | "\n", 309 | "#您可以查看检查点内部,以确保整个变量集合已由包含这些变量的 Python 对象保存并排序。\n", 310 | "#在分布式(多机)训练期间,可以将它们分片,这就是要对它们进行编号(例如 '00000-of-00001')的原因。不过,在本例中,只有一个分片。\n", 311 | "tf.train.list_variables(chkp_path)" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 25, 317 | "metadata": {}, 318 | "outputs": [ 319 | { 320 | "data": { 321 | "text/plain": [ 322 | "" 323 | ] 324 | }, 325 | "execution_count": 25, 326 | "metadata": {}, 327 | "output_type": "execute_result" 328 | } 329 | ], 330 | "source": [ 331 | "## 重新加载模型时,将重写 Python 对象中的值。\n", 332 | "new_model = MySequentialModule()\n", 333 | "new_checkpoint = tf.train.Checkpoint(model=new_model)\n", 334 | "new_checkpoint.restore(chkp_path)\n", 335 | "\n", 336 | "#shoud be the same result as above\n", 337 | "new_model(tf.constant([[2.0, 2.0, 2.0]]))" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 26, 343 | "metadata": {}, 344 | "outputs": [ 345 | { 346 | "name": "stdout", 347 | "output_type": "stream", 348 | "text": [ 349 | "INFO:tensorflow:Assets written to: __SaveModel/the_saved_model\\assets\n" 350 | ] 351 | } 352 | ], 353 | "source": [ 354 | "### 1.5.3 保存函数\n", 355 | "\n", 356 | "## 创建 SavedModel\n", 357 | "#共享经过完全训练的模型的推荐方式是使用 SavedModel。SavedModel 包含函数集合与权重集合。\n", 358 | "#您可以按以下方式保存刚刚训练的模型:\n", 359 | "tf.saved_model.save(my_model,\"__SaveModel/the_saved_model\") #saved_model.pb 文件是一个描述函数式 tf.Graph 的协议缓冲区。" 360 | ] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": 27, 365 | "metadata": {}, 366 | "outputs": [], 367 | "source": [ 368 | "#您可以将模型作为新对象加载:\n", 369 | "new_model = tf.saved_model.load(\"__SaveModel/the_saved_model\")" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 28, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "data": { 379 | "text/plain": [ 380 | "False" 381 | ] 382 | }, 383 | "execution_count": 28, 384 | "metadata": {}, 385 | "output_type": "execute_result" 386 | } 387 | ], 388 | "source": [ 389 | "#通过加载已保存模型创建的 new_model 是 TensorFlow 内部的用户对象,无需任何类知识。它不是 SequentialModule 类型的对象。\n", 390 | "isinstance(new_model, SequentialModule)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 29, 396 | "metadata": {}, 397 | "outputs": [ 398 | { 399 | "name": "stdout", 400 | "output_type": "stream", 401 | "text": [ 402 | "tf.Tensor([[0. 0.]], shape=(1, 2), dtype=float32)\n", 403 | "tf.Tensor(\n", 404 | "[[[0. 0.]\n", 405 | " [0. 0.]]], shape=(1, 2, 2), dtype=float32)\n" 406 | ] 407 | } 408 | ], 409 | "source": [ 410 | "#此新模型​​适用于已定义的输入签名。您不能向以这种方式恢复的模型添加更多签名。\n", 411 | "#因此,利用 SavedModel,您可以使用 tf.Module 保存 TensorFlow 权重和计算图,随后再次加载它们。\n", 412 | "print(my_model([[2.0, 2.0, 2.0]]))\n", 413 | "print(my_model([[[2.0, 2.0, 2.0], [2.0, 2.0, 2.0]]]))" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": 32, 419 | "metadata": {}, 420 | "outputs": [], 421 | "source": [ 422 | "### 1.5.4 Keras 模型和层\n", 423 | "\n", 424 | "#请注意,到目前为止,还没有提到 Keras。您可以在 tf.Module 上构建自己的高级 API,而我们已经拥有这些 API。\n", 425 | "#在本部分中,您将研究 Keras 如何使用 tf.Module。可在 Keras 指南中找到有关 Keras 模型的完整用户指南。\n", 426 | "\n", 427 | "## 1.Keras 层\n", 428 | "#tf.keras.layers.Layer 是所有 Keras 层的基类,它继承自 tf.Module。\n", 429 | "#您只需换出父项,然后将 __call__ 更改为 call 即可将模块转换为 Keras 层:\n", 430 | "class MyDense(tf.keras.layers.Layer):\n", 431 | " # Adding **kwargs to support base Keras layer arguments\n", 432 | " def __init__(self, in_features, out_features, **kwargs):\n", 433 | " super().__init__(**kwargs)\n", 434 | "\n", 435 | " # This will soon move to the build step; see below\n", 436 | " self.w = tf.Variable(\n", 437 | " tf.random.normal([in_features, out_features]), name='w')\n", 438 | " self.b = tf.Variable(tf.zeros([out_features]), name='b')\n", 439 | " def call(self, x):\n", 440 | " y = tf.matmul(x, self.w) + self.b\n", 441 | " return tf.nn.relu(y)\n", 442 | "\n", 443 | "simple_layer = MyDense(name=\"simple\", in_features=3, out_features=3)\n" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": 33, 449 | "metadata": {}, 450 | "outputs": [ 451 | { 452 | "data": { 453 | "text/plain": [ 454 | "" 455 | ] 456 | }, 457 | "execution_count": 33, 458 | "metadata": {}, 459 | "output_type": "execute_result" 460 | } 461 | ], 462 | "source": [ 463 | "#Keras 层有自己的 __call__,它会进行下一部分中所述的某些簿记,然后调用 call()。您应当不会看到功能上的任何变化。\n", 464 | "simple_layer([[2.0, 2.0, 2.0]])" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 34, 470 | "metadata": {}, 471 | "outputs": [ 472 | { 473 | "name": "stdout", 474 | "output_type": "stream", 475 | "text": [ 476 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", 477 | "\n" 478 | ] 479 | }, 480 | { 481 | "name": "stderr", 482 | "output_type": "stream", 483 | "text": [ 484 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", 485 | "\n" 486 | ] 487 | } 488 | ], 489 | "source": [ 490 | "##2.build 步骤\n", 491 | "#如上所述,在您确定输入形状之前,等待创建变量在许多情况下十分方便。\n", 492 | "#Keras 层具有额外的生命周期步骤,可让您在定义层时获得更高的灵活性。这是在 build() 函数中定义的。\n", 493 | "#build 仅被调用一次,而且是使用输入的形状调用的。它通常用于创建变量(权重)。\n", 494 | "#您可以根据输入的大小灵活地重写上面的 MyDense 层:\n", 495 | "\n", 496 | "class FlexibleDense(tf.keras.layers.Layer):\n", 497 | " # Note the added `**kwargs`, as Keras supports many arguments\n", 498 | " def __init__(self, out_features, **kwargs):\n", 499 | " super().__init__(**kwargs)\n", 500 | " self.out_features = out_features\n", 501 | "\n", 502 | " def build(self, input_shape): # Create the state of the layer (weights)\n", 503 | " self.w = tf.Variable(\n", 504 | " tf.random.normal([input_shape[-1], self.out_features]), name='w')\n", 505 | " self.b = tf.Variable(tf.zeros([self.out_features]), name='b')\n", 506 | "\n", 507 | " def call(self, inputs): # Defines the computation from inputs to outputs\n", 508 | " return tf.matmul(inputs, self.w) + self.b\n", 509 | "\n", 510 | "# Create the instance of the layer\n", 511 | "flexible_dense = FlexibleDense(out_features=3)" 512 | ] 513 | }, 514 | { 515 | "cell_type": "code", 516 | "execution_count": 35, 517 | "metadata": {}, 518 | "outputs": [ 519 | { 520 | "data": { 521 | "text/plain": [ 522 | "[]" 523 | ] 524 | }, 525 | "execution_count": 35, 526 | "metadata": {}, 527 | "output_type": "execute_result" 528 | } 529 | ], 530 | "source": [ 531 | "#此时,模型尚未构建,因此没有变量:\n", 532 | "flexible_dense.variables" 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": 36, 538 | "metadata": {}, 539 | "outputs": [ 540 | { 541 | "name": "stdout", 542 | "output_type": "stream", 543 | "text": [ 544 | "Model results: tf.Tensor(\n", 545 | "[[ 5.7936106 7.2969246 0.46919066]\n", 546 | " [ 8.690414 10.945387 0.703786 ]], shape=(2, 3), dtype=float32)\n" 547 | ] 548 | } 549 | ], 550 | "source": [ 551 | "#调用该函数会分配大小适当的变量。\n", 552 | "# Call it, with predictably random results\n", 553 | "print(\"Model results:\", flexible_dense(tf.constant([[2.0, 2.0, 2.0], [3.0, 3.0, 3.0]])))" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": 37, 559 | "metadata": {}, 560 | "outputs": [ 561 | { 562 | "data": { 563 | "text/plain": [ 564 | "[,\n", 568 | " ]" 569 | ] 570 | }, 571 | "execution_count": 37, 572 | "metadata": {}, 573 | "output_type": "execute_result" 574 | } 575 | ], 576 | "source": [ 577 | "flexible_dense.variables" 578 | ] 579 | }, 580 | { 581 | "cell_type": "code", 582 | "execution_count": 41, 583 | "metadata": {}, 584 | "outputs": [ 585 | { 586 | "name": "stdout", 587 | "output_type": "stream", 588 | "text": [ 589 | "Failed: Exception encountered when calling layer 'flexible_dense' (type FlexibleDense).\n", 590 | "\n", 591 | "{{function_node __wrapped____MklMatMul_device_/job:localhost/replica:0/task:0/device:CPU:0}} Matrix size-incompatible: In[0]: [1,4], In[1]: [3,3] [Op:MatMul] name: \n", 592 | "\n", 593 | "Call arguments received by layer 'flexible_dense' (type FlexibleDense):\n", 594 | " • inputs=tf.Tensor(shape=(1, 4), dtype=float32)\n" 595 | ] 596 | } 597 | ], 598 | "source": [ 599 | "#由于仅调用一次 build,因此如果输入形状与层的变量不兼容,输入将被拒绝。\n", 600 | "try:\n", 601 | " print(\"Model results:\", flexible_dense(tf.constant([[2.0, 2.0, 2.0, 2.0]])))\n", 602 | "except tf.errors.InvalidArgumentError as e:\n", 603 | " print(\"Failed:\", e)" 604 | ] 605 | }, 606 | { 607 | "cell_type": "code", 608 | "execution_count": 42, 609 | "metadata": {}, 610 | "outputs": [ 611 | { 612 | "name": "stdout", 613 | "output_type": "stream", 614 | "text": [ 615 | "Model results: tf.Tensor([[-1.8241254 4.9807124]], shape=(1, 2), dtype=float32)\n" 616 | ] 617 | } 618 | ], 619 | "source": [ 620 | "## 3.Keras 模型\n", 621 | "#您可以将模型定义为嵌套的 Keras 层。\n", 622 | "#但是,Keras 还提供了称为 tf.keras.Model 的全功能模型类。它继承自 tf.keras.layers.Layer,\n", 623 | "#因此 Keras 模型支持以同样的方式使用、嵌套和保存。Keras 模型还具有额外的功能,这使它们可以轻松训练、评估、加载、保存,甚至在多台机器上进行训练。\n", 624 | "#您可以使用几乎相同的代码定义上面的 SequentialModule,再次将 __call__ 转换为 call() 并更改父项。\n", 625 | "\n", 626 | "class MySequentialModel(tf.keras.Model):\n", 627 | " def __init__(self, name=None, **kwargs):\n", 628 | " super().__init__(**kwargs)\n", 629 | "\n", 630 | " self.dense_1 = FlexibleDense(out_features=3)\n", 631 | " self.dense_2 = FlexibleDense(out_features=2)\n", 632 | " def call(self, x):\n", 633 | " x = self.dense_1(x)\n", 634 | " return self.dense_2(x)\n", 635 | "\n", 636 | "# You have made a Keras model!\n", 637 | "my_sequential_model = MySequentialModel(name=\"the_model\")\n", 638 | "\n", 639 | "# Call it on a tensor, with random results\n", 640 | "print(\"Model results:\", my_sequential_model(tf.constant([[2.0, 2.0, 2.0]])))\n" 641 | ] 642 | }, 643 | { 644 | "cell_type": "code", 645 | "execution_count": 43, 646 | "metadata": {}, 647 | "outputs": [ 648 | { 649 | "data": { 650 | "text/plain": [ 651 | "[,\n", 655 | " ,\n", 656 | " ,\n", 660 | " ]" 661 | ] 662 | }, 663 | "execution_count": 43, 664 | "metadata": {}, 665 | "output_type": "execute_result" 666 | } 667 | ], 668 | "source": [ 669 | "#所有相同的功能都可用,包括跟踪变量和子模块。\n", 670 | "#注:为了强调上面的注意事项,嵌套在 Keras 层或模型中的原始 tf.Module 将不会收集其变量以用于训练或保存。相反,它会在 Keras 层内嵌套 Keras 层。\n", 671 | "my_sequential_model.variables" 672 | ] 673 | }, 674 | { 675 | "cell_type": "code", 676 | "execution_count": 48, 677 | "metadata": {}, 678 | "outputs": [ 679 | { 680 | "name": "stdout", 681 | "output_type": "stream", 682 | "text": [ 683 | "Model: \"model_3\"\n", 684 | "_________________________________________________________________\n", 685 | " Layer (type) Output Shape Param # \n", 686 | "=================================================================\n", 687 | " input_4 (InputLayer) [(None, 3)] 0 \n", 688 | " \n", 689 | " flexible_dense_9 (Flexible (None, 3) 12 \n", 690 | " Dense) \n", 691 | " \n", 692 | " flexible_dense_10 (Flexibl (None, 2) 8 \n", 693 | " eDense) \n", 694 | " \n", 695 | "=================================================================\n", 696 | "Total params: 20 (80.00 Byte)\n", 697 | "Trainable params: 20 (80.00 Byte)\n", 698 | "Non-trainable params: 0 (0.00 Byte)\n", 699 | "_________________________________________________________________\n" 700 | ] 701 | } 702 | ], 703 | "source": [ 704 | "#重写 tf.keras.Model 是一种构建 TensorFlow 模型的极 Python 化方式。如果要从其他框架迁移模型,这可能非常简单。\n", 705 | "#如果要构造的模型是现有层和输入的简单组合,则可以使用函数式 API 节省时间和空间,此 API 附带有关模型重构和架构的附加功能。\n", 706 | "#下面是使用函数式 API 构造的相同模型:\n", 707 | "inputs = tf.keras.Input(shape=[3,])\n", 708 | "\n", 709 | "x = FlexibleDense(3)(inputs)\n", 710 | "x = FlexibleDense(2)(x)\n", 711 | "\n", 712 | "my_functional_model = tf.keras.Model(inputs=inputs, outputs=x)\n", 713 | "my_functional_model.summary()\n" 714 | ] 715 | }, 716 | { 717 | "cell_type": "code", 718 | "execution_count": 49, 719 | "metadata": {}, 720 | "outputs": [ 721 | { 722 | "data": { 723 | "text/plain": [ 724 | "" 725 | ] 726 | }, 727 | "execution_count": 49, 728 | "metadata": {}, 729 | "output_type": "execute_result" 730 | } 731 | ], 732 | "source": [ 733 | "my_functional_model(tf.constant([[2.0, 2.0, 2.0]]))\n", 734 | "\n", 735 | "#这里的主要区别在于,输入形状是作为函数构造过程的一部分预先指定的。在这种情况下,不必完全指定 input_shape 参数;您可以将某些维度保留为 None。\n", 736 | "#注:您无需在子类化模型中指定 input_shape 或 InputLayer;这些参数和层将被忽略。" 737 | ] 738 | }, 739 | { 740 | "cell_type": "code", 741 | "execution_count": 50, 742 | "metadata": {}, 743 | "outputs": [ 744 | { 745 | "name": "stdout", 746 | "output_type": "stream", 747 | "text": [ 748 | "INFO:tensorflow:Assets written to: __KerasModel/exname_of_file\\assets\n" 749 | ] 750 | }, 751 | { 752 | "name": "stderr", 753 | "output_type": "stream", 754 | "text": [ 755 | "INFO:tensorflow:Assets written to: __KerasModel/exname_of_file\\assets\n" 756 | ] 757 | } 758 | ], 759 | "source": [ 760 | "### 1.5.5 保存keras模型\n", 761 | "#可以为 Keras 模型创建检查点,这看起来和 tf.Module 一样。\n", 762 | "#Keras 模型也可以使用 tf.saved_models.save() 保存,因为它们是模块。但是,Keras 模型具有更方便的方法和其他功能:\n", 763 | "my_sequential_model.save(\"__KerasModel/exname_of_file\")\n" 764 | ] 765 | }, 766 | { 767 | "cell_type": "code", 768 | "execution_count": 51, 769 | "metadata": {}, 770 | "outputs": [ 771 | { 772 | "name": "stdout", 773 | "output_type": "stream", 774 | "text": [ 775 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\saving\\legacy\\saved_model\\load.py:107: The name tf.gfile.Exists is deprecated. Please use tf.io.gfile.exists instead.\n", 776 | "\n" 777 | ] 778 | }, 779 | { 780 | "name": "stderr", 781 | "output_type": "stream", 782 | "text": [ 783 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\saving\\legacy\\saved_model\\load.py:107: The name tf.gfile.Exists is deprecated. Please use tf.io.gfile.exists instead.\n", 784 | "\n" 785 | ] 786 | }, 787 | { 788 | "name": "stdout", 789 | "output_type": "stream", 790 | "text": [ 791 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\saving\\legacy\\saved_model\\load.py:178: The name tf.logging.warning is deprecated. Please use tf.compat.v1.logging.warning instead.\n", 792 | "\n" 793 | ] 794 | }, 795 | { 796 | "name": "stderr", 797 | "output_type": "stream", 798 | "text": [ 799 | "WARNING:tensorflow:From c:\\Users\\yuanshuai\\AppData\\Local\\anaconda3\\envs\\tensorflow2\\Lib\\site-packages\\keras\\src\\saving\\legacy\\saved_model\\load.py:178: The name tf.logging.warning is deprecated. Please use tf.compat.v1.logging.warning instead.\n", 800 | "\n" 801 | ] 802 | }, 803 | { 804 | "name": "stdout", 805 | "output_type": "stream", 806 | "text": [ 807 | "WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.\n" 808 | ] 809 | }, 810 | { 811 | "name": "stderr", 812 | "output_type": "stream", 813 | "text": [ 814 | "WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.\n" 815 | ] 816 | } 817 | ], 818 | "source": [ 819 | "#同样地,它们也可以轻松重新加载:\n", 820 | "reconstructed_model = tf.keras.models.load_model(\"__KerasModel/exname_of_file\")" 821 | ] 822 | }, 823 | { 824 | "cell_type": "code", 825 | "execution_count": 52, 826 | "metadata": {}, 827 | "outputs": [ 828 | { 829 | "data": { 830 | "text/plain": [ 831 | "" 832 | ] 833 | }, 834 | "execution_count": 52, 835 | "metadata": {}, 836 | "output_type": "execute_result" 837 | } 838 | ], 839 | "source": [ 840 | "#Keras SavedModels 还可以保存指标、损失和优化器状态。\n", 841 | "#可以使用此重构模型,并且在相同数据上调用时会产生相同的结果:\n", 842 | "reconstructed_model(tf.constant([[2.0, 2.0, 2.0]]))\n" 843 | ] 844 | } 845 | ], 846 | "metadata": { 847 | "kernelspec": { 848 | "display_name": "Python 3", 849 | "language": "python", 850 | "name": "python3" 851 | }, 852 | "language_info": { 853 | "codemirror_mode": { 854 | "name": "ipython", 855 | "version": 3 856 | }, 857 | "file_extension": ".py", 858 | "mimetype": "text/x-python", 859 | "name": "python", 860 | "nbconvert_exporter": "python", 861 | "pygments_lexer": "ipython3", 862 | "version": "3.11.8" 863 | } 864 | }, 865 | "nbformat": 4, 866 | "nbformat_minor": 2 867 | } 868 | --------------------------------------------------------------------------------