日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

天池CV学习赛:街景字符识别-思路与上分技巧汇总

發(fā)布時間:2024/7/23 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 天池CV学习赛:街景字符识别-思路与上分技巧汇总 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Datawhale 和 天池 合作的零基礎(chǔ)入門CV - 街景字符編碼識別比賽的正式賽已經(jīng)結(jié)束。本文對一些比賽思路和上分技巧進行了匯總和整理,希望對大家深入學習CV能夠有幫助。

本文分為以下幾部分:

  • 如何優(yōu)化官方baseline的效果?

  • 其它解題思路的整理和分析

  • 字符級目標檢測的優(yōu)化技巧整理

在這里要特別感謝多位前排選手對于比賽技巧的無私分享,那么不多bb,下面直接進入正題

一、如何優(yōu)化官方baseline的效果?

本次入門賽的官方baseline入門材料,相信大家肯定都看過了:

Task1 賽題理解

Task2 數(shù)據(jù)讀取與數(shù)據(jù)擴增

Task3 字符識別模型

Task4 模型訓(xùn)練與驗證

Task5 模型集成

本質(zhì)上,baseline的思路就是將賽題轉(zhuǎn)換為了一個定長的字符識別問題,用包含多個輸出的分類問題來進行求解。

1.1 改進版baseline

那么如何進行進一步優(yōu)化呢?在比賽進行的過程中,我在天池進行了一次如何調(diào)參上分的直播分享

直播對應(yīng)的代碼可以在我們的動手學CV項目的2.5節(jié)找到

這份代碼相當于一個加強版的baseline,簡短來說,介紹了以下幾點:

  • 重新回顧baseline的代碼
  • 階段性下降的學習率調(diào)整策略
  • 分析了很多人提交出0.3-0.4分成績的原因和解決方案
  • 加入數(shù)據(jù)增強策略

這份代碼我相信是幫到了一些剛?cè)腴T的同學的,提交的成績大概在0.75分左右。

那么在這樣一個baseline的基礎(chǔ)上,如何進一步的優(yōu)化呢?

1.2 改進backbone

baseline中我們的網(wǎng)絡(luò)結(jié)構(gòu)是這樣定義的:

class SVHN_Model1(nn.Module):def __init__(self):super(SVHN_Model1, self).__init__()model_conv = models.resnet18(pretrained=True)model_conv.avgpool = nn.AdaptiveAvgPool2d(1)model_conv = nn.Sequential(*list(model_conv.children())[:-1]) # 去除最后一個fc layerself.cnn = model_convself.fc1 = nn.Linear(512, 11)self.fc2 = nn.Linear(512, 11)self.fc3 = nn.Linear(512, 11)self.fc4 = nn.Linear(512, 11)self.fc5 = nn.Linear(512, 11)def forward(self, img): feat = self.cnn(img)#print(feat.shape)feat = feat.view(feat.shape[0], -1)c1 = self.fc1(feat)c2 = self.fc2(feat)c3 = self.fc3(feat)c4 = self.fc4(feat)c5 = self.fc5(feat)return c1, c2, c3, c4, c5

我們可以對使用的backbone網(wǎng)絡(luò)進行一系列的改進:

  • 由resnet18換為更大的resnet50
  • 為每一個分類模塊加上一層全連接隱藏層
  • 為隱含層添加dropout

由resnet18換為resnet50,更深的模型就擁有更好的表達能力,添加一層隱含層同樣起到了增加模型擬合能力的作用,與此同時為隱含層添加dropout來進行一個balance,一定程度上防止過擬合。(這只是我個人對于baseline的改進方案,不一定是最優(yōu)的)

改進后的模型定義代碼如下:

