Высокая скорость обучения делает обучение модели неудачным - PullRequest
0 голосов
/ 23 декабря 2018

Я просто тренирую трехслойную нейронную сеть softmax с тензорным потоком.Это из курса Эндрю Нга, 3.11 тензорного потока.Я изменяю код, чтобы увидеть тест и точность обучения в каждой эпохе.

Когда я увеличиваю скорость обучения, стоимость составляет около 1,9, а точность остается равной 1,66 ... 7.Я считаю, что чем выше скорость обучения, тем чаще это происходит.Когда learing_rate около 0,001, такая ситуация иногда случается.Когда learing_rate около 0,0001, такой ситуации не будет.

Я просто хочу знать почему.

Это некоторые выходные данные:

learing_rate = 1
Cost after epoch 0: 1312.153492
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 100: 1.918554
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 200: 1.897831
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 300: 1.907957
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 400: 1.893983
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 500: 1.920801
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667

learing_rate = 0.01
Cost after epoch 0: 2.906999
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 100: 1.847423
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 200: 1.847042
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 300: 1.847402
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 400: 1.847197
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667
Cost after epoch 500: 1.847694
Train Accuracy: 0.16666667
Test Accuracy: 0.16666667

Это код:

def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.0001,
          num_epochs = 1500, minibatch_size = 32, print_cost = True):
    """
    Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX.

    Arguments:
    X_train -- training set, of shape (input size = 12288, number of training examples = 1080)
    Y_train -- test set, of shape (output size = 6, number of training examples = 1080)
    X_test -- training set, of shape (input size = 12288, number of training examples = 120)
    Y_test -- test set, of shape (output size = 6, number of test examples = 120)
    learning_rate -- learning rate of the optimization
    num_epochs -- number of epochs of the optimization loop
    minibatch_size -- size of a minibatch
    print_cost -- True to print the cost every 100 epochs

    Returns:
    parameters -- parameters learnt by the model. They can then be used to predict.
    """

    ops.reset_default_graph()                         # to be able to rerun the model without overwriting tf variables
    tf.set_random_seed(1)                             # to keep consistent results
    seed = 3                                          # to keep consistent results
    (n_x, m) = X_train.shape                          # (n_x: input size, m : number of examples in the train set)
    n_y = Y_train.shape[0]                            # n_y : output size
    costs = []                                        # To keep track of the cost

    # Create Placeholders of shape (n_x, n_y)
    ### START CODE HERE ### (1 line)
    X, Y = create_placeholders(n_x, n_y)
    ### END CODE HERE ###

    # Initialize parameters
    ### START CODE HERE ### (1 line)
    parameters = initialize_parameters()
    ### END CODE HERE ###

    # Forward propagation: Build the forward propagation in the tensorflow graph
    ### START CODE HERE ### (1 line)
    Z3 = forward_propagation(X, parameters)
    ### END CODE HERE ###

    # Cost function: Add cost function to tensorflow graph
    ### START CODE HERE ### (1 line)
    cost = compute_cost(Z3, Y)
    ### END CODE HERE ###

    # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer.
    ### START CODE HERE ### (1 line)
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
    ### END CODE HERE ###

    # Initialize all the variables
    init = tf.global_variables_initializer()
    # Calculate the correct predictions
    correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y))

    # Calculate accuracy on the test set
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    # Start the session to compute the tensorflow graph
    with tf.Session() as sess:

        # Run the initialization
        sess.run(init)

        # Do the training loop
        for epoch in range(num_epochs):

            epoch_cost = 0.                       # Defines a cost related to an epoch
            num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set
            seed = seed + 1
            minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

            for minibatch in minibatches:

                # Select a minibatch
                (minibatch_X, minibatch_Y) = minibatch

                # IMPORTANT: The line that runs the graph on a minibatch.
                # Run the session to execute the "optimizer" and the "cost", the feedict should contain a minibatch for (X,Y).
                ### START CODE HERE ### (1 line)
                _ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})
                ### END CODE HERE ###

                epoch_cost += minibatch_cost / num_minibatches

            # Print the cost every epoch
            if print_cost == True and epoch % 100 == 0:
                print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
                print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
                print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))
            if print_cost == True and epoch % 5 == 0:
                costs.append(epoch_cost)

        # plot the cost
        plt.plot(np.squeeze(costs))
        plt.ylabel('cost')
        plt.xlabel('iterations (per tens)')
        plt.title("Learning rate =" + str(learning_rate))
        plt.show()

        # lets save the parameters in a variable
        parameters = sess.run(parameters)
        print ("Parameters have been trained!")


        print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
        print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))

        return parameters

