设置keras层的权重

set weights of keras layers

我正在尝试使用遗传算法和 Keras 来制作贪吃蛇游戏。

我现在的问题如下:

我用每个 X 基因创建蛇的初始种群,其中 X 是 NUMBER_WEIGHTS:

INPUT = 24
NEURONS_HIDDEN_1 = 16
NEURONS_HIDDEN_2 = 16
OUTPUT = 3
NUMBER_WEIGHTS = INPUT * NEURONS_HIDDEN_1 + NEURONS_HIDDEN_1 * NEURONS_HIDDEN_2 + NEURONS_HIDDEN_2 * OUTPUT

我这样创建初始种群:

population = numpy.random.choice(numpy.arange(-1, 1, step=0.01), size=(config.NUMBER_OF_POPULATION, config.NUMBER_WEIGHTS))

我有一个for循环,对于我人口中的每条蛇启动pygame脚本,在pygame脚本中我有Keras NN,但我想传递我的权重已经生成到NN了。

我的NN目前是这样的:

from keras.layers import Dense, Activation
from keras.models import Sequential
from keras.optimizers import SGD

from utils import config
def neural_net(weights):
    model = Sequential()

    model.add(Dense(config.INPUT, input_shape=(config.INPUT,)))
    model.add(Activation('relu'))
    # create the dense input layer
    # model.add(Dense(config.INPUT, activation=keras.activations.relu(4,), input_dim=4))
    # model.add(Activation('sigmoid'))

    # create first hidden layer
    model.add(Dense(config.NEURONS_HIDDEN_1, input_shape=(config.INPUT,)))
    model.add(Activation('relu'))
    # create second hidden layer
    model.add(Dense(config.NEURONS_HIDDEN_2, input_shape=(config.NEURONS_HIDDEN_1,)))
    model.add(Activation('relu'))
    # create output layer
    model.add(Dense(config.OUTPUT, input_shape=(config.NEURONS_HIDDEN_2,)))
    model.add(Activation('softmax'))

    print(weights.shape[0])
    model.set_weights(weights)

    # create the optimizer (Stochastic Gradient Descent)
    sgd = SGD(lr=0.01, decay=0.0, momentum=0.0, nesterov=False)
    # Use mean squared error loss and SGD as optimizer
    model.compile(loss='mse', optimizer=sgd)

    return model

但是model.set_weights(权重)return这个异常:

File "neural_network.py", line 28, in neural_net
    model.set_weights(weights)
  File "C:\Users\Davide\AppData\Local\Programs\Python\Python37\lib\site-packages\keras\engine\network.py", line 527, in set_weights
    K.batch_set_value(tuples)
  File "C:\Users\Davide\AppData\Local\Programs\Python\Python37\lib\site-packages\keras\backend\tensorflow_backend.py", line 2960, in batch_set_value
    tf_keras_backend.batch_set_value(tuples)
  File "C:\Users\Davide\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow_core\python\keras\backend.py", line 3323, in batch_set_value
    x.assign(np.asarray(value, dtype=dtype(x)))
  File "C:\Users\Davide\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow_core\python\ops\resource_variable_ops.py", line 819, in assign
    self._shape.assert_is_compatible_with(value_tensor.shape)
  File "C:\Users\Davide\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow_core\python\framework\tensor_shape.py", line 1110, in assert_is_compatible_with
    raise ValueError("Shapes %s and %s are incompatible" % (self, other))
ValueError: Shapes (24, 24) and () are incompatible

Process finished with exit code 1

我们在隐藏层 1 上有 24 个输入 * 16 个神经元,然后在隐藏层 2 上有 16 个神经元 * 16 个神经元,最后在隐藏层 2 上有 16 个神经元 * 3 个输入 = 24*16+16*16+16*3 = 688

print(weights.shape[0])

是688。为什么我不能设置正确的权重?

第一次使用 AI 做项目,所以我可能完全误解了它是如何工作的

我确定模型权重和您提供的权重形状不匹配。您需要提供每个图层对应的权重,如下例所示。

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

def create_model():
  model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28),name='flatten'),
    tf.keras.layers.Dense(128, activation='relu',name='dense1'),
    tf.keras.layers.Dropout(0.2,name = 'dropout'),
    tf.keras.layers.Dense(10, name='dense2')
  ])

  model.compile(optimizer='adam',
                loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), #'sparse_categorical_crossentropy',
                metrics=['accuracy'])
  return model

# create model architecture and compile
model = create_model()
model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test) 

#saving weights
model.save_weights('./model_weights', save_format='tf')

#layer weights from the model 
layer_dict = dict([(layer.name, layer) for layer in model.layers])
print(layer_dict)

# creating the same model architecture and compile
loaded_model = create_model()

# This initializes the variables used by the optimizers,
# as well as any stateful metric variables
loaded_model.train_on_batch(x_train[:1], y_train[:1])

# loading the weights from base_model
for layer in loaded_model.layers:
  layer_name = layer.name
  print(layer.name)
  layer.set_weights(layer_dict[layer_name].get_weights())

# accessing weights of a layer by its name
layer_dict[layer_name].get_weights() 

# check the evaluation before and after are same
loaded_model.evaluate(x_test, y_test)

print(loaded_model.weights)

print(model.weights)

希望这个例子能为您解决问题提供一些见解。
完整代码 here 供您参考。