91伊人国产-91伊人久久-91伊人影院-91影视永久福利免费观看-免费毛片儿-免费女人18毛片a级毛片视频

歡迎進入儀商網!

探索人工智能產品的測試方法

眾所周知,人工智能的測試具有相當大的難度,不論是以前在互聯網就經常看到的內容推薦系統,還是金融領域常用的信息分類系統。測試介入的都不多。那么如何測試人工智能相關的產品。

我們最常做的測試其實就是直接看模型效果,效果不好就慢慢調。 為了改變這種現狀,我們希望測試人員也能做一些事情,參與到人工智能服務的質量保證當中來。在日常工作中總結了一些經驗跟大家討論一下。

什么是人工智能

簡而言之,現階段的人工智能就是:人工智能=大數據+機器學習。

現階段的人工智能是使用機器學習算法在大量的歷史數據下進行訓練,從歷史數據中找到一定的規律并對未來做出的預測行為。舉例說明,就好比銀行做過的反欺詐項目。

在銀行里有一群專家,他們的工作就是根據經驗向系統中輸入一些規則。例如某一張卡在一個城市有了一筆交易,之后1小時內在另一個城市又有了一筆交易。這些專家根據以前的經驗判斷這種情況是有盜刷的風險的。

他們在系統中輸入了幾千條這樣的規則,組成了一個專家系統。 這個專家系統是建立在人類對過往的數據所總結出的經驗下建立的。 后來我們引入了機器學習算法,對過往所有的歷史數據進行訓練,最后在25億個特征中抽取出8000萬條有效特征。

我們把這些特征就暫且當成是專家系統中的規則。8000萬對不到1萬,效果是可以預想的。當時對第一版模型上線后的數據做統計,反欺詐效果提升了7倍, 這就是二分類算法典型的業務場景。

為什么叫機器學習呢,因為它給人一種感覺,機器能像人類一樣從過去的數據中學習到經驗,只不過機器的能力更強。 如果想再稍微深究一下機器學習訓練出來的模型到底是什么,那大家可以暫且理解為一個二分類的模型主要是就是一個key,value的數據庫。

key就是在數據中抽取出來的特征,value就是這個特征的權重。 當我們想要預測一個用戶的行為的時候,就會從用戶的數據中提取特征并在模型中查找對應的權重。 最后根據這些特征的權重算出一個分,也可以說是一個概率。 如果大家看過最強大腦這個節目的話。

應該記得第一次人機大戰項目是人臉識別,第三回合的時候機器給出了兩個答案。因為當時做人臉識別項目的志愿者中有一對雙胞胎。所以機器計算出的這兩個人的概率只差了0.1%,最后為了謹慎起見機器輸出兩個答案出來。以至于吳恩達先生也很糾結到底該選哪一個答案。

再之后的人機對戰項目里我們也能看到雖然小度一路高歌,毫無敗績。但是其中是有選錯過幾次的。所以大家可以看到我們得到的答案其實是一個概率,是一個根據以往的數據進行總結并作出預測的一個行為。并不是100%準確的。即便是阿爾法狗當初也是輸過一局的。所以其實我們測試的痛點也就來了,你怎么測試一個概率呢。



這個圖就是一個人工智能服務的略縮圖。 在歷史數據上訓練出模型,并發布一個預測服務,這個預測服務可能就是一個http的接口。 然后新的數據過來以后,根據模型算出一個預測值。經過剛才的說明,我們看到數據是人工智能的根本。擁有的數據越多,越豐富,越真實,那么訓練出的模型效果越好。

測試思路

·數據測試

·分層測試

·訓練集與測試集對比

數據測試

根據我們之前對人工智能的定義,我們發現數據是人工智能的根據。 保證數據的正確定是非常必要的。 而且幾乎所有的機器學習算法對數據的容錯能力都很強,即便數據稍有偏差,它們也能通過一次一次的迭代和對比來減少誤差。 所以即便我們的數據有一點問題最后得出的模型效果可能還不差, 但是這個時候我們不能認為模型就沒問題了。 因為很可能在某些特定場景下就會出現雪崩效應。

