简体   繁体   中英

set weights of keras layers

I'm trying to do the game Snake using genetic algorithm and Keras.

My problem, right now, is the following:

I create the initial population of snake with X genes each, where X is 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

and i create the initial population like this:

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

I have a for cycle that for each snake inside my population start the pygame script, inside the pygame script i have the Keras NN, but i would like to pass the weights that i have generated to the NN.

My NN is like that for now:

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

But model.set_weights(weights) return this exception:

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

We have 24 input * 16 neuros on the hidden layer one, then 16 neurons * 16 neurons on layer hidden 2 and finally 16 neurons hidden layer 2 * 3 inputs = 24*16+16*16+16*3 = 688

And

print(weights.shape[0])

is 688. So why i can't set the correct weights?

First time doing a project using AI, so i may have completely misunderstood how this works

I am sure there is a shape mismatch in the weights of model and the weights you are providing. You need to provide weights corresponding to each layer as shown in the example below.

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)

Hope this example will give some insights for you to solve your problem.
Full code is here for your reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM