AI面試刷題版


 

(1)代碼題(leetcode類型),主要考察數據結構和基礎算法,以及代碼基本功

 

雖然這部分跟機器學習,深度學習關系不大,但也是面試的重中之重。基本每家公司的面試都問了大量的算法題和代碼題,即使是商湯、face++這樣的深度學習公司,考察這部分的時間也占到了我很多輪面試的60%甚至70%以上。我去face++面試的時候,面試官是residual net,shuffle net的作者;但他們的面試中,寫代碼題依舊是主要的部分。

 

大部分題目都不難,基本是leetcode medium的難度。但是要求在現場白板編程,思路要流暢,能做到一次性Bug-free. 並且,一般都是要給出時間復雜度和空間復雜度最優的做法。對於少數難度很大的題,也不要慌張。一般也不會一點思路也沒有,盡力給面試官展現自己的思考過程。面試官也會引導你,給一點小提示,沿着提示把題目慢慢做出來也是可以通過面試的。

 

以下是我所遇到的一些需要當場寫出完整代碼的題目:

 

<1> 二分查找。分別實現C++中的lower_bound和upper_bound. 

 

<2> 排序。 手寫快速排序,歸並排序,堆排序都被問到過。 

 

<3> 給你一個數組,求這個數組的最大子段積 

 

時間復雜度可以到O(n) 

 

<4> 給你一個數組,在這個數組中找出不重合的兩段,讓這兩段的字段和的差的絕對值最大。 

 

時間復雜度可以到O(n) 

 

<5> 給你一個數組,求一個k值,使得前k個數的方差 + 后面n-k個數的方差最小

 

時間復雜度可以到O(n) 

 

<6> 給你一個只由0和1組成的字符串,找一個最長的子串,要求這個子串里面0和1的數目相等。 

 

時間復雜度可以到O(n) 

 

<7> 給你一個數組以及一個數K, 從這個數組里面選擇三個數,使得三個數的和小於等於K, 問有多少種選擇的方法? 

 

時間復雜度可以到O(n^2) 

 

<8> 給你一個只由0和1組成的矩陣,找出一個最大的子矩陣,要求這個子矩陣是方陣,並且這個子矩陣的所有元素為1 

 

時間復雜度可以到O(n^2) 

 

<9> 求一個字符串的最長回文子串 

 

時間復雜度可以到O(n) (Manacher算法) 

 

<10> 在一個數軸上移動,初始在0點,現在要到給定的某一個x點, 每一步有三種選擇,坐標加1,坐標減1,坐標乘以2,請問最少需要多少步從0點到x點。 

 

<11> 給你一個集合,輸出這個集合的所有子集。 

 

<12> 給你一個長度為n的數組,以及一個k值(k < n) 求出這個數組中每k個相鄰元素里面的最大值。其實也就是一個一維的max pooling 

 

時間復雜度可以到O(n) 

 

<13> 寫一個程序,在單位球面上隨機取點,也就是說保證隨機取到的點是均勻的。 

 

<14> 給你一個長度為n的字符串s,以及m個短串(每個短串的長度小於10), 每個字符串都是基因序列,也就是說只含有A,T,C,G這四個字母。在字符串中找出所有可以和任何一個短串模糊匹配的子串。模糊匹配的定義,兩個字符串長度相等,並且至多有兩個字符不一樣,那么我們就可以說這兩個字符串是模糊匹配的。

 

 

 

 

 

1、A為N*k矩陣,B為M*k的矩陣,求AB的歐式距離,要求用矩陣化的方法(不用for循環...)。

其中就是求一個distance矩陣。對A、B中的每一個元素直接求解他們的歐式距離。

一、for循環

分別對A和B中的數據進行循環遍歷,計算每兩個點之間的歐式距離,然后賦值給dist矩陣。

復制代碼
import numpy as np

def compute_squared_EDM_method(A,B):
  # determin dimensions of data matrix
  num1 = A.shape[0]
  num2 = B.shape[0]
  # initialize squared EDM D
  dists = np.zeros((num1, num2))
  # iterate over upper triangle of D
  for i in range(num1):
    for j in range(num2):
        dists[i][j] = np.sqrt(np.sum(np.square(A[i] - B[j])))

  return dists
