梯度下降系列博客:4、小批量梯度下降算法代码实战

  1. 梯度下降系列博客:1、梯度下降算法基础
  2. 梯度下降系列博客:2、梯度下降算法背后的数学直觉
  3. 梯度下降系列博客:3、批量梯度下降代码实战
  4. 梯度下降系列博客:4、小批量梯度下降算法代码实战
  5. 梯度下降系列博客:5、随机梯度下降算法代码实战

小批量梯度下降 (MBGD) 算法的工作原理

在批量梯度下降 (BGD) 算法中,我们考虑算法所有迭代的所有训练示例。然而,在随机梯度下降 (SGD) 算法中,我们只考虑一个随机训练示例。现在,在小批量梯度下降 (MBGD) 算法中,我们在每次迭代中考虑训练示例的随机子集。由于这不像 SGD 那样随机,我们更接近全局最小值。然而,MBGD 很容易陷入局部最小值。让我们举个例子来更好地理解这一点。

批量梯度下降(BGD):

每次迭代的训练示例数 = 100 万 = 1⁰⁶
迭代次数 = 1000 = 1⁰³
要训练的参数数 = 10000 = 1⁰⁴
总计算量 = 1⁰⁶*1⁰³*1⁰⁴=1⁰¹³

随机梯度下降(SGD):

每次迭代的训练示例数 = 1
迭代次数 = 1000 = 1⁰³
要训练的参数数 = 10000 = 1⁰⁴
总计算量 = 1*1⁰³*1⁰⁴ = 1⁰⁷

小批量梯度下降(MBGD):

每次迭代的训练样本数 = 100 = 1⁰²
→在这里,我们考虑 1⁰⁶ 中的 1⁰² 训练样本。
迭代次数 = 1000 = 1⁰³
要训练的参数数量 = 10000 = 1⁰⁴
总计算量 = 1⁰²*1⁰³*1⁰⁴=1⁰⁹

与批量梯度下降(BGD)的比较:

BGD 中的
总计算量 = 1⁰¹³ MBGD 中的总计算量 = 1⁰⁹

评估: MBGD 在本例中比 BGD 快 1⁰⁴ 倍。

与随机梯度下降(SGD)的比较:

SGD 中的
总计算量 = 1⁰⁷ MBGD 中的总计算量 = 1⁰⁹

**评估:**在这个例子中,SGD 比 MBGD 快 1⁰² 倍。

BGD、SGD 和 MBGD 的比较

BGD 中的
总计算量 = 1⁰¹³ SGD 中的
总计算量 = 1⁰⁷ MBGD 中的总计算量 = 1⁰⁹

评估: SGD > MBGD > BGD

**注意:**请注意,我们的成本函数不一定会下降,因为我们在每次迭代中都对训练示例进行随机抽样。然而,随着我们执行越来越多的迭代,成本函数将逐渐减小。

现在,让我们看看 Mini-Batch 梯度下降 (MBGD) 算法在实践中是如何实现的。

1. 第 1 步:

首先,我们从 GitHub 存储库下载数据文件。

!wget https://raw.githubusercontent.com/Pratik-Shukla-22/Gradient-Descent/main/Advertising.csv

从 GitHub 获取数据文件

2. 第 2 步:

接下来,我们将导入一些必需的库来读取、操作和可视化数据。

#Import the required libraries:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

导入所需的库

3. 第 3 步:

接下来,我们正在读取数据文件,然后打印它的前五行。

#Read the data file:
data = pd.read_csv("Advertising.csv")
data.head()

#Output:
index,Unnamed: 0,TV,radio,newspaper,sales
0,1,230.1,37.8,69.2,22.1
1,2,44.5,39.3,45.1,10.4
2,3,17.2,45.9,69.3,9.3
3,4,151.5,41.3,58.5,18.5
4,5,180.8,10.8,58.4,12.9

读取和打印数据

4. 第 4 步:

接下来,我们将数据集划分为特征和目标变量。

#Define the feature and target variables:
X = data[["TV","radio","newspaper"]]
Y = data["sales"]

获取特征和目标变量

尺寸:X = (200, 3) & Y = (200, )

5. 第 5 步:

为了在进一步的步骤中执行矩阵计算,我们需要重塑目标变量。

#Reshape the data in Y:
Y = np.asarray(Y)
Y = np.reshape(Y,(Y.shape[0],1))

重塑 Y 中的数据

尺寸:X = (200, 3) & Y = (200, 1)

6. 第 6 步:

接下来,我们正在规范化数据集。

#Normalize the data:
X = (X - X.mean())/X.std()
Y = Y - Y.mean()/Y.std()

规范化数据

尺寸:X = (200, 3) & Y = (200, 1)

7. 第 7 步:

接下来,我们获取biasweights矩阵的初始值。我们将在执行前向传播时在第一次迭代中使用这些值。

#Function to get intial weights and bias:
def initialize_weights(n_features):
  bias = np.random.random(1)
  weights = np.random.random(n_features)

  #Reshape the bias and weights:
  bias = np.reshape(bias,(1,1))
  weights = np.reshape(weights, (1,X.shape[1]))
  
  return bias,weights