再舉個例子。當初阿爾法狗與李世石一戰成名。如果說前三盤的結果令各路專家大跌眼鏡的話。那第四盤可能是讓所有人都大跌眼鏡了。阿爾法狗連出昏招,幾乎是將這一局拱手相讓。那阿爾法狗出bug了?DeepMind團隊說,這是一個系統問題。那我們來看看這個系統到底有什么問題。根據當時公布出來的數據我們發現阿爾法狗的養成方法是這樣的。

阿爾法狗如何養成

1.整理過去人類對弈的80多萬盤棋局

2.拿1的棋譜,訓練一只狗狗,能夠預測人類下一步會下在哪里

3.拿2得到的狗狗,每天自己和自己下100萬盤棋

4.拿1和3的棋譜,再訓練一只狗狗,這就是阿爾法狗。

阿爾法狗是基于1億+盤機器棋局和80萬人類棋局訓練出來的狗狗。問題出在哪?我們看到,訓練阿爾法狗所用的棋譜,只有80萬是人類棋局,總數上億的棋局是機器對弈的。它下的每一步,都是將局面導向歷史上(也就是80萬人類棋局和1億自己對弈的棋局)勝率最大的局面。

問題就恰恰出在這里,80萬和1億。相差甚多。那么阿爾法狗選擇的所謂勝率最大,一定是贏自己的概率最大,而不是贏人類的概率最大。這樣的標準在順豐棋尚且不容易出問題,一旦遇到逆風局,它的選擇就變成了,選擇對手犯錯概率最大的棋,而這個對手恰恰就是它自己。

這就是為什么當初阿爾法狗在逆風局中下出一些匪夷所思的棋。當然這些都只是行業內的人的猜測。但從這個例子就可以看到數據的重要性。數據出現偏差會直接導致不可估計的后果。

所以我們總結出的第一個突破口就是數據測試。保證我們用來建模的數據是正確的。在這里的數據測試會跟我們以往的測試有些不一樣。

首先是數據規模的增長。數據大了里面的有些數據可能會發生一些很詭異的事情。然后是存儲介質和技術棧的變化,我們用來訓練模型的數據都會存放在hadoop集群上,所以一般都會用spark或者Hbase來編寫測試腳本。最后是驗證方式的變化,之前我們測試的時候都是精確的測試每條數據的正確性。 但是現在我們需要根據業務設定每一個字段的規則。然后掃描每一行數據,如果這條數據超出了這個字段的規定范圍,會發出報警。 假如用戶年齡這個字段,正常值可能是0~100歲。如果突然出現個300歲,那么這條數據肯定是有問題的。我們之前曾經碰見過這樣的數據。本來這條數據應該是30歲的,但卻多了個0。

針對這方面的測試,一般都是使用spark或者Hbase這種大數據處理框架把任務提交到集群上去掃描每一張表。

分層測試

雖然我們能測試用來做訓練的數據是正確的。但是一個人工智能系統是很復雜的, 我們只是保證了作為源頭的數據貌似是不夠的。以前我們測試的時候都知道把系統拆解開做分層測試,所以我們的第二個突破口就是基于這個思路。我們先來了解一下,一個模型的誕生都經理了哪些步驟。

模型誕生的步驟:

·數據引入

·數據處理(清洗,拆分,拼接等)

·特征工程

·模型訓練

·模型上線

數據引入:將歷史數據引入到系統中,并做第一步的預處理。例如處理一些明顯的異常的行為。

數據處理: 其中又包含很多種操作。 例如對數據進行清洗,拆分。 把兩張表進行拼接等。

特征工程:我們從數據中按一定規律提取一些特征出來。之后需要將提取的樣本表傳遞給機器學習算法進行訓練。




可以看到我們把數據引入到系統后,先是用SQL算子對數據做了拼接,然后清洗一些無效數據。 再把數據拆分為訓練集和測試集。分別對兩個數據集做特征抽取。之后訓練集傳遞給邏輯回歸這個機器學習算法進行訓練。訓練之后使用測試集來測試一下模型的效果。大家看到這個圖了,這是創建一個模型比較常見的流程。

