3 機(jī)器學(xué)習(xí)基礎(chǔ) 4 數(shù)據(jù)結(jié)構(gòu)&&算法 【一】深度學(xué)習(xí)中有哪些經(jīng)典的優(yōu)化器? SGD(隨機(jī)梯度下降) 隨機(jī)梯度下降的優(yōu)化算法在科研和工業(yè)界是很常用的。 很多理論和工程問題都能轉(zhuǎn)化成對(duì)目標(biāo)函數(shù)進(jìn)行最小化的數(shù)學(xué)問題。 舉個(gè)例子:梯度下降(Gradient Descent)就好比一個(gè)人想從高山上奔跑到山谷最低點(diǎn),用最快的方式奔向最低的位置。 基本的mini-batch SGD優(yōu)化算法在深度學(xué)習(xí)取得很多不錯(cuò)的成績。然而也存在一些問題需解決: 選擇恰當(dāng)?shù)某跏紝W(xué)習(xí)率很困難。 學(xué)習(xí)率調(diào)整策略受限于預(yù)先指定的調(diào)整規(guī)則。 相同的學(xué)習(xí)率被應(yīng)用于各個(gè)參數(shù)。 高度非凸的誤差函數(shù)的優(yōu)化過程,如何避免陷入大量的局部次優(yōu)解或鞍點(diǎn)。 AdaGrad(自適應(yīng)梯度) AdaGrad優(yōu)化算法(Adaptive Gradient,自適應(yīng)梯度),它能夠?qū)γ總€(gè)不同的參數(shù)調(diào)整不同的學(xué)習(xí)率,對(duì)頻繁變化的參數(shù)以更小的步長進(jìn)行更新,而稀疏的參數(shù)以更大的步長進(jìn)行更新。 與SGD的核心區(qū)別在于計(jì)算更新步長時(shí),增加了分母: 梯度平方累積和的平方根 。此項(xiàng)能夠累積各個(gè)參數(shù) 的歷史梯度平方,頻繁更新的梯度,則累積的分母逐漸偏大,那么更新的步長相對(duì)就會(huì)變小,而稀疏的梯度,則導(dǎo)致累積的分母項(xiàng)中對(duì)應(yīng)值比較小,那么更新的步長則相對(duì)比較大。 AdaGrad能夠自動(dòng)為不同參數(shù)適應(yīng)不同的學(xué)習(xí)率(平方根的分母項(xiàng)相當(dāng)于對(duì)學(xué)習(xí)率α進(jìn)進(jìn)行了自動(dòng)調(diào)整,然后再乘以本次梯度),大多數(shù)的框架實(shí)現(xiàn)采用默認(rèn)學(xué)習(xí)率α=0.01即可完成比較好的收斂。 優(yōu)勢: 在數(shù)據(jù)分布稀疏的場景,能更好利用稀疏梯度的信息,比標(biāo)準(zhǔn)的SGD算法更有效地收斂。缺點(diǎn): 主要缺陷來自分母項(xiàng)的對(duì)梯度平方不斷累積,隨時(shí)間的增加,分母項(xiàng)越來越大,最終導(dǎo)致學(xué)習(xí)率收縮到太小無法進(jìn)行有效更新。RMSProp RMSProp結(jié)合梯度平方的指數(shù)移動(dòng)平均數(shù)來調(diào)節(jié)學(xué)習(xí)率的變化。能夠在不穩(wěn)定的目標(biāo)函數(shù)情況下進(jìn)行很好地收斂。 計(jì)算梯度平方的指數(shù)移動(dòng)平均數(shù)(Exponential Moving Average), 是遺忘因子(或稱為指數(shù)衰減率),依據(jù)經(jīng)驗(yàn),默認(rèn)設(shè)置為0.9。 梯度更新的時(shí)候,與AdaGrad類似,只是更新的梯度平方的期望(指數(shù)移動(dòng)均值),其中 ,避免除數(shù)為0。默認(rèn)學(xué)習(xí)率 。 優(yōu)勢: 能夠克服AdaGrad梯度急劇減小的問題,在很多應(yīng)用中都展示出優(yōu)秀的學(xué)習(xí)率自適應(yīng)能力。尤其在不穩(wěn)定(Non-Stationary)的目標(biāo)函數(shù)下,比基本的SGD、Momentum、AdaGrad表現(xiàn)更良好。Adam Adam優(yōu)化器結(jié)合了AdaGrad和RMSProp兩種優(yōu)化算法的優(yōu)點(diǎn)。對(duì)梯度的一階矩估計(jì)(First Moment Estimation,即梯度的均值)和二階矩估計(jì)(Second Moment Estimation,即梯度的未中心化的方差)進(jìn)行綜合考慮,計(jì)算出更新步長。 實(shí)現(xiàn)簡單,計(jì)算高效,對(duì)內(nèi)存需求少。 超參數(shù)具有很好的解釋性,且通常無需調(diào)整或僅需很少的微調(diào)。 更新的步長能夠被限制在大致的范圍內(nèi)(初始學(xué)習(xí)率)。 能自然地實(shí)現(xiàn)步長退火過程(自動(dòng)調(diào)整學(xué)習(xí)率)。 很適合應(yīng)用于大規(guī)模的數(shù)據(jù)及參數(shù)的場景。 適用于不穩(wěn)定目標(biāo)函數(shù)。 然后計(jì)算梯度的指數(shù)移動(dòng)平均數(shù), 初始化為0。 類似于Momentum算法,綜合考慮之前累積的梯度動(dòng)量。 系數(shù)為指數(shù)衰減率,控制動(dòng)量和當(dāng)前梯度的權(quán)重分配,通常取接近于1的值。默認(rèn)為0.9。 接著,計(jì)算梯度平方的指數(shù)移動(dòng)平均數(shù), 初始化為0。 系數(shù)為指數(shù)衰減率,控制之前的梯度平方的影響情況。默認(rèn)為0.999。 類似于RMSProp算法,對(duì)梯度平方進(jìn)行加權(quán)均值。 由于 初始化為0,會(huì)導(dǎo)致 偏向于0,尤其在訓(xùn)練初期階段。
所以,此處需要對(duì)梯度均值 進(jìn)行偏差糾正,降低偏差對(duì)訓(xùn)練初期的影響。
同時(shí) 也要進(jìn)行偏差糾正:
最后總的公式如下所示:
其中默認(rèn)學(xué)習(xí)率 , 避免除數(shù)變?yōu)?。
從表達(dá)式中可以看出,對(duì)更新的步長計(jì)算,能夠從梯度均值和梯度平方兩個(gè)角度進(jìn)行自適應(yīng)地調(diào)節(jié),而不是直接由當(dāng)前梯度決定。
Adam的不足:
雖然Adam算法目前成為主流的優(yōu)化算法,不過在很多領(lǐng)域里(如計(jì)算機(jī)視覺的圖像識(shí)別、NLP中的機(jī)器翻譯)的最佳成果仍然是使用帶動(dòng)量(Momentum)的SGD來獲取到的。
【二】有哪些提高GAN訓(xùn)練穩(wěn)定性的Tricks? 1.輸入Normalize 生成器最后一層的輸出使用Tanh激活函數(shù)。 Normalize非常重要,沒有處理過的圖片是沒辦法收斂的。圖片Normalize一種簡單的方法是(images-127.5)/127.5,然后送到判別器去訓(xùn)練。同理生成的圖片也要經(jīng)過判別器,即生成器的輸出也是-1到1之間,所以使用Tanh激活函數(shù)更加合適。
2.替換原始的GAN損失函數(shù)和標(biāo)簽反轉(zhuǎn) 原始GAN損失函數(shù)會(huì)出現(xiàn)訓(xùn)練早期梯度消失和Mode collapse(模型崩潰)問題??梢允褂肊arth Mover distance(推土機(jī)距離)來優(yōu)化。
實(shí)際工程中用反轉(zhuǎn)標(biāo)簽來訓(xùn)練生成器更加方便,即把生成的圖片當(dāng)成real的標(biāo)簽來訓(xùn)練,把真實(shí)的圖片當(dāng)成fake來訓(xùn)練。
3.使用具有球形結(jié)構(gòu)的隨機(jī)噪聲 作為輸入 使用高斯分布進(jìn)行采樣 4.使用BatchNorm 一個(gè)mini-batch中必須只有real數(shù)據(jù)或者fake數(shù)據(jù),不要把他們混在一起訓(xùn)練。 如果能用BatchNorm就用BatchNorm,如果不能用則用instance normalization。 5.避免使用ReLU,MaxPool等操作引入稀疏梯度 GAN的穩(wěn)定性會(huì)因?yàn)橐胂∈杼荻仁艿胶艽笥绊憽?/span> 最好使用類LeakyReLU的激活函數(shù)。(D和G中都使用) 對(duì)于下采樣,最好使用:Average Pooling或者卷積+stride。 對(duì)于上采樣,最好使用:PixelShuffle或者轉(zhuǎn)置卷積+stride。 最好去掉整個(gè)Pooling邏輯,因?yàn)槭褂肞ooling會(huì)損失信息,這對(duì)于GAN訓(xùn)練沒有益處。
6.使用Soft和Noisy的標(biāo)簽 Soft Label,即使用 和 兩個(gè)區(qū)間的隨機(jī)值來代替正樣本和負(fù)樣本的Hard Label。 可以在訓(xùn)練時(shí)對(duì)標(biāo)簽加一些噪聲,比如隨機(jī)翻轉(zhuǎn)部分樣本的標(biāo)簽。 7.使用Adam優(yōu)化器 Adam優(yōu)化器對(duì)于GAN來說非常有用。 8.追蹤訓(xùn)練失敗的信號(hào) 如果生成器的損失穩(wěn)步下降,說明判別器沒有起作用。 9.在輸入端適當(dāng)添加噪聲 10.生成器和判別器差異化訓(xùn)練 多訓(xùn)練判別器,尤其是加了噪聲的時(shí)候。 11.Two Timescale Update Rule (TTUR) 對(duì)判別器和生成器使用不同的學(xué)習(xí)速度。使用較低的學(xué)習(xí)率更新生成器,判別器使用較高的學(xué)習(xí)率進(jìn)行更新。
12. Gradient Penalty (梯度懲罰) 使用梯度懲罰機(jī)制可以極大增強(qiáng) GAN 的穩(wěn)定性,盡可能減少mode collapse問題的產(chǎn)生。
13. Spectral Normalization(譜歸一化) Spectral normalization可以用在判別器的weight normalization技術(shù),可以確保判別器是K-Lipschitz連續(xù)的。
14. 使用多個(gè)GAN結(jié)構(gòu) 可以使用多個(gè)GAN/多生成器/多判別器結(jié)構(gòu)來讓GAN訓(xùn)練更穩(wěn)定,提升整體效果,解決更難的問題。
【經(jīng)典模型&&熱門模型】 【一】U-Net模型的結(jié)構(gòu)和特點(diǎn)? U-Net網(wǎng)絡(luò)結(jié)構(gòu)如下所示:
U-Net網(wǎng)絡(luò)結(jié)構(gòu) U-Net網(wǎng)絡(luò)的特點(diǎn):
全卷積神經(jīng)網(wǎng)絡(luò):使用 卷積完全取代了全連接層,使得模型的輸入尺寸不受限制。 左半部分網(wǎng)絡(luò)是收縮路徑(contracting path):使用卷積和max pooling層,對(duì)feature map進(jìn)行下采樣。 右半部分網(wǎng)絡(luò)是擴(kuò)張路徑(expansive path):使用轉(zhuǎn)置卷積對(duì)feature map進(jìn)行上采樣,并將其與收縮路徑對(duì)應(yīng)層產(chǎn)生的特征圖進(jìn)行concat操作。 上采樣可以補(bǔ)充特征信息,加上與左半部分網(wǎng)絡(luò)收縮路徑的特征圖進(jìn)行concat(通過crop操作使得兩個(gè)特征圖尺寸一致),這就相當(dāng)于在高分辨率和高維特征當(dāng)中做一個(gè)融合折中 。 U-Net提出了讓人耳目一新的編碼器-解碼器整體結(jié)構(gòu),讓U-Net充滿了生命力與強(qiáng)適應(yīng)性。 U-Net在醫(yī)療圖像,缺陷檢測以及交通場景中有非常豐富的應(yīng)用,可以說圖像分割實(shí)際場景,U-Net是當(dāng)仁不讓的通用Baseline。
U-Net的論文地址:https:///pdf/1505.04597.pdf
【二】RepVGG模型的結(jié)構(gòu)和特點(diǎn)? RepVGG模型的基本架構(gòu)由20多層 卷積組成,分成5個(gè)stage,每個(gè)stage的第一層是stride=2的降采樣,每個(gè)卷積層用ReLU作為激活函數(shù)。
RepVGG的主要特點(diǎn):
卷積在GPU上的計(jì)算密度(理論運(yùn)算量除以所用時(shí)間)可達(dá)1x1和5x5卷積的四倍. 直筒型單路結(jié)構(gòu)的計(jì)算效率比多路結(jié)構(gòu)高。 直筒型單路結(jié)構(gòu)比起多路結(jié)構(gòu)內(nèi)存占用少。 單路架構(gòu)靈活性更好,容易進(jìn)一步進(jìn)行模型壓縮等操作。 RepVGG中只含有一種算子,方便芯片廠商設(shè)計(jì)專用芯片來提高端側(cè)AI效率。 那么是什么讓RepVGG能在上述情形下達(dá)到SOTA效果呢?
答案就是 結(jié)構(gòu)重參數(shù)化(structural re-parameterization) 。
結(jié)構(gòu)重參數(shù)化邏輯 在訓(xùn)練階段,訓(xùn)練一個(gè)多分支模型,并將多分支模型等價(jià)轉(zhuǎn)換為單路模型。在部署階段,部署單路模型即可。這樣就可以同時(shí)利用多分支模型訓(xùn)練時(shí)的優(yōu)勢(性能高)和單路模型推理時(shí)的好處(速度快、省內(nèi)存)。
更多結(jié)構(gòu)重參數(shù)化細(xì)節(jié)知識(shí)將在后續(xù)的篇章中展開介紹,大家盡情期待!
【機(jī)器學(xué)習(xí)基礎(chǔ)】 【一】Accuracy、Precision、Recall、F1 Scores的相關(guān)概念? 首先介紹一下相關(guān)名詞:
TP(True Positive): 預(yù)測為正,實(shí)際為正 FP(False Positive): 預(yù)測為正,實(shí)際為負(fù) TN(True Negative):預(yù)測為負(fù),實(shí)際為負(fù) FN(false negative): 預(yù)測為負(fù),實(shí)際為正 Accuracy、Precision、Recall、F1 Scores的公式如下所示:
Accuracy(準(zhǔn)確率):分類正確的樣本數(shù)占樣本總數(shù)的比例。
Precision(精準(zhǔn)度/查準(zhǔn)率):當(dāng)前預(yù)測為正樣本類別中被正確分類的樣本比例。
Recall(召回率/查全率):預(yù)測出來的正樣本占正樣本總數(shù)的比例。
F1-score是Precision和Recall的綜合。F1-score越高,說明分類模型越穩(wěn)健。
【二】梯度爆炸和梯度消失產(chǎn)生的原因及解決方法? 梯度爆炸和梯度消失問題 一般在深層神經(jīng)網(wǎng)絡(luò)中,我們需要預(yù)防梯度爆炸和梯度消失的情況。
梯度消失(gradient vanishing problem)和梯度爆炸(gradient exploding problem)一般隨著網(wǎng)絡(luò)層數(shù)的增加會(huì)變得越來越明顯。
例如下面所示的含有三個(gè)隱藏層的神經(jīng)網(wǎng)絡(luò),梯度消失問題發(fā)生時(shí),接近輸出層的hiden layer3的權(quán)重更新比較正常,但是前面的hidden layer1的權(quán)重更新會(huì)變得很慢,導(dǎo)致前面的權(quán)重幾乎不變,仍然接近初始化的權(quán)重, 這相當(dāng)于hidden layer1沒有學(xué)到任何東西,此時(shí)深層網(wǎng)絡(luò)只有后面的幾層網(wǎng)絡(luò)在學(xué)習(xí),而且網(wǎng)絡(luò)在實(shí)際上也等價(jià)變成了淺層網(wǎng)絡(luò) 。
產(chǎn)生梯度爆炸和梯度消失問題的原因 我們來看看看反向傳播的過程:
(假設(shè)網(wǎng)絡(luò)每一層只有一個(gè)神經(jīng)元,并且對(duì)于每一層 )
可以推導(dǎo)出:
而sigmoid的導(dǎo)數(shù) 如下圖所示:
可以知道, 的最大值是 ,而我們初始化的權(quán)重 通常都小于1,因此 ,而且鏈?zhǔn)角髮?dǎo)層數(shù)非常多,不斷相乘的話,最后的結(jié)果越來越小,趨向于0,就會(huì)出現(xiàn)梯度消失的情況。
梯度爆炸則相反, 時(shí),不斷相乘結(jié)果變得很大。
梯度爆炸和梯度消失問題都是因?yàn)榫W(wǎng)絡(luò)太深,網(wǎng)絡(luò)權(quán)重更新不穩(wěn)定造成的,本質(zhì)上是梯度方向傳播的連乘效應(yīng)。
梯度爆炸和梯度消失的解決方法 使用預(yù)訓(xùn)練加微調(diào)策略。 使用ReLU、LeakyReLU等激活函數(shù)。 【Python/C/C++知識(shí)】 【一】Python中的None代表什么? None是一個(gè)特殊的常量,表示空值,其和False,0以及空字符串不同,它是一個(gè)特殊Python對(duì)象, None的類型是NoneType。
None和任何其他的數(shù)據(jù)類型比較返回False。
>>> None == 0 False >>> None == ' ' False >>> None == None True >>> None == False False
我們可以將None復(fù)制給任何變量,也可以給None賦值。
【二】Python中 和 的區(qū)別? 和 主要用于函數(shù)定義。我們可以將不定數(shù)量的參數(shù)傳遞給一個(gè)函數(shù)。
這里的不定的意思是 :預(yù)先并不知道函數(shù)使用者會(huì)傳遞多少個(gè)參數(shù), 所以在這個(gè)場景下使用這兩個(gè)關(guān)鍵字。
是用來發(fā)送 一個(gè)非鍵值對(duì)的可變數(shù)量的參數(shù)列表 給一個(gè)函數(shù)。
我們直接看一個(gè)例子:
def test_var_args (f_arg, *argv) : print('first normal arg:' , f_arg) for arg in argv: print('another arg through *argv:' , arg) test_var_args('hello' , 'python' , 'ddd' , 'test' ) -----------------結(jié)果如下----------------------- first normal arg: hello another arg through *argv: python another arg through *argv: ddd another arg through *argv: test
允許我們 將不定長度的鍵值對(duì), 作為參數(shù)傳遞給一個(gè)函數(shù) 。如果我們想要在一個(gè)函數(shù)里處理帶名字的參數(shù), 我們可以使用 。
我們同樣舉一個(gè)例子:
def greet_me (**kwargs) : for key, value in kwargs.items(): print('{0} == {1}' .format(key, value)) greet_me(name='yasoob' ) -----------結(jié)果如下------------- name == yasoob
【三】C/C++中面向?qū)ο蠛兔嫦蜻^程的區(qū)別? 面向?qū)ο螅∣bject Oriented Programming,OOP)編程模型首先抽象出各種對(duì)象(各種類),并專注于對(duì)象與對(duì)象之間的交互,對(duì)象涉及的方法和屬性都封裝在對(duì)象內(nèi)部。
面向?qū)ο蟮木幊趟枷胧且环N依賴于類和對(duì)象概念的編程方式,一個(gè)形象的例子是將大象裝進(jìn)冰箱:
冰箱是一個(gè)對(duì)象,大象也是一個(gè)對(duì)象。 冰箱有自己的方法,打開、存儲(chǔ)、關(guān)閉等;大象也有自己的方法,吃、走路等。 冰箱有自己的屬性:長、寬、高等;大象也有自己的屬性:體重、高度、體積等。 面向過程(Procedure Oriented Programming,POP)編程模型是將問題分解成若干步驟(動(dòng)作),每個(gè)步驟(動(dòng)作)用一個(gè)函數(shù)來實(shí)現(xiàn),在使用的時(shí)候,將數(shù)據(jù)傳遞給這些函數(shù)。
面向過程的編程思想通常采用自上而下、順序執(zhí)行的方式進(jìn)行,一個(gè)形象的例子依舊是將大象裝進(jìn)冰箱:
面向?qū)ο蠛兔嫦蜻^程的區(qū)別: 安全性角度 。面向?qū)ο蟊让嫦蜻^程安全性更高,面向?qū)ο髮?shù)據(jù)訪問隱藏在了類的成員函數(shù)中,而且類的成員變量和成員函數(shù)都有不同的訪問屬性;而面向過程并沒有辦法來隱藏程序數(shù)據(jù)。
程序設(shè)計(jì)角度 。面向過程通常將程序分為一個(gè)個(gè)的函數(shù);而面向?qū)ο缶幊讨型ǔJ褂靡粋€(gè)個(gè)對(duì)象,函數(shù)通常是對(duì)象的一個(gè)方法。
邏輯過程角度 。面向過程通常采用自上而下的方法;而面向?qū)ο笸ǔ2捎米韵露系姆椒ā?/span>
程序擴(kuò)展性角度 。面向?qū)ο缶幊谈菀仔薷某绦颍菀滋砑有鹿δ堋?/span>
【模型部署】 【一】主流AI端側(cè)硬件平臺(tái)有哪些? 【二】主流AI端側(cè)硬件平臺(tái)一般包含哪些模塊? 【圖像處理基礎(chǔ)】 【一】圖像噪聲的種類? 常規(guī)噪聲 對(duì)抗噪聲 【二】Python中OpenCV和PIL的區(qū)別? 在讀取圖片時(shí),OpenCV按照BGR的色彩模式渲染通道,而PIL按照RGB的色彩模式渲染通道。 OpenCV性能較優(yōu),可以作為算法與工程的必備模塊。 OpenCV的一些常用操作:
import cv2 # 導(dǎo)入OpenCV庫 import numpy as np img = cv2.imread('xxx.jpg' , 0) # 讀取圖片:灰度模式 img = cv2.imread('xxx.jpg' , -1) # 讀取圖片:BGRA模式(BGR+Alpha通道) img = cv2.imread('xxx.jpg' , 1) # 讀取圖片:BGR模式 img = cv2.imread('xxx.jpg' ) # 讀取圖片:第二參數(shù)默認(rèn)為1,BGR模式 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 將顏色通道從BGR轉(zhuǎn)為RGB if img == None: # 讀取圖片失敗 print ('image failed to load' ) cv2.imshow('src' , img) # 圖片源src為img print (img.shape) # 輸出圖片(高度h,寬度w,通道c) print (img.size) # 像素總數(shù)目 print (img.dtype) # 輸出圖片類型,uint8為[0-255] print (img) # 輸出所有像素的RGB值 cv2.waitKey() # 按鍵關(guān)閉窗口 # waitKey(delay)函數(shù)的功能是不斷刷新圖像,頻率時(shí)間為delay,單位為ms,返回值為當(dāng)前鍵盤按鍵值 # waitKey() 是在一個(gè)給定的時(shí)間內(nèi)(單位ms)等待用戶按鍵觸發(fā); 如果用戶沒有按下鍵,則接續(xù)等待(循環(huán)) imgL = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 讀取img灰度圖 cv2.imshow('gray' ,imgL) # 圖片源gray為imgL cv2.imwrite('imgL.jpg' ,imgL) # 將imgL儲(chǔ)存名為imgL.jpg的圖片 img = img.transpose(2,0,1) # 圖片矩陣變換為(通道c,高度h,寬度w) img = np.expand_dims(img, axis=0) # 圖片矩陣擴(kuò)展維度添加在第一維 print (img.shape) # (1,通道c,高度h,寬度w) print (img[10,10]) # 訪問圖片img像素[10,10],輸出 [0-255 0-255 0-255] print (imgL[10,10]) # 訪問灰色圖片img像素[10,10],輸出 0-255 img[10,10] = [255,255,255] # 修改圖片img像素點(diǎn)[10,10]為[255,255,255] imgL[10,10] = 255 # 修改灰色圖片img像素點(diǎn)[10,10]為255 img[:,:,2] = 0 # 將R通道全部修改為0 roi = img[200:550,100:450,:] # ROI操作,坐標(biāo)(高度范圍,寬度范圍,通道范圍) cv2.imshow('roi' ,roi) # 圖片源roi為roi
PIL的一些常用操作:
from PIL import Image #導(dǎo)入PIL庫 import numpy as np img = Image.open('../xx.jpg' ) # 讀取圖片 imgL = Image.open('../xx.jpg' ).convert('L' ) # 讀取圖片灰度圖 imgL.show() # 展示灰度圖 img1 = img.copy() # 復(fù)制圖片 print (img.format) # 輸出圖片格式 print (img.size) # 輸出圖片(寬度w,高度h) print (img.mode) # 輸出圖片類型,L為灰度圖,RGB為真彩色,RGBA為RGB+Alpha透明度 im.show() # 展示畫布 imgData = np.array(img) # 將對(duì)象img轉(zhuǎn)化為RGB像素值矩陣 print (imgData.shape) # 輸出圖片(寬度w,高度h,通道c) print (imgData.dtype) # 輸出圖片類型,uint8為[0-255] print (imgData) # 輸出所有像素的RGB值 imgN = Image.fromarray(imgData) # 將RGB像素值矩陣轉(zhuǎn)化為對(duì)象imgN imgN.save('xxx.jpg' ) # 儲(chǔ)存為文件xxx.jpg r ,g ,b = img.split() # 分離通道 img = Image.merge('RGB' , (b, g, r)) # 合并通道 # ROI(region of interest),只對(duì)ROI區(qū)域操作 roi = img.crop((0, 0, 300, 300)) # (左上x,左上y,右下x,右下y)坐標(biāo) roi.show() # 展示ROI區(qū)域 #捕捉異IOError,為讀取圖片失敗 try: img = Image.open('xxx.jpg' ) except IOError: print ('image failed to read' )
【計(jì)算機(jī)基礎(chǔ)】 【一】Git,GitLab,SVN的相關(guān)知識(shí) Git Git是當(dāng)前主流的一種 開源分布式版本控制系統(tǒng),可以有效、快速的進(jìn)行項(xiàng)目版本管理 。
Git沒有中央服務(wù)器,不同于SVN這種需要中央服務(wù)器的集中式版本控制系統(tǒng)。
Git的功能:版本控制(版本管理,遠(yuǎn)程倉庫,分支協(xié)作)
Git的工作流程:
Git工作流程 Git的常用命令:
git init 創(chuàng)建倉庫 git clone 克隆github上的項(xiàng)目到本地 git add 添加文件到緩存區(qū) git commit 將緩存區(qū)內(nèi)容添加到倉庫中
GitLab GitLab是一個(gè)基于Git實(shí)現(xiàn)的在線代碼倉庫軟件,可以基于GitLab搭建一個(gè)類似于GitHub的倉庫, 但是GitLab有完善的管理界面和權(quán)限控制,有較高的安全性,可用于企業(yè)和學(xué)校等場景 。
SVN SVN全名Subversion,是一個(gè)開源的版本控制系統(tǒng)。 不同于Git,SVN是集中式版本控制系統(tǒng) 。
SVN只有一個(gè)集中管理的服務(wù)器,保存所有文件的修訂版本,而協(xié)同工作的人們都通過客戶端連到這臺(tái)服務(wù)器,取出最新的文件或者提交更新。
SVN的特點(diǎn)是 安全,效率,資源共享 。
SVN的常用操作:
Checkout 檢出代碼 Update 更新代碼 Commit 提交代碼 Add 提交新增文件 Revert to this version + commit 撤銷已經(jīng)提交的代碼
【二】協(xié)程的相關(guān)概念 協(xié)程(Coroutine,又稱微線程) 運(yùn)行在線程之上,更加輕量級(jí),協(xié)程并沒有增加線程總數(shù),只是在線程的基礎(chǔ)之上通過分時(shí)復(fù)用的方式運(yùn)行多個(gè)協(xié)程,大大提高工程效率 。
協(xié)程的特點(diǎn):
協(xié)程類似于子程序,但執(zhí)行過程中,協(xié)程內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行其他的協(xié)程,在適當(dāng)?shù)臅r(shí)候再返回來接著執(zhí)行。協(xié)程之間的切換不需要涉及任何系統(tǒng)調(diào)用或任何阻塞調(diào)用。 協(xié)程只在一個(gè)線程中執(zhí)行,發(fā)生在用戶態(tài)上的一個(gè)邏輯。并且是協(xié)程之間的切換并不是線程切換,而是由程序自身控制,協(xié)程相比線程節(jié)省線程創(chuàng)建和切換的開銷。 協(xié)程中不需要多線程的鎖機(jī)制,因?yàn)橹挥幸粋€(gè)線程,也不存在同時(shí)寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比多線程高很多。 協(xié)程適用于有大量I/O操作業(yè)務(wù)的場景,可以到達(dá)很好的效果,一是降低了系統(tǒng)內(nèi)存,二是減少了系統(tǒng)切換開銷,因此系統(tǒng)的性能也會(huì)提升。
在協(xié)程中盡量不要調(diào)用阻塞I/O的方法,比如打印,讀取文件等,除非改為異步調(diào)用的方式,并且協(xié)程只有在I/O密集型的任務(wù)中才會(huì)發(fā)揮作用。
【開放性問題】 這些問題基于我的思考提出,希望除了能給大家?guī)砻嬖嚨乃伎?,也能給大家?guī)砻嬖囈酝獾乃伎?。這些問題沒有標(biāo)準(zhǔn)答案,我相信每個(gè)人心中都有自己靈光一現(xiàn)的創(chuàng)造,你的呢?
【一】如何保持?jǐn)?shù)據(jù)持續(xù)穩(wěn)定的支持業(yè)務(wù)? 在“CV兵器”基本上都是開源的情況下, 數(shù)據(jù)成為了支持業(yè)務(wù)迭代最重要的一部分,如何建立數(shù)據(jù)護(hù)城河,形成業(yè)務(wù)與數(shù)據(jù)雙向正反饋 ,是AI行業(yè)從業(yè)者必須要面對(duì)的課題。
【二】如何分辨demo業(yè)務(wù),一次性業(yè)務(wù)以及外包業(yè)務(wù)? 這個(gè)問題不僅可以考察面試者,面試者也可以用來反向判斷面試官及其背后公司的運(yùn)行邏輯。 陷入demo業(yè)務(wù),一次性業(yè)務(wù)以及外包業(yè)務(wù)的循環(huán)中是無法成長的,也不利于建立業(yè)務(wù)/產(chǎn)品的護(hù)城河 。知道了這一點(diǎn),那么如何去選擇部門,如何去選擇公司,如何去看需求,就變成了非常值得研究的事情。