【问题标题】:How to update weights manually with Keras如何使用 Keras 手动更新权重
【发布时间】:2018-12-23 13:12:36
【问题描述】:

我正在使用 Keras 构建 LSTM,并通过使用外部成本函数进行梯度下降来调整它。所以权重更新为:

weights := weights + alpha* gradient(cost)

我知道我可以使用keras.getweights() 获得权重,但是如何进行梯度下降并更新所有权重并相应地更新权重。我尝试使用initializer,但我仍然没有弄明白。我只找到了一些与 tensorflow 相关的代码,但我不知道如何将其转换为 Keras。

任何帮助、提示或建议将不胜感激!

【问题讨论】:

    标签: python performance keras recurrent-neural-network reinforcement-learning


    【解决方案1】:

    keras.layer.set_weights() 就是你要找的东西:

    import numpy as np
    from keras.layers import Dense
    from keras.models import Sequential
    
    model = Sequential()
    model.add(Dense(10, activation='relu', input_shape=(10,)))
    model.add(Dense(5, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam', loss='categorical_crossentropy')
    
    a = np.array(model.get_weights())         # save weights in a np.array of np.arrays
    model.set_weights(a + 1)                  # add 1 to all weights in the neural network
    b = np.array(model.get_weights())         # save weights a second time in a np.array of np.arrays
    print(b - a)                              # print changes in weights
    

    查看 keras 文档here 的相应页面。

    【讨论】:

    • 更正:get_weights() 返回np.arrays 的列表,而不是np.array
    • 还要注意 .assign 或 .assign_add 函数,它们为变量赋值(例如,你通过 model.trainable_weights 获得的那些)
    【解决方案2】:

    您需要一些 TensorFlow 来计算符号梯度。这是一个使用 Keras 的玩具示例,然后深入挖掘以在 TensorFlow 中手动执行逐步下降。

    from keras.models import Sequential
    from keras.layers import Dense, Activation
    from keras import backend as k
    from keras import losses
    import numpy as np
    import tensorflow as tf
    from sklearn.metrics import mean_squared_error
    from math import sqrt
    
    model = Sequential()
    model.add(Dense(12, input_dim=8, kernel_initializer='uniform', activation='relu'))
    model.add(Dense(8, kernel_initializer='uniform', activation='relu'))
    model.add(Dense(8, kernel_initializer='uniform', activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    
    inputs = np.random.random((1, 8))
    outputs = model.predict(inputs)
    targets = np.random.random((1, 8))
    rmse = sqrt(mean_squared_error(targets, outputs))
    
    print("===BEFORE WALKING DOWN GRADIENT===")
    print("outputs:\n", outputs)
    print("targets:\n", targets)
    print("RMSE:", rmse)
    
    
    def descend(steps=40, learning_rate=100.0, learning_decay=0.95):
        for s in range(steps):
    
            # If your target changes, you need to update the loss
            loss = losses.mean_squared_error(targets, model.output)
    
            #  ===== Symbolic Gradient =====
            # Tensorflow Tensor Object
            gradients = k.gradients(loss, model.trainable_weights)
    
            # ===== Numerical gradient =====
            # Numpy ndarray Objcet
            evaluated_gradients = sess.run(gradients, feed_dict={model.input: inputs})
    
            # For every trainable layer in the network
            for i in range(len(model.trainable_weights)):
    
                layer = model.trainable_weights[i]  # Select the layer
    
                # And modify it explicitly in TensorFlow
                sess.run(tf.assign_sub(layer, learning_rate * evaluated_gradients[i]))
    
            # decrease the learning rate
            learning_rate *= learning_decay
    
            outputs = model.predict(inputs)
            rmse = sqrt(mean_squared_error(targets, outputs))
    
            print("RMSE:", rmse)
    
    
    if __name__ == "__main__":
        # Begin TensorFlow
        sess = tf.InteractiveSession()
        sess.run(tf.initialize_all_variables())
    
        descend(steps=5)
    
        final_outputs = model.predict(inputs)
        final_rmse = sqrt(mean_squared_error(targets, final_outputs))
    
        print("===AFTER STEPPING DOWN GRADIENT===")
        print("outputs:\n", final_outputs)
        print("targets:\n", targets)
    

    结果:

    ===BEFORE WALKING DOWN GRADIENT===
    outputs:
     [[0.49995303 0.5000101  0.50001436 0.50001544 0.49998832 0.49991882
      0.49994195 0.4999649 ]]
    targets:
     [[0.60111501 0.70807258 0.02058449 0.96990985 0.83244264 0.21233911
      0.18182497 0.18340451]]
    RMSE: 0.33518919408969455
    RMSE: 0.05748867468895
    RMSE: 0.03369414290610595
    RMSE: 0.021872132066183464
    RMSE: 0.015070048653579693
    RMSE: 0.01164369828903875
    ===AFTER STEPPING DOWN GRADIENT===
    outputs:
     [[0.601743   0.707857   0.04268148 0.9536494  0.8448022  0.20864952
      0.17241994 0.17464897]]
    targets:
     [[0.60111501 0.70807258 0.02058449 0.96990985 0.83244264 0.21233911
      0.18182497 0.18340451]]
    

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 2020-03-28
      • 2019-01-19
      • 1970-01-01
      相关资源
      最近更新 更多