获取随机值来初始化我们的参数

维度:偏差 = (1, 1) & 权重 = (1, 3)

8. 第 8 步:

接下来,我们正在执行前向传播步骤。此步骤基于以下公式。

#Predict the value of target variable based on the random weights:
def predict(bias, weights, X):
  predicted_value = bias+np.dot(X,weights.T)
  return predicted_value

预测目标变量的值

维度:预测值 = (1, 1)+(200, 3)*(3,1) = (1, 1)+(200, 1) = (200, 1)

9. 第 9 步:

接下来,我们将计算与我们的预测相关的成本。此步骤基于以下公式。

#Calculate the cost:
def calculate_cost(Y, Y_pred):
  error = Y_pred - Y
  cost = np.sum((error)**2)/len(error)
  return cost

获取与预测相关的成本

维度:成本 = 标量值

10. 第 10 步:

接下来,我们使用梯度下降算法更新权重和偏差的参数值。此步骤基于以下公式。请注意,我们不对权重值求和的原因是我们的权重矩阵不是1*1矩阵。

#Update the parameter values:
def update_parameters(X,Y,Y_pred,bias,weights,lr):
  #Calculating the gradients:
  db = (np.sum(Y_pred-Y)*2)/len(Y)
  dw = (np.dot((Y_pred-Y).T,X)*2)/len(Y)

  #Updating the parameters:
  bias = bias - lr*db
  weights = weights - lr*dw
  
  #Return the updated parameters:
  return bias, weights

使用梯度下降算法更新参数

维度:db = sum(200, 1) = (1 , 1)

维度:dw = (1, 200) * (200, 3) = (1, 3)

维度:偏差 = (1, 1) & 权重 = (1, 3)

11. 第 11 步:

接下来,我们将使用刚刚定义的所有函数来运行梯度下降算法。此外,我们正在创建一个名为的空列表cost_list来存储所有迭代的成本值。我们将使用此列表在后续步骤中绘制图表。

#The main function to run the gradient descent algorithm:
def run_mini_batch_gradient_descent(X,Y,lr,iter):
  #Create an empty list to store cost values:
  cost_list = []

  #Get the initial values of weights and bias:
  bias, weights = initialize_weights(X.shape[1])

  for i in range(iter):
    #Shuffle indices:
    shuffled_indices = np.random.permutation(len(Y))
    #Get a random index:
    i = np.random.randint(0,len(X)-20)

    #Get a random sample of 20 examples:
    X_sample = X.iloc[shuffled_indices[i:i+20]]
    Y_sample = Y[shuffled_indices[i:i+20]]

    #Predict the value of the target variable:
    Y_pred = predict(bias, weights, X_sample)

    #Calculate the cost associated with prediction:
    cost = calculate_cost(Y_sample, Y_pred)

    #Append the cost to the list:
    cost_list.append(cost)

    #Update the parameters using gradient descent:
    bias, weights = update_parameters(X_sample,Y_sample,Y_pred,bias,weights,lr)
  
  #Return the cost list:
  return bias, weights,cost_list

小批量梯度下降算法

12. 第 12 步:

接下来,我们实际上是在调用函数来获取最终结果。请注意,我们运行的是200 iterations. 此外,我们在这里指定了learning rate of 0.01.

#Run the gradient descent algorithm:
bias, weights,cost = run_mini_batch_gradient_descent(X,Y,lr=0.01,iter=200)

运行小批量梯度下降算法 200 次迭代

13. 第 13 步:

接下来,我们在final weights完成所有迭代后打印值。

#Print the final values of weights:
print("Weights=",weights)

#Output:
Weights= [[3.81174521 2.74254003 0.03512562]]

在 200 次迭代后打印权重的最终值

14. 第 14 步:

接下来,我们在final bias完成所有迭代后打印值。

#Print the final value of bias:
print("Bias=",bias)

#Output:
Bias= [[11.15321194]]

在 200 次迭代后打印偏差的最终值

15. 第 15 步:

接下来,我们正在绘制 的图形iterations vs. cost

#Plot the graph of iter. vs cost:
plt.title("Iterations vs. Cost")
plt.xlabel("Iterations")
plt.ylabel("MSE cost")
plt.plot(cost)
plt.plot(cost,label="Mini Batch Gradient Descent")
plt.legend()
plt.show()

16. 第 16 步:

接下来,我们绘制两个具有不同学习率的图,以查看学习率在优化中的影响。在下图中,我们可以看到学习率较高(0.01)的图比学习率较慢的图收敛得更快(0.001)。其背后的原因是学习率较低的图采用较小的步长。

#Run the gradient descent algorithm:
bias1, weights1, cost1 = run_mini_batch_gradient_descent(X,Y,lr=0.01,iter=1000)
bias2, weights2, cost2 = run_mini_batch_gradient_descent(X,Y,lr=0.001,iter=1000)

