随机梯度下降的批量大小是训练数据的长度而不是 1?
Batch size for Stochastic gradient descent is length of training data and not 1?
我正在尝试绘制使用批量梯度下降、随机梯度下降和小批量随机梯度下降时的不同学习结果。
无论我在哪里看,我都读到 batch_size=1 与普通 SGD 相同,batch_size=len(train_data) 与具有相同批量梯度下降。
我知道随机梯度下降是指每次更新只使用一个数据样本,批量梯度下降使用整个训练数据集来计算 objective 函数/更新的梯度。
然而,在使用 keras 实现 batch_size 时,情况似乎恰恰相反。以我的代码为例,我将 batch_size 设置为等于 training_data
的长度
input_size = len(train_dataset.keys())
output_size = 10
hidden_layer_size = 250
n_epochs = 250
weights_initializer = keras.initializers.GlorotUniform()
#A function that trains and validates the model and returns the MSE
def train_val_model(run_dir, hparams):
model = keras.models.Sequential([
#Layer to be used as an entry point into a Network
keras.layers.InputLayer(input_shape=[len(train_dataset.keys())]),
#Dense layer 1
keras.layers.Dense(hidden_layer_size, activation='relu',
kernel_initializer = weights_initializer,
name='Layer_1'),
#Dense layer 2
keras.layers.Dense(hidden_layer_size, activation='relu',
kernel_initializer = weights_initializer,
name='Layer_2'),
#activation function is linear since we are doing regression
keras.layers.Dense(output_size, activation='linear', name='Output_layer')
])
#Use the stochastic gradient descent optimizer but change batch_size to get BSG, SGD or MiniSGD
optimizer = tf.keras.optimizers.SGD(learning_rate=0.001, momentum=0.0,
nesterov=False)
#Compiling the model
model.compile(optimizer=optimizer,
loss='mean_squared_error', #Computes the mean of squares of errors between labels and predictions
metrics=['mean_squared_error']) #Computes the mean squared error between y_true and y_pred
# initialize TimeStopping callback
time_stopping_callback = tfa.callbacks.TimeStopping(seconds=5*60, verbose=1)
#Training the network
history = model.fit(normed_train_data, train_labels,
epochs=n_epochs,
batch_size=hparams['batch_size'],
verbose=1,
#validation_split=0.2,
callbacks=[tf.keras.callbacks.TensorBoard(run_dir + "/Keras"), time_stopping_callback])
return history
train_val_model("logs/sample", {'batch_size': len(normed_train_data)})
当 运行 时,输出似乎显示每个时期的单个更新,即 SGD
:
从每个纪元的下方可以看出,它表示 1/1,我认为这意味着单次更新迭代。另一方面,如果我设置 batch_size=1 我得到 90000/90000,这是我整个数据集的大小(训练时间明智这也有意义)。
所以,我的问题是,batch_size=1 实际上是批量梯度下降而不是随机梯度下降,batch_size=len(train_data) 实际上是随机梯度下降而不是随机梯度下降批量梯度下降?
batch_size
是每次更新的大小。
这里,batch_size=1
表示每次更新的大小为1
个样本。根据您的定义,这将是 SGD。
如果你有 batch_size=len(train_data)
,这意味着每次更新你的权重都需要从你的整个数据集中得到梯度。这实际上只是很好的旧梯度下降。
批量梯度下降在中间某处,其中 batch_size 不是 1 并且批量大小不是您的整个训练数据集。以 32
为例。批量梯度下降会每 32 个示例更新一次权重,因此它仅用 1 个示例(异常值可能会产生很大影响)就可以消除 SGD 的鲁棒性,并且具有 SGD 优于常规梯度的优势 descne.t
实际上有三 (3) 个案例:
batch_size = 1
表示确实是随机梯度下降(SGD)
- 一个
batch_size
等于整个训练数据就是(batch)梯度下降(GD)
- 中间情况(在实践中实际使用)通常被称为mini-batch梯度下降
有关更多详细信息和参考,请参阅 A Gentle Introduction to Mini-Batch Gradient Descent and How to Configure Batch Size。事实上,在实践中,当我们说“SGD”时,我们通常指的是“小批量 SGD”。
这些定义实际上完全符合您的实验报告:
With batch_size=len(train_data)
(GD case),每个时期确实只需要 one 更新(因为只有一批),因此1/1
Keras 输出中的指示。
相比之下,对于 batch_size = 1
(SGD 情况),您希望更新与训练数据中的样本一样多(因为这是现在的批次数),即 90000,因此 Keras 输出中的 90000/90000
指示。
即每个纪元的更新次数(Keras 指示)等于使用的批次数(并且 not 等于批次大小)。
我正在尝试绘制使用批量梯度下降、随机梯度下降和小批量随机梯度下降时的不同学习结果。
无论我在哪里看,我都读到 batch_size=1 与普通 SGD 相同,batch_size=len(train_data) 与具有相同批量梯度下降。
我知道随机梯度下降是指每次更新只使用一个数据样本,批量梯度下降使用整个训练数据集来计算 objective 函数/更新的梯度。
然而,在使用 keras 实现 batch_size 时,情况似乎恰恰相反。以我的代码为例,我将 batch_size 设置为等于 training_data
的长度input_size = len(train_dataset.keys())
output_size = 10
hidden_layer_size = 250
n_epochs = 250
weights_initializer = keras.initializers.GlorotUniform()
#A function that trains and validates the model and returns the MSE
def train_val_model(run_dir, hparams):
model = keras.models.Sequential([
#Layer to be used as an entry point into a Network
keras.layers.InputLayer(input_shape=[len(train_dataset.keys())]),
#Dense layer 1
keras.layers.Dense(hidden_layer_size, activation='relu',
kernel_initializer = weights_initializer,
name='Layer_1'),
#Dense layer 2
keras.layers.Dense(hidden_layer_size, activation='relu',
kernel_initializer = weights_initializer,
name='Layer_2'),
#activation function is linear since we are doing regression
keras.layers.Dense(output_size, activation='linear', name='Output_layer')
])
#Use the stochastic gradient descent optimizer but change batch_size to get BSG, SGD or MiniSGD
optimizer = tf.keras.optimizers.SGD(learning_rate=0.001, momentum=0.0,
nesterov=False)
#Compiling the model
model.compile(optimizer=optimizer,
loss='mean_squared_error', #Computes the mean of squares of errors between labels and predictions
metrics=['mean_squared_error']) #Computes the mean squared error between y_true and y_pred
# initialize TimeStopping callback
time_stopping_callback = tfa.callbacks.TimeStopping(seconds=5*60, verbose=1)
#Training the network
history = model.fit(normed_train_data, train_labels,
epochs=n_epochs,
batch_size=hparams['batch_size'],
verbose=1,
#validation_split=0.2,
callbacks=[tf.keras.callbacks.TensorBoard(run_dir + "/Keras"), time_stopping_callback])
return history
train_val_model("logs/sample", {'batch_size': len(normed_train_data)})
当 运行 时,输出似乎显示每个时期的单个更新,即 SGD
从每个纪元的下方可以看出,它表示 1/1,我认为这意味着单次更新迭代。另一方面,如果我设置 batch_size=1 我得到 90000/90000,这是我整个数据集的大小(训练时间明智这也有意义)。
所以,我的问题是,batch_size=1 实际上是批量梯度下降而不是随机梯度下降,batch_size=len(train_data) 实际上是随机梯度下降而不是随机梯度下降批量梯度下降?
batch_size
是每次更新的大小。
这里,batch_size=1
表示每次更新的大小为1
个样本。根据您的定义,这将是 SGD。
如果你有 batch_size=len(train_data)
,这意味着每次更新你的权重都需要从你的整个数据集中得到梯度。这实际上只是很好的旧梯度下降。
批量梯度下降在中间某处,其中 batch_size 不是 1 并且批量大小不是您的整个训练数据集。以 32
为例。批量梯度下降会每 32 个示例更新一次权重,因此它仅用 1 个示例(异常值可能会产生很大影响)就可以消除 SGD 的鲁棒性,并且具有 SGD 优于常规梯度的优势 descne.t
实际上有三 (3) 个案例:
batch_size = 1
表示确实是随机梯度下降(SGD)- 一个
batch_size
等于整个训练数据就是(batch)梯度下降(GD) - 中间情况(在实践中实际使用)通常被称为mini-batch梯度下降
有关更多详细信息和参考,请参阅 A Gentle Introduction to Mini-Batch Gradient Descent and How to Configure Batch Size。事实上,在实践中,当我们说“SGD”时,我们通常指的是“小批量 SGD”。
这些定义实际上完全符合您的实验报告:
With
batch_size=len(train_data)
(GD case),每个时期确实只需要 one 更新(因为只有一批),因此1/1
Keras 输出中的指示。相比之下,对于
batch_size = 1
(SGD 情况),您希望更新与训练数据中的样本一样多(因为这是现在的批次数),即 90000,因此 Keras 输出中的90000/90000
指示。
即每个纪元的更新次数(Keras 指示)等于使用的批次数(并且 not 等于批次大小)。