復制代碼

 

二、使用矩陣運算的方法替代之前的循環操作。

dist=sqrt(A^2+B^2-2A.Bt)

 
dists = np.sqrt(-2 * np.dot(A, B.T) + np.sum(np.square(B), axis=1) + np.transpose(
      [np.sum(np.square(A), axis=1)]))

2、給了個label和pred示例,計算AP寫代碼。

幾個概念

PR曲線:即 以 precision 和 recall 作為 縱、橫軸坐標 的二維曲線。

AP值:Average Precision,即 平均精確度 。

 

如何衡量一個模型的性能,單純用 precision 和 recall 都不科學。於是人們想到,哎嘛為何不把 PR曲線下的面積 當做衡量尺度呢?於是就有了 AP值 這一概念。這里的 average,等於是對 precision進行 取平均

mAP值:Mean Average Precision,即 平均AP值 。

是對多個驗證集個體 求 平均AP值 。

直接通過label和pred計算AP的方法。

通過p和C計算AP和mAp方法:

Recall = TPR = TP/(TP+FN)

Precision = TP/(TP+FP) (精確度/率)

  • Accuracy = (TP+TN)/(P+N) = (TP+TN) / (TP + FN + FP + TN) (准確率,姑且這么叫吧,其中P為所有的正樣本,N為所有的負樣本)
  • F-Meature = 2(Precision*Recall)/(Precision + Recall)

https://blog.csdn.net/Jesse_Mx/article/details/79169991SSD算法評估:AP, mAP和Precision-Recall曲線

復制代碼
for i in range(len(precisions) - 2, -1, -1):
        precisions[i] = np.maximum(precisions[i], precisions[i + 1])

    # Compute mean AP over recall range
    indices = np.where(recalls[:-1] != recalls[1:])[0] + 1
    mAP = np.sum((recalls[indices] - recalls[indices - 1]) *
                 precisions[indices])
 
         
復制代碼

 

復制代碼
[so,si]=sort(-out);%out is the result from your classifier
tp=gt(si)>0;
fp=gt(si)<0;

fp=cumsum(fp);%判為負樣本的數
tp=cumsum(tp);%判為正樣本的數
rec=tp/sum(gt>0);%召回率
prec=tp./(fp+tp);%精確度

ap=VOCap(rec,prec);

function ap = VOCap(rec,prec)
//matlab 計算AP的過程
mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
    mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;%去掉mrec中重復的部分,+1是保持下標的一致
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));%area=(x(2)-x(1))*y
復制代碼

機器學習:Python實現聚類算法(二)之AP算法

 3、一維maxpooling操作長度1*k,stride=1,窗口大小n,時間復雜度要求很小。

復制代碼
tf.layers.max_pooling1d(
    inputs,
    pool_size,
    strides,
    padding='valid',
    data_format='channels_last',
    name=None
)
復制代碼
  • inputs:池的張量,秩必須為3。
  • pool_size:單個整數的整數或元組/列表,表示池化窗口的大小。
  • strides:單個整數的整數或元組/列表,指定池操作的步幅。
  • padding:一個字符串,表示填充方法,可以是“valid”或“same”,不區分大小寫。
  • data_format:一個字符串,一個channels_last(默認)或channels_first,表示輸入中維度的順序,channels_last對應於具有形狀(batch, length, channels)的輸入,而channels_first對應於具有形狀(batch, channels, length)的輸入。
  • name:字符串,圖層的名稱。

返回:

輸出張量,秩為3。

 

類似題目:對一個一維數組做核為k的max_pooling, 步長為1,並寫出時間復雜度

max pooling 的操作如下圖所示:整個圖片被不重疊的分割成若干個同樣大小的小塊(pooling size)。每個小塊內只取最大的數字,再舍棄其他節點后,保持原有的平面結構得出 output。

一維數組做max_pooling就是分段比較。

pooling的原理與Python實現