#Plot the graphs:
plt.title("Iterations vs. Cost")
plt.xlabel("Iterations")
plt.ylabel("MSE cost")
plt.plot(cost1,label="LR=0.01")
plt.plot(cost2,label="LR=0.001")
plt.legend()
plt.show()

绘制不同学习率的批量梯度下降算法图

17. 第 17 步:

把它们放在一起。

#Fetch the data file from GitHub repository:
!wget https://raw.githubusercontent.com/Pratik-Shukla-22/Gradient-Descent/main/Advertising.csv

#Import the required libraries:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#Read the data file:
data = pd.read_csv("Advertising.csv")
data.head()

#Define the feature and target variables:
X = data[["TV","radio","newspaper"]]
Y = data["sales"]

#Reshape the data in Y:
Y = np.asarray(Y)
Y = np.reshape(Y,(Y.shape[0],1))

#Normalize the data:
X = (X - X.mean())/X.std()
Y = Y - Y.mean()/Y.std()

#Function to get intial weights and bias:
def initialize_weights(n_features):
  bias = np.random.random(1)
  weights = np.random.random(n_features)

  #Reshape the bias and weights:
  bias = np.reshape(bias,(1,1))
  weights = np.reshape(weights, (1,X.shape[1]))
  
  return bias,weights
  
#Predict the value of target variable based on the random weights:
def predict(bias, weights, X):
  predicted_value = bias+np.dot(X,weights.T)
  return predicted_value
  
#Calculate the cost:
def calculate_cost(Y, Y_pred):
  error = Y_pred - Y
  cost = np.sum((error)**2)/len(error)
  return cost
  
#Update the parameter values:
def update_parameters(X,Y,Y_pred,bias,weights,lr):
  #Calculating the gradients:
  db = (np.sum(Y_pred-Y)*2)/len(Y)
  dw = (np.dot((Y_pred-Y).T,X)*2)/len(Y)

  #Updating the parameters:
  bias = bias - lr*db
  weights = weights - lr*dw
  
  #Return the updated parameters:
  return bias, weights
  
#The main function to run the gradient descent algorithm:
def run_mini_batch_gradient_descent(X,Y,lr,iter):
  #Create an empty list to store cost values:
  cost_list = []

  #Get the initial values of weights and bias:
  bias, weights = initialize_weights(X.shape[1])

  for i in range(iter):
    #Shuffle indices:
    shuffled_indices = np.random.permutation(len(Y))
    #Get a random index:
    i = np.random.randint(0,len(X)-20)

    #Get a random sample of 20 examples:
    X_sample = X.iloc[shuffled_indices[i:i+20]]
    Y_sample = Y[shuffled_indices[i:i+20]]

    #Predict the value of the target variable:
    Y_pred = predict(bias, weights, X_sample)

    #Calculate the cost associated with prediction:
    cost = calculate_cost(Y_sample, Y_pred)

    #Append the cost to the list:
    cost_list.append(cost)

    #Update the parameters using gradient descent:
    bias, weights = update_parameters(X_sample,Y_sample,Y_pred,bias,weights,lr)
  
  #Return the cost list:
  return bias, weights,cost_list
  
#Run the gradient descent algorithm:
bias, weights,cost = run_mini_batch_gradient_descent(X,Y,lr=0.01,iter=200)

#Print the final values of weights:
print("Weights=",weights)

#Print the final value of bias:
print("Bias=",bias)

#Plot the graph of iter. vs cost:
plt.title("Iterations vs. Cost")
plt.xlabel("Iterations")
plt.ylabel("MSE cost")
plt.plot(cost)
plt.plot(cost,label="Mini Batch Gradient Descent")
plt.legend()
plt.show()

#Run the gradient descent algorithm:
bias1, weights1, cost1 = run_mini_batch_gradient_descent(X,Y,lr=0.01,iter=1000)
bias2, weights2, cost2 = run_mini_batch_gradient_descent(X,Y,lr=0.001,iter=1000)

#Plot the graphs:
plt.title("Iterations vs. Cost")
plt.xlabel("Iterations")
plt.ylabel("MSE cost")
plt.plot(cost1,label="LR=0.01")
plt.plot(cost2,label="LR=0.001")
plt.legend()
plt.show()

计算:

现在,让我们统计一下在实现批量梯度下降算法时执行的计算次数。

**偏差:(**训练示例)x(迭代)x(参数)= 20 * 200 * 1 = 4000

**权重:(**训练示例)x(迭代)x(参数)= 20 * 200 * 3 = 12000

图比较:

尾注:

就这样,我们到了梯度下降系列的结尾!在本期文章中,我们深入研究了代码,以了解三种主要类型的梯度下降算法如何彼此相邻地执行,并通过这些方便的注释进行了总结:

1.批量梯度下降
精度→高
时间→更多

2.随机梯度下降
精度→低
时间→少

3. Mini-Batch梯度下降
精度→中等
时间→中等

源码:

以上所有代码请关注公众号: 猛男技术控,回复梯度下降 即可获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猛男技术控

感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值