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,且因为计算精度有限,计算的结果(每一个点)又是离散而非连续的一条曲线,所以反映到图像上一块区域而不是一个点,而那一块区域就是表示实验中容许的偏差范围。性能