知识蒸馏之手写体识别

Paddle OCR v4 微调训练文字识别SVTRNet模型实践 paddle ocr v4 微调训练文字识别模型实践 阅读详情

知识蒸馏

本文主要是根据该网站视频(https://www.bilibili.com/video/BV1s7411h7K2?t=906)进行总结,如有理解误差,望批评指点

1. 首次提出

首次提出:https://arxiv.org/pdf/1503.02531.pdf
作者的动机是想找到一个方法,把多个模型的知识提炼给单个模型。
虽然现在很多分类模型都采用交叉熵衡量预测值与真实值,然而真实值采用的one-hot向量所能提共的信息没有概率分布多。
原理:概率分布比onehot更能提供信息-暗知识。
loss=0.7KL散度(softmax_t(老师输出))+0.3交叉熵(oneHot)
两个分布的loss可以用KL散度。

2. 简单介绍

知识蒸馏,可以将一个网络的知识转移到另一个网络,两个网络可以是同构或者异构。做法是先训练一个teacher网络,然后使用这个teacher网络的输出和数据的真实标签去训练student网络。知识蒸馏,可以用来将网络从大网络转化成一个小网络,并保留接近于大网络的性能;也可以将多个网络的学到的知识转移到一个网络中,使得单个网络的性能接近emsemble的结果。

例如:水果蔬菜分类
在这里插入图片描述

3.pytorch中的一些损失函数

在这里插入图片描述

log_softmax_p = torch.log(torch.softmax(p))
loss1= F.nll_loss(log_softmax_p ,target)
loss2 = F.cross_entropy(p,target))
loss1 == loss2

在这里插入图片描述

4. 核心

在这里插入图片描述

当没有老师网络时候,仅仅将图像经过student网络,softmax之后,输出概率分布值q,将q与真实值求loss就是称为Hard loss,因为这个p是真实值的one-hot向量,我们希望q和p越接近越好。
当有老师的帮助下的时候,loss来自student和teacher 网络。且,老师输出的q‘要经过蒸馏之后(让它更加平滑)得到q’‘再与q求loss,总loss,是它们之间的和。

5. 理论分析

在这里插入图片描述
通过引入软目标:soft-target作为total loss的一部分,诱导学生网络以精简,低复杂度的训练,实现知识迁移。
其中total loss的设计采用的是 交叉熵损失和kl散度(软目标,学生预测),如上图,如果软目标交叉熵的加权系数越大,表明迁移诱导越依赖教师网络的贡献。这对训练初期是很有必要的。但是训练后期需要减少软目标的比重。

图中没加平滑时的数字识别是9,对应的概率中9的概率很小,加了平滑之后,9的比重相对而言大了。
在这里插入图片描述

6. 实例:知识蒸馏实现手写体识别

6.1 Teacher model

简单的卷积网络

class TeacherNet(nn.Module):
    def __init__(self):
        super(TeacherNet,self).__init__()
        self.conv1 = nn.Conv2d(1,32,3,1)
        self.conv2 = nn.Conv2d(32,64,3,1)
        self.dropout1 = nn.Dropout2d(0.3)
        self.dropout2 = nn.Dropout2d(0.5)
        self.fc1 = nn.Linear(9216,128)
        self.fc2 = nn.Linear(128,10)
        
    #此处没有softmax
    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x,2)
        x = self.dropout1(x)
        x = torch.flatten(x,1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        output = self.fc2(x)
        return output

6.2 Student model

更简单的线形模型

class StudentNet(nn.Module):
    def __init__(self):
        super(StudentNet,self).__init__()
        self.fc1 = nn.Linear(28*28,128)
        self.fc2 = nn.Linear(128,64)
        self.fc3 = nn.Linear(64,10)
        
    def forward(self,x):
        x = torch.flatten(x,1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        output = F.relu(self.fc3(x))
        return output
    

6.3 Teacher 教 Student

KD的Loss

def distillation(y,labels,teacher_scores,temp,alpha):
    return nn.KLDivLoss()(F.log_softmax(y/temp, dim=1),
                          F.softmax(teacher_scores/temp,dim=1))*(temp*temp*2.0*alpha)+F.cross_entropy(y,labels)*(1. - alpha)

老师教学生,前提是教师网络已经是训练好的,然后去教学生。

def train_student_kd(model,device,train_loader,optimizer,epoch):
    model.train()
    teacher_model.eval()
    trained_samples = 0
    for batch_idx,(data,target) in enumerate(train_loader):
        data,target = data.to(device),target.to(device)
        optimizer.zero_grad()
        output = model(data)
        teacher_output = teacher_model(data)
        teacher_output = teacher_output.detach()
        loss = distillation(output,target,teacher_output,temp=5.0,alpha=0.7)
        loss.backward()
        optimizer.step()
        trained_samples += len(data)
        progress = math.ceil(batch_idx / len(train_loader)*50)
        print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))