圖中的邏輯歸回就是一種機器學習算法,也是一種最簡單的二分類算法,其他的算法諸如 GBDT,SVM,DNN等算法的模型都是這個流程。我們可以看到算法上面的流程。全部與機器學習無關。他們都屬于大數據處理范疇。而且一個成型的系統在每一個模塊都會提供一些固定的接口。

例如我們公司在特征抽取算法上就提供了近百個特征抽取的接口,可以根據不同的情況使用不同的方式提取數據中的特征。 數據拆分也有很多種不同的拆分方法,按隨機拆分,分層拆分,規則拆分。

每個子模塊都會提供一些接口供上層調用。 所以既然提到接口層面的東西了,大家應該都知道怎么測了吧。 只不過有些接口并不是http或者RPC協議的。 有時候需要我們在產品的repo里寫測試用例。




訓練集與測試集對比


這是我們的第三種測試思路。 我們剛才一直用來舉例的分類算法是一種監督學習。 什么是監督學習呢,就是我們的歷史數據中是有答案的。還拿剛才的反欺詐的例子說,就是我們的數據中都有一個字段標明了這條數據是否是欺詐場景。 所以我們完全可以把歷史數據拆分為訓練集和測試集。將測試集輸入到模型中以評價模型預測出的結果的正確率如何。所以每次版本迭代都使用同樣的數據,同樣的參數配置。 統計模型效果并進行對比。當然這種測試方式是一種模糊的方式。就如我再剛開始說的一樣,這種方式無法判斷問題出在哪里。是bug,還是參數設置錯了?我們無法判斷。

常見的測試場景

1.自學習





幾乎所有的人工智能服務都必須要支持自學習場景。就像阿爾法狗一樣,它輸了一局,就會從輸的這一局中學習到經驗,以后他就不會那么下了,這也是機器學習恐怖的地方,它會變的越來越無懈可擊,以前人類還能贏上一局,但是未來可能人類再也贏不了阿爾法狗了。 做法就是我們的數據每天都是在更新的,用戶行為也是一直在變化的。所以我們的模型要有從最新的數據中進行學習的能力。

上面是常見的自學習場景流程圖。假如我們用歷史上n天的數據訓練出一個模型并發布成了一個預測的服務。 那么到了隔天的時候。我們拋棄之前第一天的數據,使用第二天到第n+1天的數據重新訓練一個模型并代替之前的模型發布一個預測服務。這樣不停的循環,每一天都收集到最新的數據參與模型訓練。 這時候大家應該明白該測試什么了。每天收集到的新數據,就是測試重點。就是我們剛才說的第一種測試思路,使用spark,Hbase這些技術,根據業務指定規則,掃描這些數據。一旦有異常就要報警。

2.預測服務

下面一個場景是預測服務的。預測服務的架構一般都滿復雜的,為了實現高可用,負載均衡等目的,所以一般都是標準的服務發現架構。以etcd這種分布式存儲機制為載體。 所有的預測服務分別以自注冊的方式來提供服務。




上面的一個圖是一個比較流行的預測服務的架構。當然我做了相應的簡化,隱去了一些細節。所有的部署任務由master寫入ETCD。 所有agent以自注冊的方式將自己的信息寫入ETCD以接受master的管理并執行部署任務。 而router也同樣讀取etcd獲取所有agent提供的預測服務的信息并負責負載均衡。 有些公司為了做高可用和彈性伸縮甚至將agent納入了kubernetes的HPA中進行管理。由此我們需要測試這套機制能實現他該有的功能。例如:

·router會按規則把壓力分發到各個agent上。

·把某個agent的預測服務被kill掉后,router會自動切換。

·預估服務掛掉,agent會自動感知并重新拉起服務。

·agent被kill掉后,也會被自動拉起。

·如果做了彈性伸縮,需要將預測服務壓到臨界點后觀察系統是否做了擴容等等。

性能測試