復制代碼
# max pooling
    for r_idx in range(0,out_row):
        for c_idx in range(0,out_col):
            startX = c_idx * poolStride
            startY = r_idx * poolStride
            poolField = temp_map[startY:startY + poolSize, startX:startX + poolSize]
            poolOut = np.max(poolField)
            outputMap[r_idx,c_idx] = poolOut
    
    # retrun outputMap
    return  outputMap
 
         
復制代碼

 

4、字符串反轉 hello world ---> dlrow olleh。

 
String str = "Hello World"; //首先定義一個Hello World字符串
StringBuilder sb = new StringBuilder(str); //創建一個StringBuilder變量,將定義的字符串傳遞進去
System.out.println(sb.reverse().toString()); //使用StringBuilder里面的函數,將字符串反轉,然后已字符串的方式輸出。

hello world 輸出 olleh dlrow

字符串翻轉集合, case1, hello world->world hello; case2, hello world->olleh dlrow

Python實現字符串反轉的幾種方法

 5、fast_Rcnn原理和實現

R-CNN,Fast R-CNN,Faster R-CNN原理及執行與訓練的實例+實現自己的目標檢測

用自己的數據訓練Faster-RCNN,tensorflow版本(一)

6、

:Pooling知道吧?我們在做cv的時候,圖像經常是不同size的,我們在訓練的時候經常通過crop圖片取得同size的輸入數據。但是訓練的時候,輸入是整張圖,【這樣會造成什么后果呢?】用沒有什么辦法可以解決這個問題呢?即測試的時候如何有效利用整張圖的信息?

 

答:測試的時候也crop,每個croped圖片有一個預測結果,通過投票的形式得到最后結果。

 

問:因為crop是overlapping的,這種方式會造成在部分圖片區域上的重復卷積,增加計算復雜度,有沒有辦法解決這個問題?

 

答:在卷積輸出層,也就是fc層前進行crop(但是網絡結構不能改變)

 

問:怎么做呢?舉個例子,原來是8x8x128的卷積輸出層,換成全圖之后,是10x12x128的卷積層,怎么連接到fc1層(假設是20維的)?

 

答:用20x8x8x128(n,c,h,w)的卷積核對10x12x128的map進行(s=1,p=0)的卷積,其實就相當於crop,得到fc1為20x3x5c,h,w的輸出

 