#         print("\r Train epoch %d:%d/%d"%(epoch,trained_samples,len(train_loader.dataset)))
        
def test_student_kd(model,device,test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data,target in test_loader:
            data,target = data.to(device),target.to(device)
            output = model(data)
            test_loss += F.cross_entropy(output, target, reduction='sum').item() 
            pred = output.argmax(dim=1,keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()
    test_loss /= len(test_loader.dataset)
    print("\r Test average loss:{:.4f},accuracy:{}/{}({:.0f}%)".format(test_loss,correct,len(test_loader.dataset),100.*correct/len(test_loader.dataset)))
    return test_loss, correct/len(test_loader.dataset)

    
def student_kd_main():
    epochs = 10
    batch_size = 64
    torch.manual_seed(0)
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    train_loader = torch.utils.data.DataLoader(datasets.MNIST('../data/MNIST',train=True,download=False,
                                                             transform=transforms.Compose([
                                                                 transforms.ToTensor(),
                                                                 transforms.Normalize((0.1307,),(0.3081,))
                                                             ])),
                                              batch_size=batch_size,shuffle=True)
    
    test_loader = torch.utils.data.DataLoader(datasets.MNIST('../data/MNIST',train=False,download=False,
                                                             transform=transforms.Compose([
                                                                 transforms.ToTensor(),
                                                                 transforms.Normalize((0.1307,),(0.3081,))
                                                             ])),
                                              batch_size=batch_size,shuffle=True)
    
    model = StudentNet().to(device)
    teacher_model = TeacherNet()
    teacher_model.load_state_dict(torch.load('teacher.pth')) #加载老师网络参数
    
    optimizer = torch.optim.Adadelta(model.parameters())
    student_history = []
    for epoch in range(1,epochs+1):
        train_student_kd(model,device,train_loader,optimizer,epoch)
        loss , acc = test_student_kd(model,device,test_loader)
        student_history.append((loss,acc))
    torch.save(model.state_dict(),'student.pth')
    return model,student_history

在这里插入图片描述

保姆级教程:用PaddleOCR的PP-OCRv5_server_det模型,从零训练一个能识别手写字的文本检测器 本文详细介绍了如何使用PaddleOCR的PP-OCRv5_server_det模型从零训练一个高精度手写体文本检测器。通过分析手写体的特殊挑战,提供数据准备、模型训练和参数调优的全流程实战指南,帮助开发者解决真实场景中的手写体检测难题,提升识别准确率。 阅读详情

相关推荐

【知识蒸馏】知识蒸馏(Knowledge Distillation)技术详解

知识蒸馏综述

Roaddd的博客 4万+

算法进阶 | 深度学习知识蒸馏的研究综述(建议收藏!)

常用的模型压缩方法有4种:知识蒸馏(Knowledge Distillation,KD)、 轻量化模型架构、 剪枝(Pruning)、 量化(Quantization)。知识蒸馏是一种在深度学习中用于模型压缩和知识传递的技术。它通过将大型复杂模型(教师模型)的知识转移给小型简单模型(学生模型),从而优化学生模型的性能。

csdn_xmj的博客 6574

知识蒸馏 | 知识蒸馏的算法原理与其他拓展介绍

如有错误,恳请指出。 这篇博客将记录我看视频后对知识蒸馏的笔记,视频链接见参考资料[1],其中包含知识蒸馏的算法原理(训练流程与测试流程),以及知识蒸馏能够正常工作的背后机理与其发展的趋势及展望。 在这篇博客中,主要都是介绍没有涉及具体的代码,我另外还将会记录一下知识蒸馏的测试过程,见另外的一篇博客。 文章目录框架1. 知识蒸馏的算法原理1.1 知识的表示与迁移1.2 训练流程1.3 推理过程1.4 KD与Labe Smoothing的区别2. 知识蒸馏的应用场景3. 知识蒸馏的背后机理4. 知识蒸馏.

Clichong 8011

低分辨率人脸识别--蒸馏法《Low-resolution Face Recognition in the Wild via Selective Knowledge Distillation》

针对低分辨率图像识别,模糊图像识别。蒸馏法提出了一个新的解决思路

Eva_Hua的专栏 1310

知识蒸馏 综述 Knowledge Distillation: A Survey

Knowledge Distillation: A Survey 本文译自Knowledge Distillation: A Survey,论文地址:https://arxiv.org/abs/2006.05525 (有翻译不周之处,敬请指正) 1. Introduction 深度学习取得了巨大进步,但是受限于庞大的计算量和参数量很难实际应用与资源受限设备上。 为了使深度模型更加高效,主要有以下两个方向的研究: 高效的网络模块构建:如MobileNets, ShuffeNets .

doctor_strange**** 1万+

知识蒸馏

目录 一 引言 1.1 深度学习的优点 1.2 深度学习的缺点 二 什么是知识蒸馏 2.1 模型压缩 2.2 什么是学习 2.3 什么是知识蒸馏 2.4 知识蒸馏的一般流程 三 知识蒸馏的分类 3.1 模型结构的种类 3.2 知识的分类 3.3 如何蒸馏 四 输出层知识蒸馏 《Distilling the Knowledge in a Neural Network 》 2015 五 中间层知识蒸馏 《Learning Metrics from Teachers: Comp

oldsummer 2万+

CRNN模型蒸馏技术:小模型也能有大性能

本文介绍了一种面向OCR场景的CRNN模型蒸馏方案,通过“教师-学生”框架,成功将高性能CRNN的能力迁移到轻量级模型中,解决了工业部署中精度与效率不可兼得的难题。其核心优势体现在:高精度:继承CRNN对中文序列建模的强大能力强鲁棒:配合图像预处理,适应复杂现实场景快推理:CPU环境下<1秒响应,无GPU依赖易集成:提供WebUI与API双模式服务。

weixin_32869687的博客 911

知识蒸馏简介(Knowledge Distillation)

知识蒸馏的背景,概念,知识传递形式,不同蒸馏方法的优缺点,例子的相关介绍

qq_46684028的博客 1万+

千问3.5-2B效果惊艳展示:低光照图主体识别、手写体中文OCR、复杂场景问答

本文介绍了如何在星图GPU平台上自动化部署千问3.5-2B镜像,实现多模态视觉理解功能。该镜像具备低光照图像识别、手写体中文OCR和复杂场景问答等核心能力,特别适用于教育领域的作业批改辅助、商业场景的商品图像理解等实际应用。通过简单的部署流程,用户可快速体验前沿的视觉语言模型技术。

weixin_35750483的博客 686

什么是特征蒸馏?什么是知识蒸馏?

​​特征蒸馏是一种知识迁移方法,它将教师模型在中间层学到的特征表示(如语义、结构、上下文信息)迁移到学生模型中,让学生模型不仅学会“做什么”(输出),还学会“怎么看”(特征),从而提升整体性能。​​。

m0_74027860的博客 2428

知识蒸馏 Knowledge Distillation for Sentiment Analysis:将知识从复杂模型转移到简单模型

本节将介绍知识蒸馏在情感分析中的算法原理,并阐述其具体操作步骤。本文对知识蒸馏在情感分析领域的应用进行了全面系统的介绍。首先,我们阐述了知识蒸馏的基本原理和操作步骤。然后,我们详细介绍了知识蒸馏在情感分析中的数学模型和公式。接着,我们通过项目实践,展示了知识蒸馏在情感分析中的实际应用。最后,我们探讨了知识蒸馏在情感分析领域的实际应用场景和未来发展趋势。

AI天才研究院 1120

全网最细图解知识蒸馏(涉及知识点:知识蒸馏实现代码,知识蒸馏训练过程,推理过程,蒸馏温度,蒸馏损失函数)

hard targets的预测结果不科学,因为马和驴比马和汽车相似的多。所以驴和汽车都是0,没有表现出这个信息,所以要用soft targets.第二行和第三行是使用百分之3的训练样本并分别用hard target和soft target,结果显示。soft target使我们常用的概率版的标签值。比如输入下面的图片预测。教师网络预测出的soft target具有很多信息。此时学生网络已经训练好,把X输入到学生网络得到结果。学生网络的输入是教师网络的输出。【精读AI论文】知识蒸馏。最后对这两项加权求和。

分享计算机视觉,C++,网络摄像头研发,音视频开发,嵌入式等知识。 2万+

【大语言模型 37】知识蒸馏深度实战:大模型向小模型迁移

本文深入探讨了知识蒸馏技术在大语言模型领域的应用,详细阐述了如何将庞大复杂的大模型知识有效迁移到轻量级小模型中。文章系统介绍了知识蒸馏的理论基础、多种蒸馏损失函数设计、特征匹配与注意力迁移技术、渐进式蒸馏策略以及全面的效果评估方法。通过实战案例和完整代码实现,读者将掌握从理论到实践的知识蒸馏全流程,了解如何在保持模型性能的同时显著降低计算资源需求,实现大语言模型的高效部署与应用。

熵数实验室 1509

知识蒸馏算法原理

知识蒸馏算法原理 “蒸馏”的概念大概就是将本身不够纯净的水通过加热变成水蒸气,冷凝之后就成更纯净的水 知识蒸馏同样使用这种原理,将不太纯净的“知识”通过“蒸馏”的方式获得更加有用或者纯净的“知识” 体现在神经网络中如下图所示: 一个大而臃肿,但知识丰富且高效的“教师网络”,通过转换精准将特定领域的知识传授给“学生网络”,让“学生网络”在某个方面做得很好,并且不那么臃肿,类似“模型压缩” 为什么不直接使用教师网络?因为将算法应用在现实生活中很多设备的算力会被限制,因此需要尽可能.

charles_zhang_的博客 1万+

用Python玩转Carla-Apollo联合仿真:手把手教你实现自动驾驶测试

本文详细介绍了如何使用Python实现Carla-Apollo联合仿真,从环境搭建到自动驾驶算法测试的全流程。通过Carla提供的高逼真仿真环境和Apollo的自动驾驶算法栈,开发者可以高效验证感知、规划和控制模块。文章包含环境配置、Python API操作、桥接实现及实战测试,为自动驾驶开发提供完整解决方案。

wasm7browser的博客 267

ESP32语音交互实战:离线唤醒与DeepSeek大模型集成

本文详细介绍了如何将ESP32-S3开发板与天问ASRPRO语音模块结合,实现离线语音唤醒并集成DeepSeek大模型的智能交互系统。通过串口通信与API调用,系统可处理本地指令及复杂语义请求,适用于低成本、高隐私保护的AIoT语音交互场景。

rust6ferris的博客 872

【目标检测】YOLOv5遇上知识蒸馏

本文主要来研究知识蒸馏的相关知识,并尝试用知识蒸馏的方法对YOLOv5进行改进。

兴趣使然的创作者 1万+

CrackerXI+脱壳实战:解决iOS应用逆向中的加密文件问题

本文详细介绍了如何使用CrackerXI+工具对iOS应用进行脱壳,解决App Store应用因FairPlay DRM加密而无法进行静态分析的难题。通过图形化界面一键操作,CrackerXI+能高效获取解密后的可执行文件,为逆向工程奠定基础。文章涵盖工具选型、实战步骤及常见问题排查,是iOS逆向入门与进阶的实用指南。

seed的博客 259

一文搞懂【知识蒸馏】【Knowledge Distillation】算法原理

知识蒸馏就是把一个大的教师模型的知识萃取出来,把他浓缩到一个小的学生模型,可以理解为一个大的教师神经网络把他的知识教给小的学生网络,这里有一个知识的迁移过程,从教师网络迁移到了学生网络身上,教师网络一般是比较臃肿,所以教师网络把知识教给学生网络,学生网络是一个比较小的网络,这样就可以用学生网络去做一些轻量化网络做的事情。

Coding... 8万+

CentOS7 编译升级GCC至9.3.0

1)下载GCC9.2.0源码并解压 从GCC官方FTP下载地址可以看到GCC最新版本为9.3.0。由于官网下载速度慢,实际上用清华大学的镜像站进行下载,代码如下: wget -c /opt/tmp/ https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz #考虑到安装失败的可能性,创建一个临时文件夹来安装GCC...

haha123486的博客 1万+

告别ArcGIS小红叉:从‘无法验证登录信息’到成功连接在线资源的完整排错记录

本文详细记录了从Windows便签的网络错误到ArcGIS连接问题的完整排错过程。通过分析代理服务器、DNS配置和系统网络设置,解决了ArcGIS无法验证登录信息的问题,提供了实用的网络优化方案和技术排错思路。

weixin_26800111的博客 390

Springer知识蒸馏专著解读:面向图像识别的知识蒸馏综述

本篇综述首先按照基于响应、特征和关系三种层面的知识类型总结了离线知识蒸馏的工作。通过剖析离线知识蒸馏需要预训练教师的问题,引出了在线知识蒸馏和自知识蒸馏。面向实际场景中,本文又引入了跨模态知识蒸馏和无数据的知识蒸馏。此外,本文展示了一些用于提升知识蒸馏效果的扩展机制,例如多教师知识蒸馏、注意力机制知识蒸馏和对抗知识蒸馏。本文对以上领域的代表性相关工作进行调研,并总结核心思想与贡献,对未来知识蒸馏的挑战进行展望。

Python_cocola的博客 1284

【Burp入门第二十二篇】BurpSuite配置Hea插件教程+添加配置项

HaE是一个基于BurpSuite Java插件API开发的辅助型框架式插件,旨在实现对HTTP消息的高亮标记和信息提取。该插件通过自定义正则表达式匹配响应报文或请求报文,并对匹配成功的报文进行标记和提取。

等风来 9632
上一篇: RuntimeError: CUDA out of memory. Tried to allocate 22.00 MiB (GPU 0; 10.76 GiB total capacity; 9.61
下一篇: python对比两个excel表 【超简单】
snow5618
博客等级 码龄9年 141粉丝 51原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值