天天看點

前端智能化漫談 (4) - pix2code結果編輯距離分析前端智能化漫談 (4) - pix2code結果編輯距離分析

前端智能化漫談 (4) - pix2code結果編輯距離分析

Levenshtein距離分析

從實用的角度,我們先采用萊文斯坦距離,也就是編輯距離來分析一下pix2code的結果。因為Levenshtein距離是從DSL角度來看,需要人工修改時的最小編輯次數,是以從這個角度來分析是有其意義的。

我們分别用greedy和beam 3兩種方法對于datasets/android/eval_set下面的png都生成一遍gui,分别存放于../android_greedy和../android_beam3目錄。

可以用這樣的指令:

python3 ./generate.py ../bin pix2code ../datasets/android/eval_set/ ../android_greedy/ greedy
python3 ./generate.py ../bin pix2code ../datasets/android/eval_set/ ../android_beam3/ 3           

然後我們就可以寫一個pix2code_levenshtein函數來比較它們之間的差别,記得安裝python_levenshtein庫:

def pix2code_levenshtein(path1, path2):
    count = 0
    score = 0
    average_score = 0
    for f in os.listdir(path2):
        if f.find(".gui") != -1:
            f1 = os.path.join(path1,f)
            f2 = os.path.join(path2,f)
            print(f)
            if os.path.exists(f1) and os.path.exists(f2):
                print(f1)
                txt1 = open(f1).read()
                txt1 = txt1.replace(" ","")
                print(txt1)
                print(f2)
                txt2 = open(f2).read()
                txt2 = txt2.replace(" ","")
                print(txt2)
                this_score = Levenshtein.distance(txt1,txt2)
                print('This score:',this_score)
                print(Levenshtein.ratio(txt1,txt2))
                count = count + 1
                score = score + this_score
                average_score = score / count
                print('Current score:',average_score)           

樣例分析

我們随機挑選10個檔案分析一下

greedy和beam 3都能100%正确識别

例子:

完全正确的例子就不分析了。

以greedy擷取的結果為例:

stack{
row{
switch
}
row{
switch
}
row{
radio
}
row{
label,slider,label
}
}
footer{
btn-home,btn-dashboard,btn-home
}           

greedy和beam 3同樣識别錯誤

10個樣例中有4例是這樣的情況。

102D9F19-4FAB-4144-9996-589C22991D61

标準答案如下:

../datasets/android/eval_set/102D9F19-4FAB-4144-9996-589C22991D61.gui
stack{
row{
switch
}
row{
label,btn
}
row{
switch,switch
}
}
footer{
btn-search,btn-dashboard,btn-notifications
}           

不管是greedy還是beam 3,都錯了兩處,将footer中間的btn-dashboard和右邊的btn-notifications給識别成了btn-home。

../android_greedy/102D9F19-4FAB-4144-9996-589C22991D61.gui
stack{
row{
switch
}
row{
label,btn
}
row{
switch,switch
}
}
footer{
btn-search,btn-home,btn-home
}           

48CCC704-865B-48FC-B64C-C9DA057E5F61

這個case兩種算法都隻錯了一處,與上例第二處錯誤一樣,将btn-notifications給識别成了btn-home。

stack{
row{
switch
}
row{
label,btn,btn
}
}
footer{
btn-dashboard,btn-notifications
}

../android_greedy/48CCC704-865B-48FC-B64C-C9DA057E5F61.gui
stack{
row{
switch
}
row{
label,btn,btn
}
}
footer{
btn-dashboard,btn-home
}           

54BC253F-DA31-4904-BC18-233CC0083E2F

這個比較複雜,不管greedy還是beam 3下都不能正确認别。标準答案如下:

stack{
row{
radio
}
row{
label,btn
}
row{
radio
}
row{
check
}
row{
label,slider,label
}
row{
switch
}
row{
check
}
row{
label,btn
}
}
footer{
btn-dashboard,btn-home,btn-dashboard
}           

不管是在greedy識别中還是beam 3識别中,第三行和第四行的check和radio識别反了。

第6行和第7行沒識别出來,在第8行後多識别出一行。

另外,footer上的三個都識别錯了。

stack{
row{
radio
}
row{
label,btn
}
row{
check
}
row{
radio
}
row{
label,slider,label
}
row{
label,btn
}
row{
radio
}
}
footer{
btn-home,btn-dashboard,btn-notifications
}           

CCF7369F-FCE4-4801-8936-E251EE90038C

這個case也相對簡單,标準答案如下:

stack{
row{
switch
}
row{
switch
}
row{
check
}
row{
switch
}
}
footer{
btn-notifications,btn-home,btn-home
}           

greedy和beam 3都是兩處錯誤,一處是switch識别成了radio;另一處是footer上最左邊的的btn-notifications被識别成了btn-home。

