如何使用 Keras 手动更新权重

问题描述 投票:0回答:3

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

weights := weights + alpha* gradient(cost)

我知道我可以用

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

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

python performance keras recurrent-neural-network reinforcement-learning
3个回答
25
投票

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 文档的相应页面这里


6
投票

您需要一些 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]]

0
投票

我从头开始制作了自己的神经网络,没有使用 keras,但问题是梯度变为零,所以我的权重没有更新 这是我的 bainary_crossentropy 导数 def BCE_d(y_true,y_pred): ε = 1e-15 y_pred = np.clip(y_pred, epsilon, 1 - epsilon) 返回(y_pred - y_true)/(y_pred *(1 - y_pred))

enter code here

请告诉我是否有任何问题,因为该值变得太高或太低

© www.soinside.com 2019 - 2024. All rights reserved.