我們要接觸的性能測試跟互聯網的不太一樣。我們知道預測服務仍然還是訪問密集型業務。但是模型調研的過程是屬于計算密集型業務。我們要模擬的情況不再是高并發。而是不同的數據規模,數據分布和數據類型。我們日常的性能測試都是需要在各種不同的數據下跑各種不同的算子和參數。所以我們首先需要一種造數機制,能幫助我們按需求生成大規模的數據。我們選擇的是spark,利用分布式計算在hadoop集群上生成大量的數據。

原理也很簡單,接觸過spark的同學肯定都知道在spark中生成一個RDD有兩種方式, 一種是從文件中讀取,另一種是從內存中的一個list種解析。第一種方式肯定不是我們想要的, 所以從內存中的list解析就是我們選擇的方式。假如我們想生成一個10億行的數據。就可以先使用python 的xrange造一個生成器以防止內存被撐爆。然后用這個生成器初始化一個有著10億行的空的RDD,定義并操作RDD的每一行去生成我們想要的數據,然后設置RDD的分片以及消耗的container,內存,cpu等參數。提交到集群上利用集群龐大的計算資源幫助我們在段時間內生成我們需要的數據。 前兩天我再一個3個節點的集群上造過一個1.5T的數據,大概用了5個小時。這樣一開始的時候我們是寫spark腳本來完成這些事。后來需求越來越多,我們發現可以造數做成一個工具。把表和字段都提取到配置文件中進行定義。就這樣我們成立了shannon這個項目。慢慢的從造數腳本到造數工具再到造數平臺。

它的架構特別簡單,就是對原生spark的應用,這里我就不展示spark的架構是什么樣了。就貼一下造數工具的設計圖吧。



簡單來說shannon分了3層。最底層是基本數據類型層。負責字段實例化,定義并實現了shannon支持的所有數據類型。例如,隨機,枚舉,主鍵,unique key,控制分布,大小,范圍等等。

測試環境管理

常見的測試場景我們基本上都說完了。 我們再說一說測試環境管理的問題。 為了能夠保證研發和測試效率,一個能夠支撐大規模測試環境的基礎設施是十分必要的。為什么這么說呢?

首先但凡是涉及到機器學習的業務,運行時間都非常慢。 有時候做測試的時候跑一個模型要幾個小時甚至一天都是有的。也就是說,我們運行測試的成本比較高。如果在運行測試的途中環境出了什么問題那么損失還是很大的。多人共用一套環境難免會有互相踩踏的情況,例如一個RD在測試自己的模塊,另一個人上來把服務重啟了。這時候我們心里一般就是一萬頭某種動物飄過。所以我們一般希望每個人都能擁有一套獨立的環境甚至一個人多套環境。這就增加了測試環境的數量。尤其是團隊越來越大的時候,測試環境的數量已經到達了一個恐怖的量級。

其次如果各位所在的公司也像我們一樣做TO B的業務,那么我們的測試環境就需要多版本管理,要有能力隨時快速的搭建起特定版本的產品環境供開發,產品,測試,以及技術支持人員使用。所以這無疑又增加了環境管理設置的復雜度。

再有就是隨著環境數量的擴張,我們的環境從單節點走向集群,這時候我們對環境調度能力的要求會比較高,例如我們要對環境的資源進行計算和限制,保證最大化利用資源的同時不會撐爆系統。例如我們要保證系統有足夠的冗余,在某些環境出現故障的時候能夠自動檢測出來并在冗余節點進行恢復。例如我們需要能夠實現多租戶管理,執行資源管控,限制超售行為. 例如我們希望系統有一定能力的無人值守運維能力等等。

所以我們經過一段時間的討論和實驗,引入了k8s+docker來完成這個目標。docker的優勢大家應該都知道,快速,標準化,隔離性,可遷移性都不錯。 通過鏡像我們可以迅速的將測試環境的數量提升一個量級,鏡像的版本管理正適合TO B業務的多版本管理。 之所以選擇k8s,是因為k8s相較于swarm和mesos 都擁有著更強大的功能和更簡單的部署方式。剛才說的預測服務需要部署很多個agent,使用k8s的話只需要設置一下replica set的數量,k8s就會自動幫我們維護好這個數量的實例了,很方便 。k8s的調度機制能很輕松的滿足我們剛才說的對于災難恢復,冗余,多租戶,高可用,負載均衡,資源管理等要求。所以我們當初懷揣著對google莫名的憧憬走上了k8s的踩坑之旅。




