0
本文作者: skura | 2019-10-01 09:57 |
我妻子幾乎每天都會(huì)問這個(gè)問題:我今天該穿什么?這是一個(gè)很難回答的問題,因?yàn)槭紫任覜]有時(shí)尚感,而 Yumi 恰恰相反,她有時(shí)裝設(shè)計(jì)學(xué)位。其次,我記性不好,我想不起來她過去幾周穿了什么衣服,回答可能千篇一律。
所以,有一天,我決定利用周末的時(shí)間來開發(fā)一種我認(rèn)為可以解決她的問題的技術(shù)。
在開始之前,我想感謝她在這個(gè)項(xiàng)目和我所有其他瘋狂的項(xiàng)目中給予的所有支持。親愛的,你是最棒的!
研究
我開始做一些研究,找出我需要建立什么樣的模型。我試著把自己當(dāng)成她,找出我需要什么樣的信息來決定今天穿什么衣服。
我有什么衣服?(CH)
顯然,我需要從我現(xiàn)在擁有的衣服中推薦一件衣服。所以我認(rèn)為這是一個(gè)必須要有的信息。
過去幾周我穿了什么?(CD)
你肯定不想連續(xù)幾天一次又一次地穿同樣的衣服。盡管這并不是非常關(guān)鍵,但知道自己在過去幾周里穿了些什么,對(duì)于提供更多樣的推薦還是很有用的。除此之外,知道關(guān)于天氣和今天要做什么對(duì)推薦系統(tǒng)也很有用,你需要知道哪件衣服適合哪種場(chǎng)合和天氣。
今天的天氣(W)
不用擔(dān)心你穿的衣服會(huì)受到那天天氣的影響。
事件(E)
當(dāng)你要去參加一個(gè)聚會(huì)時(shí),你可能想穿一件好看淑女的衣服,但是如果你要去遠(yuǎn)足,你會(huì)想穿一件適合運(yùn)動(dòng)的衣服。
綜上所述,今天要穿的衣服(CTWT)可以用以下函數(shù)來描述:
CTWT = Func(CH, CD, W, E)
我只需要建立一個(gè)系統(tǒng)來實(shí)現(xiàn)這樣的函數(shù),聽起來很簡(jiǎn)單吧?我開始瘋狂地發(fā)揮想象力,最后決定做一個(gè)語(yǔ)音助理設(shè)備,上面會(huì)有一塊屏幕,Yumi 可以問「我今天應(yīng)該穿什么?」屏幕上就會(huì)附上推薦服裝的照片。甚至是,它將顯示 Yumi 穿那些衣服的樣子,以提供直觀的選擇。這個(gè)設(shè)備還能夠解釋它做出這種建議的理由,這樣它就可以回答 Yumi 的后續(xù)問題「你為什么推薦我這樣穿?」。
這項(xiàng)技術(shù)肯定會(huì)涉及很多人工智能。興奮之余,我開始為這個(gè)人工智能尋找一個(gè)名字和一個(gè)角色,并最終決定命名為 faAi。它的發(fā)音是「Fei」,代表人工智能時(shí)尚助理。
行動(dòng)計(jì)劃
我開始記下我需要執(zhí)行的任務(wù):
建立一個(gè)照片日記,記錄她每天穿什么(CD),標(biāo)記事件和天氣。
建立她自己的服裝照片目錄(CH)
在她的衣柜上安裝一個(gè)語(yǔ)音助手機(jī)器人
制作服裝目錄的一個(gè)簡(jiǎn)單方法是將她所有的衣服逐一拍照。她會(huì)每天自拍。然而,為了客戶體驗(yàn)和自動(dòng)化,將這個(gè)過程自動(dòng)化對(duì)我來說是不可拒絕的。我需要一個(gè)系統(tǒng),自動(dòng)建立她的服裝目錄和穿搭日記,而不需要她自己動(dòng)手。
經(jīng)過一番思考,我想出了這個(gè)計(jì)劃:如果我在房子里的某個(gè)地方安裝攝像頭,自動(dòng)拍下她全身的照片會(huì)怎么樣?
相機(jī)應(yīng)該足夠智能,只給她拍張照片,而不會(huì)拍下我、我父母和別的親戚。它還需要能夠識(shí)別她穿的衣服,將它們存儲(chǔ)在衣服日記中,并且將每件衣服存儲(chǔ)在對(duì)應(yīng)的衣服目錄中。
除了相機(jī),我還需要一個(gè)計(jì)算設(shè)備來執(zhí)行以上所有的智能操作。完美滿足要求的設(shè)備是 AWS DeepLens。這是一個(gè)支持深度學(xué)習(xí)的攝像頭,你可以在設(shè)備上部署無數(shù)的人工智能模型。
從這一點(diǎn)開始,我開始意識(shí)到這將是一個(gè)大項(xiàng)目。我肯定需要建立一個(gè)人工智能模型,在視頻幀中識(shí)別人臉和身體,并進(jìn)行面部識(shí)別。在 Yumi 的臉被識(shí)別之后,下一個(gè)人工智能模型需要識(shí)別她的衣服,并執(zhí)行搜索,如果我們沒有在她的目錄中添加這件衣服,那就創(chuàng)建一個(gè)新條目。不管怎樣,如果這是一件新衣服,一個(gè)條目也會(huì)被添加到衣服日記中,并標(biāo)記對(duì)應(yīng)的天氣和事件。
為了保持頭腦清醒,我決定將這個(gè)項(xiàng)目分成幾個(gè)階段,第一階段的重點(diǎn)是自動(dòng)構(gòu)建衣服日記。因?yàn)槲也恍枰⒎b目錄,我還不需要建立服裝識(shí)別系統(tǒng)。盡管最終目標(biāo)是在她的衣柜上加上一個(gè)語(yǔ)音助理,但我希望在第一階段完成時(shí)她已經(jīng)可以使用一些功能。所以,我增加了一個(gè)額外的任務(wù),建立一個(gè)移動(dòng)應(yīng)用程序,她可以用這個(gè)程序來瀏覽她的衣服日記,這至少可以幫助她決定穿什么。
服裝日記自動(dòng)生成器
我的第一個(gè)任務(wù)是找到安裝這臺(tái)相機(jī)的位置。把相機(jī)裝在她的衣柜里可能不是個(gè)好主意,因?yàn)槲艺娴牟幌胍馔獾仄毓獠缓线m的照片。另外,我只想在她外出時(shí)把這些衣服加到她的日記里,沒有必要記錄她在家里穿著睡衣的樣子。
經(jīng)過一番搜尋,我找到了一個(gè)完美的地點(diǎn)。在一個(gè)柜子上,可以直接看到家的大門。好吧,你需要穿過大門才能離開房子。
用 AWS DeepLens 檢測(cè)人和人臉
我的下一個(gè)任務(wù)是建立一個(gè)運(yùn)行在我的 AWS DeepLens 中的人工智能目標(biāo)檢測(cè)模型,它可以檢測(cè)人和臉的存在和位置,用面部識(shí)別檢測(cè)出他們是誰(shuí),然后將他們?nèi)淼膱D像裁剪到衣服日記中。
我使用 Amazon SageMaker 構(gòu)建了一個(gè)自定義的對(duì)象檢測(cè)模型,并將其部署到 AWS DeepLens 中。不過這里就不贅述細(xì)節(jié)了,我將在一個(gè)單獨(dú)的博客中公布全部細(xì)節(jié)。
在 AWS DeepLens 上運(yùn)行的人臉和目標(biāo)檢測(cè)
AWS DeepLens 提供了一個(gè)名為 Project Stream 的非常有用的特性,可以在其中顯示和注釋視頻幀,并在你的 web 瀏覽器上觀看它們。這樣,我可以很容易地觀察我的模型的性能,并繪制一些文本和框來幫助我調(diào)試。正如你在上圖中看到的,我的模型正準(zhǔn)確地辨認(rèn)出 Yumi 的全身和臉部。我對(duì)準(zhǔn)確度很滿意。
在正確的位置檢測(cè)到人
下一個(gè)要解決的問題是,只有當(dāng)人靠近門區(qū)域時(shí)才觸發(fā)拍照,這通常發(fā)生在有人打算離開房子的情況下。然而,下面的一段視頻顯示了一個(gè)假陽(yáng)性檢測(cè),這個(gè)人只是從前客廳走向餐廳。
假陽(yáng)性檢測(cè)
看看下面我的房子平面圖,可以清楚地看到兩個(gè)紅色箭頭,這兩個(gè)箭頭指示的是導(dǎo)致假陽(yáng)性檢測(cè)的人的行走路徑。而我們只想抓住在綠色區(qū)域的人。最簡(jiǎn)單的解決方案是,只有當(dāng)一個(gè)人的邊界框的頂部和底部完全位于屏幕內(nèi)部時(shí),才拍下他。使用上述假陽(yáng)性情況測(cè)試此邏輯將正確跳過此圖像,因?yàn)檫吔缈虻牡撞吭谄聊恢狻?/p>
當(dāng)邊框的頂部和底部都完全位于屏幕內(nèi)部時(shí),將觸發(fā)正確的圖像捕獲。
正確檢測(cè)
為了確保我已經(jīng)覆蓋了所有可能的假陽(yáng)性情況,我需要運(yùn)行一整天的系統(tǒng)。首先,我必須完成系統(tǒng)的下一部分,它將檢測(cè)到的人的裁剪圖像發(fā)送到我的圖像記錄器 s3 存儲(chǔ)器中。這樣我就可以在沒有監(jiān)督的情況下運(yùn)行系統(tǒng)一整天,并且在試運(yùn)行結(jié)束時(shí)簡(jiǎn)單地檢查該存儲(chǔ)器中的所有圖像。
從物聯(lián)網(wǎng)設(shè)備發(fā)送圖像的最佳方式是通過 MQTT 消息傳遞系統(tǒng),這是非常容易做到的,特別是在你創(chuàng)建 AWS DeepLens 項(xiàng)目時(shí)已經(jīng)提供了很好的示例代碼。我只需要添加一些額外的代碼行,將裁剪后的圖像編碼為 jpeg 流,并對(duì)它們進(jìn)行 base64 編碼,這樣我就可以通過 MQTT 將其作為字符串消息發(fā)送。
client = greengrasssdk.client('iot-data')
iotTopic = '$aws/things/{}/infer'.format( os.environ['AWS_IOT_THING_NAME'])
personImageRaw = cv2.imencode('.jpg', personImage)[1]
personImageStr = base64.b64encode(personImageRaw)
client.publish(topic=iotTopic, payload=personImageStr)
消息將由云中的 MQTT 主題訂閱者接收,然后觸發(fā) lambda 函數(shù)以 base64 解碼圖像并將其保存到 s3 存儲(chǔ)器中。從 MQTT 字符串解碼圖像非常簡(jiǎn)單,只需下面的一行代碼。
jpgStream = base64.b64decode(event
有了以上這些,我一整天都在運(yùn)行這個(gè)系統(tǒng),周末過得很愉快。
排除岳母
在運(yùn)行了一整天的系統(tǒng)之后,我的圖像記錄器顯示了很多有趣的圖像。一些圖像是正確的檢測(cè),如下所示,這是好的。
正確檢測(cè)
看到我的其他家庭成員被記錄在案是意料之中的事,然而其他的事情引起了我的注意。在所有拍攝的照片中,95% 都是我岳母(更具體地說是她的上半身)的照片。
岳母正在做她的傳統(tǒng)餃子
查看下面的原始視頻片段日志,可以發(fā)現(xiàn)原因。
坐在廚房長(zhǎng)凳后面的岳母
顯然,她通過了檢測(cè)邏輯,因?yàn)樗娜说捻敳亢偷撞浚ㄓ捎谂c廚房長(zhǎng)凳的遮擋,只檢測(cè)到一半的身體)完全在屏幕內(nèi)。她花了很多時(shí)間在廚房里,這個(gè)系統(tǒng)捕捉了她的很多照片。這會(huì)導(dǎo)致這個(gè)過程進(jìn)一步走下軌道,做很多不必要的面部識(shí)別,這是不好的。然而,看到她一整天被記錄下來的無數(shù)照片,讓我想起她每天都在忙著為我們準(zhǔn)備飯菜和幫助我們帶寶寶。對(duì)我來說她是世界上最好的岳母…
好吧,不管她有多棒,我不希望她的照片在處理過程中占據(jù)主導(dǎo)地位。這個(gè)問題只需引入一個(gè)禁區(qū)就可以解決。其目的是排除排除線左側(cè)的檢測(cè)(如下紅線所示)。
排除婆婆的區(qū)域
再運(yùn)行一整天的系統(tǒng),就發(fā)現(xiàn)不會(huì)有婆婆坐在廚房的長(zhǎng)凳后面的照片了!
檢測(cè)到正確的人
我的下一個(gè)挑戰(zhàn)是添加一個(gè)面部識(shí)別模塊,只記錄 Yumi 或我自己的圖像。澄清一下,不是說我需要用這個(gè)系統(tǒng)來推薦我穿什么衣服,而是為了讓我自己可以輕松地測(cè)試這個(gè)系統(tǒng),而不必讓她一直在鏡頭前擺姿勢(shì)。
我真的很想在邊緣做面部識(shí)別,以節(jié)省成本。不過,經(jīng)過進(jìn)一步調(diào)查,這似乎很難。一個(gè)合適的面部識(shí)別系統(tǒng)是相當(dāng) GPU 密集的,這將為一個(gè)已經(jīng)很慢的系統(tǒng)增加一個(gè)重要的處理時(shí)間。目前,我的面部/人檢測(cè)系統(tǒng)以每秒 1 幀的速度運(yùn)行。任何比這慢的速度都會(huì)降低抓拍成功的幾率。像這里描述的一個(gè)簡(jiǎn)單的面部識(shí)別系統(tǒng)對(duì)我來說不起作用,因?yàn)樗荒茏R(shí)別一個(gè)直接的正面人臉。
基于以上這些原因,我決定在云中做面部識(shí)別。我設(shè)置了另一個(gè) lambda 函數(shù),當(dāng)我的圖像記錄器中有一個(gè)新條目時(shí),該函數(shù)將被觸發(fā)。這個(gè) lambda 函數(shù)被稱為 AWS Rekognition——通過面部識(shí)別來識(shí)別人(Facial Recognition to identify the person)。如果確定此人是我或 Yumi,將創(chuàng)建 Postgres 數(shù)據(jù)庫(kù)條目。這個(gè) Postgres 數(shù)據(jù)庫(kù)就是我們一直在談?wù)摰姆b日記。拍攝圖像時(shí)的時(shí)間、溫度和天氣狀況(晴天、下雨、多云)以及確定的人員姓名也作為條目的一部分存儲(chǔ)。目前的溫度和天氣是通過向氣象局打一個(gè) RSS 電話獲得的。最后,圖像還將被復(fù)制到另一個(gè) s3 存儲(chǔ)器中,該存儲(chǔ)器充當(dāng)公共圖像服務(wù)器,我的移動(dòng)應(yīng)用程序可以訪問該服務(wù)器。這樣我就可以確保只有滿足條件的圖像集是公開的,而且將來我甚至可以添加額外的檢查來確保公開的圖像中沒有敏感的圖像。
使用 AWS 識(shí)別——面部識(shí)別是相當(dāng)直接的。我只需要?jiǎng)?chuàng)建一個(gè)包含我想讓系統(tǒng)識(shí)別的人的人臉集合。對(duì)于每個(gè)人臉(我和 Yumi),我需要調(diào)用 IndexFace 將它們添加到集合中。檢查一個(gè)面是否在集合中就像只調(diào)用一個(gè) api 一樣簡(jiǎn)單。
打造時(shí)尚日記應(yīng)用
這是第一階段中最激動(dòng)人心的部分,因?yàn)樽詈笪覍⒛軌蛟谝苿?dòng)應(yīng)用程序上可視化服裝日記。我們都是 iphone 用戶,所以移動(dòng)應(yīng)用程序必須在 iphone 上運(yùn)行?,F(xiàn)在有很多方法來構(gòu)建移動(dòng)應(yīng)用程序,比如使用像 PhoneGap 這樣的 html5 框架,像 Ionic 和 Xamarin 這樣的交叉開發(fā)框架,或者直接使用 Xcode。不過,由于過去我是一個(gè) iOS 開發(fā)人員,因此顯然我的選擇是 Xcode。
為了提供對(duì) Postgres 衣服日記的訪問,我使用 lambda 函數(shù)構(gòu)建了一個(gè)公共 REST API。用它構(gòu)建一個(gè)功能性 REST API 實(shí)在是太容易了,以至于我對(duì)此印象深刻。通常,你將花費(fèi)大部分開發(fā)時(shí)間處理基礎(chǔ)設(shè)施和部署,例如編寫 REST 應(yīng)用程序框架、URL 路由、部署腳本等,而不是編寫實(shí)際的 API 代碼。如果你需要編寫的 API 像我的例子中那樣簡(jiǎn)單,那么它就更普遍了。
最后,下面是整個(gè)端到端架構(gòu)圖。
faAi 架構(gòu)圖
我設(shè)法在一天內(nèi)完成了應(yīng)用程序和 REST API,包括設(shè)計(jì)應(yīng)用程序啟動(dòng)屏幕和圖標(biāo)。如下圖所示,應(yīng)用程序的界面非常直觀:一個(gè)可滾動(dòng)的垂直列表,顯示按日期分組的 Yumi 的圖像、天氣(下雨,多云或晴天)圖標(biāo)、一天的溫度等。我現(xiàn)在可以說系統(tǒng)已經(jīng)開發(fā)完成了!作為一個(gè)有經(jīng)驗(yàn)的軟件開發(fā)人員,我知道下一個(gè)重要的步驟是 QA。
faAi 應(yīng)用程序
QA
我整個(gè)星期都在運(yùn)行這個(gè)系統(tǒng),看起來它工作正常。我拍到了尤米進(jìn)出房子的照片,沒有一個(gè)假陽(yáng)性!我還在她的手機(jī)上安裝了這個(gè)應(yīng)用程序,這樣她就可以開始使用它并給我反饋。
盡管取得了很好的成績(jī),但在下一階段我還需要改進(jìn)和補(bǔ)充一些東西。
更好的姿態(tài)檢測(cè)
一半的圖像是以非理想姿勢(shì)拍攝的。例如,當(dāng)她走到換鞋長(zhǎng)凳前,抱著我們的孩子,或者穿著一件夾克,上面蓋著她實(shí)際穿的衣服,一條腿向上笨拙地側(cè)身時(shí)。我還發(fā)現(xiàn)了一些例子,她有時(shí)并不是準(zhǔn)備出門,而是穿著睡衣站在門前。faAi 還不是很聰明,只要它檢測(cè)到一張臉,不管姿勢(shì)的質(zhì)量如何,它都會(huì)拍照。
faAi 抓拍到的非理想姿勢(shì)
對(duì)于這個(gè)階段來說,這并不是什么大不了的事情,因?yàn)槲覀兊哪繕?biāo)是開發(fā)一個(gè)移動(dòng)應(yīng)用程序,讓她可以瀏覽服裝日志。她能很容易地過濾掉其他壞姿勢(shì)或不相關(guān)的照片。為了解決這個(gè)問題,需要一個(gè)更復(fù)雜的系統(tǒng),我將在未來的階段嘗試。目前,最簡(jiǎn)單的解決辦法是讓她脫掉外套,面對(duì)鏡頭,在出門或進(jìn)屋時(shí)迅速擺好姿勢(shì),這樣拍的前幾張照片就很好了。
事件檢測(cè)
這是我在這一階段沒有時(shí)間完成的任務(wù),我將在下一階段處理。知道她出門的原因也有助于過濾掉不需要的抓拍,例如:她出去扔垃圾的時(shí)候。
現(xiàn)在就這樣了,我很高興達(dá)到了一個(gè)里程碑,但是還有很多挑戰(zhàn)需要我去解決,解決所有問題之后才能有一個(gè)完整的端到端系統(tǒng)。但是沒有挑戰(zhàn)的生活有什么意思呢?
請(qǐng)繼續(xù)關(guān)注下一階段!
雷鋒網(wǎng)雷鋒網(wǎng)雷鋒網(wǎng)
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。