首页/新闻资讯/正文详情

T7周:咖啡豆识别

发布时间:2026/9/26 11:13:21 来源:云帆数科 栏目:资讯中心
T7周:咖啡豆识别
本文为365天深度学习训练营中的学习记录博客原作者K同学啊学习目的 要求自己搭建VGG-16网络框架调用官方的VGG-16网络框架 拔高可选验证集准确率达到100%使用PPT画出VGG-16算法框架图发论文需要这项技能 探索难度有点大在不影响准确率的前提下轻量化模型○ 目前VGG16的Total params是134,276,932一、 前期准备关于环境语言环境Python3.6编译器vsCode深度学习环境TensorFlow 2.6.21.数据导入import tensorflow as tf import os,PIL,pathlib import matplotlib.pyplot as plt import numpy as np from tensorflow import keras from tensorflow.keras import layers,modelsdata_dir C:/Users/hsq/Desktop/train/D7/ data_dir pathlib.Path(data_dir)image_count len(list(data_dir.glob(*/*.png))) print(图片总数为,image_count)注意图片后缀格式格式不对读出来的图片数量可能为0二、数据预处理1. 加载数据使用image_dataset_from_directory方法将磁盘中的数据加载到tf.data.Dataset中batch_size 32 img_height 224 img_width 224 关于image_dataset_from_directory()的详细介绍可以参考文章https://mtyjkh.blog.csdn.net/article/details/117018789 train_ds tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split0.2, subsettraining, seed123, image_size(img_height, img_width), batch_sizebatch_size)代码运行结果 关于image_dataset_from_directory()的详细介绍可以参考文章https://mtyjkh.blog.csdn.net/article/details/117018789 val_ds tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split0.2, subsetvalidation, seed123, image_size(img_height, img_width), batch_sizebatch_size)代码运行结果注意划分比例0.1、0.2、0.3训练集和验证集划分数量不同class_names train_ds.class_names print(class_names)代码运行结果本次为4分类任务2. 可视化数据plt.figure(figsize(10, 4)) # 图形的宽为10高为5 for images, labels in train_ds.take(1): for i in range(10): ax plt.subplot(2, 5, i 1) plt.imshow(images[i].numpy().astype(uint8)) plt.title(class_names[labels[i]]) plt.axis(off)代码运行结果3. 再次检查数据for image_batch, labels_batch in train_ds: print(image_batch.shape) print(labels_batch.shape) break代码运行结果Image_batch是形状的张量32,224,224,3。这是一批形状224x224x3的32张图片Label_batch是形状32的张量这些标签对应32张图片共4个标签4. 配置数据集shuffle()打乱数据prefetch()预取数据加速运行。cache()将数据集缓存到内存当中加速运行AUTOTUNE tf.data.AUTOTUNE train_ds train_ds.cache().shuffle(1000).prefetch(buffer_sizeAUTOTUNE) val_ds val_ds.cache().prefetch(buffer_sizeAUTOTUNE)normalization_layer layers.experimental.preprocessing.Rescaling(1./255) train_ds train_ds.map(lambda x, y: (normalization_layer(x), y)) val_ds val_ds.map(lambda x, y: (normalization_layer(x), y))image_batch, labels_batch next(iter(val_ds)) first_image image_batch[0] # 查看归一化后的数据 print(np.min(first_image), np.max(first_image))代码运行结果三、调用官方VGG-16from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input from tensorflow.keras.preprocessing import image # 加载VGG16卷积部分冻结权重 base_model VGG16(weightsimagenet, include_topFalse, input_shape(224,224,3)) base_model.trainable True # 冻结预训练参数 for layer in base_model.layers: if layer.name.startswith(block5): layer.trainable True else: layer.trainable False # 构建自己的分类头 inputs tf.keras.Input(shape(224,224,3)) x preprocess_input(inputs) x base_model(x, trainingFalse) x tf.keras.layers.GlobalAveragePooling2D()(x) outputs tf.keras.layers.Dense(4, activationsoftmax)(x) # 4分类 model tf.keras.Model(inputs, outputs) model.summary()注意分类头标签数量修改代码运行结果四、训练模型1.设置动态学习率# 设置初始学习率 initial_learning_rate 1e-4 lr_schedule tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate, decay_steps60, # 敲黑板这里是指 steps不是指epochs decay_rate0.96, # lr经过一次衰减就会变成 decay_rate*lr staircaseTrue) # 将指数衰减学习率送入优化器 optimizer tf.keras.optimizers.Adam(learning_ratelr_schedule) model.compile(optimizeroptimizer, losstf.keras.losses.CategoricalCrossentropy(from_logits True), metrics[accuracy])2.早停与保存最佳模型参数from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping epochs 100 # 保存最佳模型参数 checkpointer ModelCheckpoint(best_model.h5, monitorval_accuracy, verbose1, save_best_onlyTrue, save_weights_onlyTrue) # 设置早停 earlystopper EarlyStopping(monitorval_accuracy, min_delta0.001, patience20, verbose1)3. 模型训练history model.fit(train_ds, validation_dataval_ds, epochsepochs, callbacks[checkpointer, earlystopper])代码运行结果五、模型评估1. Loss与Accuracy图from datetime import datetime current_time datetime.now() # 获取当前时间 acc history.history[accuracy] val_acc history.history[val_accuracy] loss history.history[loss] val_loss history.history[val_loss] epochs_range range(len(loss)) plt.figure(figsize(12, 4)) plt.subplot(1, 2, 1) plt.plot(epochs_range, acc, labelTraining Accuracy) plt.plot(epochs_range, val_acc, labelValidation Accuracy) plt.legend(loclower right) plt.title(Training and Validation Accuracy) plt.xlabel(current_time) # 打卡请带上时间戳否则代码截图无效 plt.subplot(1, 2, 2) plt.plot(epochs_range, loss, labelTraining Loss) plt.plot(epochs_range, val_loss, labelValidation Loss) plt.legend(locupper right) plt.title(Training and Validation Loss) plt.show()代码运行结果验证集预测效果未达100%对模型进行解冻from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input from tensorflow.keras.preprocessing import image # 加载VGG16卷积部分冻结权重 base_model VGG16(weightsimagenet, include_topFalse, input_shape(224,224,3)) base_model.trainable True # 冻结预训练参数 for layer in base_model.layers: if layer.name.startswith(block5): layer.trainable True else: layer.trainable False # 构建自己的分类头 inputs tf.keras.Input(shape(224,224,3)) x preprocess_input(inputs) x base_model(x, trainingFalse) x tf.keras.layers.GlobalAveragePooling2D()(x) outputs tf.keras.layers.Dense(17, activationsoftmax)(x) # 10分类 model tf.keras.Model(inputs, outputs) model.summary()代码运行结果仅提升至89%六、手动搭建VGG-16模型这是之前学习Pytorch时使用PPT制作的结构框架图from tensorflow.keras import layers, models, Input from tensorflow.keras.models import Model from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout def VGG16(nb_classes, input_shape): input_tensor Input(shapeinput_shape) # 1st block x Conv2D(64, (3,3), activationrelu, paddingsame,nameblock1_conv1)(input_tensor) x Conv2D(64, (3,3), activationrelu, paddingsame,nameblock1_conv2)(x) x MaxPooling2D((2,2), strides(2,2), name block1_pool)(x) # 2nd block x Conv2D(128, (3,3), activationrelu, paddingsame,nameblock2_conv1)(x) x Conv2D(128, (3,3), activationrelu, paddingsame,nameblock2_conv2)(x) x MaxPooling2D((2,2), strides(2,2), name block2_pool)(x) # 3rd block x Conv2D(256, (3,3), activationrelu, paddingsame,nameblock3_conv1)(x) x Conv2D(256, (3,3), activationrelu, paddingsame,nameblock3_conv2)(x) x Conv2D(256, (3,3), activationrelu, paddingsame,nameblock3_conv3)(x) x MaxPooling2D((2,2), strides(2,2), name block3_pool)(x) # 4th block x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock4_conv1)(x) x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock4_conv2)(x) x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock4_conv3)(x) x MaxPooling2D((2,2), strides(2,2), name block4_pool)(x) # 5th block x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock5_conv1)(x) x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock5_conv2)(x) x Conv2D(512, (3,3), activationrelu, paddingsame,nameblock5_conv3)(x) x MaxPooling2D((2,2), strides(2,2), name block5_pool)(x) # full connection x Flatten()(x) x Dense(4096, activationrelu, namefc1)(x) x Dense(4096, activationrelu, namefc2)(x) output_tensor Dense(nb_classes, activationsoftmax, namepredictions)(x) model Model(input_tensor, output_tensor) return model modelVGG16(len(class_names), (img_width, img_height, 3)) model.summary()代码运行结果手动搭建模型验证集准确率达99%五、轻量化模型1.替换全连接层为全局平均池化GAP这是VGG-16轻量化最应该做的一步。VGG-16的3个全连接层FC占了整个模型约 90% 的参数约1.2亿。做法移除最后的 Flatten FC(4096) FC(4096) FC(1000)改为 GlobalAveragePooling2D() 直接接 FC(1000)。效果参数量瞬间从 1.38亿 降至 ~1500万。精度影响由于GAP相当于强制让每个特征图对应一个类别不仅不掉点反而能提升泛化能力防止全连接层过拟合。在ImageNet上原版VGG-16 Top-1准确率约71.5%改为GAP后约71.2% 仅降0.3%但体积缩小十倍。2.通道剪枝Channel Pruning—— 针对卷积层移除3个FC后剩下的2000万参数主要来自卷积层。VGG-16的通道数64→128→256→512存在大量冗余。做法在训练后计算每个卷积核的 L1/L2范数权重绝对值之和剪掉贡献最小范数最低的20%~30%通道。然后在小学习率下微调Fine-tune3~5个epoch。效果FLOPs计算量减少约 30%~40%。精度影响微调后精度通常能 恢复到原模型的98%~99%即Top-1下降约0.5%~1%。3.SVD 矩阵 分解 —— 专门针对全连接层如果你坚持保留FC如果你不愿用GAP仍想保留FC层可以用 SVD奇异值分解 对 FC(4096) 的权重矩阵进行低秩近似。做法将 4096 x 25088 的巨型矩阵拆解为两个小矩阵相乘中间插入一个低秩层如 FC(1024)将参数量从 1亿 压缩到 4000万。精度影响无需重新训练直接分解后进行单精度微调精度损失可控制在 0.2% 以内。4.替换为深度 可分离卷积Depthwise Separable Conv—— 针对卷积块这是最激进的轻量化方式将每个 3x3 Conv 替换为 深度卷积DW 逐点卷积PW。做法把 Conv3-64 替换为 DepthwiseConv2D(3x3) Conv2D(1x1)计算量可减少约 8~9倍。精度影响如果从头训练精度下降明显约5%~8%。但如果你先训练好原版VGG-16然后进行“知识蒸馏”用原版作为教师网络指导学生网络精度可维持在 71% 左右几乎不掉点。5.INT8 量化纯推理 阶段—— 完全不影响模型结构这是唯一能在“不改动任何网络结构”前提下实现轻量化的方法。做法训练完成后使用 TensorRT 或 PyTorch 的 torch.quantization 将权重和激活从 FP32 转为 INT8。效果模型体积缩小为原来的 1/4推理速度提升 2~3倍在CPU上尤为明显。精度影响通过“校准Calibration”数据集在ImageNet上INT8量化后Top-1精度损失通常 0.5%几乎可以忽略不计。六、感想本周在Tensorflow上继续学习调用预训练模型进一步熟悉了VGG-16模型架构的搭建。关于模型轻量化仅简单了解有待深入学习。

相关推荐

软件工程的术语大全 · 庖丁解牛
软件工程的术语大全 · 庖丁解牛

根因 早期软件是作坊式开发,想到哪里写到哪里,缺少规范。项目常常出现需求频繁变更、工期失控、BUG堆积、代码难以维护、交付延期、上线即崩溃,项目失败率极高。 软件工程,就是把工程化思维引入软件研发,用一套标准化流… · 2026/9/26 11:13:15

P1040 加分二叉树【洛谷算法习题】
P1040 加分二叉树【洛谷算法习题】

P1040 加分二叉树 网页链接 P1040 加分二叉树 题目描述 设一个 nnn 个节点的二叉树 tree\text{tree}tree 的中序遍历为(1,2,3,…,n)(1,2,3,\ldots,n)(1,2,3,…,n),其中数字 1,2,3,…,n1,2,3,\ldots,n1,2,3,…,n 为节点编号。每个节点都有一个分数(均… · 2026/9/26 11:13:15

《深度学习》期末练习题 | 判断题第4篇(逐题精讲)
《深度学习》期末练习题 | 判断题第4篇(逐题精讲)

《深度学习》期末练习题 | 判断题第4篇(逐题精讲) 前言:本篇为《深度学习》期末练习题判断题系列的第4篇,涵盖题号 49~56,涉及自注意力机制、Transformer、YOLOv5 目标检测、COCO/VOC 数据集等核心知识点。每道题均附详… · 2026/9/26 11:13:15

Claude Code 实战:AI 结对编程如何真正提效:从踩坑到可复用方案(TaoToken 统一 Key 配置篇)
Claude Code 实战:AI 结对编程如何真正提效:从踩坑到可复用方案(TaoToken 统一 Key 配置篇)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:56:07

多通道返回多条结果,最终给模型几条?TaoToken 配置骨架与验证动作
多通道返回多条结果,最终给模型几条?TaoToken 配置骨架与验证动作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:56:07

企业级大模型自迭代平台:小时级LoRA闭环与Mint Recursive实践
企业级大模型自迭代平台:小时级LoRA闭环与Mint Recursive实践

1. “自迭代后训练平台”不是口号,而是企业模型演进的基础设施重构 “做一个能自迭代的后训练平台,Mind Lab要让更多企业拥有自己的模型”——这句话乍看像一句宣传语,但拆开来看,它其实精准锚定了当前大模型落地最痛的三个断层&a… · 2026/9/26 12:56:01

大模型提示词语义缓存与可观测性诊断系统实战
大模型提示词语义缓存与可观测性诊断系统实战

1. 项目概述:这不是“缓存优化”,而是提示工程基础设施的范式升级最近看到不少同行在技术群和论坛里刷屏讨论“OpenAI为GPT-6推出改进的提示词缓存系统与诊断工具”这个消息,但翻遍OpenAI官网、GitHub仓库、官方博客和开发者文档,… · 2026/9/26 12:56:01

自蒸馏提升AI工具调用成功率的实战方法
自蒸馏提升AI工具调用成功率的实战方法

1. 项目概述:当大模型“自己教自己”来稳住工具调用这根弦你有没有遇到过这样的场景:一个精心设计的AI工作流,前端界面丝滑,提示词反复打磨,API密钥配置无误,可一到关键步骤——比如查实时股价、调数据库、… · 2026/9/26 12:56:01

K8S常见Ingress Controller类型盘点:用TaoToken统一Key接入AI辅助排障的配置骨架
K8S常见Ingress Controller类型盘点:用TaoToken统一Key接入AI辅助排障的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:55:24

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码