人們的不斷探索下,「使用人工智能自動生成網頁」的方法已經變得越來越接近實用化了。本文介紹的這種名為 SketchCode 的卷積神經網絡能夠把網站圖形用戶界面的設計草圖直接轉譯成代碼行,為前端開發者們分擔部分設計流程。目前,該模型在訓練后的 BLEU 得分已達 0.76。
你可以在 GitHub 上找到這個項目的代碼:https://github.com/ashnkumar/sketch-code
為用戶創造直觀、富有吸引力的網站是各家公司的重要目標,而且這是個快速進行原型、設計、用戶測試循環的過程。像 Facebook 這樣的大公司有著讓整個團隊專注于設計流程的人力,改動可能需要幾周的時間,并涉及到多種利益相關者;而小型企業就沒有這樣的資源,因此其用戶界面可能受到一些影響。
我在 Insight 當中的目標是使用現代深度學習算法大大簡化設計工作流程,并使得任何規模的公司都能快速地創造并測試網頁。
現有的設計工作流程
現有工作流程涉及多個利益相關者
一個典型的設計工作流程如下所示:
產品經理進行用戶研究,從而制定技術參數表
設計人員將接受這些要求并嘗試創建低保真原型,最終創建高保真原型
工程師將這些設計轉化為代碼并最終將產品交付給用戶
開發周期的時間長度很快就會變成瓶頸,像 Airbnb 這樣的公司已經開始使用機器學習來提高這個過程的效率了。(參見:https://airbnb.design/sketching-interfaces/)
Airbnb 內部 AI 工具演示:從草圖到代碼
雖然這種工具很有希望成為機器輔助設計的例子,但是尚不清楚這種模型在端到端的情況下能完全訓練到什么程度,也不清楚它在多大程度上依賴于手工制作的圖像特征。這肯定是無法知道的,因為它目前還是 Airbnb 專有的非開源方案。我想創造一個「從繪圖到代碼」技術的開源版本,可供更多開發者和設計者使用。
理想情況下,我的模型可以采用簡單的網站設計手繪原型,并立即從該圖像生成一個可用的 HTML 網站:
SketchCode 模型需要繪制好的網站線框圖并能生成 HTML 代碼
實際上,上面的例子是一個從我模型測試集圖像生成的實際網站!你可以在我的 Github 頁面中查看它:https://github.com/ashnkumar/sketch-code
從圖像標注中獲取靈感
我正在解決的問題屬于程序綜合(https://en.wikipedia.org/wiki/Program_synthesis)這個廣義任務范疇,即工作源代碼的自動生成。盡管很多程序綜合能處理從自然語言要求或執行軌跡所生成的代碼,但在我這個案例中,我可以從一個源圖像(手繪線框圖)開始,自動獲得想要的代碼。
機器學習領域中,有一個名為圖像字幕生成的領域(https://cs.stanford.edu/people/karpathy/deepimagesent/),該領域有著充分的研究,旨在學習將圖像和文本相連的模型,特別是生成關于源圖片內容的描述。
圖像標注模型生成源圖片的描述
我從最近一篇名為 pix2code 的論文和 Emil Wallner 使用該方法的一個相關項目獲得了靈感(參見:前端慌不慌?用深度學習自動生成 HTML 代碼),并決定將我的任務重構成圖像字幕生成問題的一部分,即將線框圖作為輸入圖像,將對應的 HTML 代碼作為輸出文本。
獲取正確的數據集
考慮到圖像標注的方法,我心中理想的訓練數據集是成千上萬對手繪線框圖和它們 HTML 代碼的等價物。不出所料,我無法找到這種數據集,因此我不得不為該任務創建自己的數據。
我從 pix2code 論文中提到的一個開源數據集(https://github.com/tonybeltramelli/pix2code)入手,它由 1750 張人工生成的網頁截圖和其對應源代碼構成。
pix2code 中生成的網站圖像及其源代碼數據集
這個數據集對我而言是個很好的開始,其中有一些有趣的地方:
數據集中每個生成的網站都包含幾個簡單的 Bootstrap 元素例如按鈕、文本框和 DIV。雖然這意味著我的模型將會因把這幾個元素作為「詞匯」(模型可選擇用于生成網站的元素)而受限制,這種方法應該很容易推廣到更大的元素詞匯表中。
每個示例的源代碼包含領域專用語言(DSL)的標記,這些符號是由論文作者創建的。每個標記對應于 HTML 和 CSS 的片段,且有一個編譯器將 DSL 轉化為工作使用的 HTML 代碼。
讓圖片更像手繪的
將網站的多彩主題切換成手寫主題。
為了調整數據集以適應我的任務,我得把網站的圖片弄得像是手繪的。對圖片的手繪化都得益于 OpenCV 和 PIL library 的灰度轉換和輪廓檢測功能。
最終,我決定直接通過一系列操作來直接修改原網站的 CSS 樣式表:
通過改變頁面元素的邊框半徑實現按鈕和 div 的圓潤化
調整邊框的粗細以模仿手繪素描,并添加陰影
將字體改為類手寫字體
我的最終版本又增加了一個步驟,通過加入傾斜,偏移和旋轉來進行數據增強,以模仿實際繪制的素描的不確定性。
使用圖像標注模型架構
現在我已經準備好我的數據了,我可以把它輸入模型進行訓練了!
我用的這個用于圖像標注的模型包括三個主要部分:
一個卷積神經網路(CNN)視覺模型用于提取源圖片特征
一種由編碼源代碼標記序列的門控循環單元(GRU)組成的語言模型
一個解碼器模型(也是一個 GRU),它以前兩個步的輸出作為輸入,預測序列中的下一個標記
使用標記序列作為輸入來訓練模型
為了訓練這個模型,我把源代碼分成標記序列。其中一個序列及其源圖像是模型的單個輸入,其標簽是文檔中的下一個標記。該模型使用交叉熵成本(cross-entropy cost)作為其損失函數,將模型預測的下一個標記與實際的標記進行比較。
在模型從頭開始生成代碼的推理階段,該過程稍有不同。該圖像仍然通過 CNN 網絡進行處理,但文本處理僅提供一個開始序列。在每一步中,模型對序列中下一個標記的預測將返回到當前輸入序列,同時作為新的輸入序列輸入到模型中。重復此操作直到模型預測出 <END> 標記或進程達到每個文檔的標記數的預定義上限。
一旦從模型中生成了一組預測標記,編譯器就會將 DSL 標記轉換為 HTML,這些 HTML 可以在任何瀏覽器中展示出來。
用 BLEU 得分評估模型
我決定用 BLEU 評分(https://machinelearningmastery.com/calculate-bleu-score-for-text-python/)來評估模型。這是機器翻譯任務中經常會用到的評估標準,它試圖在給定相同輸入的情況下,評估機器生成的文本與人類可能寫的文本的近似程度。
實質上,BLEU 通過比較生成文本和參考文本的 n-元 序列,生成精修改后的文本。它非常適合這個項目,因為它會影響生成的 HTML 中的實際元素,以及它們之間的相互關系。
然后這是最棒的——我完全可以通過檢查生成的網站來理解 BLEU 得分!
BLEU 得分可視化
一個完美的 1.0 的 BLEU 分數將在正確的位置生成源圖像的正確元素,而較低的得分可以預測錯誤的元素和/或將它們放在相對于彼此錯誤的位置。最終我的模型能夠在測試集上得到 0.76 的 BLEU 分數。
福利 - 定制樣式
我覺察到的一個額外福利是,由于模型只生成頁面的骨架(文檔的標記),我可以在編譯過程中添加一個自定義的 CSS 層,并且可以即時看到網站的不同風格。
一次轉換 => 同時生成多種樣式
將樣式與模型生成過程分離,給使用模型帶來了很多好處:
想要將 SketchCode 模型應用到自己公司產品中的前端工程師可以按原樣使用該模型,只需更改一個 CSS 文件以符合其公司的樣式要求
可擴展性已內置 - 使用一張源圖像,模型輸出可立即編譯為 5、10 或 50 種不同的預定義樣式,因此用戶可以看到他們網站的多個版本,并在瀏覽器中瀏覽這些網站
總結與展望
通過利用圖像標注的研究成果,SketchCode 能夠在幾秒鐘內將手繪網站線框圖轉換為可用的 HTML 網站。
該模型有些局限性,大概包括以下幾點:
由于這個模型是用一個只有 16 個元素的詞匯進行訓練的,它不能預測訓練數據之外的標記。下一步可能是使用更多元素(如圖像,下拉菜單和表單)生成其他樣例網站——Bootstrap components 是個練手的好網站:https://getbootstrap.com/docs/4.0/components/buttons/
實際生產環境中,網站有很多變化。創建一個更能反映這種變化的訓練數據集的好方法是去爬取實際的網站,捕獲他們的 HTML / CSS 代碼以及網站內容的截圖
手繪素描也有很多變化,CSS 修改技巧沒有被模型完全學會。在手繪素描上生成更多變化的一種好方法是使用生成對抗網絡來創建逼真的繪制網站圖像
我很期待看到項目的進一步發展!
助GPT-4V視覺模型,可以輕松的將一張草圖生成一個靜態頁面。現在這已經不是什么稀奇事了。
主要是分享一下它的Prompt,很簡單,用戶畫好草圖后,將草圖保存成png圖片,傳給GPT-4V,然后GPT返回一個標準的HTML,并且所有的樣式表采用Tailwind CSS的格式,這樣只要頁面引用了TailwindCSS,就能直接正常顯示樣式。
并且,除了草圖,它還可以傳入之前生成的HTML,這樣可以基于之前的HTML進行修改,而不是重頭生成。
只能說GPT-4V的模型能力真的強
以下是Prompt:
作為一位精通 Tailwind CSS 的資深網頁開發者,當用戶提供給你一個應用程序初步草圖時,你的任務是制作一個包含 HTML、Tailwind CSS 和 JavaScript 的高保真網頁,并將所有額外的 CSS 和 JavaScript 代碼直接嵌入到這個 HTML 文件中。如果需要使用圖片,你可以從 Unsplash 獲取,或者簡單使用純色矩形代替。用戶可能會用藍色或紅色的文字、箭頭或圖示來給出具體說明。有時,他們甚至會提供其它網站的截圖作為設計參考,你需要根據這些參考盡可能地復制其風格、字體、顏色和布局。此外,如果用戶提供了之前的設計 HTML,你需要在此基礎上進行改進。根據用戶的要求,對設計進行相應的調整。在草圖中,舊版設計的 HTML 會顯示為一個白色矩形。在制作過程中,你有創意自由來讓應用程序更加完善和詳細。使用 JavaScript 模塊和 unpkg 來導入任何必需的依賴項。回答時只提供 HTML 文件的內容。
項目地址:https://github.com/tldraw/draw-a-ui
(OF作品展示)
OF之前介紹了用python實現數據可視化、數據分析及一些小項目,但基本都是后端的知識。想要做一個好看的小系統,我們還要學一些前端的知識,今天OF將講解如何用pycharm(全棧開發不錯的工具)做一張好看的網頁,以后我們就可以自己開發網頁/網站放到互聯網上。
主要內容:網頁前端布局
適用人群:Python初學者,前端初學者
準備軟件:pycharm
1) 下載完成pycharm, 點擊file-New Project...
2) 按下圖步驟創建一個項目,目前我們選擇Pure python即可,以后我們可以學習用Django/flask等框架來做完整的系統
1)在創建的項目空白處鼠標右鍵-New-HTML File
2)輸入英文的網頁名字,盡量不要輸入中文/特殊字符
當雙擊打開我們創建后的HTML文件,大家會看到下面的界面
在開始開發網頁前,我們需要自己設計下想要把網頁做成什么樣,為了節省成本OF都是自己設計的頁面樣式,可以手繪,也可以在PPT上畫。
我們先學習一個比較簡單的布局如下圖,大家可以看到下圖已經畫出了我們需要添加的內容,要注意的地方是比如Taylor的圖片和文字一定要用<div class=bord>框住,否則Taylor圖片與文字將會是左右的關系,而不是上下
根據上述的css名字定義,先填充<body>內的代碼,那么我們就完成一半的工作了,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="intro">
<p class="peo">人物介紹</p>
</div>
<div id="pic1">
<div class="bord">
<img class="img" src="pic/Taylor.png"/>
<p class="word">Taylor</p>
</div>
<div class="bord">
<img class="img" src="pic/yan.png"/>
<p class="word">東</p>
</div>
<div class="bord">
<img class="img" src="pic/song.png"/>
<p class="word">喬</p>
</div>
</div>
</body>
</html>
1)鼠標移到代碼處,在右上角我們會看到一排瀏覽器,我們點擊其中一個運行
2)目前看到的網頁內容從上到下顯示
首先我們簡要了解下flex布局,大家可以看到下圖中#main的style樣式中display:flex,在body部分將3個顏色內容框在<div id="main">中,運行結果是3個顏色的內容橫向展示了,而不是上下
1)那么我們先從“人物介紹”的布局開始,“人物介紹”居中展現(用flex中justify-content:center),而且下面有一條黑線,OF準備用border樣式來實現,所以在<div id=intro>里另加了個<div class=peo>,代碼如下:
(注:style中的#main對應body中的id=main, .main對應class=main)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#intro {
display: -webkit-flex; /* Safari */
display: flex;
justify-content: center;
}
.peo {
max-width: 10rem;
border-bottom: 0.2rem solid #000000;
font-family: sans-serif;
font-size: 1.5rem;
color: #0070C0;
line-height: 3rem;
}
</style>
</head>
<body>
<div id="intro">
<p class="peo">人物介紹</p>
</div>
<div id="pic1">
<div class="bord">
<img class="img" src="pic/Taylor.png"/>
<p class="word">Taylor</p>
</div>
<div class="bord">
<img class="img" src="pic/yan.png"/>
<p class="word">東</p>
</div>
<div class="bord">
<img class="img" src="pic/song.png"/>
<p class="word">喬</p>
</div>
</div>
</body>
</html>
運行結果:
2)圖片部分是3個<div class=bord>橫向展示,所以要在框住它們的<div id=pic1>樣式中設置flex布局,在<style>里加入以下代碼:
#pic1 {
display: -webkit-flex; /* Safari */
display: flex;
justify-content: center;
}
運行結果:
3)圖片之間靠太近,圖片大小不一致,文字沒居中,我們在<style>里加入以下代碼:
.bord{
padding: 1rem 2rem;
}
.img {
border: 0.2rem solid #e3e3e3;
max-width: 15rem;
height: 22rem;
}
.word {
text-align: center;
}
運行結果:
今天我們學會了flex布局,今后所有的網頁排版都可以實現了,祝愿大家都有所收獲,完整的代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#intro {
display: -webkit-flex; /* Safari */
display: flex;
justify-content: center;
}
.peo {
max-width: 10rem;
border-bottom: 0.2rem solid #000000;
font-family: sans-serif;
font-size: 1.5rem;
color: #0070C0;
line-height: 3rem;
}
#pic1 {
display: -webkit-flex; /* Safari */
display: flex;
justify-content: center;
}
.bord{
padding: 1rem 2rem;
}
.img {
border: 0.2rem solid #e3e3e3;
max-width: 15rem;
height: 22rem;
}
.word {
text-align: center;
}
</style>
</head>
<body>
<div id="intro">
<p class="peo">人物介紹</p>
</div>
<div id="pic1">
<div class="bord">
<img class="img" src="pic/Taylor.png"/>
<p class="word">Taylor</p>
</div>
<div class="bord">
<img class="img" src="pic/yan.png"/>
<p class="word">東</p>
</div>
<div class="bord">
<img class="img" src="pic/song.png"/>
<p class="word">喬</p>
</div>
</div>
</body>
</html>
今天的知識比較基礎但非常實用,每天學會一個小技能,積少成多,以后就能成為大神。如果大家對網頁上的實現有什么不懂的,盡請留言,OF一定會一一解答的。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。