parameters = model(X_train, Y_train, X_test, Y_test,learning_rate=0.001)

Ответы [ 3 ]

0 голосов
/ 23 декабря 2018

При более высокой скорости обучения конвергенция может происходить быстро.Но когда фактический разрыв между текущим значением и локальными минимумами очень меньше по сравнению со скоростью обучения, модель будет колебаться вокруг локальных минимумов, не сходясь к ней.

Когда скорость обучения очень мала, это может не произойти.Но сближение займет много времени.Поэтому в качестве скорости обучения лучше использовать оптимальное значение.

0 голосов
/ 23 декабря 2018

Читая другие ответы, я все еще не совсем удовлетворен несколькими моментами, тем более, что я чувствую, что эту проблему можно (и было) хорошо визуализировать, чтобы коснуться приведенных здесь аргументов.

Во-первых, я согласен с большей частью того, что @Shubham Panchal упомянул в своем ответе, и он упоминает некоторые разумные начальные значения:Высокий уровень обучения обычно приводит к тому, что вы не в конвергенции, а в бесконечном колебании вокруг решения.Слишком малая скорость обучения, как правило, приводит к очень медленной конвергенции, и вы можете выполнить много «дополнительной работы».Визуализировано в этой инфографике здесь (игнорируйте параметр) для пространства двухмерных параметров: gradient descent with different parameters

Вероятно, ваша проблема связана с «чем-то похожим», как в правильном изображении.Кроме того, и это то, что не было упомянуто до сих пор, это то, что оптимальная скорость обучения (если есть даже такая вещь) в значительной степени зависит от вашей конкретной постановки проблемы;для моих проблем плавная конвергенция могла бы быть с темпом обучения, величина которого отличается от вашей.(К сожалению) также имеет смысл просто опробовать несколько значений, чтобы сузить их, где вы можете достичь какого-то разумного результата, то есть того, что вы сделали в своем посте.

Кроме того, мы также можем рассмотреть возможные решенияк этой проблеме.Один из хитрых приемов, который мне нравится применять к моим моделям, заключается в том, чтобы время от времени снижать скорость обучения.Существуют различные доступные реализации этого в большинстве сред:

  • Keras позволяет устанавливать скорость обучения с помощью функции обратного вызова LearningRateScheduler.
  • PyTorchпозволяет вам напрямую управлять скоростью обучения следующим образом: optimizer.param_groups[0]['lr'] = new_value.
  • TensorFlow имеет несколько функций , которые позволяют вам затухать соответствующим образом.

Короче говоря,Идея состоит в том, чтобы начать с относительно высокой скорости обучения (я все же предпочитаю значения от 0,01 до 0,1 для начала), а затем постепенно уменьшать их, чтобы в конечном итоге вы достигли локального минимума.

Также обратите внимание, что существует целая область исследований на тему невыпуклых оптимизаций, то есть как убедиться, что вы в итоге нашли «наилучшее возможное» решение, а не просто застряли в локальном минимуме,Но я думаю, что это пока выходит за рамки.

0 голосов
/ 23 декабря 2018

С точки зрения градиентного спуска,

  1. Более высокие скорости обучения, такие как 1,0 и 1,5, заставляют оптимизатор делать большие шаги к минимумам функции потерь.Если скорость обучения равна 1, то изменение в весах больше.Из-за больших шагов иногда оптимизатор пропускает минимумы, и потери снова начинают увеличиваться.
  2. Оптимальными являются более низкие скорости обучения, такие как 0,001 и 0,01.Здесь мы делим изменение в весах на 100 или 1000, таким образом, делая его меньше.В результате оптимизатор делает меньшие шаги в направлении минимумов и, следовательно, не пропускает минимумы так легко.
  3. Более высокие скорости обучения делают модель сходящейся быстрее, но могут пропускать минимумы.Более низкие скорости обучения занимают много времени, но обеспечивают оптимальную конвергенцию.
...