class SVHN_Model2(nn.Module):def __init__(self):super(SVHN_Model2, self).__init__()# resnet18model_conv = models.resnet18(pretrained=True)model_conv.avgpool = nn.AdaptiveAvgPool2d(1)model_conv = nn.Sequential(*list(model_conv.children())[:-1]) # 去除最后一個fc layerself.cnn = model_convself.hd_fc1 = nn.Linear(512, 128)self.hd_fc2 = nn.Linear(512, 128)self.hd_fc3 = nn.Linear(512, 128)self.hd_fc4 = nn.Linear(512, 128)self.hd_fc5 = nn.Linear(512, 128)self.dropout_1 = nn.Dropout(0.25)self.dropout_2 = nn.Dropout(0.25)self.dropout_3 = nn.Dropout(0.25)self.dropout_4 = nn.Dropout(0.25)self.dropout_5 = nn.Dropout(0.25)self.fc1 = nn.Linear(128, 11)self.fc2 = nn.Linear(128, 11)self.fc3 = nn.Linear(128, 11)self.fc4 = nn.Linear(128, 11)self.fc5 = nn.Linear(128, 11)def forward(self, img):feat = self.cnn(img)feat = feat.view(feat.shape[0], -1)feat1 = self.hd_fc1(feat)feat2 = self.hd_fc2(feat)feat3 = self.hd_fc3(feat)feat4 = self.hd_fc4(feat)feat5 = self.hd_fc5(feat)feat1 = self.dropout_1(feat1)feat2 = self.dropout_2(feat2)feat3 = self.dropout_3(feat3)feat4 = self.dropout_4(feat4)feat5 = self.dropout_5(feat5)c1 = self.fc1(feat1)c2 = self.fc2(feat2)c3 = self.fc3(feat3)c4 = self.fc4(feat4)c5 = self.fc5(feat5)return c1, c2, c3, c4, c5

改進后的模型訓(xùn)起來會慢很多,不過增加了模型的表達力,自然效果也會好一些。此外,你也可以嘗試一些更"state-of-the-arts"的模型,比如SENet,EfficientNet等。

1.3 數(shù)據(jù)增強優(yōu)化

關(guān)于數(shù)據(jù)增強,我們在直播中已經(jīng)探討過了,從原理上分析我們更應(yīng)該用一些基于空間、位置相關(guān)的數(shù)據(jù)增強,比如Randomcrop,平移,旋轉(zhuǎn)等。而顏色空間相關(guān)的變換,也可以嘗試,但很可能會起到副作用。

數(shù)據(jù)增強是非常普遍的訓(xùn)練技巧了,肯定要用,但對這個賽題的結(jié)果提升不會很顯著。關(guān)于這部分,這位小伙伴寫的比賽實驗記錄對相關(guān)的實驗進行了很詳細的記錄,大家感興趣可以閱讀一下~

1.4 和文本長度相關(guān)的探索

baseline方案將識別問題轉(zhuǎn)化為了定長識別問題,那么定多長合適?就是個值得思考的問題,有的小伙伴通過一個小腳本進行了統(tǒng)計,訓(xùn)練集中的樣本的字符長度分別為1,2,3,4,5,6的樣本數(shù)量分別為4636,16262,7813,1280,8,1。

可以看到,數(shù)據(jù)集中長度為5和6的圖片都是可以忽略不計的,因此主動放棄這部分極少數(shù)情況的case可以很好的為模型“減負”,從而獲得更好的效果。

baseline模型設(shè)定定長len=5,不妨嘗試下len=4,會帶來進一步的提升。

我們的這個方案需要CNN自己找到文字在圖中的位置,還要自己判斷出字符的個數(shù)并完成正確的識別,感覺上是相當難的任務(wù),之所以能夠work是因為場景相對來說比較簡單。

如果你做了一些更進一步得分析工作你會發(fā)現(xiàn),模型對于長度不同的圖片的效果是不一樣的。更詳細來說,根據(jù)我的訓(xùn)練日志的記錄,訓(xùn)練時第3個字符的loss是相對比較小的,而預(yù)測時長度為3的圖片出現(xiàn)的預(yù)測錯誤是比較多的,主要是漏檢。

