【得物技术】机器学习在图形验证码识别上的应用
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? · 機器學習 · 圖形驗證碼識別應用?·
?
偶然看到小伙伴們的討論:具體內容還不太了解,但似乎在說登錄界面驗證碼的事兒。
驗證碼是測試過程中經常遇到的一個問題,于是不禁思考:如何在自動化測試的過程中對驗證碼進行高效的識別和處理,以此來提升測試效率?
?
首先,對于簡單的拖放驗證碼(drag-and-drop),可以使用selenium的拖放函數,來操作被拖放的元素并設定拖放的距離、拖放到的目標元素。
以下的例子展示了運用拖放操作在http://pythonscraping.com/pages/javascript/draggableDemo.html的頁面,來證明訪問者不是一個機器人。
頁面中的message元素中展示了一條信息,內容為:
Prove you are not a bot, by dragging the square from the blue area to the read area!
很快地,python就會運行完畢,并得到第二條信息:
You are definitely not a bot!
當然這是一種較為簡單的驗證碼情況,如果是對于一個陌生的網頁,實現這樣的操作可能會有一點困難,尤其是絕大多數網站的驗證碼遠比這復雜。
實際環境中,我們常見的驗證碼是圖形驗證碼,以上的操作就并不適用了。
因此下面我就談談自己對于運用機器學習算法進行圖像驗證碼的識別的一點粗淺看法。
?
· 問題分析?·
?
要弄清怎樣讓機器識別圖像驗證碼,先來想想,我們作為充滿智慧的人類是怎樣認出一張驗證碼中的字符的:
1) 對圖像進行瀏覽,找出N個字符在圖像中的位置;
2) 對找到的字符依次進行辨認,并最終得到整個驗證碼的結果。
?
其實想要讓計算機識別一張圖像驗證碼,步驟也是類似的,比如:
1) 采取某種策略對包含多個字符的圖像進行拆分,使得每個圖像中盡量只包含一個字符;
2) 對得到的子圖像依次進行識別,得到概率最高的結果,并將全部結果依次組合則得到最終結果。
?
?
第一個步驟常被稱之為圖像分割。如果大家對動態規劃有一點印象的話,就會更容易理解了,因為圖像分割的作用與之類似,即將大的問題拆分為若干個子問題,依次攻破。
?
第二個步驟則是一個比較標準的監督學習(Supervised Learning)問題中的分類問題。監督學習主要分為回歸(Regression)問題和分類(Classification)問題兩類,其區別在于,回歸問題所產生的結果是連續的,而分類問題的結果是離散的。
?
一個典型的分類問題的例子是:已知某城市若干套房子的面積與其對應的房價,以此為依據,對給出面積的房子進行房價預測。
那么已知的信息用圖像表達出來就會像這樣:
而一個機器學習算法給出的一條擬合函數可能會像這樣:
雖然實際中的回歸問題往往會有更多的維度,即可能對于預測房價而言,面積不是唯一的影響因素,還會有更多的信息能造成影響,如房子所在的區域、周圍的學校、與最近警察局的距離、樓層等等,這些因素作為“參數(Parameters)”,以不同的程度對最終的結果:房價產生著影響。
工程師們往往需要考慮使用哪些,或是注重哪些參數來獲得一個較優的結果。
而對于分類問題,相信只要你再稍微往后看看,就會有一個清晰的認識了。
不知你有沒有注意到,對于監督學習而言,已知的數據必須包含參數以及結果兩方面的信息,否則如果你不知道房子的任何價格信息,就無法做出預測。
與之對應的另一個大類的問題叫做“非監督學習(Unsupervised Learning)”,我們很快也會談到。
對于兩個步驟分別可能存在的難點,我們也會在之后進行討論。
?
· 環境準備?·
?
對于傳統算法的機器學習而言,無論是MATLAB還是python都是很常用的。
不過說到神經網絡,由于TensorFlow,PyTorch等開源工具被廣泛使用,python可能就要略勝一籌了。
Anaconda是一個開源的Python包管理器,它可以方便我們對多個虛擬環境的管理,并簡單地處理好不同包之間的版本依賴問題。
如果你還在使用Python2,那么建議更換到Python3,因為有許多包已經不再對Python2提供更新。
至于其他各種相關的Python包,在之后用到的時候會單獨進行列出。
· 數據集準備 ·
?
產生一個圖像驗證碼的數據集并不是一件太復雜的事情。大致步驟如下:
1) 在指定的字符集合(如0-9,A-Z,甚至是漢字等)中隨機選取N個字符;
2) 將產生的字符放置于背景圖像之上;
3) 在圖像之上增加噪聲;
4) 對產生的字符進行隨機的縮放、旋轉、投影等變換;
5) 得到驗證碼。
?
如果是為了產生驗證碼作為數據集,還會有額外的兩個步驟:
6)將產生的驗證碼進行存儲;
7)將產生的驗證碼對應的字符進行記錄,寫入文件。
?
道理說完了,不過在python中,也不乏存在簡簡單單就可以產生一個圖像驗證碼的庫。這里我使用到了captcha。
在安裝后,使用如下的代碼就可以產生一個驗證碼:
?
產生的驗證碼如下:
?
更進一步的,使用一個循環來批量產生驗證碼并寫入稱為文件就可以得到一個個驗證碼的圖像了,由此可以得到訓練集,它們將用來進行模型的訓練。
在產生驗證碼的同時,對其字符內容進行記錄。一個簡單的思路是使用一個list來存儲,并使用諸如Pandas之類的庫將其寫入一個csv文件,便于將來讀取。
采用類似的方法,我們再來生成一個數量小一些的測試集,用于在模型訓練完成后檢驗訓練的成果:
· 數據預處理?·
?
?
不難看出,一張驗證碼的圖像還是有挺多噪點的。
在機器學習中,圖像常常被讀取為“灰度圖(Gray Scale Image)”。灰度圖保存了各個像素的灰度信息,用0-255表示,分別對映了從黑到白的不同深淺程度。使用灰度圖并不是說彩色圖像不好,而是在彩色圖片上進行訓練會需要更大的數據量,畢竟多出了R,G,B三條通道。
?
對于這樣一個相對較簡單的問題,我覺得就沒有必要使用彩色圖像了。事實上,現在越來越多的相對復雜的機器學習任務是在彩色圖像上進行的。另一方面,灰度圖常常可以便于區分出圖像的前景和背景,所以對于降噪而言,可能會更容易一點。
?
對于從RGB圖像得到灰度圖的計算,
公式為:
?
當然,這可是python,基本沒有什么需要我們自己處理的算法。
使用如下的代碼以產生一個灰度圖的例子:
?
這里我們使用了matplotlib庫來進行圖像的顯示,“cmap="gray"”的參數用于指定該庫以灰度圖的形式進行圖像的顯示,否則整張圖片就會被顯示得綠油油的。
這段代碼產生的結果如下:
?
?
通過觀察我們可以得到,大多數噪點的顏色要比字符更深,即其灰度值要更低;而背景的顏色要比字符更淺,即其灰度值更高。
通過閾值進行圖像的“二值化”(僅包含0與255,即黑白兩色),可以在一定程度上進行噪點的去除,便于之后的圖像分割與圖像分類。
如下的代碼進行了該步驟:
值得注意的是,這兩個閾值僅是針對此數據集而選取的兩個值。
如果使用的是與此不同的數據集,則需要選取別的方式進行二值化。
二值化的結果如圖所示:
可以看到,大多數噪點被去除了。當然,我們同時也丟失了一部分信息。
對于剩下的離散噪點,一個處理的思路是,對整個圖像進行遍歷,檢測每個像素其周圍八個點的灰度值,在這個九宮格內,黑色的像素點數量小于一定閾值的點,即視為離散噪點進行清除。
這是一個效率不高的寫法,不過很便于看懂究竟做了怎樣的操作。
如果你想的話,可以自己進行優化。
處理后得到的圖像如下:
接下來,便是采取同樣的方法對整個數據集進行這樣的處理。
在處理結束后,由于數據量較大,在之后的聚類的步驟中,不僅需要的時間較長,對內存也會有相當大的占用。
如果在這個過程中發生因為諸如內存不足而崩潰的情況,就需要重新將圖片讀取為灰度圖再進行處理,這就有點麻煩了。
一個解決方法是使用諸如pickle的庫,將得到的train_array與test_array作為二進制文件存儲:
· 圖像分割?·
?
之前已經提到過圖像分割對于大問題拆分的意義。
對于一個具有4位字符,每個字符的范圍從數字到大小寫字母的分類問題,共有624種可能的結果,而對于拆分完的圖像,分類器只需要決定它是62個可能中的哪一個就可以了——這樣即使是瞎蒙,也能提高很多的準確率。
?
對于圖像驗證碼的圖像分割問題,我大致有以下幾種思路:
?
1)使用若干個預先設計好的filter,依次對圖像進行點乘。
對于點乘得到的若干個結果,選取響應的值較高的,并且距離相對合理的,即可完成對圖像的分割。
用圖像來講解就像這樣:
?
?
這一方法的難點在于,如何設計filter,以及如何選取filter產生的結果。
由于字符數量較多,且可能包含多種變換的結果,需要經驗豐富的工程師才能決定設計怎樣的filter。
如果filter的數量過多,不僅會增大計算量,也會在結果的選取過程中增加噪音,難以獲得最優解。
人為的設計出優秀filter不是一件容易的事,也許需要一支相當龐大團隊的努力,這就使得實現一個這樣的算法很難。不過這樣的思路是很可取的,之后我們也還會再見到。
?
2)通過某種算法進行判斷。最簡單的比如,縱向切割,每檢測到一條不存在點的線即進行切割。
這一方法的缺點在于,對于粘連的字符難以拆分。
如果兩個字符粘連在一起,還可以通過平均切割等方法大致獲得結果,但如果有更多的字符粘連,甚至所有的字符都粘連在一起,這一方法就可能完全失效了。
?
3)通過某種聚類(Cluster)算法,得到圖像分割的結果。
聚類算法是非監督學習的一種,用于在無標簽的情況下,將數據集拆分為若干個類。
在傳統機器學習方法中,常見的聚類算法包括K-Means,EM-GMM,Mean-Shift等。
而在神經網絡中,常通過Encoder-Decoder模型來實現聚類任務。
接下來是這三個常用到的傳統學習中的聚類算法的介紹:
?
-
K-means算法
對于K-means而言,它的目標函數在于最小化其點與中心的總方差和:
假設聚類中心已知,則只需要選取可以最小化各點到聚類中心的方差的分配方式:
那么對于每個點而言,采取如下方式將每個點分配到離它最近的聚類中心:
同理,如果我們已知每個點到最近聚類中心的距離,也很容易得到聚類中心的問題。
然而實際上,對于這兩個前提,我們都沒法直接知道,這就像先有雞還是先有蛋的問題了。
幸好工程上而言,這個問題是可解的。
常用的方法是:
隨機選取若干個初始的聚類中心;
重復:
- 通過歐氏距離計算每個點到其到不同聚類中心的距離,以得到其應屬于的聚類;
- 對于每一個聚類,重新計算新的聚類中心為其平均點;直到收斂。
對于K-means而言,最終的結果依賴于初始化的聚類中心。
因此,如果運氣不好,你可能需要多次使用K-means才能得到一個比較合理的聚類結果。
工程上也常常使用多次K-means算法獲得聚類中心后,取使得目標方程值最小的解。
由于使用了歐式距離,K-means算法會得到一個圓形的聚類。
K-means算法的圖形演示如下:
?
-
EM-GMM算法
一個多元的高斯混合模型(GMM)可以獲得橢圓狀的聚類。
橢圓的形狀由高斯分布的協方差矩陣所決定,而位置由均值所決定。
高斯混合模型是一個高斯分布的加權和:
每個高斯分布代表了一個橢圓的聚類。
實踐中,常用期望最大化(Expectation Maximization, EM)算法來對于GMM進行計算。
當有隱變量(hidden/unseen variables)時,EM算法常用來獲得最大似然估計解。
對于GMM的EM算法求解過程如下:
E-step:計算聚類的關系,將分配給聚類?j
注意,這里使用的分配實際是一種軟分配,即一個點可以分數化地分配給不同的聚類。
? ? 2.?M-step:更新每個高斯分布聚類的均值、協方差和權重
-
計算聚類中的點(軟性的):
-
權重:
-
均值:
-
協方差:
由于圓實際上是一種特殊的橢圓,所以在協方差相等時,使用EM-GMM算法獲得的聚類結果應與K-means的結果相同。
使用EM-GMM算法常常能夠得到這樣的聚類結果:
?
-
Mean-Shift算法
Mean-Shift算法的理念在于,對于集合中的每個點逐步地計算其梯度并相應的移動,最終移動到同一個局部最優的點,即屬于同一個聚類。
實踐中,具體步驟如下:
1) 從一個初始點x開始;
2) 重復:
? ? ?- 根據高斯kernel,找到x在一定半徑內的最近鄰居;
? ? ?- 將x作為其臨近點的均值,直到x不再變化。
該步驟的圖形演示如下:
更直白一些的說,就是隨機初始化一個半徑固定的圓,然后將其圓心一直向數據集密度最大的方向移動。
多次迭代后,當其不再移動時,即到達了一個聚類中心位置,而圓的半徑以內的點則為該聚類中的點。對于mean-shift算法而言,其變量自然就是圓的半徑了。
?
在這一問題中,一個比較接近于mean-shift的實現(同時也是比較常用的)算法被稱為分水嶺算法(Watershed Algorithm)。
想象有一條連綿起伏的山脈,這時突然下起了大雨,山與山之間低的地方自然就積滿了水,圖像也就這樣被分割了。在實現中,“下雨”的過程實質上就是梯度下降的過程。
這樣聽上去,聚類算法似乎很適合實現這樣的目標。事實上,對于較為簡單的驗證碼(字符分隔界限較明顯、較為容易分隔的情況),聚類算法能夠進行分類,但對于復雜的情況,或許結果就不是那么理想了。
以下為使用K-means算法對之前驗證碼進行聚類后的結果:
可以看到,C和9兩個字符已經被分割開,而X與6則完全被混淆到了一起。
原因可能是:
字符并不符合于圓形的分布,又或是K-means在這種情況下難以得到一個好的初始化點等等。
更關鍵的問題在于,如果我們這時候去檢查聚類中心的橫坐標的位置,并將其對應結果依次從左到右顯示:
可以看到,更像“6”的結果3出現在更像“x”的結果4之前,如果直接進行標注,這樣的標注就可以被認為是“臟數據”。
使用分水嶺算法得到的結果也并不理想:
對于傳統算法的機器學習而言,解決一個較為困難的問題,往往需要一支數十人甚至數百人的工程師團隊,花費數月甚至數年的時間進行設計。
鑒于這樣的分割結果,直接圖像分類肯定是走不下去了。所以我接下來我會對常見的分類算法進行一些介紹,然后一起來看看運用神經網絡是否能解決這個問題。
在圖像分割之后,有一些諸如對圖像進行“歸一化(normalization)”的技巧。
在這一問題中,使用歸一化可以在一定程度上實現對于圖像方向向量的校正,通過一個設計好的“確定方向邊界框(Oriented Bounding Box)”可以是達到這一效果的一個思路。
· 圖像分類?·
?
針對這一問題,進行分類的主要難點在于,由于諸某些字符的先天性的難以辨別,這會對分類器的收斂造成困難。
諸如0與O,I與l - 你真的能認出這兩個誰是誰嗎?!
不過對于這個問題,我也并不能想到什么好的解決方式,所以只能視若無睹了。
?
在真正開始訓練之前,對于數據集還可以采取的一種常見策略叫做“數據增強(Data Augmentation)”。
大致上來說,數據增強常常就是對于數據集中的數據采取某種方式的變化,來擴大數據集。
不過要注意,對于采取的具體變化要小心。對于這個問題,可以采取的簡單的變化方式主要有“投影(Shearing)”,“旋轉(Rotation)”,“偏移(Shifting)”和“縮放(Zooming)”。
在進行旋轉時,要注意只能在一個較小的幅度內進行,如對于“7”進行180度的旋轉,就會變成一個類似于“L”的形狀,然而其標簽仍然為“7”,這顯然就是一個噪音了。也可以通過增加一些噪音,如“高斯噪聲(Gaussian Noise)”來實現數據增強,讓模型更為健壯。
實現這一功能的代碼如下:
其實對于這一問題而言,數據增強并不是必須的,因為獲得一個新的驗證碼太容易了,并且我們已經有了一個相當大的訓練集了。如果花費足夠的時間產生一個足夠龐大并且分布較為均勻的數據集,且與測試集服從相似的分布,模型在測試集上的表現就不會太差。
這里使用的數據增強的方式,在生成驗證碼圖片的過程中是常常用到的,所以并不是什么必須的,或是能顯著提升準確率的手段。這里提及更多的是作為一種介紹。
可能你注意到,在剛剛的代碼塊中用到了一個名為keras的Python庫。Keras基本可以理解為一套便于開發人員開發高級神經網絡的API,它支持使用TensorFlow,Theano等作為后端運行。個人感覺而言,它的語法要比原生的TensorFlow多少友好一些。
?
分類算法又可分為“二分類算法”和“多分類算法”兩種。顧名思義,二分類算法就是對于數據集,只能將它們分為兩種類別的算法。常見的二分類算法包括邏輯回歸(Logistic Regression,LR)、支持向量機(Support Vector Machine,SVM)等。而最常見的多分類算法就是決策樹(Decision Tree)了。
?
-
邏輯回歸
? ? ? ? 分類器:
? ? ? ? 對于線性函數:
? ? ? ? 給定特征向量,一個類的概率是:
? ? ? ? ?sigmoid函數:
? ? ? ? ?邏輯回歸的損失函數:
? ? ? ? ?訓練:
? ? ? ? ?最大化訓練集的可能性
? ? ? ? ?通過正則化(regularization)防? 止過擬合——通過交叉驗證選取正則化超參數C
? ? ? ? ?進行分類:
?
? ? ? ? ?對于給定樣本x*:
-
?選取概率最高的類別p(y|x*):
-
?否則,直接使用f(x*)
對于邏輯回歸這樣的二分類分類器,通過一些手段,也可將它們用于解決多分類問題。
其一是使用諸如“1-vs-rest”策略。換言之,即將多分類問題劃分為若干個二分類問題,使用多個二分類分類器進行解決。
另一個得到多分類分類器的方法時定義一個多分類目標函數,并給每個類別C分配一個權重向量Wc。
通過softmax函數定義概率:
-
?支持向量機
對于一個分類問題而言,可能會有若干個分類器:
? ? ? 對于SVM而言,其目的就是要找【邊緣(margin)最大】的那個分類器。
? ? ? ?SVM這樣決策的優點在于,在保證所有點都被正確分類的同時,也保證了最大不確定性。
訓練:
對于給定訓練集:
首先定義邊緣距離:
? ? ?從點Xi到超參數W的距離:
? ? ?邊界距離是到所有距離中的最短距離:
目標函數為:
預測時,對于新的數據點
可以看到,SVM產生的決策邊界是線性的。
可以使用“核函數(kernel function)”使得SVM可以做出非線性的判斷。
這其實是一種將數據集向高維轉化,使得數據集在高維上線性可分的做法。
?
-
?K近鄰法
K近鄰法(K-Nearest Neighbors)是一種很簡單的分類算法。
每次有新的樣本,分類器就會找到在已知樣本中距離其最近的K個,然后選取其中的大多數來作為新樣本的分類。
這并不是一種好的分類方法,因為分類器什么都沒有學到。
-
決策樹
決策樹也是一種較為簡單的分類器,你可以將它想象成流程圖。
對于一個“與”運算:
?
?
? ? ? ? 產生的一個決策樹如下:
?
使用分類器的劣勢在于,它很容易過擬合。幸好,這可以通過Bagging策略進行彌補。由于決策樹本身是一種較為簡單的分類器(占用資源少,運算速度快),使得其常常與Boosting和Bagging這兩種策略相結合使用,以產生更好的結果。
Boosting:訓練多個分類器,每個新的分類器專注于之前的分類器分類錯誤的部分。
Bagging:訓練多個分類器,每個分類器只使用訓練集中的隨機一部分子集進行訓練。在預測時,使用所有的分類器來投票,得到這個新樣本的分類結果。使用決策樹的Bagging策略又被稱為“隨機森林(Random Forest)”分類器。
· 用神經網絡進行驗證碼識別?·
?
使用神經網絡解決該問題,可以使用兩種思路。
1)多分類任務
多分類任務,也就是之間所介紹過的,最終的結果只有一個標簽,但是標簽會有若干種類別。
2)多標簽任務
對于多標簽任務而言,一條數據可能有一個或多個標簽。
想象你正在聽一首歌曲,如果你在里面聽到說唱,那么說唱就是這首歌曲的一個標簽。同樣的,這首歌曲還可以有諸如流行、古典……等等標簽。
只要你在其中聽到了相應的特征,它就有可能作為這首歌曲的一個標簽,得到該標簽對應的概率。
在訓練神經網絡時,不同任務使用的激活函數和損失函數關系如下:
如果你想對多標簽任務有更多的了解,可以查閱收錄于 2014 TKDE 的張敏靈與 周志華的論文:
A review on multi-label learning algorithms。
限于時間和篇幅的關系,對于神經網絡相關的內容這里也就不做過多的討論了,如果說起來,恐怕這篇文章就要沒完沒了了。以下為神經網絡的一個實現:
這里使用了卷積神經網絡(Convolution Neural Network,CNN)。CNN在計算機視覺問題中被廣泛使用。相比于傳統的DNN(Deep Neural Network,這里即MLP,Multi-Layer Perceptron多層感知機),它能夠同時兼顧“整體”與“局部”,找到不同區域間的關聯關系。
這個模型中包含了很多神經網絡(也可以用于傳統機器學習)的常見內容,比如“優化器(optimizer)”(近幾年最常用的應該就是Adam,雖然有很多大佬并不喜歡它)、“池化(Pooling)”(最常見比如MaxPooling,即在一個矩陣中取最大值,然后將這個矩陣進行縮小,通過這個過程神經網絡可以“看得更廣”)、“dropout”(一部分結點不響應也做出決策,使得神經網絡更加robust,用于解決過擬合)、還有激活函數(ReLU、sigmoid等等……),大家有興趣可以自己多去了解。
這里使用神經網絡的方法,也可以說是對于使用神經網絡而言最簡單的方法:定義好一個網絡結構,然后把數據塞進去,看看結果怎么樣。如果結果不太理想的話,就調整網絡結構再試試。
這也正是使用神經網絡和使用傳統機器學習算法的一個顯著區別:神經網絡由數據驅動,人為的干預往往也只是定向的輸入數據,通過數據來校正網絡;而傳統機器學習算法則由工程師預先設計好各種情況,如果算法的結果不夠好,常常也只是因為設計好的算法對于某些情況處理不當。因此,你也大可以修改網絡的結構,或者使用別的網絡來試試。
?
上述的代碼使用的是運用多標簽任務的方法的,你也可以修改為多分類任務的網絡(應該只需要修改全連接層的激活函數和損失函數即可,并且根據我的查閱,這一方法也是可行的,并且準確率可以到很高的程度),來看看結果如何。
當然,也不是所有人在運用神經網絡的時候,都使用這種“端到端(end-to-end)的方法,即一個神經網絡解決所有問題。你也可以對于輸入網絡的數據進行更多的預處理(預處理也可以由別的結構的網絡來完成),來看看是否能得到更好的結果。
更進一步地說,這里所采用的CNN網絡是解決CV(Computer Vision,計算機視覺)問題的一個常見解決方法,而對于圖形驗證碼問題,也可以采取NLP(Natural Language Processing)的思路進行解決。
使用一些RNN(Recurrent Neural Network, 循環神經網絡),例如前幾年比較流行的LSTM,也可以對這個問題進行求解。
這里的網絡事實上只預測了36個分類。
訓練過程的截圖在此:
可以看到在第5個epoch,模型在驗證集(10000個的訓練集中,9000個用于訓練而1000個用于驗證集——一個不參與訓練,只檢驗模型訓練成果的數據集)上的表現已經開始下降,這說明模型已經開始過擬合于訓練集。當然這個過程其實不一定要手動干預,使用早停法(early stop)就可以實現。可以看到,我大約在準確率為95.81%的時候停止了訓練。
模型的一個預測結果如下,可以看到這是一個正確的預測。
模型在測試集上的表現為0.9390625,也就是大約93.9%。
· 結語 ·
?
當然,驗證碼的形式多樣,越來越復雜的驗證碼也越來越難以攻破。
例如部分網站現在所采用的圖像驗證碼,為給出多張圖片,要求用戶在找出其中具有某種物體的圖片并進行選擇。這個問題的難度,就遠超于單純的字符識別問題了。對于這樣的問題,就要求算法應具備識別相當數量物體(例如,數百種物體:轎車、大象、花朵、紅綠燈等等)的能力。
?
綜上所述,針對于測試工作而言,最好用的方法肯定還是和開發哥哥姐姐們商量一下,繞過一下驗證碼,不僅省去了開發整個識別驗證碼系統的時間,還可以提高通過的準確率,畢竟無論怎樣的機器學習方法都不可能產出100%的準確率(假設訓練集不可能包含所有可能情況)。
?
?
?
?
?
-END-
?
?
?
文/ PokemonFish
?
總結
以上是生活随笔為你收集整理的【得物技术】机器学习在图形验证码识别上的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL中的关联子查询
- 下一篇: AppBarLayout.Behavio