stack{
row{
switch
}
row{
switch
}
row{
radio
}
row{
switch
}
}
footer{
btn-home,btn-home,btn-home
}           

greedy模式與beam 3模式下表現不同的

DBC890B4-0490-4A9B-88F6-8625F518F269

這個case中,greedy錯了6處,beam 3錯了4處。

stack{
row{
switch
}
row{
radio
}
row{
label,slider,label
}
row{
switch
}
row{
switch
}
}
footer{
btn-home,btn-dashboard,btn-dashboard
}           

greedy下對第三行的識别基本失敗。

第四行和第五行的switch,greedy下隻識别成一個radio。

另外,footer上錯了兩個。

stack{
row{
switch
}
row{
radio
}
row{
switch,switch,btn,btn
}
row{
radio
}
}
footer{
btn-dashboard,btn-notifications,btn-dashboard
}           

beam 3搜尋對于第三行的支援很好。第4行第5行的switch還是沒識别出來。

最後,footer的錯誤與greedy時一樣。

stack{
row{
switch
}
row{
radio
}
row{
label,slider,label
}
row{
radio
}
}
footer{
btn-dashboard,btn-notifications,btn-dashboard
}           

68F022A8-0C01-4684-A9B2-27E586C2D918

stack{
row{
switch
}
row{
check
}
row{
label,slider,label
}
row{
check
}
}
footer{
btn-search,btn-search,btn-notifications
}           

在greedy模式下,check被識别成了radio

stack{
row{
switch
}
row{
check
}
row{
label,slider,label
}
row{
radio
}
}
footer{
btn-search,btn-search,btn-notifications
}           

而在beam 3模式下,有3處識别錯誤,第2行沒識别出來,另外footer上錯了兩個:

stack{
row{
switch
}
row{


}
row{
label,slider,label
}
row{
radio
}
}
footer{
btn-notifications,btn-search,btn-notifications
}           

7C656D6E-0402-4D53-9450-CC948F07A8D4

stack{
row{
switch
}
row{
switch
}
row{
btn,btn,switch,switch
}
row{
label,btn
}
row{
label,slider,label
}
row{
switch
}
row{
label,btn,btn,btn
}
row{
switch,btn,btn
}
}
footer{
btn-home,btn-search,btn-search,btn-search
}           

到這麼複雜的情況下,不管是greedy和beam 3都亂了套,各有十幾處錯誤。

greedy的情況:

stack{
row{
switch
}
row{
switch
}
row{
btn,switch,switch
}
row{
label,btn,btn,btn
}
row{
switch
}
row{
label,slider,label
}
row{
label,btn
}
row{
switch
}
row{
label,btn
}
}
footer{
btn-home,btn-search,btn-search,btn-search
}           

beam 3的情況:

stack{
row{
switch
}
row{
switch
}
row{
btn,switch,}
row{
label,btn,btn,btn
}
row{
label,slider,label
}
row{
switch
}
row{
label,btn
}
row{
label,slider,btn,btn
}
}
footer{
btn-search,btn-search,btn-search,btn-home
}           

8B5AF397-CBD8-4B2C-B8A6-3E9D036B4F2F

我們再來看一個複雜點的例子,标準答案如下:

stack{
row{
btn,switch,btn
}
row{
switch
}
row{
btn,btn,btn,btn
}
row{
label,slider,label
}
row{
radio
}
row{
check
}
row{
check
}
}
footer{
btn-notifications,btn-home,btn-notifications,btn-notifications
}           

greedy算法在第一行識别就把中間的switch識别成了btn。

stack{
row{
btn,btn,btn
}
row{
switch
}
row{
label,slider,label
}
row{
check
}
row{
label,slider,label
}
row{
btn
}
row{
radio
}
}
footer{
btn-home,btn-home,btn-home,btn-home
}           

beam 3的表現要好一些,但是在row中識别出了row,,,,是個敗筆:

stack{
row{
btn,btn,btn
}
row{
switch
}
row{


row,,,,


row{
label,slider,label
}
row{
check
}
row{
check
}
}
footer{
btn-search,btn-notifications,btn-home,btn-home
}           

beam 3可正确識别而greedy不能正确識别的case

9DB2E273-687B-4C00-952C-354C1AE1BF99

greedy對于同一行較多控件情況下的識别能力不如beam 3,在第1行第4個控件識别上出了問題,标準答案如下:

stack{
row{
btn,switch,switch,btn
}
row{
check
}
row{
switch
}
}
footer{
btn-dashboard,btn-home
}           

greedy時最後一個btn識别成了switch

stack{
row{
btn,switch,switch,switch
}
row{
check
}
row{
switch
}
}
footer{
btn-dashboard,btn-home
}           

樣例總結

這10個case中,greedy模式下的平均Levenshtein距離32.1,beam 3模式下為28.

250張Android測試集,greedy平均編輯距離為27.9,beam 3模式下32.

繼續閱讀