我分析這是因為(個人觀點可能存在誤導(dǎo)):對于輸出第一個字符結(jié)果的fc layer來說,所有圖片它都會參于訓(xùn)練,而輸出第二個字符結(jié)果的fc layer,只有當圖片字符數(shù)>=2,它才會參于“有效”訓(xùn)練,以此類推。所以越是對應(yīng)靠后的fc layer,訓(xùn)練的越不充分,越容易過擬合導(dǎo)致實際效果越差。

因此可以圍繞不同長度的圖片效果不同來做些文章,依然是這篇比賽實驗記錄

他嘗試了兩個方案,可供大家參考,提供些思路:

  • 損失加權(quán)
  • 樣本加權(quán)

其中第二個方案,樣本加權(quán)看起來是更合理來解決這個問題的,我們可以通過重復(fù)采樣,提高較長的字符數(shù)量的圖片出現(xiàn)的比例,來讓對應(yīng)第3個字符和第4個字符對應(yīng)的輸出層訓(xùn)練的更充分。

這是個蠻有新意的角度,你是否還可以碰撞出其它的idea來解決這個問題呢~

1.5 集成學習

對于這個比賽來說,比較適合baseline的集成方案是:

首先將單模型盡可能訓(xùn)到最高,然后單模型的輸出使用TTA(test time augmentation),可以大幅提升單模型的預(yù)測效果。

然后訓(xùn)練多個有差異化的模型,將多個單模型的預(yù)測結(jié)果進行投票,得到最終的預(yù)測結(jié)果。單模型間的差異化可以從數(shù)據(jù)的角度通過重新劃分訓(xùn)練集和驗證集來達到,也可以從模型的角度,使用不同的backbone來達到。從原理上講,單模型間越是獨立和具有差異化,融合的效果就越好。

1.6 讓baseline進入Top 2%的6行代碼

最后再偷偷告訴你一個,只需修改6行代碼,就能讓目前的優(yōu)化后baseline單模型進入Top 2%的方法。

不知大家有沒有發(fā)現(xiàn),測試集相比于訓(xùn)練數(shù)據(jù),要更簡單。

具體地,體現(xiàn)在測試集最終的分數(shù)反而要比驗證集高一些,如果你直接觀察數(shù)據(jù),也可以看出來,測試集的圖片中字符在圖片中的占比更大,而訓(xùn)練集中圖片的字符占比更小。直觀感受就是訓(xùn)練數(shù)據(jù)和測試集對應(yīng)的場景不一致,訓(xùn)練集的字符感覺更“遠”,預(yù)處難度也更高。

提示到這里,你可以先停下來思考下,如果是你,會如何來針對這個問題進行優(yōu)化呢?

驗證集圖片示例:

測試集圖片示例:

對于這個問題,很多人很自然的想到了進行目標檢測,這也是幾乎所有前排選手的一致選擇。但是,我們的baseline就沒有一戰(zhàn)之力了嗎?當然不是,我個人用resnet50作為backbone將單模型的分數(shù)訓(xùn)到了0.91,相當于正式賽Top2%的分數(shù),而且因為我沒有時間做太多的超參數(shù)調(diào)整實驗,這個成績也并沒有達到baseline的上限。

那么baseline要如何相應(yīng)的進行改造來解決這個問題呢?

文字描述出來就是:訓(xùn)練時把場景拉近,測試基本保持不變,這樣一定程度上讓訓(xùn)練和測試的數(shù)據(jù)的場景更加一致,從而讓模型學到的預(yù)測能力完全發(fā)揮出來。

可以有很多方案來達到這個目的,最簡單有效的方法僅僅需要修改數(shù)據(jù)增強相關(guān)的6行代碼,我用TODO作為后綴標注出來,代碼如下:

