{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":6243,"databundleVersionId":868544,"sourceType":"competition"},{"sourceId":1173340,"sourceType":"datasetVersion","datasetId":665647}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"导入所需的程序包# Importing Required Packages","metadata":{"papermill":{"duration":0.037505,"end_time":"2022-03-15T11:50:33.372117","exception":false,"start_time":"2022-03-15T11:50:33.334612","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#导入所需库准备进行机器学习或深度学习项目的数据预处理和模型训练\nimport numpy as np \nimport pandas as pd \nimport os\nimport glob\nimport tensorflow as tf  #用于进行数值计算，特别是神经网络的研究和开发\nimport time\nfrom sklearn.model_selection import train_test_split  #提供用于模型选择的工具\nfrom collections import Counter\nfrom sklearn.model_selection import train_test_split\nfrom collections import Counter\nimport cv2\nfrom concurrent import futures  \nimport threading  \nimport matplotlib.pyplot as plt  #用于创建静态、交互式、发布质量的图形\n%matplotlib inline\nfrom sklearn.preprocessing import LabelEncoder\nfrom tensorflow.keras.utils import to_categorical\nimport datetime\nfrom prettytable import PrettyTable\n","metadata":{"papermill":{"duration":5.57698,"end_time":"2022-03-15T11:50:38.98425","exception":false,"start_time":"2022-03-15T11:50:33.40727","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T11:59:28.525039Z","iopub.execute_input":"2024-06-21T11:59:28.525444Z","iopub.status.idle":"2024-06-21T11:59:28.534280Z","shell.execute_reply.started":"2024-06-21T11:59:28.525409Z","shell.execute_reply":"2024-06-21T11:59:28.533279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"读取数据集# Reading the Dataset","metadata":{"papermill":{"duration":0.035429,"end_time":"2022-03-15T11:50:39.055278","exception":false,"start_time":"2022-03-15T11:50:39.019849","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#获取训练集中的图像，并找到特定类型的图像文件，统计每种类型的文件数量\nprint(os.listdir(\"../input/intel-mobileodt-cervical-cancer-screening\"))\n\nbase_dir = os.path.join('../input/intel-mobileodt-cervical-cancer-screening/train/train')  #定义变量，指向路径\ntype1_dir = os.path.join(base_dir,'Type_1')\ntype2_dir = os.path.join(base_dir,'Type_2')\ntype3_dir = os.path.join(base_dir,'Type_3')\n\ntype1_files = glob.glob(type1_dir+'/*.jpg')\ntype2_files = glob.glob(type2_dir+'/*.jpg')\ntype3_files = glob.glob(type3_dir+'/*.jpg')\n\nlen(type1_files),len(type2_files),len(type3_files)\n\n","metadata":{"papermill":{"duration":0.416269,"end_time":"2022-03-15T11:50:39.50687","exception":false,"start_time":"2022-03-15T11:50:39.090601","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T11:59:28.536097Z","iopub.execute_input":"2024-06-21T11:59:28.536404Z","iopub.status.idle":"2024-06-21T11:59:28.565219Z","shell.execute_reply.started":"2024-06-21T11:59:28.536379Z","shell.execute_reply":"2024-06-21T11:59:28.564297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#构建数据帧映射图像和癌症类型\nnp.random.seed(42)  #设置一个固定的随机数种子，设置使结果可以重复\n\nfiles_df = pd.DataFrame({\n    'filename': type1_files + type2_files + type3_files,  #将之前找到的三种类型（Type_1, Type_2, Type_3）的文件名列表连接起来，形成一个新的列表\n    'label': ['Type_1'] * len(type1_files) + ['Type_2'] * len(type2_files) + ['Type_3'] * len(type3_files)  \n                                      #根据每种类型文件的数量，创建了一个与文件名列表长度相同的标签列表。每个文件名都有一个对应的标签，指示其所属的类型\n}).sample(frac=1, random_state=42).reset_index(drop=True)  #对创建的DataFrame进行随机抽样\n\nfiles_df.head()   #重新设置索引，并从0开始为每一行分配一个新的整数索引\n\n","metadata":{"papermill":{"duration":0.058034,"end_time":"2022-03-15T11:50:39.600419","exception":false,"start_time":"2022-03-15T11:50:39.542385","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T11:59:28.566383Z","iopub.execute_input":"2024-06-21T11:59:28.566721Z","iopub.status.idle":"2024-06-21T11:59:28.579820Z","shell.execute_reply.started":"2024-06-21T11:59:28.566691Z","shell.execute_reply":"2024-06-21T11:59:28.578899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"拆分数据集# Split Dataset","metadata":{"papermill":{"duration":0.035513,"end_time":"2022-03-15T11:50:39.672929","exception":false,"start_time":"2022-03-15T11:50:39.637416","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#拆分训练、开发和测试集\n#train_files, val_files, train_labels, val_labels先将分割后的数据赋值给了四个变量\ntrain_files, test_files, train_labels, test_labels = train_test_split(files_df['filename'].values,                                                                    \n                                                                      files_df['label'].values, \n                                                                      test_size=0.3, random_state=42)\n#使用了`train_test_split`函数将数据集分为训练集和测试集，`test_size=0.3`表示测试集的大小占总数据集的30%，剩下的70%将作为训练集\ntrain_files, val_files, train_labels, val_labels = train_test_split(train_files,\n                                                                    train_labels, \n                                                                    test_size=0.1, random_state=42)\n##将训练集分割成两部分：训练集和验证集\nprint(train_files.shape, val_files.shape, test_files.shape)\nprint('Train:', Counter(train_labels), '\\nVal:', Counter(val_labels), '\\nTest:', Counter(test_labels))\n\n","metadata":{"papermill":{"duration":0.051352,"end_time":"2022-03-15T11:50:39.760236","exception":false,"start_time":"2022-03-15T11:50:39.708884","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T11:59:28.581101Z","iopub.execute_input":"2024-06-21T11:59:28.581696Z","iopub.status.idle":"2024-06-21T11:59:28.591946Z","shell.execute_reply.started":"2024-06-21T11:59:28.581663Z","shell.execute_reply":"2024-06-21T11:59:28.591018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"数据集维度摘要## Summary of the dataset dimensions\n","metadata":{"papermill":{"duration":0.036328,"end_time":"2022-03-15T11:50:39.833125","exception":false,"start_time":"2022-03-15T11:50:39.796797","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#快速并行地读取一组图像文件的尺寸，并获得这些尺寸的统计信息\ndef get_img_shape_parallel(idx, img, total_imgs):    #定义了函数`get_img_shape_parallel`，包括三个参数：图像的索引`idx`、图像文件的路径`img`和总图像数量`total_imgs`。\n    if idx % 5000 == 0 or idx == (total_imgs - 1):\n        print('{}: working on img num: {}'.format(threading.current_thread().name,\n                                                  idx))\n    return cv2.imread(img).shape  #使用OpenCV的`cv2.imread`函数读取图像文件，并返回图像的尺寸（形状）。\n  \nex = futures.ThreadPoolExecutor(max_workers=None)\ndata_inp = [(idx, img, len(train_files)) for idx, img in enumerate(train_files)]\nprint('Starting Img shape computation:')\ntrain_img_dims_map = ex.map(get_img_shape_parallel, #使用线程池执行器的`map`方法并行地对`data_inp`中的每个元组调用`get_img_shape_parallel`函数。返回一个迭代器，其中包含每个图像的尺寸。\n                            [record[0] for record in data_inp],\n                            [record[1] for record in data_inp],\n                            [record[2] for record in data_inp])\ntrain_img_dims = list(train_img_dims_map)  #将迭代器转换为列表`train_img_dims`，以便能够访问所有图像的尺寸\nprint('Min Dimensions:', np.min(train_img_dims, axis=0)) \nprint('Avg Dimensions:', np.mean(train_img_dims, axis=0))\nprint('Median Dimensions:', np.median(train_img_dims, axis=0))\nprint('Max Dimensions:', np.max(train_img_dims, axis=0))\n\n","metadata":{"papermill":{"duration":141.357546,"end_time":"2022-03-15T11:53:01.226635","exception":false,"start_time":"2022-03-15T11:50:39.869089","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T11:59:28.594203Z","iopub.execute_input":"2024-06-21T11:59:28.594553Z","iopub.status.idle":"2024-06-21T12:00:00.896057Z","shell.execute_reply.started":"2024-06-21T11:59:28.594522Z","shell.execute_reply":"2024-06-21T12:00:00.895374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#使用多线程高效地加载和预处理大量图像数据\nIMG_DIMS = (224, 224)\n\ndef get_img_data_parallel(idx, img, total_imgs):\n    if idx % 5000 == 0 or idx == (total_imgs - 1):\n        print('{}: working on img num: {}'.format(threading.current_thread().name,\n                                                  idx))\n    img = cv2.imread(img)\n    img = cv2.resize(img, dsize=IMG_DIMS, \n                     interpolation=cv2.INTER_CUBIC)\n    img = np.array(img, dtype=np.float32)\n    return img\n#读取图像，调整图像大小到指定的尺寸，并将图像数据转换为浮点型数组。函数还会在特定条件下打印当前处理的图像索引和线程名称\n\nex = futures.ThreadPoolExecutor(max_workers=None)\ntrain_data_inp = [(idx, img, len(train_files)) for idx, img in enumerate(train_files)]\nval_data_inp = [(idx, img, len(val_files)) for idx, img in enumerate(val_files)]\ntest_data_inp = [(idx, img, len(test_files)) for idx, img in enumerate(test_files)]\n#这是一个线程池执行器，用于管理多个线程并发执行任务\n\nprint('Loading Train Images:')\ntrain_data_map = ex.map(get_img_data_parallel, \n                        [record[0] for record in train_data_inp],\n                        [record[1] for record in train_data_inp],\n                        [record[2] for record in train_data_inp])\ntrain_data = np.array(list(train_data_map))\n\nprint('\\nLoading Validation Images:')\nval_data_map = ex.map(get_img_data_parallel, \n                        [record[0] for record in val_data_inp],\n                        [record[1] for record in val_data_inp],\n                        [record[2] for record in val_data_inp])\nval_data = np.array(list(val_data_map))\n\nprint('\\nLoading Test Images:')\ntest_data_map = ex.map(get_img_data_parallel, \n                        [record[0] for record in test_data_inp],\n                        [record[1] for record in test_data_inp],\n                        [record[2] for record in test_data_inp])\ntest_data = np.array(list(test_data_map)\n\ntrain_data.shape, val_data.shape, test_data.shape  \n#对于训练集、验证集和测试集，分别使用了 `ex.map` 来并发地处理所有图像","metadata":{"papermill":{"duration":223.672182,"end_time":"2022-03-15T11:56:44.936788","exception":false,"start_time":"2022-03-15T11:53:01.264606","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:00:00.897149Z","iopub.execute_input":"2024-06-21T12:00:00.897483Z","iopub.status.idle":"2024-06-21T12:00:59.488167Z","shell.execute_reply.started":"2024-06-21T12:00:00.897457Z","shell.execute_reply":"2024-06-21T12:00:59.487086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"查看一些示例图像# Viewing some sample images\n","metadata":{"papermill":{"duration":0.039082,"end_time":"2022-03-15T11:56:45.01562","exception":false,"start_time":"2022-03-15T11:56:44.976538","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用Matplotlib库来创建一个图形窗口，显示16张从训练数据集中随机选择的图片及其对应的标签\nplt.figure(1 , figsize = (8 , 8))\nn = 0 \nfor i in range(16):\n    n += 1 \n    r = np.random.randint(0 , train_data.shape[0] , 1)\n    plt.subplot(4 , 4 , n)\n    plt.subplots_adjust(hspace = 0.5 , wspace = 0.5)\n    plt.imshow(train_data[r[0]]/255.)\n    plt.title('{}'.format(train_labels[r[0]]))\n    plt.xticks([]) , plt.yticks([])","metadata":{"papermill":{"duration":1.026501,"end_time":"2022-03-15T11:56:46.082054","exception":false,"start_time":"2022-03-15T11:56:45.055553","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:00:59.489775Z","iopub.execute_input":"2024-06-21T12:00:59.490130Z","iopub.status.idle":"2024-06-21T12:01:00.664613Z","shell.execute_reply.started":"2024-06-21T12:00:59.490096Z","shell.execute_reply":"2024-06-21T12:01:00.663682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#准备数据以供神经网络模型使用，使用标签对文本类别进行编码\nBATCH_SIZE = 64\nNUM_CLASSES = 2\nEPOCHS = 20\nINPUT_SHAPE = (224, 224, 3)\n#进行数据定义\ntrain_imgs_scaled = train_data / 255.\nval_imgs_scaled = val_data / 255.\n#进行数据归一化\nle = LabelEncoder()\nle.fit(train_labels)\ntrain_labels_enc = le.transform(train_labels)\nval_labels_enc = le.transform(val_labels)\n#将整数编码的标签转换为独热编码。\ntrain_labels_1hotenc = to_categorical(train_labels_enc, num_classes=3)\nval_labels_1hotenc = to_categorical(val_labels_enc, num_classes=3)\n\nprint(train_labels[:6], train_labels_enc[:6])  \nprint(train_labels[:6], train_labels_1hotenc[:6])","metadata":{"papermill":{"duration":0.240047,"end_time":"2022-03-15T11:56:46.367661","exception":false,"start_time":"2022-03-15T11:56:46.127614","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:00.667770Z","iopub.execute_input":"2024-06-21T12:01:00.668139Z","iopub.status.idle":"2024-06-21T12:01:00.865487Z","shell.execute_reply.started":"2024-06-21T12:01:00.668103Z","shell.execute_reply":"2024-06-21T12:01:00.864462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#缩放测试集并对测试标签进行热编码\ntest_imgs_scaled = test_data / 255.#将测试集中的图像数据归一化到0到1的范围，因为原始图像数据通常是0到255的整数\ntest_imgs_scaled.shape, test_labels.shape\n\nle = LabelEncoder()#将文本标签转换为整数\nle.fit(test_labels)#对测试标签进行拟合\ntest_labels_enc = le.transform(test_labels)#将测试标签转换为整数编码\n\ntest_labels_1hotenc = to_categorical(test_labels_enc, num_classes=3)#将整数编码的测试标签转换为独热编码\n\n\nprint(test_labels[:6], test_labels_enc[:6])\nprint(test_labels[:6], test_labels_1hotenc[:6])","metadata":{"papermill":{"duration":0.136063,"end_time":"2022-03-15T11:56:46.550277","exception":false,"start_time":"2022-03-15T11:56:46.414214","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:00.866632Z","iopub.execute_input":"2024-06-21T12:01:00.866914Z","iopub.status.idle":"2024-06-21T12:01:00.952464Z","shell.execute_reply.started":"2024-06-21T12:01:00.866887Z","shell.execute_reply":"2024-06-21T12:01:00.951216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# VGG16 Model","metadata":{"papermill":{"duration":0.045968,"end_time":"2022-03-15T11:56:46.644521","exception":false,"start_time":"2022-03-15T11:56:46.598553","status":"completed"},"tags":[]}},{"cell_type":"code","source":"vgg16Net = tf.keras.applications.vgg16.VGG16(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nvgg16Net.trainable = False\n# Freeze the layers\nfor layer in vgg16Net.layers:\n    layer.trainable = False\n    \nbase_vgg16 = vgg16Net\nbase_out_vgg16 = base_vgg16.output\npool_out_vgg16 = tf.keras.layers.Flatten()(base_out_vgg16)\nhidden1_vgg16 = tf.keras.layers.Dense(512, activation='relu')(pool_out_vgg16)\ndrop1_vgg16 = tf.keras.layers.Dropout(rate=0.3)(hidden1_vgg16)\nhidden2_vgg16 = tf.keras.layers.Dense(512, activation='relu')(drop1_vgg16)\ndrop2_vgg16 = tf.keras.layers.Dropout(rate=0.3)(hidden2_vgg16)\nout_vgg16 = tf.keras.layers.Dense(3, activation='softmax')(drop2_vgg16)\n\nvgg16_model = tf.keras.Model(inputs=base_vgg16.input, outputs=out_vgg16)\nvgg16_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nvgg16_model.summary()\n\n\n#这段代码定义了一个基于VGG16的卷积神经网络模型，并对模型进行了配置和编译。下面是对代码的详细解释：\n### 加载VGG16模型\n#- `vgg16Net = tf.keras.applications.vgg16.VGG16(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)` 这行代码加载了VGG16模型，但没有包含顶部的全连接层（`include_top=False`）。模型权重来自于ImageNet数据集（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n### 冻结VGG16层\n#- `vgg16Net.trainable = False` 这行代码将整个VGG16模型设置为不可训练，即冻结了所有的层。\n#- `for layer in vgg16Net.layers: layer.trainable = False` 这个循环确保了所有VGG16的层都被设置为不可训练。\n### 构建自定义模型\n#- `base_vgg16 = vgg16Net` 将加载的VGG16模型赋值给 `base_vgg16`。\n#- `base_out_vgg16 = base_vgg16.output` 获取VGG16模型的输出。\n#- `pool_out_vgg16 = tf.keras.layers.Flatten()(base_out_vgg16)` 将VGG16的输出展平，准备连接到全连接层。\n#- `hidden1_vgg16 = tf.keras.layers.Dense(512, activation='relu')(pool_out_vgg16)` 添加第一个全连接层，包含512个神经元，激活函数为ReLU。\n#- `drop1_vgg16 = tf.keras.layers.Dropout(rate=0.3)(hidden1_vgg16)` 添加第一个Dropout层，丢弃率为0.3，用于减少过拟合。\n#- `hidden2_vgg16 = tf.keras.layers.Dense(512, activation='relu')(drop1_vgg16)` 添加第二个全连接层，同样包含512个神经元，激活函数为ReLU。\n#- `drop2_vgg16 = tf.keras.layers.Dropout(rate=0.3)(hidden2_vgg16)` 添加第二个Dropout层，丢弃率同样为0.3。\n#- `out_vgg16 = tf.keras.layers.Dense(3, activation='softmax')(drop2_vgg16)` 添加输出层，包含3个神经元，激活函数为softmax，用于多类别分类。\n### 创建和编译模型\n#- `vgg16_model = tf.keras.Model(inputs=base_vgg16.input, outputs=out_vgg16)` 创建了一个新的Keras模型，输入是VGG16的输入，输出是自定义的输出层。\n#- `vgg16_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])` 编译模型，使用RMSprop优化器，学习率为1e-4，损失函数为多类别交叉熵，评估指标为准确率。\n### 打印模型摘要\n#- `vgg16_model.summary()` 打印模型的结构摘要，包括每一层的名称、输出形状和参数数量。\n### 注意事项\n#- 在这段代码中，输出层的神经元数量设置为3，但如果之前提到的是两个类别，那么输出层应该只有两个神经元。请确保输出层的神经元数量与实际的类别数目相匹配。\n#- 如果VGG16模型是从头开始训练的，而不是使用预训练的权重，那么可能需要解冻一些顶部的卷积层，以便让模型能够学习新的特征。在这种情况下，可以将 `vgg16Net.trainable` 设置为 `True`，并选择性地冻结底部的卷积层。\n### 总结\n##这段代码定义了一个迁移学习模型，该模型使用VGG16作为特征提取器，并添加了自己的全连接层来进行分类。模型被配置为适用于多类别分类任务，并且已经准备好进行训练。","metadata":{"papermill":{"duration":3.304752,"end_time":"2022-03-15T11:56:49.995025","exception":false,"start_time":"2022-03-15T11:56:46.690273","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:00.953763Z","iopub.execute_input":"2024-06-21T12:01:00.954148Z","iopub.status.idle":"2024-06-21T12:01:01.285389Z","shell.execute_reply.started":"2024-06-21T12:01:00.954111Z","shell.execute_reply":"2024-06-21T12:01:01.284500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_start = time.time()\nvgg16_history = vgg16_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nvgg16_stop = time.time()\n\n\n#这段代码展示了如何使用训练数据对VGG16模型进行训练，并记录训练开始和结束的时间。下面是对代码的详细解释：\n### 记录训练开始时间\n#- `vgg16_start = time.time()` 这行代码记录了训练开始的当前时间，单位是秒。\n### 训练VGG16模型\n#- `vgg16_history = vgg16_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=(val_imgs_scaled, val_labels_1hotenc), verbose=1)` 这行代码使用训练数据对VGG16模型进行训练。`x=train_imgs_scaled` 是输入数据，`y=train_labels_1hotenc` 是标签数据，`batch_size=BATCH_SIZE` 指定了每批次的样本数量，`epochs=EPOCHS` 指定了训练的轮数，`validation_data=(val_imgs_scaled, val_labels_1hotenc)` 提供了验证数据，`verbose=1` 表示在训练过程中显示进度条。\n### 记录训练结束时间\n#- `vgg16_stop = time.time()` 这行代码记录了训练结束的当前时间，单位是秒。\n### 计算训练时间\n#- 为了计算训练所花费的总时间，你需要将 `vgg16_stop` 减去 `vgg16_start`。例如：`training_time = vgg16_stop - vgg16_start`。这将给出训练过程的持续时间，单位是秒。\n### 总结\n#这段代码执行了VGG16模型的训练，并记录了训练的起始和结束时间。训练历史（`vgg16_history`）包含了训练过程中的性能指标，如损失值和准确率，这些指标可以在后续分析中用来评估模型的性能和调整训练参数。通过计算训练时间，可以了解训练过程的效率，这对于调整训练策略和资源分配是有帮助的。","metadata":{"papermill":{"duration":59.903155,"end_time":"2022-03-15T11:57:49.948705","exception":false,"start_time":"2022-03-15T11:56:50.04555","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:01.286662Z","iopub.execute_input":"2024-06-21T12:01:01.286957Z","iopub.status.idle":"2024-06-21T12:01:52.605266Z","shell.execute_reply.started":"2024-06-21T12:01:01.286931Z","shell.execute_reply":"2024-06-21T12:01:52.604200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## VGG16 Summary","metadata":{"papermill":{"duration":0.147868,"end_time":"2022-03-15T11:57:50.244726","exception":false,"start_time":"2022-03-15T11:57:50.096858","status":"completed"},"tags":[]}},{"cell_type":"code","source":"vgg16_trainTime=vgg16_stop-vgg16_start\nvgg16_model_accuracy = vgg16_history.history['accuracy'][np.argmin(vgg16_history.history['loss'])]\nvgg16_model_score=vgg16_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nvgg16_Summary = PrettyTable([\"VGG16\",\" \"])\nvgg16_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(vgg16_model_accuracy*100)])\nvgg16_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(vgg16_model_score[1]*100)])\nvgg16_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(vgg16_model_score[0]*100)])\nvgg16_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(vgg16_trainTime)])\nprint(vgg16_Summary)\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('VGG16 Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(vgg16_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\nax1.plot(epoch_list, vgg16_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, vgg16_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, vgg16_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, vgg16_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n#您的代码片段主要完成了以下几个任务：\n\n1. 计算VGG16模型训练所需的时间。\n2. 从训练历史中获取模型在损失最小的那一次迭代时的准确性。\n3. 使用测试数据集评估模型的性能，包括准确性和损失。\n4. 使用PrettyTable创建一个表格来展示模型的性能指标。\n5. 使用Matplotlib绘制训练和验证过程中的准确性和损失曲线图。\n\n#以下是对代码的逐行解释：\n#vgg16_trainTime = vgg16_stop - vgg16_start # 计算训练时间\n#vgg16_model_accuracy = vgg16_history.history['accuracy'][np.argmin(vgg16_history.history['loss'])] # 获取损失最小时的准确性\n#vgg16_model_score = vgg16_model.evaluate(test_imgs_scaled, test_labels_1hotenc) # 使用测试数据集评估模型\n#vgg16_Summary = PrettyTable([\"VGG16\", \"\"]) # 创建一个表格来展示模型的性能指标\n#vgg16_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(vgg16_model_accuracy * 100)]) # 添加模型准确性到表格\n#vgg16_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(vgg16_model_score[1] * 100)]) # 添加测试准确性到表格\n#vgg16_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(vgg16_model_score[0] * 100)]) # 添加测试损失到表格\n#vgg16_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(vgg16_trainTime)]) # 添加训练时间到表格\n#print(vgg16_Summary) # 打印表格\n#f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4)) # 创建一个图形和两个子图\n#t = f.suptitle('VGG16 Perfomance', fontsize=12) # 设置图形标题\n#f.subplots_adjust(top=0.85, wspace=0.3) # 调整子图之间的间距\n#max_epoch = len(vgg16_history.history['accuracy']) + 1 # 计算最大迭代次数\n#epoch_list = list(range(1, max_epoch)) # 创建一个迭代次数列表\n#ax1.plot(epoch_list, vgg16_history.history['accuracy'], label='Train Accuracy') # 绘制训练准确性曲线\n#ax1.plot(epoch_list, vgg16_history.history['val_accuracy'], label='Validation Accuracy') # 绘制验证准确性曲线\n#ax1.set_xticks(np.arange(1, max_epoch, 5)) # 设置X轴刻度\n#ax1.set_ylabel('Accuracy Value') # 设置Y轴标签\n#ax1.set_xlabel('Epoch') # 设置X轴标签\n#ax1.set_title('Accuracy') # 设置子图标题\n#l1 = ax1.legend(loc=\"best\") # 添加图例\n#ax2.plot(epoch_list, vgg16_history.history['loss'], label='Train Loss') # 绘制训练损失曲线\n#ax2.plot(epoch_list, vgg16_history.history['val_loss'], label='Validation Loss') # 绘制验证损失曲线\n#ax2.set_xticks(np.arange(1, max_epoch, 5)) # 设置X轴刻度\n#ax2.set_ylabel('Loss Value') # 设置Y轴标签\n#ax2.set_xlabel('Epoch') # 设置X轴标签\n#ax2.set_title('Loss') # 设置子图标题\n#l2 = ax2.legend(loc=\"best\") # 添加图例\n#在这段代码中，`vgg16_history.history['accuracy']` 和 `vgg16_history.history['loss']` 分别代表了训练过程中的准确性和损失值的历史记录。`np.argmin(vgg16_history.history['loss'])` 用于找到损失值最小的那个迭代，因为通常模型在损失值最小的时候达到最佳状态。`vgg16_model.evaluate(test_imgs_scaled, test_labels_1hotenc)` 方法用于评估模型在测试数据集上的表现，返回的是测试集的损失和准确性。\n#最后，`plt.subplots` 和 `plt.plot` 方法用于绘制训练和验证过程中的准确性和损失曲线图，这些图表可以帮助我们直观地看到模型在训练过程中的表现和收敛情况。","metadata":{"papermill":{"duration":7.474749,"end_time":"2022-03-15T11:57:57.866271","exception":false,"start_time":"2022-03-15T11:57:50.391522","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:52.606555Z","iopub.execute_input":"2024-06-21T12:01:52.606864Z","iopub.status.idle":"2024-06-21T12:01:55.553327Z","shell.execute_reply.started":"2024-06-21T12:01:52.606837Z","shell.execute_reply":"2024-06-21T12:01:55.552379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **VGG19**","metadata":{"papermill":{"duration":0.153741,"end_time":"2022-03-15T11:57:58.174583","exception":false,"start_time":"2022-03-15T11:57:58.020842","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用VGG19预训练模型\nvgg19Net = tf.keras.applications.vgg19.VGG19(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nvgg19Net.trainable = False\n#冻结图层\nfor layer in vgg16Net.layers:\n    layer.trainable = False\n    \nbase_vgg19 = vgg16Net\nbase_out_vgg19= base_vgg19.output\npool_out_vgg19 = tf.keras.layers.Flatten()(base_out_vgg19)\nhidden1_vgg19 = tf.keras.layers.Dense(512, activation='relu')(pool_out_vgg19)\ndrop1_vgg19 = tf.keras.layers.Dropout(rate=0.3)(hidden1_vgg19)\nhidden2_vgg19 = tf.keras.layers.Dense(512, activation='relu')(drop1_vgg19)\ndrop2_vgg19 = tf.keras.layers.Dropout(rate=0.3)(hidden2_vgg19)\nout_vgg19 = tf.keras.layers.Dense(3, activation='softmax')(drop2_vgg19)\n\nvgg19_model = tf.keras.Model(inputs=base_vgg19.input, outputs=out_vgg19)\nvgg19_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nvgg19_model.summary()\n\n\n#这段代码定义了一个基于VGG19的卷积神经网络模型，并对模型进行了配置和编译。下面是对代码的详细解释：\n### 加载VGG19模型\n#- `vgg19Net = tf.keras.applications.vgg19.VGG19(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)` 这行代码加载了VGG19模型，但没有包含顶部的全连接层（`include_top=False`）。模型权重来自于ImageNet数据集（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n### 冻结VGG19层\n#- `vgg19Net.trainable = False` 这行代码将整个VGG19模型设置为不可训练，即冻结了所有的层。\n#- `for layer in vgg16Net.layers: layer.trainable = False` 这个循环试图冻结VGG16模型的层，但实际上应该冻结VGG19模型的层。因此，这里的变量名 `vgg16Net` 应该是 `vgg19Net`。\n### 构建自定义模型\n#- `base_vgg19 = vgg16Net` 将加载的VGG16模型赋值给 `base_vgg19`，但这里应该是VGG19模型，所以应该是 `base_vgg19 = vgg19Net`。\n#- `base_out_vgg19 = base_vgg19.output` 获取VGG19模型的输出。\n#- `pool_out_vgg19 = tf.keras.layers.Flatten()(base_out_vgg19)` 将VGG19的输出展平，准备连接到全连接层。\n#- `hidden1_vgg19 = tf.keras.layers.Dense(512, activation='relu')(pool_out_vgg19)` 添加第一个全连接层，包含512个神经元，激活函数为ReLU。\n#- `drop1_vgg19 = tf.keras.layers.Dropout(rate=0.3)(hidden1_vgg19)` 添加第一个Dropout层，丢弃率为0.3，用于减少过拟合。\n#- `hidden2_vgg19 = tf.keras.layers.Dense(512, activation='relu')(drop1_vgg19)` 添加第二个全连接层，同样包含512个神经元，激活函数为ReLU。\n#- `drop2_vgg19 = tf.keras.layers.Dropout(rate=0.3)(hidden2_vgg19)` 添加第二个Dropout层，丢弃率同样为0.3。\n#- `out_vgg19 = tf.keras.layers.Dense(3, activation='softmax')(drop2_vgg19)` 添加输出层，包含3个神经元，激活函数为softmax，用于多类别分类。\n### 创建和编译模型\n#- `vgg19_model = tf.keras.Model(inputs=base_vgg19.input, outputs=out_vgg19)` 创建了一个新的Keras模型，输入是VGG19的输入，输出是自定义的输出层。\n#- `vgg19_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])` 编译模型，使用RMSprop优化器，学习率为1e-4，损失函数为多类别交叉熵，评估指标为准确率。\n### 打印模型摘要\n#- `vgg19_model.summary()` 打印模型的结构摘要，包括每一层的名称、输出形状和参数数量。\n### 注意事项\n#- 在这段代码中，有几个地方的变量名和操作对象不匹配，比如 `vgg16Net` 应该是 `vgg19Net`，`base_vgg19` 应该指向 `vgg19Net` 而不是 `vgg16Net`。\n#- 如果VGG19模型是从头开始训练的，而不是使用预训练的权重，那么可能需要解冻一些顶部的卷","metadata":{"papermill":{"duration":1.340985,"end_time":"2022-03-15T11:57:59.668275","exception":false,"start_time":"2022-03-15T11:57:58.32729","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:55.554607Z","iopub.execute_input":"2024-06-21T12:01:55.554900Z","iopub.status.idle":"2024-06-21T12:01:55.951392Z","shell.execute_reply.started":"2024-06-21T12:01:55.554874Z","shell.execute_reply":"2024-06-21T12:01:55.950498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg19_start = time.time()\nvgg19_history = vgg19_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nvgg19_stop = time.time()\n\n#这段代码展示了如何使用训练数据对VGG19模型进行训练，并记录训练开始和结束的时间。下面是对代码的详细解释：\n### 记录训练开始时间\n#- `vgg19_start = time.time()` 这行代码记录了训练开始的当前时间，单位是秒。\n### 训练VGG19模型\n#- `vgg19_history = vgg19_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=(val_imgs_scaled, val_labels_1hotenc), verbose=1)` 这行代码使用训练数据对VGG19模型进行训练。`x=train_imgs_scaled` 是输入数据，`y=train_labels_1hotenc` 是标签数据，`batch_size=BATCH_SIZE` 指定了每批次的样本数量，`epochs=EPOCHS` 指定了训练的轮数，`validation_data=(val_imgs_scaled, val_labels_1hotenc)` 提供了验证数据，`verbose=1` 表示在训练过程中显示进度条。\n### 记录训练结束时间\n#- `vgg19_stop = time.time()` 这行代码记录了训练结束的当前时间，单位是秒。\n### 计算训练时间\n#- 为了计算训练所花费的总时间，你需要将 `vgg19_stop` 减去 `vgg19_start`。例如：`training_time = vgg19_stop - vgg19_start`。这将给出训练过程的持续时间，单位是秒。\n### 总结\n#这段代码执行了VGG19模型的训练，并记录了训练的起始和结束时间。训练历史（`vgg19_history`）包含了训练过程中的性能指标，如损失值和准确率，这些指标可以在后续分析中用来评估模型的性能和调整训练参数。通过计算训练时间，可以了解训练过程的效率，这对于调整训练策略和资源分配是有帮助的。","metadata":{"papermill":{"duration":43.472684,"end_time":"2022-03-15T11:58:43.302101","exception":false,"start_time":"2022-03-15T11:57:59.829417","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:01:55.952530Z","iopub.execute_input":"2024-06-21T12:01:55.952820Z","iopub.status.idle":"2024-06-21T12:02:47.294004Z","shell.execute_reply.started":"2024-06-21T12:01:55.952794Z","shell.execute_reply":"2024-06-21T12:02:47.293104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## VGG19 Summary","metadata":{"papermill":{"duration":0.257609,"end_time":"2022-03-15T11:58:43.817419","exception":false,"start_time":"2022-03-15T11:58:43.55981","status":"completed"},"tags":[]}},{"cell_type":"code","source":"vgg19_trainTime=vgg19_stop-vgg19_start\nvgg19_model_accuracy = vgg19_history.history['accuracy'][np.argmin(vgg19_history.history['loss'])]\nvgg19_model_score=vgg19_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nvgg19_Summary = PrettyTable([\"Vgg19\",\" \"])\nvgg19_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(vgg19_model_accuracy*100)])\nvgg19_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(vgg19_model_score[1]*100)])\nvgg19_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(vgg19_model_score[0]*100)])\nvgg19_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(vgg19_trainTime)])\nprint(vgg19_Summary)\n\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('VGG19 Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(vgg19_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\nax1.plot(epoch_list, vgg19_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, vgg19_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, vgg19_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, vgg19_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n\n#您的代码片段已经包含了使用VGG19模型进行训练的关键步骤，并且还计算了模型的训练时间、准确率和测试损失。此外，您还使用了matplotlib库来绘制训练和验证过程中的准确性和损失曲线图。\n#以下是对您代码的简要说明：\n#- `vgg19_trainTime = vgg19_stop - vgg19_start` 这行代码计算了模型训练所需的时间。\n#- `vgg19_model_accuracy = vgg19_history.history['accuracy'][np.argmin(vgg19_history.history['loss'])]` 这行代码找到了训练过程中损失最小的点，并获取了那个点对应的准确率作为模型的最终准确率。\n#- `vgg19_model_score = vgg19_model.evaluate(test_imgs_scaled, test_labels_1hotenc)` 这行代码使用测试数据集评估了模型的性能，并返回了测试集的准确率和损失。\n#- `vgg19_Summary` 是一个漂亮表格，用于展示模型的性能指标。\n#- `plt.subplots(1, 2, figsize=(12, 4))` 这行代码创建了一个包含两个子图的图形，用于分别绘制训练和验证的准确性和损失曲线。\n#- `ax1.plot(epoch_list, vgg19_history.history['accuracy'], label='Train Accuracy')` 和 `ax2.plot(epoch_list, vgg19_history.history['loss'], label='Train Loss')` 这两行代码分别绘制了训练过程中的准确性和损失曲线。\n#- `ax1.plot(epoch_list, vgg19_history.history['val_accuracy'], label='Validation Accuracy')` 和 `ax2.plot(epoch_list, vgg19_history.history['val_loss'], label='Validation Loss')` 这两行代码分别绘制了验证过程中的准确性和损失曲线。\n#最后，您使用 `print(vgg19_Summary)` 打印出了模型的性能总结，并用matplotlib绘制了训练和验证的曲线图。这些图表可以帮助您直观地了解模型在训练和验证过程中的表现。","metadata":{"papermill":{"duration":2.008864,"end_time":"2022-03-15T11:58:46.092156","exception":false,"start_time":"2022-03-15T11:58:44.083292","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:02:47.296514Z","iopub.execute_input":"2024-06-21T12:02:47.296808Z","iopub.status.idle":"2024-06-21T12:02:50.255302Z","shell.execute_reply.started":"2024-06-21T12:02:47.296781Z","shell.execute_reply":"2024-06-21T12:02:50.254187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Xception","metadata":{"papermill":{"duration":0.263947,"end_time":"2022-03-15T11:58:46.618293","exception":false,"start_time":"2022-03-15T11:58:46.354346","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用Xception训练的模型\nXception = tf.keras.applications.Xception(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nXception.trainable = False\n#冻结图层\nfor layer in Xception.layers:\n    layer.trainable = False\n    \nbase_Xception = Xception\nbase_out_Xception = base_Xception.output\npool_out_Xception = tf.keras.layers.Flatten()(base_out_Xception)\nhidden1_Xception = tf.keras.layers.Dense(512, activation='relu')(pool_out_Xception)\ndrop1_Xception = tf.keras.layers.Dropout(rate=0.3)(hidden1_Xception)\nhidden2_Xception = tf.keras.layers.Dense(512, activation='relu')(drop1_Xception)\ndrop2_Xception = tf.keras.layers.Dropout(rate=0.3)(hidden2_Xception)\nout_Xception = tf.keras.layers.Dense(3, activation='softmax')(drop2_Xception)\n\nXception_model = tf.keras.Model(inputs=base_Xception.input, outputs=out_Xception)\nXception_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nXception.summary()\n\n\n#这段代码定义了一个基于Xception的卷积神经网络模型，并对模型进行了配置和编译。下面是对代码的详细解释：\n\n### 加载Xception模型\n#- `Xception = tf.keras.applications.Xception(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)` 这行代码加载了Xception模型，但没有包含顶部的全连接层（`include_top=False`）。模型权重来自于ImageNet数据集（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n### 冻结Xception层\n#- `Xception.trainable = False` 这行代码将整个Xception模型设置为不可训练，即冻结了所有的层。\n#- `for layer in Xception.layers: layer.trainable = False` 这个循环冻结了Xception模型的所有层。\n### 构建自定义模型\n#- `base_Xception = Xception` 将加载的Xception模型赋值给 `base_Xception`。\n#- `base_out_Xception = base_Xception.output` 获取Xception模型的输出。\n#- `pool_out_Xception = tf.keras.layers.Flatten()(base_out_Xception)` 将Xception的输出展平，准备连接到全连接层。\n#- `hidden1_Xception = tf.keras.layers.Dense(512, activation='relu')(pool_out_Xception)` 添加第一个全连接层，包含512个神经元，激活函数为ReLU。\n#- `drop1_Xception = tf.keras.layers.Dropout(rate=0.3)(hidden1_Xception)` 添加第一个Dropout层，丢弃率为0.3，用于减少过拟合。\n#- `hidden2_Xception = tf.keras.layers.Dense(512, activation='relu')(drop1_Xception)` 添加第二个全连接层，同样包含512个神经元，激活函数为ReLU。\n#- `drop2_Xception = tf.keras.layers.Dropout(rate=0.3)(hidden2_Xception)` 添加第二个Dropout层，丢弃率同样为0.3。\n#- `out_Xception = tf.keras.layers.Dense(3, activation='softmax')(drop2_Xception)` 添加输出层，包含3个神经元，激活函数为softmax，用于多类别分类。\n### 创建和编译模型\n#- `Xception_model = tf.keras.Model(inputs=base_Xception.input, outputs=out_Xception)` 创建了一个新的Keras模型，输入是Xception的输入，输出是自定义的输出层。\n#- `Xception_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])` 编译模型，使用RMSprop优化器，学习率为1e-4，损失函数为多类别交叉熵，评估指标为准确率。\n### 打印模型摘要\n#- `Xception.summary()` 打印模型的结构摘要，包括每一层的名称、输出形状和参数数量。注意这里应该是 `Xception_model.summary()`，因为我们需要打印的是我们刚刚创建的模型的摘要，而不是原始的Xception模型。\n### 注意事项\n#- 在这段代码中，`Xception.summary()` 应该是 `Xception_model.summary()`，以打印新创建的模型的摘要。\n#- 如果Xception模型是从头开始训练的，而不是使用预训练的权重，那么可能需要解冻一些顶部的卷积层，以便它们可以在特定任务的数据上进行微调。\n#接下来，您可以使用类似之前VGG16和VGG19模型的代码来训练这个Xception模型，并评估其性能。","metadata":{"papermill":{"duration":1.842791,"end_time":"2022-03-15T11:58:48.724419","exception":false,"start_time":"2022-03-15T11:58:46.881628","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:02:50.258836Z","iopub.execute_input":"2024-06-21T12:02:50.259163Z","iopub.status.idle":"2024-06-21T12:02:51.420458Z","shell.execute_reply.started":"2024-06-21T12:02:50.259135Z","shell.execute_reply":"2024-06-21T12:02:51.419567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Xception_start = time.time()\nXception_history = Xception_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nXception_stop = time.time()\n\n\n\n#这段代码展示了如何使用训练数据对Xception模型进行训练，并记录训练开始和结束的时间。下面是对代码的详细解释：\n### 记录训练开始时间\n#- `Xception_start = time.time()` 这行代码记录了训练开始的当前时间，单位是秒。\n### 训练Xception模型\n#- `Xception_history = Xception_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=(val_imgs_scaled, val_labels_1hotenc), verbose=1)` 这行代码使用训练数据对Xception模型进行训练。`x=train_imgs_scaled` 是输入数据，`y=train_labels_1hotenc` 是标签数据，`batch_size=BATCH_SIZE` 指定了每批次的样本数量，`epochs=EPOCHS` 指定了训练的轮数，`validation_data=(val_imgs_scaled, val_labels_1hotenc)` 提供了验证数据，`verbose=1` 表示在训练过程中显示进度条。\n### 记录训练结束时间\n#- `Xception_stop = time.time()` 这行代码记录了训练结束的当前时间，单位是秒。\n### 计算训练时间\n#- 为了计算训练所花费的总时间，你需要将 `Xception_stop` 减去 `Xception_start`。例如：`training_time = Xception_stop - Xception_start`。这将给出训练过程的持续时间，单位是秒。\n### 总结\n#这段代码执行了Xception模型的训练，并记录了训练的起始和结束时间。训练历史（`Xception_history`）包含了训练过程中的性能指标，如损失值和准确率，这些指标可以在后续分析中用来评估模型的性能和调整训练参数。通过计算训练时间，可以了解训练过程的效率，这对于调整训练策略和资源分配是有帮助的。","metadata":{"papermill":{"duration":58.806934,"end_time":"2022-03-15T11:59:47.844128","exception":false,"start_time":"2022-03-15T11:58:49.037194","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:02:51.421584Z","iopub.execute_input":"2024-06-21T12:02:51.421847Z","iopub.status.idle":"2024-06-21T12:03:57.658615Z","shell.execute_reply.started":"2024-06-21T12:02:51.421823Z","shell.execute_reply":"2024-06-21T12:03:57.657646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Xception Summary","metadata":{"papermill":{"duration":0.36104,"end_time":"2022-03-15T11:59:48.57103","exception":false,"start_time":"2022-03-15T11:59:48.20999","status":"completed"},"tags":[]}},{"cell_type":"code","source":"Xception_trainTime=Xception_stop-Xception_start\nXception_model_accuracy = Xception_history.history['accuracy'][np.argmin(Xception_history.history['loss'])]\nXception_model_score=Xception_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nXception_Summary = PrettyTable([\"Xception\",\" \"])\nXception_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(Xception_model_accuracy*100)])\nXception_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(Xception_model_score[1]*100)])\nXception_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(Xception_model_score[0]*100)])\nXception_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(Xception_trainTime)])\nprint(Xception_Summary)\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('Xception  Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(Xception_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\nax1.plot(epoch_list, Xception_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, Xception_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, Xception_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, Xception_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n#您的代码片段展示了如何使用Xception模型进行训练，并记录了训练的起始和结束时间。此外，它还计算了模型的训练时间、准确率和测试损失，并使用PrettyTable库创建了一个漂亮的表格来展示这些性能指标。最后，它使用matplotlib库绘制了训练和验证过程中的准确性和损失曲线图。\n#以下是对您代码的简要说明：\n#- `Xception_trainTime = Xception_stop - Xception_start` 这行代码计算了模型训练所需的时间。\n#- `Xception_model_accuracy = Xception_history.history['accuracy'][np.argmin(Xception_history.history['loss'])]` 这行代码找到了训练过程中损失最小的点，并获取了那个点对应的准确率作为模型的最终准确率。\n#- `Xception_model_score = Xception_model.evaluate(test_imgs_scaled, test_labels_1hotenc)` 这行代码使用测试数据集评估了模型的性能，并返回了测试集的准确率和损失。\n#- `Xception_Summary` 是一个漂亮表格，用于展示模型的性能指标。\n#- `plt.subplots(1, 2, figsize=(12, 4))` 这行代码创建了一个包含两个子图的图形，用于分别绘制训练和验证的准确性和损失曲线。\n#- `ax1.plot(epoch_list, Xception_history.history['accuracy'], label='Train Accuracy')` 和 `ax2.plot(epoch_list, Xception_history.history['loss'], label='Train Loss')` 这两行代码分别绘制了训练过程中的准确性和损失曲线。\n#- `ax1.plot(epoch_list, Xception_history.history['val_accuracy'], label='Validation Accuracy')` 和 `ax2.plot(epoch_list, Xception_history.history['val_loss'], label='Validation Loss')` 这两行代码分别绘制了验证过程中的准确性和损失曲线。\n#最后，您使用 `print(Xception_Summary)` 打印出了模型的性能总结，并用matplotlib绘制了训练和验证的曲线图。这些图表可以帮助您直观地了解模型在训练和验证过程中的表现。","metadata":{"papermill":{"duration":2.831622,"end_time":"2022-03-15T11:59:51.767438","exception":false,"start_time":"2022-03-15T11:59:48.935816","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:03:57.659928Z","iopub.execute_input":"2024-06-21T12:03:57.662781Z","iopub.status.idle":"2024-06-21T12:04:02.807005Z","shell.execute_reply.started":"2024-06-21T12:03:57.662736Z","shell.execute_reply":"2024-06-21T12:04:02.805917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ResNet ","metadata":{"papermill":{"duration":0.375382,"end_time":"2022-03-15T11:59:52.520271","exception":false,"start_time":"2022-03-15T11:59:52.144889","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用ResNet训练的模型\nResNet = tf.keras.applications.ResNet50(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nResNet.trainable = False\n#冻结图层\nfor layer in ResNet.layers:\n    layer.trainable = False\n    \nbase_ResNet = ResNet\nbase_out_ResNet = base_ResNet.output\npool_out_ResNet = tf.keras.layers.Flatten()(base_out_ResNet)\nhidden1_ResNet = tf.keras.layers.Dense(512, activation='relu')(pool_out_ResNet)\ndrop1_ResNet = tf.keras.layers.Dropout(rate=0.3)(hidden1_ResNet)\nhidden2_ResNet = tf.keras.layers.Dense(512, activation='relu')(drop1_ResNet)\ndrop2_ResNet = tf.keras.layers.Dropout(rate=0.3)(hidden2_ResNet)\nout_ResNet = tf.keras.layers.Dense(3, activation='softmax')(drop2_ResNet)\n\nResNet_model = tf.keras.Model(inputs=base_ResNet.input, outputs=out_ResNet)\nResNet_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nResNet.summary()\n\n\n#这段代码定义了一个基于ResNet50的卷积神经网络模型，并对模型进行了配置和编译。下面是对代码的详细解释：\n### 加载ResNet50模型\n#- `ResNet = tf.keras.applications.ResNet50(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)` 这行代码加载了ResNet50模型，但没有包含顶部的全连接层（`include_top=False`）。模型权重来自于ImageNet数据集（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n### 冻结ResNet层\n#- `ResNet.trainable = False` 这行代码将整个ResNet模型设置为不可训练，即冻结了所有的层。\n#- `for layer in ResNet.layers: layer.trainable = False` 这个循环冻结了ResNet模型的所有层。\n### 构建自定义模型\n#- `base_ResNet = ResNet` 将加载的ResNet模型赋值给 `base_ResNet`。\n#- `base_out_ResNet = base_ResNet.output` 获取ResNet模型的输出。\n#- `pool_out_ResNet = tf.keras.layers.Flatten()(base_out_ResNet)` 将ResNet的输出展平，准备连接到全连接层。\n#- `hidden1_ResNet = tf.keras.layers.Dense(512, activation='relu')(pool_out_ResNet)` 添加第一个全连接层，包含512个神经元，激活函数为ReLU。\n#- `drop1_ResNet = tf.keras.layers.Dropout(rate=0.3)(hidden1_ResNet)` 添加第一个Dropout层，丢弃率为0.3，用于减少过拟合。\n#- `hidden2_ResNet = tf.keras.layers.Dense(512, activation='relu')(drop1_ResNet)` 添加第二个全连接层，同样包含512个神经元，激活函数为ReLU。\n#- `drop2_ResNet = tf.keras.layers.Dropout(rate=0.3)(hidden2_ResNet)` 添加第二个Dropout层，丢弃率同样为0.3。\n#- `out_ResNet = tf.keras.layers.Dense(3, activation='softmax')(drop2_ResNet)` 添加输出层，包含3个神经元，激活函数为softmax，用于多类别分类。\n### 创建和编译模型\n#- `ResNet_model = tf.keras.Model(inputs=base_ResNet.input, outputs=out_ResNet)` 创建了一个新的Keras模型，输入是ResNet的输入，输出是自定义的输出层。\n#- `ResNet_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])` 编译模型，使用RMSprop优化器，学习率为1e-4，损失函数为多类别交叉熵，评估指标为准确率。\n### 打印模型摘要\n#- `ResNet.summary()` 打印模型的结构摘要，包括每一层的名称、输出形状和参数数量。注意这里应该是 `ResNet_model.summary()`，因为我们需要打印的是我们刚刚创建的模型的摘要，而不是原始的ResNet模型。\n### 注意事项\n#- 在这段代码中，`ResNet.summary()` 应该是 `ResNet_model.summary()`，以打印新创建的模型的摘要。\n#- 如果ResNet模型是从头开始训练的，而不是使用预训练的权重，那么可能需要解冻一些顶部的卷积层，以便它们可以在特定任务的数据上进行微调。\n#接下来，您可以使用类似之前VGG16、VGG19和Xception模型的代码来训练这个ResNet模型，并评估其性能。","metadata":{"papermill":{"duration":2.649153,"end_time":"2022-03-15T11:59:55.558121","exception":false,"start_time":"2022-03-15T11:59:52.908968","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:04:02.808426Z","iopub.execute_input":"2024-06-21T12:04:02.808794Z","iopub.status.idle":"2024-06-21T12:04:04.774951Z","shell.execute_reply.started":"2024-06-21T12:04:02.808763Z","shell.execute_reply":"2024-06-21T12:04:04.774074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ResNet_start = time.time()\nResNet_history = ResNet_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nResNet_stop = time.time()\n\n#这段代码展示了如何使用训练数据对ResNet模型进行训练，并记录训练开始和结束的时间。下面是对代码的详细解释：\n### 记录训练开始时间\n#- `ResNet_start = time.time()` 这行代码记录了训练开始的当前时间，单位是秒。\n### 训练ResNet模型\n#- `ResNet_history = ResNet_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=(val_imgs_scaled, val_labels_1hotenc), verbose=1)` 这行代码使用训练数据对ResNet模型进行训练。`x=train_imgs_scaled` 是输入数据，`y=train_labels_1hotenc` 是标签数据，`batch_size=BATCH_SIZE` 指定了每批次的样本数量，`epochs=EPOCHS` 指定了训练的轮数，`validation_data=(val_imgs_scaled, val_labels_1hotenc)` 提供了验证数据，`verbose=1` 表示在训练过程中显示进度条。\n### 记录训练结束时间\n#- `ResNet_stop = time.time()` 这行代码记录了训练结束的当前时间，单位是秒。\n### 计算训练时间\n#- 为了计算训练所花费的总时间，你需要将 `ResNet_stop` 减去 `ResNet_start`。例如：`training_time = ResNet_stop - ResNet_start`。这将给出训练过程的持续时间，单位是秒。\n### 总结\n#这段代码执行了ResNet模型的训练，并记录了训练的起始和结束时间。训练历史（`ResNet_history`）包含了训练过程中的性能指标，如损失值和准确率，这些指标可以在后续分析中用来评估模型的性能和调整训练参数。通过计算训练时间，可以了解训练过程的效率，这对于调整训练策略和资源分配是有帮助的。\n#接下来，您可以使用类似之前模型的代码来计算训练时间、准确率和测试损失，并绘制训练和验证的性能曲线。","metadata":{"papermill":{"duration":44.909437,"end_time":"2022-03-15T12:00:41.080389","exception":false,"start_time":"2022-03-15T11:59:56.170952","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:04:04.775999Z","iopub.execute_input":"2024-06-21T12:04:04.776327Z","iopub.status.idle":"2024-06-21T12:04:59.523989Z","shell.execute_reply.started":"2024-06-21T12:04:04.776300Z","shell.execute_reply":"2024-06-21T12:04:59.523002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ResNet Summary","metadata":{"papermill":{"duration":0.527083,"end_time":"2022-03-15T12:00:42.081546","exception":false,"start_time":"2022-03-15T12:00:41.554463","status":"completed"},"tags":[]}},{"cell_type":"code","source":"ResNet_trainTime=ResNet_stop-ResNet_start\nResNet_model_accuracy = ResNet_history.history['accuracy'][np.argmin(ResNet_history.history['loss'])]\nResNet_model_score=ResNet_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nResNet_Summary = PrettyTable([\"ResNet\",\" \"])\nResNet_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(ResNet_model_accuracy*100)])\nResNet_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(ResNet_model_score[1]*100)])\nResNet_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(ResNet_model_score[0]*100)])\nResNet_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(ResNet_trainTime)])\nprint(ResNet_Summary)\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('ResNet  Transfer Learning Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(ResNet_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\nax1.plot(epoch_list, ResNet_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, ResNet_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, ResNet_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, ResNet_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n\n#这段代码是在使用TensorFlow库中的ResNet50模型进行迁移学习的过程中，对模型进行训练、评估并记录相关性能指标的代码。下面是对代码的详细解释：\n### 计算训练时间\n#- `ResNet_start = time.time()` 这行代码记录了训练开始的当前时间。\n#- `ResNet_stop = time.time()` 这行代码记录了训练结束的当前时间。\n#- `ResNet_trainTime = ResNet_stop - ResNet_start` 这行代码计算了训练所花费的总时间。\n### 模型评估\n#- `ResNet_model_accuracy = ResNet_history.history['accuracy'][np.argmin(ResNet_history.history['loss'])]` 这行代码找到了训练过程中损失最小的点，并获取了该点对应的准确性。\n#- `ResNet_model_score = ResNet_model.evaluate(test_imgs_scaled, test_labels_1hotenc)` 这行代码使用测试数据集对模型进行评估，并返回了测试集的损失和准确性。\n### 创建性能总结表\n#- `ResNet_Summary = PrettyTable([\"ResNet\", \"\"])` 这行代码创建了一个漂亮的表格，用于展示模型的性能总结。\n#- `ResNet_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(ResNet_model_accuracy * 100)])` 这行代码向表格中添加了模型的准确率。\n#- `ResNet_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(ResNet_model_score[1] * 100)])` 这行代码向表格中添加了测试集的准确率。\n#- `ResNet_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(ResNet_model_score[0] * 100)])` 这行代码向表格中添加了测试集的损失。\n#- `ResNet_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(ResNet_trainTime)])` 这行代码向表格中添加了训练所花费的时间。\n### 打印性能总结表\n#- `print(ResNet_Summary)` 这行代码打印出了性能总结表。\n### 绘制训练和验证性能曲线\n#- `f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))` 这行代码创建了一个图形窗口和两个子图。\n#- `t = f.suptitle('ResNet Transfer Learning Performance', fontsize=12)` 这行代码为图形窗口添加了标题。\n#- `ax1.plot(epoch_list, ResNet_history.history['accuracy'], label='Train Accuracy')` 这行代码在第一个子图中绘制了训练集的准确率曲线。\n#- `ax1.plot(epoch_list, ResNet_history.history['val_accuracy'], label='Validation Accuracy')` 这行代码在第一个子图中绘制了验证集的准确率曲线。\n#- `ax2.plot(epoch_list, ResNet_history.history['loss'], label='Train Loss')` 这行代码在第二个子图中绘制了训练集的损失曲线。\n#- `ax2.plot(epoch_list, ResNet_history.history['val_loss'], label='Validation Loss')` 这行代码在第二个子图中绘制了验证集的损失曲线。\n### 设置图表属性\n#- `ax1.set_xticks(np.arange(1, max_epoch, 5))` 这行代码设置了x轴的刻度。\n#- `ax1.set_ylabel('Accuracy Value')` 这行代码设置了y轴的标签。\n#- `ax1.set_xlabel('Epoch')` 这行代码设置了x轴的标签。\n#- `ax1.set_title('Accuracy')` 这行代码设置了子图的标题。\n#- `ax2.set_xticks(np.arange(1, max_epoch, 5))` 这行代码设置了x轴的刻度。\n#- `ax2.set_ylabel('Loss Value')` 这行代码设置了y轴的标签。\n#- `ax2.set_xlabel('Epoch')` 这行代码设置了x轴的标签。\n#- `ax2.set_title('Loss')` 这行代码设置了子图的标题。\n### 添加图例\n#- `ax1.legend(loc=\"best\")` 这行代码在第一个子图中添加了图例。\n#- `ax2.legend(loc=\"best\")` 这行代码在第二个子图中添加了图例。\n#这段代码执行了ResNet模型的训练，并记录了训练的起始和结束时间。通过计算训练时间，可以了解训练过程的效率，这对于调整训练策略和资源分配是有帮助的。此外，代码还计算了模型在训练和验证集上的性能，并绘制了相应的性能曲线，以便于分析模型的学习动态和性能表现。最后，代码打印了模型的性能总结表，并显示了图形化的性能曲线，以便于更直观地理解模型的性能。","metadata":{"papermill":{"duration":2.811899,"end_time":"2022-03-15T12:00:45.368136","exception":false,"start_time":"2022-03-15T12:00:42.556237","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:04:59.525226Z","iopub.execute_input":"2024-06-21T12:04:59.525563Z","iopub.status.idle":"2024-06-21T12:05:07.383868Z","shell.execute_reply.started":"2024-06-21T12:04:59.525537Z","shell.execute_reply":"2024-06-21T12:05:07.382930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# InceptionV3","metadata":{"papermill":{"duration":0.47956,"end_time":"2022-03-15T12:00:46.325337","exception":false,"start_time":"2022-03-15T12:00:45.845777","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用InceptionV3训练的模型\nInceptionV3 = tf.keras.applications.InceptionV3(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nInceptionV3.trainable = False\n# Freeze the layers\nfor layer in InceptionV3.layers:\n    layer.trainable = False\n    \nbase_InceptionV3 = InceptionV3\nbase_out_InceptionV3 = base_InceptionV3.output\npool_out_InceptionV3 = tf.keras.layers.Flatten()(base_out_InceptionV3)\nhidden1_InceptionV3 = tf.keras.layers.Dense(512, activation='relu')(pool_out_InceptionV3)\ndrop1_InceptionV3 = tf.keras.layers.Dropout(rate=0.3)(hidden1_InceptionV3)\nhidden2_InceptionV3 = tf.keras.layers.Dense(512, activation='relu')(drop1_InceptionV3)\ndrop2_InceptionV3 = tf.keras.layers.Dropout(rate=0.3)(hidden2_InceptionV3)\nout_InceptionV3 = tf.keras.layers.Dense(3, activation='softmax')(drop2_InceptionV3)\n\nInceptionV3_model = tf.keras.Model(inputs=base_InceptionV3.input, outputs=out_InceptionV3)\nInceptionV3_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nInceptionV3.summary()\n\n\n#这段代码定义了一个基于InceptionV3的卷积神经网络模型，并对模型进行了配置和编译。下面是对代码的详细解释：\n### 加载InceptionV3模型\n#- `InceptionV3 = tf.keras.applications.InceptionV3(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)` 这行代码加载了InceptionV3模型，但没有包含顶部的全连接层（`include_top=False`）。模型权重来自于ImageNet数据集（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n### 冻结InceptionV3层\n#- `InceptionV3.trainable = False` 这行代码将整个InceptionV3模型设置为不可训练，即冻结了所有的层。\n#- `for layer in InceptionV3.layers: layer.trainable = False` 这个循环冻结了InceptionV3模型的所有层。\n### 构建自定义模型\n#-# `base_InceptionV3 = InceptionV3` 将加载的InceptionV3模型赋值给 `base_InceptionV3`。\n#- `base_out_InceptionV3 = base_InceptionV3.output` 获取InceptionV3模型的输出。\n#- `pool_out_InceptionV3 = tf.keras.layers.Flatten()(base_out_InceptionV3)` 将InceptionV3的输出展平，准备连接到全连接层。\n#- `hidden1_InceptionV3 = tf.keras.layers.Dense(512, activation='relu')(pool_out_InceptionV3)` 添加第一个全连接层，包含512个神经元，激活函数为ReLU。\n#- `drop1_InceptionV3 = tf.keras.layers.Dropout(rate=0.3)(hidden1_InceptionV3)` 添加第一个Dropout层，丢弃率为0.3，用于减少过拟合。\n#- `hidden2_InceptionV3 = tf.keras.layers.Dense(512, activation='relu')(drop1_InceptionV3)` 添加第二个全连接层，同样包含512个神经元，激活函数为ReLU。\n#- `drop2_InceptionV3 = tf.keras.layers.Dropout(rate=0.3)(hidden2_InceptionV3)` 添加第二个Dropout层，丢弃率同样为0.3。\n#- `out_InceptionV3 = tf.keras.layers.Dense(3, activation='softmax')(drop2_InceptionV3)` 添加输出层，包含3个神经元，激活函数为softmax，用于多类别分类。\n### 创建和编译模型\n#- `InceptionV3_model = tf.keras.Model(inputs=base_InceptionV3.input, outputs=out_InceptionV3)` 创建了一个新的Keras模型，输入是InceptionV3的输入，输出是自定义的输出层。\n#- `InceptionV3_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])` 编译模型，使用RMSprop优化器，学习率为1e-4，损失函数为多类别交叉熵，评估指标为准确率。\n### 打印模型摘要\n#- `InceptionV3.summary()` 打印模型的结构摘要，包括每一层的名称、输出形状和参数数量。注意这里应该是 `InceptionV3_model.summary()`，因为我们需要打印的是我们刚刚创建的模型的摘要，而不是原始的InceptionV3模型。\n### 注意事项\n#- 在这段代码中，`InceptionV3.summary()` 应该是 `InceptionV3_model.summary()`，以打印新创建的模型的摘要。\n#- 如果InceptionV3模型是从头开始训练的，而不是使用预训练的权重，那么可能需要解冻一些顶部的卷积层，以便它们可以在特定任务的数据上进行微调。\n#接下来，您可以使用类似之前VGG16、VGG19、Xception和ResNet模型的代码来训练这个InceptionV3模型，并评估其性能。","metadata":{"papermill":{"duration":2.893698,"end_time":"2022-03-15T12:00:49.697878","exception":false,"start_time":"2022-03-15T12:00:46.80418","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:05:07.385019Z","iopub.execute_input":"2024-06-21T12:05:07.385330Z","iopub.status.idle":"2024-06-21T12:05:10.428621Z","shell.execute_reply.started":"2024-06-21T12:05:07.385302Z","shell.execute_reply":"2024-06-21T12:05:10.427635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"InceptionV3_start = time.time()\nInceptionV3_history = InceptionV3_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nInceptionV3_stop = time.time()\n\n\n#这段代码使用了Python中的`time`模块来测量执行特定操作所需的时间，并且使用了一个名为InceptionV3的机器学习模型进行训练。下面是对这段代码的逐行解释：\n#1. `InceptionV3_start = time.time()`\n #  这行代码记录了当前的时间戳，这个时间戳将被用来计算后续代码块执行所花费的时间。`time.time()`函数返回自纪元时间（1970年1月1日00:00:00 UTC）以来的秒数。\n#2. `InceptionV3_history = InceptionV3_model.fit(...)`\n  # 这是训练InceptionV3模型的核心部分。`model.fit()`方法是Keras框架中用于训练模型的函数。它接受多个参数，包括训练数据(`x=train_imgs_scaled`)、对应的标签(`y=train_labels_1hotenc`)、批量大小(`batch_size=BATCH_SIZE`)、训练周期数(`epochs=EPOCHS`)、验证数据(`validation_data=(val_imgs_scaled, val_labels_1hotenc)`)以及是否显示训练过程的详细信息(`verbose=1`)。\n   #- `train_imgs_scaled`：可能是经过某种预处理（如缩放）后的训练图像数据。\n  # - `train_labels_1hotenc`：可能是训练数据的标签，以一种称为“独热编码”的形式表示。\n  # - `BATCH_SIZE`：每次更新模型权重时使用的样本数量。\n  # - `EPOCHS`：整个训练数据集将被遍历多少次。\n  # - `val_imgs_scaled`和`val_labels_1hotenc`：验证数据及其对应的标签，用于评估模型在未见过的数据上的表现。\n   #- `verbose`：控制训练过程的输出。`verbose=1`表示显示进度条。\n #  该函数返回一个历史对象，其中包含了训练过程中的各种统计信息，如损失值和精度等，这些信息存储在`InceptionV3_history`变量中。\n#3. `InceptionV3_stop = time.time()`\n  # 这行代码再次调用`time.time()`来获取当前时间戳。与`InceptionV3_start`一起，这两个时间戳的差值将给出`model.fit()`函数执行所花费的总时间。\n#通过比较`InceptionV3_start`和`InceptionV3_stop`的值，我们可以计算出训练InceptionV3模型所需的精确时间。这对于性能分析和优化是非常有用的。","metadata":{"papermill":{"duration":46.43628,"end_time":"2022-03-15T12:01:36.622476","exception":false,"start_time":"2022-03-15T12:00:50.186196","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:05:10.429823Z","iopub.execute_input":"2024-06-21T12:05:10.430100Z","iopub.status.idle":"2024-06-21T12:06:30.442970Z","shell.execute_reply.started":"2024-06-21T12:05:10.430075Z","shell.execute_reply":"2024-06-21T12:06:30.442090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## InceptionV3 Summary","metadata":{"papermill":{"duration":0.586877,"end_time":"2022-03-15T12:01:37.79771","exception":false,"start_time":"2022-03-15T12:01:37.210833","status":"completed"},"tags":[]}},{"cell_type":"code","source":"InceptionV3_trainTime=InceptionV3_stop-InceptionV3_start\nInceptionV3_model_accuracy = InceptionV3_history.history['accuracy'][np.argmin(InceptionV3_history.history['loss'])]\nInceptionV3_model_score=InceptionV3_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nInceptionV3_Summary = PrettyTable([\"InceptionV3\",\" \"])\nInceptionV3_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(InceptionV3_model_accuracy*100)])\nInceptionV3_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(InceptionV3_model_score[1]*100)])\nInceptionV3_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(InceptionV3_model_score[0]*100)])\nInceptionV3_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(InceptionV3_trainTime)])\nprint(InceptionV3_Summary)\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('InceptionV3  Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(InceptionV3_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\n\nax1.plot(epoch_list, InceptionV3_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, InceptionV3_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, InceptionV3_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, InceptionV3_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n#这段代码主要用于评估InceptionV3模型的性能，并可视化训练过程中的准确率和损失变化。下面是对这段代码的逐行解释：\n#1. `InceptionV3_trainTime=InceptionV3_stop-InceptionV3_start`\n #  计算InceptionV3模型训练所花费的时间，通过减去训练开始和结束时记录的时间戳来实现。\n#2. `InceptionV3_model_accuracy = InceptionV3_history.history['accuracy'][np.argmin(InceptionV3_history.history['loss'])]`\n #  从训练历史中找到损失最小的那个epoch的训练准确率，并将其赋值给`InceptionV3_model_accuracy`。\n#3. `InceptionV3_model_score=InceptionV3_model.evaluate(test_imgs_scaled,test_labels_1hotenc)`\n #  使用测试数据评估模型的性能，返回测试集上的损失和准确率，并将其赋值给`InceptionV3_model_score`。\n#4. `InceptionV3_Summary = PrettyTable([\"InceptionV3\",\" \"])`\n #  创建一个PrettyTable对象，用于以表格形式展示模型的性能指标。\n#5. `InceptionV3_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(InceptionV3_model_accuracy*100)])`\n #  添加一行到表格中，显示最佳epoch的训练准确率（转换为百分比）。\n#6. `InceptionV3_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(InceptionV3_model_score[1]*100)])`\n  # 添加一行到表格中，显示测试集上的准确率（转换为百分比）。\n#7. `InceptionV3_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(InceptionV3_model_score[0]*100)])`\n  # 添加一行到表格中，显示测试集上的损失（转换为百分比）。\n#8. `InceptionV3_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(InceptionV3_trainTime)])`\n #  添加一行到表格中，显示训练模型所花费的时间（单位：秒）。\n#9. `print(InceptionV3_Summary)`\n  # 打印出包含模型性能指标的表格。\n#10. `f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))`\n #   创建一个包含两个子图的Figure对象，用于绘制训练和验证的准确率以及损失曲线。\n#11. `t = f.suptitle('InceptionV3 Performance', fontsize=12)`\n  #  设置Figure标题。\n#12. `f.subplots_adjust(top=0.85, wspace=0.3)`\n  #  调整子图之间的间距。\n#13. `max_epoch = len(InceptionV3_history.history['accuracy'])+1`\n  #  计算总共的训练epoch数。\n#14. `epoch_list = list(range(1,max_epoch))`\n  #  创建一个列表，包含从1到最大epoch数的整数，用于绘制x轴。\n#15. `ax1.plot(epoch_list, InceptionV3_history.history['accuracy'], label='Train Accuracy')`\n  #  在第一个子图中绘制训练准确率随epoch的变化曲线。\n#16. `ax1.plot(epoch_list, InceptionV3_history.history['val_accuracy'], label='Validation Accuracy')`\n  #  在第一个子图中绘制验证准确率随epoch的变化曲线。\n#17. `ax1.set_xticks(np.arange(1, max_epoch, 5))`\n  #  设置x轴刻度，每5个epoch显示一个刻度。\n#18. `ax1.set_ylabel('Accuracy Value')`\n #   设置第一个子图的y轴标签。\n#19. `ax1.set_xlabel('Epoch')`\n  #  设置第一个子图的x轴标签。\n#20. `ax1.set_title('Accuracy')`\n  #  设置第一个子图的标题。\n#21. `l1 = ax1.legend(loc=\"best\")`\n #   在第一个子图中添加图例。\n#22. `ax2.plot(epoch_list, InceptionV3_history.history['loss'], label='Train Loss')`\n  #  在第二个子图中绘制训练损失随epoch的变化曲线。\n#23. `ax2.plot(epoch_list, InceptionV3_history.history['val_loss'], label='Validation Loss')`\n  #  在第二个子图中绘制验证损失随epoch的变化曲线。\n#24. `ax2.set_xticks(np.arange(1, max_epoch, 5))`\n #   设置第二个子图的x轴刻度。\n#25. `ax2.set_ylabel('Loss Value')`\n  #  设置第二个子图的y轴标签。\n#26. `ax2.set_xlabel('Epoch')`\n  #  设置第二个子图的x轴标签。\n#27. `ax2.set_title('Loss')`\n  #  设置第二个子图的标题。\n#28. `l2 = ax2.legend(loc=\"best\")`\n   # 在第二个子图中添加图例。\n#这段代码的目的是为了展示InceptionV3模型在训练过程中的性能，包括训练和验证的准确率以及损失，并通过图表直观地呈现这些信息。","metadata":{"papermill":{"duration":3.955136,"end_time":"2022-03-15T12:01:42.343376","exception":false,"start_time":"2022-03-15T12:01:38.38824","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:06:30.444357Z","iopub.execute_input":"2024-06-21T12:06:30.444791Z","iopub.status.idle":"2024-06-21T12:06:49.761751Z","shell.execute_reply.started":"2024-06-21T12:06:30.444756Z","shell.execute_reply":"2024-06-21T12:06:49.760832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# MobileNet","metadata":{"papermill":{"duration":0.594247,"end_time":"2022-03-15T12:01:43.536907","exception":false,"start_time":"2022-03-15T12:01:42.94266","status":"completed"},"tags":[]}},{"cell_type":"code","source":"#使用InceptionV3训练的模型\nMobileNet = tf.keras.applications.MobileNet(include_top=False, weights='imagenet', \n                                        input_shape=INPUT_SHAPE)\nMobileNet.trainable = False\n# Freeze the layers\nfor layer in MobileNet.layers:\n    layer.trainable = False\n    \nbase_MobileNet = MobileNet\nbase_out_MobileNet = base_MobileNet.output\npool_out_MobileNet = tf.keras.layers.Flatten()(base_out_MobileNet)\nhidden1_MobileNet = tf.keras.layers.Dense(512, activation='relu')(pool_out_MobileNet)\ndrop1_MobileNet = tf.keras.layers.Dropout(rate=0.3)(hidden1_MobileNet)\nhidden2_MobileNet = tf.keras.layers.Dense(512, activation='relu')(drop1_MobileNet)\ndrop2_MobileNet = tf.keras.layers.Dropout(rate=0.3)(hidden2_MobileNet)\nout_MobileNet = tf.keras.layers.Dense(3, activation='softmax')(drop2_MobileNet)\n\nMobileNet_model = tf.keras.Model(inputs=base_MobileNet.input, outputs=out_MobileNet)\nMobileNet_model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\nMobileNet.summary()\n\n\n#这段代码展示了如何使用TensorFlow和Keras库来创建一个基于预训练的MobileNet模型的神经网络，并对该模型进行了一些修改以适应新的任务。下面是对这段代码的逐行解释：\n#1. `MobileNet = tf.keras.applications.MobileNet(include_top=False, weights='imagenet', input_shape=INPUT_SHAPE)`\n  # 这里创建了一个MobileNet模型，但是没有包含顶层的分类器（`include_top=False`），这意味着我们只使用了模型的卷积基。模型加载了ImageNet数据集的预训练权重（`weights='imagenet'`），并且指定了输入图像的形状（`input_shape=INPUT_SHAPE`）。\n#2. `MobileNet.trainable = False`\n   #这行代码冻结了MobileNet模型的所有层，使得它们在后续的训练过程中不会被更新。\n#3. `for layer in MobileNet.layers:` ... `layer.trainable = False`\n  # 这一段循环遍历了MobileNet模型的所有层，并将它们的`trainable`属性设置为`False`，确保所有的层都不会在训练过程中更新权重。\n#4. `base_MobileNet = MobileNet`\n  # 这里只是给MobileNet模型起了一个别名`base_MobileNet`。\n#5. `base_out_MobileNet = base_MobileNet.output`\n   #获取`base_MobileNet`的输出作为后续层的输入。\n#6. `pool_out_MobileNet = tf.keras.layers.Flatten()(base_out_MobileNet)`\n  # 这里添加了一个Flatten层，将卷积层的输出展平为一维张量，以便输入到全连接层。\n#7. `hidden1_MobileNet = tf.keras.layers.Dense(512, activation='relu')(pool_out_MobileNet)`\n  # 添加了一个具有512个神经元的全连接层（Dense层），激活函数为ReLU。\n#8. `drop1_MobileNet = tf.keras.layers.Dropout(rate=0.3)(hidden1_MobileNet)`\n  # 添加了一个Dropout层，丢弃率设置为0.3，用于减少过拟合。\n#9. `hidden2_MobileNet = tf.keras.layers.Dense(512, activation='relu')(drop1_MobileNet)`\n   #又添加了一个具有512个神经元的全连接层，激活函数为ReLU。\n#10. `drop2_MobileNet = tf.keras.layers.Dropout(rate=0.3)(hidden2_MobileNet)`\n  #  再次添加了一个Dropout层，丢弃率设置为0.3。\n#11. `out_MobileNet = tf.keras.layers.Dense(3, activation='softmax')(drop2_MobileNet)`\n   # 最后添加了一个具有3个输出的全连接层，激活函数为Softmax，用于多类别分类。\n#12. `MobileNet_model = tf.keras.Model(inputs=base_MobileNet.input, outputs=out_MobileNet)`\n  #  创建了一个新的Keras模型`MobileNet_model`，其输入是`base_MobileNet`的输入，输出是最后的`out_MobileNet`层。\n#13. `MobileNet_model.compile(...`\n   # 编译了模型，指定了优化器（`RMSprop`，学习率为1e-4），损失函数（`categorical_crossentropy`），以及评估指标（`accuracy`）。\n#14. `MobileNet.summary()`\n   # 打印了原始MobileNet模型的摘要信息，展示了每一层的名称、输出形状和参数数量。\n#总的来说，这段代码定义了一个迁移学习的过程，其中预训练的MobileNet模型的卷积基被用作特征提取器，而顶部的几层则是新添加的，用于适应特定的分类任务。由于`MobileNet.trainable = False`，模型的卷积基在训练过程中不会被更新，只有新增的全连接层会被训练。","metadata":{"papermill":{"duration":1.562668,"end_time":"2022-03-15T12:01:45.694942","exception":false,"start_time":"2022-03-15T12:01:44.132274","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:06:49.763033Z","iopub.execute_input":"2024-06-21T12:06:49.763445Z","iopub.status.idle":"2024-06-21T12:06:50.609916Z","shell.execute_reply.started":"2024-06-21T12:06:49.763410Z","shell.execute_reply":"2024-06-21T12:06:50.609018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MobileNet_start = time.time()\nMobileNet_history = MobileNet_model.fit(x=train_imgs_scaled, y=train_labels_1hotenc, \n                    batch_size=BATCH_SIZE,\n                    epochs=EPOCHS, \n                    validation_data=(val_imgs_scaled, val_labels_1hotenc),\n                    verbose=1)\nMobileNet_stop = time.time()\n\n\n#这段代码使用了Python中的`time`模块来测量执行特定操作所需的时间，并且使用了一个名为MobileNet的机器学习模型进行训练。下面是对这段代码的逐行解释：\n#1. `MobileNet_start = time.time()`\n  # 这行代码记录了当前的时间戳，这个时间戳将被用来计算后续代码块执行所花费的时间。`time.time()`函数返回自纪元时间（1970年1月1日00:00:00 UTC）以来的秒数。\n#2. `MobileNet_history = MobileNet_model.fit(...)`\n  # 这是训练MobileNet模型的核心部分。`model.fit()`方法是Keras框架中用于训练模型的函数。它接受多个参数，包括训练数据(`x=train_imgs_scaled`)、对应的标签(`y=train_labels_1hotenc`)、批量大小(`batch_size=BATCH_SIZE`)、训练周期数(`epochs=EPOCHS`)、验证数据(`validation_data=(val_imgs_scaled, val_labels_1hotenc)`)以及是否显示训练过程的详细信息(`verbose=1`)。\n  # - `train_imgs_scaled`：可能是经过某种预处理（如缩放）后的训练图像数据。\n  # - `train_labels_1hotenc`：可能是训练数据的标签，以一种称为“独热编码”的形式表示。\n  # - `BATCH_SIZE`：每次更新模型权重时使用的样本数量。\n  # - `EPOCHS`：整个训练数据集将被遍历多少次。\n  # - `val_imgs_scaled`和`val_labels_1hotenc`：验证数据及其对应的标签，用于评估模型在未见过的数据上的表现。\n  # - `verbose`：控制训练过程的输出。`verbose=1`表示显示进度条。\n   #该函数返回一个历史对象，其中包含了训练过程中的各种统计信息，如损失值和精度等，这些信息存储在`MobileNet_history`变量中。\n#3. `MobileNet_stop = time.time()`\n   #这行代码再次调用`time.time()`来获取当前时间戳。与`MobileNet_start`一起，这两个时间戳的差值将给出`model.fit()`函数执行所花费的总时间。\n#通过比较`MobileNet_start`和`MobileNet_stop`的值，我们可以计算出训练MobileNet模型所需的精确时间。这对于性能分析和优化是非常有用的。","metadata":{"papermill":{"duration":44.282194,"end_time":"2022-03-15T12:02:30.897252","exception":false,"start_time":"2022-03-15T12:01:46.615058","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:06:50.611313Z","iopub.execute_input":"2024-06-21T12:06:50.611665Z","iopub.status.idle":"2024-06-21T12:07:30.064473Z","shell.execute_reply.started":"2024-06-21T12:06:50.611631Z","shell.execute_reply":"2024-06-21T12:07:30.063631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MobileNet Summary","metadata":{"papermill":{"duration":0.700356,"end_time":"2022-03-15T12:02:32.304275","exception":false,"start_time":"2022-03-15T12:02:31.603919","status":"completed"},"tags":[]}},{"cell_type":"code","source":"MobileNet_trainTime=MobileNet_stop-MobileNet_start\nMobileNet_model_accuracy = MobileNet_history.history['accuracy'][np.argmin(MobileNet_history.history['loss'])]\nMobileNet_model_score=MobileNet_model.evaluate(test_imgs_scaled,test_labels_1hotenc)\nMobileNet_Summary = PrettyTable([\"MobileNet\",\" \"])\nMobileNet_Summary.add_row([\"Model Accuracy in %\", \"{:.2f}\".format(MobileNet_model_accuracy*100)])\nMobileNet_Summary.add_row([\"Test Accuracy in %\", \"{:.2f}\".format(MobileNet_model_score[1]*100)])\nMobileNet_Summary.add_row([\"Test Loss in %\", \"{:.2f}\".format(MobileNet_model_score[0]*100)])\nMobileNet_Summary.add_row([\"Time Taken To Train in Seconds\", \"{:.2f}\".format(MobileNet_trainTime)])\nprint(MobileNet_Summary)\n\n####graph\n\nf, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('MobileNet Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\n\nmax_epoch = len(MobileNet_history.history['accuracy'])+1\nepoch_list = list(range(1,max_epoch))\n\nax1.plot(epoch_list, MobileNet_history.history['accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, MobileNet_history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\n\nax2.plot(epoch_list, MobileNet_history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, MobileNet_history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\n\n#这段代码是用于训练和评估一个名为\"MobileNet\"的卷积神经网络模型的Python脚本。以下是对代码的详细解释：\n### 变量定义和初始化\n#- `MobileNet_trainTime`：用于记录训练模型所花费的总时间。\n#- `MobileNet_history`：保存了模型在每个epoch（训练周期）结束时的训练和验证数据，包括准确率和损失值。\n#- `MobileNet_model_accuracy`：在训练过程中，模型在验证集上的最佳准确率。\n#- `MobileNet_model_score`：模型在测试集上的得分，包括准确率和损失值。\n#- `MobileNet_Summary`：使用`PrettyTable`库创建的表格，用于显示模型的性能指标。\n#- `test_imgs_scaled`和`test_labels_1hotenc`：测试集中的图像数据和标签数据。\n### 模型训练和评估\n##- `MobileNet_model_accuracy`计算的是在训练过程中，模型在验证集上达到最小损失时的准确率。\n#- `MobileNet_model_score`是模型在测试集上的评估结果，包括准确率和损失值。\n### 性能指标显示\n#- `MobileNet_Summary`表格用于显示模型的性能指标，包括模型准确率、测试准确率、测试损失和训练时间。\n### 图形绘制\n#- 代码还包括了绘制训练和验证准确率以及损失曲线的部分，这有助于可视化模型在训练过程中的表现。\n### 注意事项\n#- 代码中使用了`np.argmin(MobileNet_history.history['loss'])`来找到损失值最小的epoch，这通常是模型性能最好的时刻。\n#- `MobileNet_history.history['accuracy']`和`MobileNet_history.history['loss']`分别代表训练和验证的准确率和损失值列表。\n#- `MobileNet_history.history['val_accuracy']`和`MobileNet_history.history['val_loss']`分别代表验证集的准确率和损失值列表。\n##以上解释基于代码的结构和常见的机器学习实践。如果您需要更详细的解释或者有其他关于这段代码的问题，请随时告诉我。","metadata":{"papermill":{"duration":2.192684,"end_time":"2022-03-15T12:02:35.209418","exception":false,"start_time":"2022-03-15T12:02:33.016734","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:07:30.065575Z","iopub.execute_input":"2024-06-21T12:07:30.065831Z","iopub.status.idle":"2024-06-21T12:07:37.892941Z","shell.execute_reply.started":"2024-06-21T12:07:30.065806Z","shell.execute_reply":"2024-06-21T12:07:37.892062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Summary","metadata":{"papermill":{"duration":0.704328,"end_time":"2022-03-15T12:02:36.618672","exception":false,"start_time":"2022-03-15T12:02:35.914344","status":"completed"},"tags":[]}},{"cell_type":"code","source":"Summary = PrettyTable([\"Model Name\", \"Model Train Accuracy in %\", \"Model Test Accuracy in %\",\"Time Taken To Train in Seconds\"])\nSummary.add_row([\"Vgg16\", \"{:.2f}\".format(vgg16_model_accuracy*100),\"{:.2f}\".format(vgg16_model_score[1]*100),\"{:.2f}\".format(vgg16_trainTime)])\nSummary.add_row([\"Vgg19\", \"{:.2f}\".format(vgg19_model_accuracy*100),\"{:.2f}\".format(vgg19_model_score[1]*100),\"{:.2f}\".format(vgg19_trainTime)])\nSummary.add_row([\"Xception\", \"{:.2f}\".format(Xception_model_accuracy*100),\"{:.2f}\".format(Xception_model_score[1]*100),\"{:.2f}\".format(Xception_trainTime)])\nSummary.add_row([\"ResNet\", \"{:.2f}\".format(ResNet_model_accuracy*100),\"{:.2f}\".format(ResNet_model_score[1]*100),\"{:.2f}\".format(ResNet_trainTime)])\nSummary.add_row([\"InceptionV3\", \"{:.2f}\".format(InceptionV3_model_accuracy*100),\"{:.2f}\".format(InceptionV3_model_score[1]*100),\"{:.2f}\".format(InceptionV3_trainTime)])\nSummary.add_row([\"MobileNet\", \"{:.2f}\".format(MobileNet_model_accuracy*100),\"{:.2f}\".format(MobileNet_model_score[1]*100),\"{:.2f}\".format(MobileNet_trainTime)])\n\nprint(Summary)\nf, ax = plt.subplots(2, 2, figsize=(15, 12))\nt = f.suptitle('Summary', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\nepoch_list = list(range(1,21))\n\n\nax[0,0].plot(epoch_list, vgg16_history.history['accuracy'], label='vgg16')\nax[0,0].plot(epoch_list, vgg19_history.history['accuracy'], label='vgg19')\nax[0,0].plot(epoch_list, Xception_history.history['accuracy'], label='Xception')\nax[0,0].plot(epoch_list, ResNet_history.history['accuracy'], label='ResNet')\nax[0,0].plot(epoch_list, InceptionV3_history.history['accuracy'], label='InceptionV3')\nax[0,0].plot(epoch_list, MobileNet_history.history['accuracy'], label='MobileNet')\nax[0,0].set_xticks(np.arange(1, max_epoch, 5))\nax[0,0].set_ylabel('Accuracy Value')\nax[0,0].set_xlabel('Epoch')\nax[0,0].set_title('Train Accuracy')\nl1 = ax[0,0].legend(loc=\"best\")\n\n\nax[0,1].plot(epoch_list, vgg16_history.history['loss'], label='vgg16')\nax[0,1].plot(epoch_list, vgg19_history.history['loss'], label='vgg19')\nax[0,1].plot(epoch_list, Xception_history.history['loss'], label='Xception')\nax[0,1].plot(epoch_list, ResNet_history.history['loss'], label='ResNet')\nax[0,1].plot(epoch_list, InceptionV3_history.history['loss'], label='InceptionV3')\nax[0,1].plot(epoch_list, MobileNet_history.history['loss'], label='MobileNet')\nax[0,1].set_xticks(np.arange(1, max_epoch, 5))\nax[0,1].set_ylabel('Loss Value')\nax[0,1].set_xlabel('Epoch')\nax[0,1].set_title('Train Loss')\nl2 = ax[0,1].legend(loc=\"best\")\n\nax[1,0].plot(epoch_list, vgg16_history.history['val_accuracy'], label='vgg16')\nax[1,0].plot(epoch_list, vgg19_history.history['val_accuracy'], label='vgg19')\nax[1,0].plot(epoch_list, Xception_history.history['val_accuracy'], label='Xception')\nax[1,0].plot(epoch_list, ResNet_history.history['val_accuracy'], label='ResNet')\nax[1,0].plot(epoch_list, InceptionV3_history.history['val_accuracy'], label='InceptionV3')\nax[1,0].plot(epoch_list, MobileNet_history.history['val_accuracy'], label='MobileNet')\nax[1,0].set_xticks(np.arange(1, max_epoch, 5))\nax[1,0].set_ylabel('Accuracy Value')\nax[1,0].set_xlabel('Epoch')\nax[1,0].set_title(' Validation Accuracy')\nl3 = ax[1,0].legend(loc=\"best\")\n\n\nax[1,1].plot(epoch_list, vgg16_history.history['val_loss'], label='vgg16')\nax[1,1].plot(epoch_list, vgg19_history.history['val_loss'], label='vgg19')\nax[1,1].plot(epoch_list, Xception_history.history['val_loss'], label='Xception')\nax[1,1].plot(epoch_list, ResNet_history.history['val_loss'], label='ResNet')\nax[1,1].plot(epoch_list, InceptionV3_history.history['val_loss'], label='InceptionV3')\nax[1,1].plot(epoch_list, MobileNet_history.history['val_loss'], label='MobileNet')\nax[1,1].set_xticks(np.arange(1, max_epoch, 5))\nax[1,1].set_ylabel('Loss Value')\nax[1,1].set_xlabel('Epoch')\nax[1,1].set_title('Validation Loss')\nl4 = ax[1,1].legend(loc=\"best\")\n\n\n\n#您提供的代码片段是一段Python代码，用于创建一个表格来展示不同模型的训练精度、测试精度和训练时间。这段代码使用了PrettyTable库来美化输出的表格，并且使用了matplotlib库来绘制训练过程中的准确度变化曲线图。\n#代码解释\n#创建表格\n#Summary = PrettyTable([\"Model Name\", \"Model Train Accuracy in %\", \"Model Test Accuracy in %\",\"Time Taken To Train in Seconds\"])\n#这一行代码初始化了一个PrettyTable对象，设置了列名为模型名称、模型训练准确度、模型测试准确度和训练时间。\n#添加数据到表格\n#Summary.add_row([\"Vgg16\", \"{:.2f}\".format(vgg16_model_accuracy*100),\"{:.2f}\".format(vgg16_model_score[1]*100),\"{:.2f}\".format(vgg16_trainTime)])\n#Summary.add_row([\"Vgg19\", \"{:.2f}\".format(vgg19_model_accuracy*100),\"{:.2f}\".format(vgg19_model_score[1]*100),\"{:.2f}\".format(vgg19_trainTime)])\n#Summary.add_row([\"Xception\", \"{:.2f}\".format(Xception_model_accuracy*100),\"{:.2f}\".format(Xception_model_score[1]*100),\"{:.2f}\".format(Xception_trainTime)])\n#Summary.add_row([\"ResNet\", \"{:.2f}\".format(ResNet_model_accuracy*100),\"{:.2f}\".format(ResNet_model_score[1]*100),\"{:.2f}\".format(ResNet_trainTime)])\n#Summary.add_row([\"InceptionV3\", \"{:.2f}\".format(InceptionV3_model_accuracy*100),\"{:.2f}\".format(InceptionV3_model_score[1]*100),\"{:.2f}\".format(InceptionV3_trainTime)])\n#Summary.add_row([\"MobileNet\", \"{:.2f}\".format(MobileNet_model_accuracy*100),\"{:.2f}\".format(MobileNet_model_score[1]*100),\"{:.2f}\".format(MobileNet_trainTime)])\n#这几行代码向表格中添加了不同模型的数据。vgg16_model_accuracy, vgg19_model_accuracy, Xception_model_accuracy, ResNet_model_accuracy, InceptionV3_model_accuracy, MobileNet_model_accuracy 和 vgg16_trainTime, vgg19_trainTime, Xception_trainTime, ResNet_trainTime, InceptionV3_trainTime, MobileNet_trainTime 是变量，它们代表了不同模型的训练准确度、测试准确度和训练时间。\n#打印表格\n#print(Summary)\n#这行代码将表格打印出来，以便查看。\n#绘制图表\n#f, ax = plt.subplots(2, 2, figsize=(15, 12))\n#t = f.suptitle('Summary', fontsize=12)\n#f.subplots_adjust(top=0.85, wspace=0.3)\n#epoch_list = list(range(1,21))\n#ax[0,0].plot(epoch_list, vgg16_history.history['accuracy'], label='vgg16')\n#ax[0,0].plot(epoch_list, vgg19_history.history['accuracy'], label='vgg19')\n#ax[0,0].plot(epoch_list, Xception_history.history['accuracy'], label='Xception')\n#ax[0,0].plot(epoch_list, ResNet_history.history['accuracy'],","metadata":{"papermill":{"duration":1.411925,"end_time":"2022-03-15T12:02:38.788725","exception":false,"start_time":"2022-03-15T12:02:37.3768","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-06-21T12:07:37.894495Z","iopub.execute_input":"2024-06-21T12:07:37.895054Z","iopub.status.idle":"2024-06-21T12:07:39.066943Z","shell.execute_reply.started":"2024-06-21T12:07:37.895018Z","shell.execute_reply":"2024-06-21T12:07:39.066040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction ","metadata":{}},{"cell_type":"code","source":" from matplotlib import pyplot\nimg='../input/intel-mobileodt-cervical-cancer-screening/test/test/1.jpg'\ndata = pyplot.imread(img)\npyplot.imshow(data)\nax = pyplot.gca()\npyplot.show()\n\n\ntest1_data_inp = [(idx, img, len(test_files)) for idx, img in enumerate([img])]\ntest1_data_map = ex.map(get_img_data_parallel, \n                        [record[0] for record in test1_data_inp],\n                        [record[1] for record in test1_data_inp],\n                        [record[2] for record in test1_data_inp])\ntest1_data = np.array(list(test1_data_map))\ntest1_imgs_scaled = test1_data / 255.\n\nprint(\"######Generate a vgg16 prediction########\")\nvgg16_prediction = vgg16_model.predict(test1_imgs_scaled)\n\nif (vgg16_prediction[0][0] >= vgg16_prediction[0][1]) and (vgg16_prediction[0][0] >= vgg16_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in vgg16\".format(vgg16_prediction[0][0]*100))\nelif (vgg16_prediction[0][1] >= vgg16_prediction[0][0]) and (vgg16_prediction[0][1] >= vgg16_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in vgg16\".format(vgg16_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in vgg16\".format(vgg16_prediction[0][2]*100))\n    \nprint(\"                                                                 \")    \nprint(\"######Generate a vgg19 prediction########\")\nvgg19_prediction = vgg19_model.predict(test1_imgs_scaled)\n\nif (vgg19_prediction[0][0] >= vgg19_prediction[0][1]) and (vgg19_prediction[0][0] >= vgg19_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in vgg19\".format(vgg19_prediction[0][0]*100))\nelif (vgg19_prediction[0][1] >= vgg19_prediction[0][0]) and (vgg19_prediction[0][1] >= vgg19_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in vgg19\".format(vgg19_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in vgg19\".format(vgg19_prediction[0][2]*100))\n    \n    \nprint(\"                                                                 \")    \nprint(\"######Generate a Xception  prediction########\")\nXception_prediction = Xception_model.predict(test1_imgs_scaled)\n\nif (Xception_prediction[0][0] >= Xception_prediction[0][1]) and (Xception_prediction[0][0] >= Xception_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in Xception\".format(Xception_prediction[0][0]*100))\nelif (Xception_prediction[0][1] >= Xception_prediction[0][0]) and (Xception_prediction[0][1] >= Xception_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in Xception\".format(Xception_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in Xception\".format(Xception_prediction[0][2]*100))\n    \nprint(\"                                                                 \")    \nprint(\"######Generate a ResNet prediction########\")\nResNet_prediction = ResNet_model.predict(test1_imgs_scaled)\n\nif (ResNet_prediction[0][0] >= ResNet_prediction[0][1]) and (ResNet_prediction[0][0] >= ResNet_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in ResNet\".format(ResNet_prediction[0][0]*100))\nelif (ResNet_prediction[0][1] >= ResNet_prediction[0][0]) and (ResNet_prediction[0][1] >= ResNet_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in ResNet\".format(ResNet_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in ResNet\".format(ResNet_prediction[0][2]*100))\n    \nprint(\"                                                                 \")    \nprint(\"######Generate a InceptionV3  prediction########\")\nInceptionV3_prediction = InceptionV3_model.predict(test1_imgs_scaled)\n\nif (InceptionV3_prediction[0][0] >= InceptionV3_prediction[0][1]) and (InceptionV3_prediction[0][0] >= InceptionV3_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in InceptionV3 \".format(InceptionV3_prediction[0][0]*100))\nelif (InceptionV3_prediction[0][1] >= vgg19_prediction[0][0]) and (InceptionV3_prediction[0][1] >= InceptionV3_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in InceptionV3\".format(InceptionV3_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in InceptionV3\".format(InceptionV3_prediction[0][2]*100))\n    \n    \nprint(\"                                                                 \")    \nprint(\"######Generate a MobileNet prediction########\")\nMobileNet_prediction = MobileNet_model.predict(test1_imgs_scaled)\n\nif (MobileNet_prediction[0][0] >= MobileNet_prediction[0][1]) and (MobileNet_prediction[0][0] >= MobileNet_prediction[0][2]):\n    print(\"Test image is Classified as Type 1 with {:.2f}% in MobileNet\".format(MobileNet_prediction[0][0]*100))\nelif (MobileNet_prediction[0][1] >= MobileNet_prediction[0][0]) and (MobileNet_prediction[0][1] >= MobileNet_prediction[0][2]):\n    print(\"Test image is Classified as Type 2 with {:.2f}% in MobileNet\".format(MobileNet_prediction[0][1]*100))\nelse:\n    print(\"Test image is Classified as Type 3 with {:.2f}% in MobileNet\".format(MobileNet_prediction[0][2]*100))\n    \n#这段代码是一段使用Python编写的脚本，它使用了matplotlib库来读取和显示图像，然后使用预训练的VGG16和VGG19模型对图像进行分类预测。下面是对这段代码的详细解释：\n#1. `from matplotlib import pyplot`：这行代码导入了matplotlib库中的pyplot模块，通常用于绘制图形和图像显示。\n#2. `img='../input/intel-mobileodt-cervical-cancer-screening/test/test/1.jpg'`：这行代码定义了一个变量`img`，它存储了要处理的图像文件的路径。\n#3. `data = pyplot.imread(img)`：这行代码使用`pyplot.imread`函数从指定的路径读取图像文件，并将图像数据存储在变量`data`中。\n#4. `pyplot.imshow(data)`：这行代码使用`pyplot.imshow`函数显示读取的图像数据。\n#5. `ax = pyplot.gca()`：这行代码获取当前的图形轴对象，用于后续的图形操作。\n#6. `pyplot.show()`：这行代码显示图像。\n#7. `test1_data_inp = [(idx, img, len(test_files)) for idx, img in enumerate([img])]`：这行代码创建了一个列表`test1_data_inp`，其中包含了图像的索引、图像路径以及测试文件的总数。\n#8. `ex.map(get_img_data_parallel,...)`：这部分代码使用了`ex.map`函数，这个函数可能是某个自定义的并行处理函数或者来自某个第三方库（如dask或multiprocessing），用于并行处理图像数据。`get_img_data_parallel`可能是一个用于处理图像数据的函数。\n#9. `test1_data = np.array(list(test1_data_map))`：这行代码将处理后的图像数据转换为NumPy数组。\n#10. `test1_imgs_saled = test1_data / 255.`：这行代码对图像数据进行了归一化处理，将其像素值缩放到0到1之间。\n#11. `vgg16_prediction = vgg16_model.predict(test1_imgs_scaled)`：这行代码使用预训练的VGG16模型对归一化后的图像数据进行预测。\n#12. 接下来的条件语句根据VGG16模型的预测结果判断图像属于哪一类，并将预测的概率转换为百分比打印出来。\n#13. 类似地，后面的代码块使用VGG19模型对同一图像数据进行预测，并根据预测结果进行分类和输出。\n#整体来看，这段代码的主要目的是加载一个图像文件，对其进行预处理，然后使用VGG16和VGG19这两个不同的预训练卷积神经网络模型进行分类预测，并输出预测结果。","metadata":{"execution":{"iopub.status.busy":"2024-06-21T12:07:39.068106Z","iopub.execute_input":"2024-06-21T12:07:39.068399Z","iopub.status.idle":"2024-06-21T12:08:03.250023Z","shell.execute_reply.started":"2024-06-21T12:07:39.068373Z","shell.execute_reply":"2024-06-21T12:08:03.249063Z"},"trusted":true},"execution_count":null,"outputs":[]}]}