0.導航
項目 | 內容 |
---|---|
這個做業屬於哪一個課程 | 人工智能實戰 |
這個做業的要求在哪裏 | 第三次做業:使用minibatch的方式進行梯度降低 |
我在這個課程的目標是 | 開拓視野,積累AI實戰經驗 |
這個做業在哪一個具體方面幫助我 | 瞭解單變量線性迴歸的幾種方法,掌握Mini-Batch梯度降低的具體實現過程 |
1.具體做業內容
###(1)使用minibatch的方式進行梯度降低 -採用隨機選取數據的方式 -batch size分別選擇5,10,15進行運行 -示例代碼位置:Here ###(2)複習講過的課程(連接),並回答關於損失函數的 2D 示意圖的問題: -問題2:爲何是橢圓而不是圓?如何把這個圖變成一個圓? -問題3:爲何中心是個橢圓區域而不是一個點?git
2.代碼部分(做業1)
改寫讀取數據集的函數ReadData(),使得能夠隨機選取數據github
def ReadData(): Xfile = Path(x_data_name) Yfile = Path(y_data_name) if Xfile.exists() & Yfile.exists(): X = np.load(Xfile) Y = np.load(Yfile) idx = np.arange(X.size) np.random.shuffle(idx) X = X[idx] Y = Y[idx] return X.reshape(1,-1),Y.reshape(1,-1) else: return None,None
改寫InitializeHyperParameters(method)函數網絡
def InitializeHyperParameters(method): if method=="MiniBatch_BatchSize_5": eta = 0.1 max_epoch = 50 batch_size = 5 elif method=="MiniBatch_BatchSize_10": eta = 0.1 max_epoch = 50 batch_size = 10 elif method=="MiniBatch_BatchSize_15": eta = 0.1 max_epoch = 50 batch_size = 15 return eta, max_epoch, batch_size
而後對主函數稍做包裝修改dom
def main(method): eta, max_epoch,batch_size = InitializeHyperParameters(method) W, B = InitialWeights(1,1,0) # calculate loss to decide the stop condition loss = 5 dict_loss = {} # read data X, Y = ReadData() # count of samples num_example = X.shape[1] num_feature = X.shape[0] # if num_example=200, batch_size=10, then iteration=200/10=20 max_iteration = (int)(num_example / batch_size) for epoch in range(max_epoch): print("epoch=%d" %epoch) for iteration in range(max_iteration): # get x and y value for one sample batch_x, batch_y = GetBatchSamples(X,Y,batch_size,iteration) # get z from x,y batch_z = ForwardCalculationBatch(W, B, batch_x) # calculate gradient of w and b dW, dB = BackPropagationBatch(batch_x, batch_y, batch_z) # update w,b W, B = UpdateWeights(W, B, dW, dB, eta) # calculate loss for this batch loss = CheckLoss(W,B,X,Y) print(epoch,iteration,loss,W,B) prev_loss = loss dict_loss[loss] = CData(loss, W, B, epoch, iteration) # end for # end for ShowLossHistory(dict_loss, method) w,b,cdata = GetMinimalLossData(dict_loss) print(cdata.w, cdata.b) print("epoch=%d, iteration=%d, loss=%f" %(cdata.epoch, cdata.iteration, cdata.loss)) #ShowResult(X, Y, W, B, epoch) print(w,b) x = 346/1000 result = ForwardCalculationBatch(w, b, x) print(result) loss_2d(X,Y,200,dict_loss,method,cdata)
if __name__ == '__main__': main("MiniBatch_BatchSize_5"); main("MiniBatch_BatchSize_10"); main("MiniBatch_BatchSize_15");
運行獲得結果進行對比
能夠看到隨着batch_size的增大,曲線變得平滑,個體樣本的噪聲被顯著下降 再來看看Loss_2D生成的圖像
也是隨着batch_size的增大,曲線變得更加平滑,可是與此同時生成圖片(即運行速度)顯著變慢,說明計算量明顯上升,因此當曲線平滑到必定程度,即batch_size達到較大的某個值之後,再增大batc_size對結果偏差減少帶來的優點會小於所以消耗更多性能和時間帶來的不足,所以當batch_size取到最合適的值時,有最佳效果。這也是介於SGD和BGD二者之間的Mini-Batch方法的優點所在。ide
3.問題回答(做業2)
###問題2:爲何是橢圓而不是圓?如何把這個圖變成一個圓? -答:損失函數以下 能夠想見,由於w和b對J的貢獻的係數不等,所以圖像是一個橢圓而非一個圓,變成圓 只須要使其貢獻相等便可,但此時w和b就沒有什麼區別了,所以沒有實際意義。函數
###問題3:爲何中心是個橢圓區域而不是一個點? -答:我我的的理解是:中心部分和全局最優的差距很是小,由於中心部分那塊區域的導數接近於0,且因爲計算精度有限,計算的結果(每一個點)又是離散而非連續的一條曲線,所以反映到圖像上一塊區域而不是一個點,而那一塊區域就是表示實驗中容許的偏差範圍。性能