首先說一下我們都用容器做什么。主要三大類,第一種是諸如testlink,jenkins這種基礎服務。第二種是產品的測試環境,這是占比最多的。然后就是我們的測試執行機器了。例如UI自動化,我們采取的是分別將selenium hub和node docker化的做法。如下圖:




當UI自動化的case增多的時候,分布式運行往往是最好的解決方案。 目前我們通過這種方式容器化了20個瀏覽器進行并發測試。這些鏡像都有官方的版本,使用起來還是蠻方面的。
然后說一下比較關鍵的網絡解決方案,我們從單機到集群,中途歷經了集中網絡模型的變化。從一開始的端口映射,到利用路由規則給容器分配真實的ip,再到給每個容器在DHCP和DNS服務器上注冊和續租。到最后我們演進出了下面這個k8s的網絡模型。



我們知道每個docker宿主機都會自己維護一個私有網絡。如果想讓容器跨主機通訊或者外部訪問容器。一般就是通過三種方式: 端口映射,路由規則以及overlay網絡。我們選擇在k8s中引入的overlay網絡是weave,以解決夸主機通信問題。安裝kube-dns實現服務發現。之后為了能讓外部訪問容器服務, 使用了k8s提供的ingress機制來實現。這個ingress網絡其實就是在集群中啟動一個容器,這個容器既能訪問容器網絡的同是還監聽了宿主機的80端口。容器里是一個nginx,它會負責幫忙轉發請求。nginx負責轉發的有servicename和path,這里我們是無法使用路徑進行轉發的。所以我們在公司內部的DNS上做了泛域名解析。所有testenv為后綴的域名都會解析成集群的master節點的ip。這樣我們的請求就能命中nginx中固定的servicename并做轉發了。通過這種機制我們就可以很方面的訪問容器提供的服務。當然ingress的缺點是暫時還無法做4層轉發。如果要訪問4層協議的服務暫時還是只能暴露node port。

我們這個測試環境的管理平臺主要的架構是這樣的:



集群中所有的鏡像都過公司內部搭建的鏡像倉庫進行共享,我們在集群之上安裝了各種服務來滿足測試環境的需要。例如使用NFS做數據持久化,Heapster+Grafana+InfluxDB做性能監控,kube-DNS做服務發現,dashboard提供web管理界面,weave做集群網絡,ingress做服務的轉發。并且我們在這個整體上針對k8s的APIserver做了一層cli的封裝。我們嘗試過腳本管理,web服務管理,但是發現大家對這些方式的接受度都不高。我們面對的大多數都是一幫做夢都在寫代碼的人,所以我們換做提供一個cli的方式可以讓使用者更靈活來定制自己需要的服務。通過這種形式,我們在公司內部搭建了一個可以提供測試資源的私有云,配合jenkins我們可以很方便的一鍵部署我們需要的環境并執行UT,接口,UI自動化測試等等,并提供一個詳細的測試報告。下面是我們的部署一個環境后所提供的測試報告。



聲明: 聲明:凡本網注明"來源:儀商網"的所有作品,版權均屬于儀商網,未經本網授權不得轉載、摘編使用。
經本網授權使用,并注明"來源:儀商網"。違反上述聲明者,本網將追究其相關法律責任。
本網轉載并注明自其它來源的作品,歸原版權所有人所有。目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。如有作品的內容、版權以及其它問題的,請在作品發表之日起一周內與本網聯系,否則視為放棄相關權利。
本網轉載自其它媒體或授權刊載,如有作品內容、版權以及其它問題的,請聯系我們。相關合作、投稿、轉載授權等事宜,請聯系本網。
QQ:2268148259、3050252122。