train_loader = torch.utils.data.DataLoader(SVHNDataset(train_path, train_label,transforms.Compose([transforms.Resize((80, 160)), # TODOtransforms.RandomCrop((64, 128)), # TODOtransforms.ColorJitter(0.3, 0.3, 0.2),transforms.RandomRotation(5),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])),batch_size=40,shuffle=True,num_workers=2, ) val_loader = torch.utils.data.DataLoader(SVHNDataset(val_path, val_label,transforms.Compose([transforms.Resize((80, 160)), # TODOtransforms.CenterCrop((64, 128)), # TODOtransforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])),batch_size=40,shuffle=False,num_workers=2, ) test_loader = torch.utils.data.DataLoader(SVHNDataset(test_path, test_label,transforms.Compose([transforms.Resize((68, 136)), # TODOtransforms.RandomCrop((64, 128)), # TODOtransforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])),batch_size=40,shuffle=False,num_workers=2, )

這個優(yōu)化雖然很trick,但是效果顯著,大家可以思考下這6行代碼的修改是如何帶來成績的巨大提升的。

二、不同解題思路的整理與分析

除了baseline的思路以外,還有多種不同的解題思路,這里簡單進行總結(jié)。

2.1 CRNN

純識別的思路,除了baseline的定長字符識別方案外,還可以用CRNN來做,屬于一種端到端的不定長字符識別的解決方案。

關(guān)于CRNN,賽事組織者 阿水 已經(jīng)為我們提供了一個CRNN baseline,感謝去可以學習一下~

2.2 檢測+識別

除了兩種端到端的識別方案,還可以引入目標檢測來解題,根據(jù)具體使用中檢測框粒度的不同,還可以細分為三種不同的方案:

方案一:文本行檢測+文本行識別

方案二:字符級目標檢測+字符識別模型

方案三:純目標檢測方案

根據(jù)我最近兩周持續(xù)對前排選手進行的騷擾+在線乞討收集到的情報來看,前排選手使用的普遍是方案三,但是方案一、方案二也有人用,而且成績不差。也就是說,對于這個賽題,從實際結(jié)果上看這三個方案上限差不多。

方案一是更標準的字符識別類問題的解決方案,如果我們的問題不是數(shù)字之間無關(guān)聯(lián)的門牌號識別,而是比如場景文字識別,那么方案一由于可以對不同字符間的關(guān)聯(lián)進行建模,效果將會顯著優(yōu)于其它方案,但是本賽題這種優(yōu)勢無法發(fā)揮出來。

而方案三作為一種端到端的解決方案,思路更直接,整個訓(xùn)練流程更簡單,更容易在有限的比賽時間內(nèi)優(yōu)化出好的效果,再加上有眾多簡單好用的開源庫,因此也是絕大多數(shù)前排選手選擇的原因。

三、字符級目標檢測的優(yōu)化技巧整理

本文的最后一部分,再針對大家使用最多的字符級目標檢測的方案,進行一些簡單的整理。

網(wǎng)絡(luò)框架選擇方面,前排普遍采用的是YOLOv3-v5的版本,還有一位選手使用的CenterNet獲得了非常好的效果。

除了模型訓(xùn)練的各種小的trick以外,如何對模型結(jié)果進行后處理,以及如何融合多個模型的結(jié)果,會對最終結(jié)果有很大影響。關(guān)于這部分,眾多選手都在天池的論壇熱心分享了自己的經(jīng)驗,細節(jié)太多很難一一列舉,我也有很多要學習的地方,這里就不班門弄斧了,感興趣的小伙伴趕快去學習吧~

天池街景字符識別總結(jié)

第五名 yolov4 加 投票法方案

街景字符編碼識別-第6名 線上0.938 方案分享

yolov5加全局nms 第八名方案分享

零基礎(chǔ)入門CV賽事-分享一些適合新手的0.92+的上分技巧吧~

真正零基礎(chǔ),單模型非融合,上93的最簡單技巧

參賽歷程以及方案分享

零基礎(chǔ)CV賽–街景字符識別,小小白分享,從0.002~0.926


寫在最后

如果覺得有收獲,可否給我們的 動手學CV 項目點個star呢,我的老火雞~

總結(jié)

以上是生活随笔為你收集整理的天池CV学习赛:街景字符识别-思路与上分技巧汇总的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。