ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

深度学习实战-基于BiT-ResNet50的纺织品缺陷图像识别模型

深度学习实战-基于BiT-ResNet50的纺织品缺陷图像识别模型 ‍♂️ 个人主页艾派森的个人主页✍作者简介Python学习者 希望大家多多支持我们一起进步如果文章对你有帮助的话欢迎评论 点赞 收藏 加关注目录1.项目背景2.数据集介绍3.技术工具4.实验过程4.1导入数据4.2数据预处理4.3特征工程4.4构建模型4.5训练模型4.6模型评估5.总结源代码1.项目背景在纺织品的自动化生产与质量控制过程中面料表面常因设备磨损、原料瑕疵或工艺波动产生断经、纬斜、污渍及破洞等各类微小缺陷。这些缺陷如果未能被及时精准地检测出来不仅会造成原材料的大量浪费还会直接影响最终产品的质量与品牌信誉。传统的纺织品缺陷检测主要依赖人工目视抽检这种方式不仅劳动强度大、效率低下而且极易受到工人主观疲劳和经验差异的影响难以满足现代工业高质高效的生产要求。随着智能制造与计算机视觉技术的快速发展利用深度学习模型实现纺织品缺陷的自动精准识别已成为工业界和学术界的研究热点。然而纺织品背景纹理纷繁复杂缺陷形态多变且占比极小对传统卷积神经网络的特征提取能力提出了巨大挑战。为此本项目基于 Big Transfer (BiT-ResNet50) 强劲的预训练特征表示能力结合特定数据增强与高性能数据管道构建了一套高精度的纺织品缺陷智能识别系统旨在提供一种稳定、高效且具备高泛化能力的工业级缺陷检测解决方案。2.数据集介绍本实验数据集来源于Kaggle为纺织品缺陷检测数据集利用旋转检测纺织品纹理缺陷在纺织面料领域罕见的异常情况可能会发生从而影响面料的质量。为了避免这种情况的发生检测缺陷至关重要。本数据集仅用于教学目的。3.技术工具Python版本:3.9代码编辑器jupyter notebook4.实验过程4.1导入数据在工业级纺织品缺陷检测任务中精准捕获布料表面的微小瑕疵是保障生产质量的核心。本小节首先导入实验所需的深度学习与数据处理基础库包括用于构建张量与训练模型的 TensorFlow、加载预训练模型的 TensorFlow Hub以及用于数据操作与性能指标评估的 H5Py、Pandas、Matplotlib 和 Scikit-Learn 等工具。随后通过读取训练元数据文件train64.csv对原始标注字段进行清洗与二值化映射将复杂的瑕疵类型统一归一化为“损坏damaged”与“良好good”两类并将对应的标签数值化为 1 和 0从而构建出清晰明确的二分类监督学习目标。# ---------------------------------------------------------------------- # 1. 导入项目所需的第三方依赖库 # ---------------------------------------------------------------------- import os import glob import pickle import tensorflow as tf # 用于将数据集转换为 Tensor 格式以及构建与训练深度学习模型 import tensorflow_hub as hub # 用于下载和调用预训练模型如 BiT-ResNet50 import numpy as np import h5py # 用于操作和读取 .h5 格式的数据集文件 import pandas as pd import plotly.express as px import matplotlib.pyplot as plt from sklearn.metrics import classification_report # 用于输出模型评估指标报告如准确率、召回率等 from sklearn.metrics import f1_score # 用于计算模型的 F1 分数 from tqdm import tqdm # 用于在循环或迭代操作中显示动态进度条 # ---------------------------------------------------------------------- # 2. 读取并预处理标注 CSV 文件 # ---------------------------------------------------------------------- # 加载训练集的元数据 CSV 文件 train_df64 pd.read_csv(/kaggle/input/textiledefectdetection/train64.csv) # 将缺陷类型统一处理若不为 good 则归类为 damaged有缺陷否则为 good完好 train_df64[indication_type] train_df64.indication_type.apply(lambda row: damaged if row!good else good) # 将缺陷数值标签映射为二分类数值非 0 表示有缺陷标记为 10 表示无缺陷标记为 0 train_df64[indication_value] train_df64.indication_value.apply(lambda row: 1 if row!0 else 0) # 查看数据框的前 5 行确认格式转换是否正确 train_df64.head()数据读取与标签转换完成后我们需要对数据集中不同类别有缺陷与无缺陷的样本分布情况进行可视化分析。通过计算各类别的占比并绘制柱状图可以直观地观察数据集是否存在类别不平衡问题从而指导后续的数据预处理与模型训练策略。# ---------------------------------------------------------------------- # 3. 计算并可视化不同类别的样本分布比例 # ---------------------------------------------------------------------- # 计算各类别的百分比保留两位小数并绘制柱状图 (train_df64.indication_type.value_counts(normalizeTrue).round(2)*100).to_frame().plot.bar(legendFalse, figsize(8, 6)) # 设置 X 轴和 Y 轴的标签及其字号大小 plt.xlabel(Classes, fontsize18) plt.ylabel(Count (%), fontsize18) # 设置图像标题及其字号大小 plt.title(Distribution of Classes, fontsize20) # 设置 X 轴刻度标签不旋转水平显示及其字号大小 plt.xticks(rotation0, fontsize15) plt.show()可以发现数据非常不平衡需要进行处理4.2数据预处理为了将存放于.h5层级文件中的图像数据高效提取并转化为标准的本地目录结构以便于 TensorFlow 框架的读取与数据管道构建我们需要实现一个数据转换类H5ToStorage。该类不仅能通过生成器Generator逐条读取图像及其标签信息还针对训练集进行了数据增强处理如随机水平/垂直翻转从而增加无缺陷good样本的多样性平衡数据分布。# ---------------------------------------------------------------------- # 定义 H5 数据转换与图像提取生成器类 # ---------------------------------------------------------------------- class H5ToStorage: def __init__(self, hdf_path, ds_nametrain): # 保存传入的 HDF5 文件路径 self.path hdf_path # 初始化类别列表打开 HDF5 文件获取顶层存储的所有类别名称 self.classes [] with h5py.File(self.path, r) as hf: for class_ in hf: self.classes.append(class_) # 保存数据集类型标识如 train 或 test self.name ds_name # 生成器函数用于迭代读取 HDF5 文件中的 (图像矩阵, 类别名称, 旋转角度) def generate_img_arr(self): for class_ in self.classes: with h5py.File(self.path, r) as hf: for angle in hf[class_]: for img in hf[class_][f{angle}]: # 逐条产出图像像素数组、所属类别及对应角度 yield img, class_, angle # 针对训练集生成本地图像目录并进行数据增强 def generate_train_dirs(self): # 创建训练集存放的目标路径结构 path f./dataset/{self.name} os.makedirs(f{path}/good/) os.makedirs(f{path}/damaged/) # 注释掉的代码随机亮度调节层 # random_bright tf.keras.layers.RandomBrightness(factor0.05) # 定义 TensorFlow 数据增强层随机水平与垂直翻转 random_flip tf.keras.layers.RandomFlip(horizontal_and_vertical) gen self.generate_img_arr() metadata {} # 遍历生成器产出的所有图像数据 for i, data in enumerate(gen): img, label, angle data # 如果是无缺陷good样本则进行 4 次增强扩充平衡样本数量 if label good: for j in range(4): img_path f{path}/{label}/{i}_aug{j}.jpeg # 将图像转为张量并恢复像素范围 [0, 255]应用随机翻转增强 img random_flip(tf.expand_dims(np.squeeze(img), axis2)*255., trainingTrue) # 将处理后的图像以灰度图形式保存到本地磁盘 plt.imsave(img_path, np.squeeze(img), cmapgray) # 如果是有缺陷damaged样本则直接恢复像素范围并保存 else: img_path f{path}/damaged/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) # 记录图像保存路径与角度的映射关系 metadata[img_path] angle return metadata # 针对测试集生成本地图像目录不应用数据增强 def generate_test_dirs(self): # 创建测试集存放的目标路径结构 path f./dataset/{self.name} os.makedirs(f{path}/good/) os.makedirs(f{path}/damaged/) gen self.generate_img_arr() metadata {} # 遍历生成器产出的数据直接归一化恢复并保持原图保存 for i, data in enumerate(gen): img, label, angle data if label good: img_path f{path}/{label}/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) else: img_path f{path}/damaged/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) # 记录图像保存路径与角度元数据 metadata[img_path] angle return metadata # 执行入口根据数据集类型train / test调度对应的解析与保存函数 def to_storage(self): if self.name train: self.generate_train_dirs() elif self.name test: self.generate_test_dirs() # ---------------------------------------------------------------------- # 实例化转换类并分别生成训练集与测试集的本地图像数据 # ---------------------------------------------------------------------- # 实例化训练集生成器对象并执行转换与保存 train_gen H5ToStorage(/kaggle/input/textiledefectdetection/matchingtDATASET_train_64.h5, train) train_dict train_gen.to_storage() # 实例化测试集生成器对象并执行转换与保存 test_gen H5ToStorage(/kaggle/input/textiledefectdetection/matchingtDATASET_train_64.h5, test) test_dict test_gen.to_storage()4.3特征工程完成本地图像文件的保存后我们需要借助 TensorFlow 的tf.keras.utils.image_dataset_from_directory接口将硬盘上的图像文件加载为内存中的高性能数据管道Data Pipeline。在此阶段我们设置图像分辨率为 64 x 64色彩模式为灰度图grayscale同时采用prefetch和cache优化内存读取效率以极大提升后续模型训练时的吞吐速度。# ---------------------------------------------------------------------- # 1. 定义训练集与测试集本地路径 # ---------------------------------------------------------------------- test_dir /kaggle/working/dataset/test train_dir /kaggle/working/dataset/train # ---------------------------------------------------------------------- # 2. 构建训练集数据管道Data Pipeline # ---------------------------------------------------------------------- IMG_SIZE (64, 64) # 统一将输入图像尺寸调整为 64x64 像素 # 从本地目录批量加载训练集图像自动根据子文件夹名称damaged / good分配整数标签 train_data tf.keras.utils.image_dataset_from_directory(directorytrain_dir, image_sizeIMG_SIZE, color_modegrayscale, label_modeint, # 标签编码形式为整数数字类型 [0, 1] batch_size64) # 设定批次大小Batch Size为 64 # 获取并打印训练集中的类别名称映射 class_names train_data.class_names print(fThe class_names are as follows: {class_names}) # 启用数据管道性能优化利用预取prefetch和缓存cache加速 GPU 训练过程中的数据加载 train_data train_data.prefetch(buffer_sizetf.data.AUTOTUNE).\ cache() # ---------------------------------------------------------------------- # 3. 构建测试集数据管道 # ---------------------------------------------------------------------- # 从本地目录加载测试集图像设置为不打乱顺序shuffleFalse确保预测结果与真实标签对应 test_data tf.keras.utils.image_dataset_from_directory(directorytest_dir, image_sizeIMG_SIZE, color_modegrayscale, shuffleFalse, batch_size64, label_modeint) # 针对测试集数据管道开启 prefetch 与 cache 性能优化 test_data test_data.prefetch(buffer_sizetf.data.AUTOTUNE).\ cache()经过数据预处理阶段的数据增强对无缺陷图像进行翻转扩充后我们需要再次统计并绘制当前训练集中“有缺陷damaged”与“无缺陷good”图像的数量占比以验证增强后的数据集类别比例是否得到显著改善。# ---------------------------------------------------------------------- # 4. 重新统计经过增强处理后的训练集类别数量与占比 # ---------------------------------------------------------------------- # 统计 damaged 子目录下扩充后的图像总数 damaged_counts 0 for _ in os.listdir(f{train_dir}/damaged): damaged_counts 1 # 统计 good 子目录下扩充后的图像总数 good_counts 0 for _ in os.listdir(f{train_dir}/good): good_counts 1 # 计算训练集图像总数 total damaged_counts good_counts # 构建包含各类占比数据的 Pandas Series 对象并四舍五入保留两位小数 new_train_df64 pd.Series({damaged: damaged_counts/total, good: good_counts/total}).round(2) # ---------------------------------------------------------------------- # 5. 绘制增强后的类别分布百分比柱状图 # ---------------------------------------------------------------------- (new_train_df64*100).to_frame().plot.bar(legendFalse, figsize(8, 6)) plt.xlabel(Classes, fontsize18) plt.ylabel(Count (%), fontsize18) plt.title(Distribution of Classes, fontsize20) plt.xticks(rotation0, fontsize15) plt.show()为了直观检查图像数据管道加载的效果以及图像像素是否保持正常我们编写一个可视化函数explore_data。该函数通过随机打乱shuffle并抽取部分批次图像以多行多列网格Grid的形式随机展示训练集中的图像及其对应的分类标签。# ---------------------------------------------------------------------- # 6. 定义并执行训练集图像可视化数据探索函数 # ---------------------------------------------------------------------- def explore_data(n_rows, n_cols, figsize): count 0 # 创建指定行数和列数的子图画布 fig, axs plt.subplots(n_rows, n_cols, figsizefigsize) fig.suptitle(Training Data Exploration, fontsize18, y0.95) # 从打乱后的数据集中随机抽取 1 个 batch 并解包unbatch与子图网格一一对应绑定 for data, ax in zip(train_data.shuffle(10000).take(1).unbatch(), axs.ravel()): img, label data # 关闭坐标轴显示 ax.axis(off) # 将子图标题设置为具体的类别名称damaged 或 good ax.set_title(f{class_names[label]}) # 以灰度色彩映射显示单通道图像 ax.imshow(np.squeeze(img), cmapgray) count 1 # 当绘制数量达到预设的子图网格总量n_rows * n_cols时停止循环 if count n_rows * n_cols: break; # 调用探索函数绘制 2 行 6 列共 12 张图像样本进行可视化检验 explore_data(n_rows2, n_cols6, figsize(15, 6))4.4构建模型在模型构建阶段我们借助迁移学习Transfer Learning技术调用 TensorFlow Hub 上预训练的BiT-ResNet50 (Big Transfer ResNet50)作为基础特征提取器。由于 BiT-ResNet50 模型的标准输入需要 3 通道RGB图像而我们的数据集为 1 通道灰度图因此我们在模型最前端巧用 1 x 1 的卷积层Conv2D将通道数从 1 扩展至 3。随后接上预训练特征提取层设置为不可训练trainableFalse以冻结权重最后叠加全连接层与 Sigmoid 激活函数构建出一个高效的二分类识别网络。# ---------------------------------------------------------------------- # 1. 从 TensorFlow Hub 加载预训练的 BiT-ResNet50 特征提取器 # ---------------------------------------------------------------------- import tensorflow_hub as hub # 加载基于 ImageNet-21k 预训练的 BiT-ResNet50 模型层并将权重冻结trainableFalse module hub.KerasLayer(https://tfhub.dev/google/experts/bit/r50x1/in21k/angiosperm/1, trainableFalse, namefeature_extraction_layer, input_shapeIMG_SIZE(3,)) # ---------------------------------------------------------------------- # 2. 构建 Sequential 顺序分类模型 # ---------------------------------------------------------------------- model tf.keras.Sequential( [ # 使用 1x1 卷积将单通道灰度图 (64, 64, 1) 升维映射为 3 通道 (64, 64, 3)以适配 BiT-ResNet50 的输入格式需求 tf.keras.layers.Conv2D(3, 1, paddingsame, activationrelu), # 预训练特征提取层提取图像的高阶抽象特征 module, # 隐藏全连接层256 个神经元采用 ReLU 激活函数 tf.keras.layers.Dense(256, activationrelu, namedense_layer), # 输出层单个神经元采用 Sigmoid 激活函数用于二分类概率输出 0~1 tf.keras.layers.Dense(1, activationsigmoid, nameoutput_layer) ] ) # ---------------------------------------------------------------------- # 3. 显式指定输入形状构建模型并打印模型结构摘要 # ---------------------------------------------------------------------- # 传入单通道图像张量形状 (Batch_Size, Height, Width, Channels) model.build((None, 64, 64, 1)) # 查看网络各层参数量与结构细节 model.summary()构建好网络拓扑结构后我们可以使用 Keras 提供的plot_model工具将模型架构绘制成直观的流程图。这不仅方便检查输入/输出张量在各个网络层之间的形状变化Shapes还能在博客中更清晰地向读者展示模型的整体层次结构。# ---------------------------------------------------------------------- # 4. 可视化绘制模型网络结构拓扑图 # ---------------------------------------------------------------------- tf.keras.utils.plot_model( model, # to_filemodel.png, # 如需保存图片到本地取消此行注释即可 show_shapesTrue, # 显示各层的输入输出张量形状Shape show_dtypeFalse, # 不显示数据类型 show_layer_namesTrue, # 显示各层的名称 rankdirTB, # 图像排布方向从上到下Top to Bottom expand_nestedFalse, # 不展开嵌套模型 dpi96, # 图像输出分辨率 layer_rangeNone, # 绘制所有层 )4.5训练模型在完成模型结构的搭建后我们需要对其进行编译Compile。由于本项目是二分类任务损失函数选择二元交叉熵BinaryCrossentropy优化器采用Adam算法初始学习率设为 0.01并选用准确率accuracy作为评估指标。在正式开始训练fit时我们将训练集数据输入网络设定训练轮数为 10并传入测试集作为验证集来实时监控模型的泛化性能。同时引入回调函数Callbacks以实现动态调整学习率与提前终止训练防止模型过拟合。# ---------------------------------------------------------------------- # 1. 配置损失函数、优化器与评估指标编译模型 # ---------------------------------------------------------------------- # 定义二分类交叉熵损失函数因为输出层已使用 Sigmoid 激活函数所以 from_logitsFalse binary_categorical_loss tf.keras.losses.BinaryCrossentropy(from_logitsFalse) # 定义 Adam 优化器设置初始学习率为 0.01 optimizer tf.keras.optimizers.Adam(learning_rate0.01) # 编译模型组装损失函数、优化器和准确率评估指标 model.compile( lossbinary_categorical_loss, optimizeroptimizer, metrics[accuracy] ) # ---------------------------------------------------------------------- # 2. 设置训练超参数并启动模型训练 # ---------------------------------------------------------------------- EPOCHS 10 # 设定总训练轮数为 10 STEPS_PER_EPOCH len(train_data) # 计算每个 Epoch 的迭代步数等于训练集批次总量 # 执行模型训练并将训练过程中的 Loss 和 Accuracy 历史指标保存至 training_history_1 training_history_1 model.fit(train_data, epochsEPOCHS, steps_per_epochSTEPS_PER_EPOCH, validation_datatest_data.shuffle(10000), # 使用打乱后的测试集作为验证集 validation_stepsint(0.5 * len(test_data)), # 每次验证时仅使用 50% 的测试数据进行快速评估 callbacks[reduce_lr, early_stopping] # 加入回调函数以动态调参和防止过拟合 )4.6模型评估在模型训练完成后我们需要在测试集上对其进行全面评估。评估过程分为三个阶段首先在整个测试集上计算最终的损失值Loss与准确率Accuracy其次通过绘制训练与验证曲线直观观察模型的收敛轨迹最后获取测试集的真实标签与模型预测概率生成详细的分类评估报告包含精确率 Precision、召回率 Recall 以及 F1 分数。首先调用model.evaluate函数在测试集上进行整体性能评估# ---------------------------------------------------------------------- # 1. 在完整的测试数据集上评估模型性能输出 Loss 和 Accuracy # ---------------------------------------------------------------------- model.evaluate(test_data)其次传入训练历史记录training_history_1绘制训练集与验证集在各个 Epoch 下的损失曲线和准确率变化曲线# ---------------------------------------------------------------------- # 2. 绘制训练与验证过程中的评估曲线损失曲线与准确率曲线 # ---------------------------------------------------------------------- plot_evaluation_curves(training_history_1, 2)最后获取测试集的真实标签y_labels_1与预测概率y_preds_1将连续的预测概率通过四舍五入np.round转化为 0/1 二分类预测值并打印分类性能报告# ---------------------------------------------------------------------- # 3. 提取测试集的真实标签与模型预测值生成详细分类评估报告 # ---------------------------------------------------------------------- # 调用自定义函数提取测试集中的真实标签 (y_labels_1) 和预测概率 (y_preds_1) y_labels_1, y_preds_1 get_labels(test_data, model) # 打印分类报告表头 print(\n\n############### Classification Report ###############\n\n) # 对预测概率进行四舍五入二值化0.5 判定为 10.5 判定为 0并计算各项评估指标 print(classification_report(y_labels_1, np.round(y_preds_1)))5.总结本项目针对纺织面料生产中偶发性缺陷难以高效识别的痛点基于 Kaggle 纺织品缺陷检测数据集构建并实现了一套基于 BiT-ResNet50 迁移学习的智能图像识别方案。通过对 HDF5 格式图像数据的离线解析与数据增强有效克服了原始样本类别不平衡的问题并结合 $1 \times 1$ 卷积降维映射与 TensorFlow 高性能数据管道完成了高效的模型训练与验证。实验结果表明该模型在包含 72,000 个测试样本的验证集上展现出了极其卓越的泛化能力与鲁棒性测试集 Loss 低至 0.0081整体准确率达到 99.74%且各类别的 Precision、Recall 和 F1-score 均保持在 0.99 以上的高水准充分证实了 BiT-ResNet50 架构在纺织品微小缺陷检测任务中的实用价值与高精度表现。源代码# import the libraries import os import glob import pickle import tensorflow as tf # used for creating tensors out of the dataset and training the model import tensorflow_hub as hub # downloading and using pre-trained models import numpy as np import h5py # to manipulate the dataset as its in .h5 format import pandas as pd import plotly.express as px import matplotlib.pyplot as plt from sklearn.metrics import classification_report # essential for models evaluation from sklearn.metrics import f1_score from tqdm import tqdm # getting a progress bar for an iterable object # load the train64.csv file train_df64 pd.read_csv(/kaggle/input/textiledefectdetection/train64.csv) train_df64[indication_type] train_df64.indication_type.apply(lambda row: damaged if row!good else good) train_df64[indication_value] train_df64.indication_value.apply(lambda row: 1 if row!0 else 0) train_df64.head() # plot the distribution of classes (train_df64.indication_type.value_counts(normalizeTrue).round(2)*100).to_frame().plot.bar(legendFalse, figsize(8, 6)) plt.xlabel(Classes, fontsize18) plt.ylabel(Count (%), fontsize18) plt.title(Distribution of Classes, fontsize20) plt.xticks(rotation0, fontsize15); # create an object that will take the dataset and produce the dataset in a format required for tensorflow datasets API class H5ToStorage: def __init__(self, hdf_path, ds_nametrain): self.path hdf_path self.classes [] with h5py.File(self.path, r) as hf: for class_ in hf: self.classes.append(class_) self.name ds_name # a generator to load the (img, class, angle) def generate_img_arr(self): for class_ in self.classes: with h5py.File(self.path, r) as hf: for angle in hf[class_]: for img in hf[class_][f{angle}]: yield img, class_, angle # utilize the generator to create new images and load it back to Storage def generate_train_dirs(self): # create the datasets directories path f./dataset/{self.name} os.makedirs(f{path}/good/) os.makedirs(f{path}/damaged/) # random_bright tf.keras.layers.RandomBrightness(factor0.05) random_flip tf.keras.layers.RandomFlip(horizontal_and_vertical) gen self.generate_img_arr() metadata {} for i, data in enumerate(gen): img, label, angle data if label good: for j in range(4): img_path f{path}/{label}/{i}_aug{j}.jpeg img random_flip(tf.expand_dims(np.squeeze(img), axis2)*255., trainingTrue) plt.imsave(img_path, np.squeeze(img), cmapgray) else: img_path f{path}/damaged/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) metadata[img_path] angle return metadata def generate_test_dirs(self): # create the datasets directories path f./dataset/{self.name} os.makedirs(f{path}/good/) os.makedirs(f{path}/damaged/) gen self.generate_img_arr() metadata {} for i, data in enumerate(gen): img, label, angle data if label good: img_path f{path}/{label}/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) else: img_path f{path}/damaged/{i}.jpeg plt.imsave(img_path, np.squeeze(img)*255., cmapgray) metadata[img_path] angle return metadata def to_storage(self): if self.name train: self.generate_train_dirs() elif self.name test: self.generate_test_dirs() # generate train data train_gen H5ToStorage(/kaggle/input/textiledefectdetection/matchingtDATASET_train_64.h5, train) train_dict train_gen.to_storage() # generate test data test_gen H5ToStorage(/kaggle/input/textiledefectdetection/matchingtDATASET_train_64.h5, test) test_dict test_gen.to_storage() # train data test data paths test_dir /kaggle/working/dataset/test train_dir /kaggle/working/dataset/train # create train data pipeline IMG_SIZE (64, 64) # define image size train_data tf.keras.utils.image_dataset_from_directory(directorytrain_dir, image_sizeIMG_SIZE, color_modegrayscale, label_modeint, # label type is encoding of the form [1, 2, 3, ...] batch_size64) # batch_size is 32 by default, but 128 will be used for this use-case # classes in train_data class_names train_data.class_names print(fThe class_names are as follows: {class_names}) train_data train_data.prefetch(buffer_sizetf.data.AUTOTUNE).\ cache() # create test data pipeline test_data tf.keras.utils.image_dataset_from_directory(directorytest_dir, image_sizeIMG_SIZE, color_modegrayscale, shuffleFalse, batch_size64, label_modeint) test_data test_data.prefetch(buffer_sizetf.data.AUTOTUNE).\ cache() # check the proportions of classes damaged_counts 0 for _ in os.listdir(f{train_dir}/damaged): damaged_counts 1 good_counts 0 for _ in os.listdir(f{train_dir}/good): good_counts 1 total damaged_counts good_counts new_train_df64 pd.Series({damaged: damaged_counts/total, good: good_counts/total}).round(2) # check the classes distribution (new_train_df64*100).to_frame().plot.bar(legendFalse, figsize(8, 6)) plt.xlabel(Classes, fontsize18) plt.ylabel(Count (%), fontsize18) plt.title(Distribution of Classes, fontsize20) plt.xticks(rotation0, fontsize15) plt.show() # explore the train data def explore_data(n_rows, n_cols, figsize): count 0 fig, axs plt.subplots(n_rows, n_cols, figsizefigsize) # plot 20 figures fig.suptitle(Training Data Exploration, fontsize18, y0.95) for data, ax in zip(train_data.shuffle(10000).take(1).unbatch(), axs.ravel()): img, label data ax.axis(off) ax.set_title(f{class_names[label]}) ax.imshow(np.squeeze(img), cmapgray) count1 if count n_rows*n_cols: break; explore_data(n_rows2, n_cols6, figsize(15, 6)) import tensorflow_hub as hub # feature extractor trained on angiosperms module hub.KerasLayer(https://tfhub.dev/google/experts/bit/r50x1/in21k/angiosperm/1, trainableFalse, namefeature_extraction_layer, input_shapeIMG_SIZE(3,)) # build the sequential model model tf.keras.Sequential( [ tf.keras.layers.Conv2D(3, 1, paddingsame, activationrelu), # the following feature extraction layer wont accept the data of shape (None, 64, 64, 1) # to solve this issue, it is required that the channels are expanded form 1 to 3 by using 1x1 convolution module, # feature extractor layer tf.keras.layers.Dense(256, activationrelu, namedense_layer), tf.keras.layers.Dense(1, activationsigmoid, nameoutput_layer) # making predictions ] ) # build the model and check summary model.build((None, 64, 64, 1)) model.summary() # plot the model tf.keras.utils.plot_model( model, # to_filemodel.png, show_shapesTrue, show_dtypeFalse, show_layer_namesTrue, rankdirTB, expand_nestedFalse, dpi96, layer_rangeNone, ) # Define the loss function binary_categorical_loss tf.keras.losses.BinaryCrossentropy(from_logitsFalse) # Define the optimizer optimizer tf.keras.optimizers.Adam(learning_rate0.01) # Compile the model model.compile( lossbinary_categorical_loss, optimizeroptimizer, metrics[accuracy] ) # train the model EPOCHS 10 STEPS_PER_EPOCH len(train_data) training_history_1 model.fit(train_data, epochsEPOCHS, steps_per_epochSTEPS_PER_EPOCH, validation_datatest_data.shuffle(10000), validation_stepsint(0.5 * len(test_data)), callbacks[reduce_lr, early_stopping] ) model.evaluate(test_data) plot_evaluation_curves(training_history_1, 2) # create classification_report y_labels_1, y_preds_1 get_labels(test_data, model) print(\n\n############## Classification Report ###############\n\n) print(classification_report(y_labels_1, np.round(y_preds_1)))资料获取更多粉丝福利关注下方公众号获取
返回列表