Closed cqray1990 closed 2 months ago
可以的话,贴一两个你这边的测试样例,我看看训练集中有没有覆盖类似场景
之前试过两阶段的,但是还有文字方向的问题,定位文本拉直,还有弯曲文本的,楼主有头试过其他方式? 楼主哟试过合合的印章识别?他的很准,而且清晰的一般不会错,错的不离谱,感觉他不是用这个方式做的,难道他的海量数据很多?
可以尝试我的在线识别模型,我看你这个圆形印章是可以识别的,椭圆印章我这边没做任何优化,可能效果不能保证。
由于我这个在线平台是先印章检测,检测模型正在优化中,训练的印章都是正常图标中的印章检测,直接裁剪出来的印章可能不太符合这个使用场景,后期会覆盖
目前主流的端到端和多阶段都有,具体你可以参考印章识别的一些比赛。
1.我这边先前是多阶段的,印章检测、文本定位、透视变换、ocr识别,当然了多阶段也区分各种,有的是弯曲文字直接识别,有的是变换成矩形。 2.数据很重要,尤其是字符识别这边需要的数据就更多了,从最基础的来说,你得覆盖常用字典里面的字吧?然后是不是得覆盖一些长短词?
应该是数据集不足导致的,数据集太少,会导致模型有时候会胡说八道 你可以尝试搞一个假样本制作工具,多搞一些背景有字的样本
是的,有点类似asr里面,没做过噪音增强的训练容易把噪音识别出来一些乱七八糟的内容,不想重新训练就直接上阈值过滤掉
目前主流的端到端和多阶段都有,具体你可以参考印章识别的一些比赛。
1.我这边先前是多阶段的,印章检测、文本定位、透视变换、ocr识别,当然了多阶段也区分各种,有的是弯曲文字直接识别,有的是变换成矩形。 2.数据很重要,尤其是字符识别这边需要的数据就更多了,从最基础的来说,你得覆盖常用字典里面的字吧?然后是不是得覆盖一些长短词?
多阶段效果好?,有分印章形状?而且都要做文字方向判断,不然文字定位之后,拉直或者直接切出来都有方向问题,可以推荐一些多阶段的方式?ABENet,TPS PGNet都有试过
1.多阶段效果好? 很难说好多少?相对来说端到端会更好,但是多阶段会更快 2.之前有想介绍下多阶段,但是怕你误入歧途。。。如果说文本180度翻转的方向问题,这个可以参考ocr的操作,训练个文本方向分类器。具体的话,你可以画图演示下相关方向问题吗?
1.多阶段效果好? 很难说好多少?相对来说端到端会更好,但是多阶段会更快 2.之前有想介绍下多阶段,但是怕你误入歧途。。。如果说文本180度翻转的方向问题,这个可以参考ocr的操作,训练个文本方向分类器。具体的话,你可以画图演示下相关方向问题吗? 多阶段试过,就是模型太多了,文本检测之后,是否需要将弯曲的文本拉值呢,拉值之后再去分方向,还是直接弯曲的识别呢,用控制点拉直的,控制点找不准,导致拉值效果不太好 @Gmgge
看下ICDAR` 2023 Competition on Reading the Seal Title的排行榜技术方案可以了解更多。
个人觉得这个时候不要太担心拉直扭曲的问题,因为如果你的训练集都这样,且能训练收敛的话就没有问题,毕竟有人用深度学习来做扭曲纠正的。
如果你实在担心,或者说你不想再重新训练ocr,先前实验过针对圆印章是检测到位置与角度之后之后,会进行印章圆弧拟合,拟合到之后,再针对圆环切割拉直,该方案不再需要定位弧形文本区域,而且不需要重新训练ocr即可达到不错的精度。
ICDAR` 2023 Competition on Reading the Seal Title
看下ICDAR` 2023 Competition on Reading the Seal Title的排行榜技术方案可以了解更多。
个人觉得这个时候不要太担心拉直扭曲的问题,因为如果你的训练集都这样,且能训练收敛的话就没有问题,毕竟有人用深度学习来做扭曲纠正的。
如果你实在担心,或者说你不想再重新训练ocr,先前实验过针对圆印章是检测到位置与角度之后之后,会进行印章圆弧拟合,拟合到之后,再针对圆环切割拉直,该方案不再需要定位弧形文本区域,而且不需要重新训练ocr即可达到不错的精度。
@针对圆形的极坐标切割拉直?圆印章角度怎么检测?直接角度分类?
可以尝试下有角度的目标检测。
大佬,我想使用旋转目标检测模型先检测出印章中的每一个字,然后再对单个字符做方向分类,再送到识别模型进行识别,你觉得这样可行么?
昨晚应该是写了一堆,有点忙结果忘了点comment。。。
大概解释下,单个文字的检测识别,算是传统方法思路,如果说非常关注单个孤立文字or数字的准确率,可以使用该逻辑来尝试。
在印章识别领域,可以尝试弯曲文本行识别,基于语义分割的文本行检测,目前很多都是可以做弯曲文本的检测的。识别阶段并非一定要做透视变换把文字扭曲正,因为基于transformer的网络从逻辑和实验上都是可以直接解决该问题的。但是这不表明显示的弯曲文本纠正是不可以接受的策略,如果你的弯曲策略很完善,后续识别可以使用更简单的网络结构,既可以保证准确率,也可以大大提升速度。
昨晚应该是写了一堆,有点忙结果忘了点comment。。。
大概解释下,单个文字的检测识别,算是传统方法思路,如果说非常关注单个孤立文字or数字的准确率,可以使用该逻辑来尝试。
在印章识别领域,可以尝试弯曲文本行识别,基于语义分割的文本行检测,目前很多都是可以做弯曲文本的检测的。识别阶段并非一定要做透视变换把文字扭曲正,因为基于transformer的网络从逻辑和实验上都是可以直接解决该问题的。但是这不表明显示的弯曲文本纠正是不可以接受的策略,如果你的弯曲策略很完善,后续识别可以使用更简单的网络结构,既可以保证准确率,也可以大大提升速度。
试了一下单个字符的检测,对于一些印章文字有一定间隔的识别还是很准的,但是对于那些文字很多间隔很小的印章就不行了,不知道百度的印章识别接口是如何实现的,识别的好准。。有的字人都不太看得清,它都能给识别出来,还是对的
昨晚应该是写了一堆,有点忙结果忘了点comment。。。
大概解释下,单个文字的检测识别,算是传统方法思路,如果说非常关注单个孤立文字or数字的准确率,可以使用该逻辑来尝试。
在印章识别领域,可以尝试弯曲文本行识别,基于语义分割的文本行检测,目前很多都是可以做弯曲文本的检测的。识别阶段并非一定要做透视变换把文字扭曲正,因为基于transformer的网络从逻辑和实验上都是可以直接解决该问题的。但是这不表明显示的弯曲文本纠正是不可以接受的策略,如果你的弯曲策略很完善,后续识别可以使用更简单的网络结构,既可以保证准确率,也可以大大提升速度。
还有大佬,您有联系方式吗?我这边有一些真实的人工标注的印章数据集可以提供,也想跟您探讨探讨技术方面的一些问题。
你是需要每个字的坐标吗? 不需要坐标的话,这个模型就可以达到很高的识别率
你是需要每个字的坐标吗? 不需要坐标的话,这个模型就可以达到很高的识别率
这个模型我试了,确实不错,但是百度接口是怎么做到,连人都看不清楚的字,还能识别正确的。。太奇怪了。 这个百度识别出的是滦南县鸿涛门窗厂,关键人家确实是这个名字。。
我用这个模型训练大概100个epoch,样本量12000,0.05的验证集,为什么到80个epoch的时候,loss就差不多是0了,但是精度还算正常,eval_cer大概0.0125,eval_acc大概90.8,这个算过拟合么?
这个模型结构是可以支持到很高准确度的,给你一些我训练的方法 1.样本数量问题,你可以试着生成一些假样本(可以先用大量假样本训练一个base模型,然后用真样本强化微调) 2.更多的样本增强,我使用了 颜色变换、灰度化和二值化、对比度、仿射变换、高斯模糊、高斯噪声、亮度、分段仿射变换 3.模型参数量增大(欠拟合) 4.增大dropout参数(过拟合)
希望可以帮到你
这个模型结构是可以支持到很高准确度的,给你一些我训练的方法 1.样本数量问题,你可以试着生成一些假样本(可以先用大量假样本训练一个base模型,然后用真样本强化微调) 2.更多的样本增强,我使用了 颜色变换、灰度化和二值化、对比度、仿射变换、高斯模糊、高斯噪声、亮度、分段仿射变换 3.模型参数量增大(欠拟合) 4.增大dropout参数(过拟合)
希望可以帮到你
如果我的印章中最大字符长度也就32左右,那设置模型参数的时候是不是不要设置的过长比较好一点? 还有如果要增大模型的参数量,是不是就不能用现有的这些预训练模型了?要用微软的trocr-base-printed预训练模型?我现在用的是TAL_OCR_CHN这个预训练模型,大概100多M,用微软的base得有1个多G,large模型得两个多G。。
1.因为这是生成式的模型,只要设置的比你的最大字符长度大就可以了。我认为设置的长度并不会有影响。 2.修改了模型,肯定就要自己从头训练了,没法用现有的预训练
from transformers import (
TrOCRConfig,
TrOCRProcessor,
TrOCRForCausalLM,
ViTConfig,
ViTModel,
VisionEncoderDecoderModel,
Seq2SeqTrainingArguments,
Seq2SeqTrainer,
ViTImageProcessor,
RobertaTokenizer,
default_data_collator,
)
vocab_file_path = 'cust-data/weights/vocab.json'
merges_file_path = 'cust-data/weights/merges.txt'
image_processor = ViTImageProcessor(size={"height": 384, "width": 384})
tokenizer = RobertaTokenizer(vocab_file=vocab_file_path, merges_file=merges_file_path)
processor = TrOCRProcessor(image_processor=image_processor, tokenizer=tokenizer)
vocab = tokenizer.get_vocab()
vocab_inp = {vocab[key]: key for key in vocab}
vit_config = ViTConfig(hidden_size=384,
num_hidden_layers=12,
num_attention_heads=6,
intermediate_size=1536,
hidden_act="gelu",
hidden_dropout_prob=0.0,
decoder_start_token_id=2,
attention_probs_dropout_prob=0.0,
initializer_range=0.02,
layer_norm_eps=1e-12,
image_size=384,
patch_size=16,
num_channels=3,
qkv_bias=True,
encoder_stride=16,)
encoder = ViTModel(vit_config)
trocr_config = TrOCRConfig(vocab_size=len(tokenizer),
cross_attention_hidden_size=384,
d_model=256,
decoder_layers=6,
decoder_attention_heads=8,
decoder_ffn_dim=1024,
activation_function="gelu",
max_position_embeddings=512,
dropout=0.1,
attention_dropout=0.0,
activation_dropout=0.0,
decoder_start_token_id=2,
init_std=0.02,
decoder_layerdrop=0.0,
use_cache=True,
scale_embedding=False,
use_learned_position_embeddings=True,
layernorm_embedding=True,
pad_token_id=1,
bos_token_id=0,
eos_token_id=2,
)
decoder = TrOCRForCausalLM(trocr_config)
model = VisionEncoderDecoderModel(encoder=encoder, decoder=decoder)
model.config.decoder_start_token_id = tokenizer.cls_token_id
model.config.pad_token_id = tokenizer.pad_token_id
model.config.eos_token_id = tokenizer.sep_token_id
model.save_pretrained("./test_model")
processor.save_pretrained('./test_model')
1.因为这是生成式的模型,只要设置的比你的最大字符长度大就可以了。我认为设置的长度并不会有影响。 2.修改了模型,肯定就要自己从头训练了,没法用现有的预训练
模型定义参考 你可以通过调整参数 来增大模型参数量
from transformers import ( TrOCRConfig, TrOCRProcessor, TrOCRForCausalLM, ViTConfig, ViTModel, VisionEncoderDecoderModel, Seq2SeqTrainingArguments, Seq2SeqTrainer, ViTImageProcessor, RobertaTokenizer, default_data_collator, ) vocab_file_path = 'cust-data/weights/vocab.json' merges_file_path = 'cust-data/weights/merges.txt' image_processor = ViTImageProcessor(size={"height": 384, "width": 384}) tokenizer = RobertaTokenizer(vocab_file=vocab_file_path, merges_file=merges_file_path) processor = TrOCRProcessor(image_processor=image_processor, tokenizer=tokenizer) vocab = tokenizer.get_vocab() vocab_inp = {vocab[key]: key for key in vocab} vit_config = ViTConfig(hidden_size=384, num_hidden_layers=12, num_attention_heads=6, intermediate_size=1536, hidden_act="gelu", hidden_dropout_prob=0.0, decoder_start_token_id=2, attention_probs_dropout_prob=0.0, initializer_range=0.02, layer_norm_eps=1e-12, image_size=384, patch_size=16, num_channels=3, qkv_bias=True, encoder_stride=16,) encoder = ViTModel(vit_config) trocr_config = TrOCRConfig(vocab_size=len(tokenizer), cross_attention_hidden_size=384, d_model=256, decoder_layers=6, decoder_attention_heads=8, decoder_ffn_dim=1024, activation_function="gelu", max_position_embeddings=512, dropout=0.1, attention_dropout=0.0, activation_dropout=0.0, decoder_start_token_id=2, init_std=0.02, decoder_layerdrop=0.0, use_cache=True, scale_embedding=False, use_learned_position_embeddings=True, layernorm_embedding=True, pad_token_id=1, bos_token_id=0, eos_token_id=2, ) decoder = TrOCRForCausalLM(trocr_config) model = VisionEncoderDecoderModel(encoder=encoder, decoder=decoder) model.config.decoder_start_token_id = tokenizer.cls_token_id model.config.pad_token_id = tokenizer.pad_token_id model.config.eos_token_id = tokenizer.sep_token_id model.save_pretrained("./test_model") processor.save_pretrained('./test_model')
根据你的这套配置的话模型的参数量大概有多少?我感觉small模型的参数拟合不太够,精度达不到要求,base模型的参数又有点大了,训练时间太久了,14000的数据集,两张12G的3060卡,要训练40个小时。。数据集是1万的合成印章+4000的人工标注,后面还会增加,这得搞多久。。
这只是个参考代码,你需要自己调整参数(保存后只有114MB) 中文训练确实耗时,字太多了。这个我也没有好办法
这只是个参考代码,你需要自己调整参数(保存后只有114MB) 中文训练确实耗时,字太多了。这个我也没有好办法
是哎,只要涉及到中文文字识别的都太蛋疼了,基本的至少要覆盖3-5千,还有一大堆生僻字,可能都有5-7千了。。你用你的这套配置大概能达到多少的精度?
现在的训练不在我这了,所以这只是参考代码,具体参数我也没看。 线上版本应该有98左右
现在的训练不在我这了,所以这只是参考代码,具体参数我也没看。 线上版本应该有98左右
98精度有点强了。。我用仓库作者的这套配置,在训练集上也就95左右。。看来参数还是要慢慢调的
可以的话,贴一两个你这边的测试样例,我看看训练集中有没有覆盖类似场景