問:但是此時fc1層改變了(從20編程20x3x5, fc2層與之的連接也就失效了, 怎么解決?

 

答:(用5x20x1x1的卷積核再操作,得到5x3x5的輸出結果

 

要得到一個五維的輸出向量,對3x5區域做一個平均就可以了(每個channel是3x5=15個結果,即對卷積層輸出卷積操作得到3x5個不同feature預測的結果,就是15個crop對應的結果)

 

問:為什么選InceptionV3

 

答:實現方便,top1正確率和其他比較新的模型差不多

 

 [LeetCode] Maximum Product Subarray的4種解法

leetcode每日解題思路 221 Maximal Square

LeetCode:Subsets I II

(2)數學題或者"智力"題。

如果一個女生說,她集齊了十二個星座的前男友,我們應該如何估計她前男友的數量?

如何理解矩陣的「秩」?:

  • 「秩」是圖像經過矩陣變換之后的空間維度
  • 「秩」是列空間的維度

矩陣低秩的意義?:低秩表征着一種冗余程度。
秩越低表示數據冗余性越大,因為用很少幾個基就可以表達所有數據了。相反,秩越大表示數據冗余性越小。

一個m*n的矩陣,如果秩很低(秩r遠小於m,n),則它可以拆成一個m*r矩陣和一個r*n矩陣之積(類似於SVD分解)。后面這兩個矩陣所占用的存儲空間比原來的m*n矩陣小得多。

如何理解矩陣特征值?:

VD的效果就是..用一個規模更小的矩陣去近似原矩陣...
A_{m\times n} \approx U_{m\times r} \Sigma_{r\times r} V_{r\times n}
這里A就是代表圖像的原矩陣..其中的\Sigma_{r\times r}尤其值得關注,它是由A的特征值從大到小放到對角線上的..也就是說,我們可以選擇其中的某些具有“代表性”的特征值去近似原矩陣!

 

為什么梯度反方向是函數值下降最快的方向?

導數的幾何意義可能很多人都比較熟悉: 當函數定義域和取值都在實數域中的時候,導數可以表示函數曲線上的切線斜率。 除了切線的斜率,導數還表示函數在該點的變化率。

 

將上面的公式轉化為下面圖像為:

(3)機器學習基礎

邏輯回歸SVM決策樹

邏輯回歸和SVM的區別是什么?各適用於解決什么問題?

這兩種算法都是基於回歸的概念。

邏輯回歸相對容易理解,就是通過Sigmoid函數將線性方程ax+b對應到一個隱狀態P,P=S(ax+b),然后根據發生概率(p)與沒有發生概率(1-p)的大小決定因變量的取值,0或者1。具體操作就是p除以1-p再取對數,這個變換增加了取值區間的范圍;改變了函數值與自變量間的曲線關系,根據大量實驗數據,這個變換往往能使函數值和自變量之間呈線性關系。

SVM則是通過一個非線性映射p,把樣本空間映射到一個高維乃至無窮維的特征空間中(Hilbert空間),使得在原來的樣本空間中非線性可分的問題轉化為在特征空間中的線性可分的問題.簡單地說,就是升維和線性化。作為分類、回歸等問題來說,很可能在低維樣本空間無法線性處理的樣本集,在高維特征空間中卻可以通過一個線性超平面實現線性划分(或回歸)。一般的升維都會帶來計算的復雜化,但SVM方法巧妙地應用核函數的展開定理簡化了計算,不需要知道非線性映射的顯式表達式

。簡單來說,SVM是在高維特征空間中建立線性學習機,幾乎不增加計算的復雜性,並且在某種程度上避免了“維數災難”,這一切要歸功於核函數的展開和計算理論.

綜上所述,邏輯回歸和SVM都可以用於分類問題的解決,其主要區別就在於映射函數選擇上的不同,邏輯回歸常用於處理大數據,而SVM則正好相反。

SVM的處理方法是只考慮support vectors,也就是和分類最相關的少數點,去學習分類器。

而邏輯回歸通過非線性映射,大大減小了離分類平面較遠的點的權重,相對提升了與分類最相關的數據點的權重,兩者的根本目的都是一樣的。

svm考慮局部(支持向量),而logistic回歸考慮全局

1.損失函數不一樣,邏輯回歸的損失函數是log loss,svm的損失函數是hinge loss
2.損失函數的優化方法不一樣,邏輯回歸用剃度下降法優化,svm用smo方法進行優化
3.邏輯回歸側重於所有點,svm側重於超平面邊緣的點
4.svm的基本思想是在樣本點中找到一個最好的超平面

Linear SVM 和 LR 有什么異同?

相同點:

1,LR和SVM都是分類算法。
2,如果不考慮核函數,LR和SVM都是線性分類算法,即分類決策面都是線性的。
3,LR和SVM都是監督學習算法。

不同點:

1,本質上是其loss function不同。
2,支持向量機只考慮局部的邊界線附近的點,而邏輯回歸考慮全局(遠離的點對邊界線的確定也起作用)。
線性SVM不直接依賴於數據分布,分類平面不受一類點影響;LR則受所有數據點的影響,如果數據不同類別strongly unbalance,一般需要先對數據做balancing。
3,在解決非線性問題時,支持向量機采用核函數的機制,而LR通常不采用核函數的方法。
​這個問題理解起來非常簡單。分類模型的結果就是計算決策面,模型訓練的過程就是決策面的計算過程。通過上面的第二點不同點可以了解,在計算決策面時,SVM算法里只有少數幾個代表支持向量的樣本參與了計算,也就是只有少數幾個樣本需要參與核計算(即kernal machine解的系數是稀疏的)。然而,LR算法里,每個樣本點都必須參與決策面的計算過程,也就是說,假設我們在LR里也運用核函數的原理,那么每個樣本點都必須參與核計算,這帶來的計算復雜度是相當高的。所以,在具體應用時,LR很少運用核函數機制。​
4,​線性SVM依賴數據表達的距離測度,所以需要對數據先做normalization,LR不受其影響。
5,SVM的損失函數就自帶正則!!!(損失函數中的1/2||w||^2項),這就是為什么SVM是結構風險最小化算法的原因!!!而LR必須另外在損失函數上添加正則項!!!

本節來自算法比較-SVM和logistic回歸,該博客里有些寫的並不准確,具有參考價值。

在Andrew NG的課里講到過:
1. 如果Feature的數量很大,跟樣本數量差不多,這時候選用LR或者是Linear Kernel的SVM
2. 如果Feature的數量比較小,樣本數量一般,不算大也不算小,選用SVM+Gaussian Kernel
3. 如果Feature的數量比較小,而樣本數量很多,需要手工添加一些feature變成第一種情況

SVM(支持向量機)屬於神經網絡范疇嗎?

可以說神經網絡是通過多個感知器(Perceptron)的組合疊加來解決非線性的分類問題. 而SVM通過核函數視圖非線性的問題的數據集轉變為核空間中一個線性可分的數據集.
另外, 神經網絡非常依賴參數. 比如學習率, 隱含層的結構與節點個數. 參數的好壞會極大影響神經網絡的分類效果. 而SVM是基於最大邊緣的思想, 只有少量的參數需要調整.

如何理解決策樹的損失函數?

各種機器學習的應用場景分別是什么?例如,k近鄰,貝葉斯,決策樹,svm,邏輯斯蒂回歸和最大熵模型。

主成分分析,奇異值分解

SVD 降維體現在什么地方?

為什么PCA不被推薦用來避免過擬合?:

PCA是一種無監督學習,其存在的假設是:方差越大信息量越多。但是信息(方差)小的特征並不代表表對於分類沒有意義,可能正是某些方差小的特征直接決定了分類結果,而PCA在降維過程中完全不考慮目標變量的做法會導致一些關鍵但方差小的分類信息被過濾掉。

隨機森林,GBDT, 集成學習

為什么說bagging是減少variance,而boosting是減少bias?

基於樹的adaboost和Gradient Tree Boosting區別?

機器學習算法中GBDT和XGBOOST的區別有哪些?

為什么在實際的 kaggle 比賽中 gbdt 和 random forest 效果非常好?

過擬合

機器學習中用來防止過擬合的方法有哪些?

1 獲取更多數據,2 數據增強&噪聲數據3 簡化模型.

提前終止,L1和L2正則化 

正則化的一個最強大最知名的特性就是能向損失函數增加“懲罰項”(penalty)。所謂『懲罰』是指對損失函數中的某些參數做一些限制。最常見的懲罰項是L1和L2:

  • L1懲罰項的目的是將權重的絕對值最小化
  • L2懲罰項的目的是將權重的平方值最小化

Dropout-深度學習

機器學習中使用「正則化來防止過擬合」到底是一個什么原理?為什么正則化項就可以防止過擬合?

 

(4)深度學習基礎

 

卷積神經網絡,循環神經網絡,LSTM與GRU,梯度消失與梯度爆炸,激活函數,防止過擬合的方法,dropout,batch normalization,各類經典的網絡結構,各類優化方法

卷積神經網絡工作原理直觀的解釋?

卷積神經網絡的復雜度分析:時間和空間,以及影響。

CNN(卷積神經網絡)、RNN(循環神經網絡)、DNN(深度神經網絡)的內部網絡結構有什么區別?

bp算法中為什么會產生梯度消失?

梯度下降法是萬能的模型訓練算法嗎?

LSTM如何來避免梯度彌散和梯度爆炸?

sgd有多種改進的形式(rmsprop,adadelta等),為什么大多數論文中仍然用sgd?

你有哪些deep learning(rnn、cnn)調參的經驗?

Adam那么棒,為什么還對SGD念念不忘 (1)

Adam那么棒,為什么還對SGD念念不忘 (2)

全連接層的作用是什么?

深度學習中 Batch Normalization為什么效果好?

為什么現在的CNN模型都是在GoogleNet、VGGNet或者AlexNet上調整的?

Krizhevsky等人是怎么想到在CNN里用Dropout和ReLu的?

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM