【问题标题】:How to implement momentum-based stochastic gradient descent (SGD)如何实现基于动量的随机梯度下降 (SGD)
【发布时间】:2017-02-12 18:57:26
【问题描述】:

我正在使用 python 代码 network3.py (http://neuralnetworksanddeeplearning.com/chap6.html) 来开发卷积神经网络。现在我想通过添加动量学习规则来稍微修改代码如下:

velocity = momentum_constant * velocity - learning_rate * gradient
params = params + velocity

有人知道怎么做吗?特别是,如何设置或初始化速度?我在下面发布了 SGD 的代码:

def __init__(self, layers, mini_batch_size):
    """Takes a list of `layers`, describing the network architecture, and
    a value for the `mini_batch_size` to be used during training
    by stochastic gradient descent.

    """
    self.layers = layers
    self.mini_batch_size = mini_batch_size
    self.params = [param for layer in self.layers for param in layer.params]
    self.x = T.matrix("x")
    self.y = T.ivector("y")
    init_layer = self.layers[0]
    init_layer.set_inpt(self.x, self.x, self.mini_batch_size)
    for j in xrange(1, len(self.layers)):
        prev_layer, layer  = self.layers[j-1], self.layers[j]
        layer.set_inpt(
            prev_layer.output, prev_layer.output_dropout, self.mini_batch_size)
    self.output = self.layers[-1].output
    self.output_dropout = self.layers[-1].output_dropout


def SGD(self, training_data, epochs, mini_batch_size, eta,
        validation_data, test_data, lmbda=0.0):
    """Train the network using mini-batch stochastic gradient descent."""
    training_x, training_y = training_data
    validation_x, validation_y = validation_data
    test_x, test_y = test_data

    # compute number of minibatches for training, validation and testing
    num_training_batches = size(training_data)/mini_batch_size
    num_validation_batches = size(validation_data)/mini_batch_size
    num_test_batches = size(test_data)/mini_batch_size

    # define the (regularized) cost function, symbolic gradients, and updates
    l2_norm_squared = sum([(layer.w**2).sum() for layer in self.layers])
    cost = self.layers[-1].cost(self)+\
           0.5*lmbda*l2_norm_squared/num_training_batches
    grads = T.grad(cost, self.params)
    updates = [(param, param-eta*grad)
               for param, grad in zip(self.params, grads)]

    # define functions to train a mini-batch, and to compute the
    # accuracy in validation and test mini-batches.
    i = T.lscalar() # mini-batch index
    train_mb = theano.function(
        [i], cost, updates=updates,
        givens={
            self.x:
            training_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
            self.y:
            training_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
        })
    validate_mb_accuracy = theano.function(
        [i], self.layers[-1].accuracy(self.y),
        givens={
            self.x:
            validation_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
            self.y:
            validation_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
        })
    test_mb_accuracy = theano.function(
        [i], self.layers[-1].accuracy(self.y),
        givens={
            self.x:
            test_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
            self.y:
            test_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
        })
    self.test_mb_predictions = theano.function(
        [i], self.layers[-1].y_out,
        givens={
            self.x:
            test_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
        })
    # Do the actual training
    best_validation_accuracy = 0.0
    for epoch in xrange(epochs):
        for minibatch_index in xrange(num_training_batches):
            iteration = num_training_batches*epoch+minibatch_index
            if iteration % 1000 == 0:
                print("Training mini-batch number {0}".format(iteration))
            cost_ij = train_mb(minibatch_index)
            if (iteration+1) % num_training_batches == 0:
                validation_accuracy = np.mean(
                    [validate_mb_accuracy(j) for j in xrange(num_validation_batches)])
                print("Epoch {0}: validation accuracy {1:.2%}".format(
                    epoch, validation_accuracy))
                if validation_accuracy >= best_validation_accuracy:
                    print("This is the best validation accuracy to date.")
                    best_validation_accuracy = validation_accuracy
                    best_iteration = iteration
                    if test_data:
                        test_accuracy = np.mean(
                            [test_mb_accuracy(j) for j in xrange(num_test_batches)])
                        print('The corresponding test accuracy is {0:.2%}'.format(
                            test_accuracy))

【问题讨论】:

    标签: python momentum


    【解决方案1】:

    我只是从头开始编写 SDG(不使用 theano),但从您的代码来看,您需要

    1) 用一堆零(每个渐变一个)启动velocities

    2) 在您的更新中包含速度;像

    updates = [(param, param-eta*grad +momentum_constant*vel)
               for param, grad, vel in zip(self.params, grads, velocities)]
    

    3) 修改您的训练函数以返回每次迭代的梯度,以便您可以更新velocities

    【讨论】:

    • 您能否在答案中写出 1) 和 3) 的代码。我只是 Python 的初学者。 theano.function 是您提到的训练功能吗?谢谢!!
    • 您的训练函数是一个 theano 函数,但并非所有的 theano 函数都是训练函数。例如,仅在您发布的代码中就有 3 个不同的实例。这听起来可能很苛刻,但如果你不知道如何用零初始化一个数组(第 1 点),那么你应该 a)暂时忘记机器学习,b)在 numpy 中做一些科学编程的教程。 Theano 也是如此。其他一切都将是黑魔法(对你来说)。
    • 这是我的课堂作业。我必须努力继续前进!
    猜你喜欢
    • 2021-02-20
    • 2016-09-25
    • 2018-07-14
    • 2011-07-04
    • 1970-01-01
    • 2021-09-28
    • 2018-05-17
    • 1970-01-01
    • 2016-06-13
    相关资源
    最近更新 更多