установить вес слоев керас - PullRequest
0 голосов
/ 03 мая 2020

Я пытаюсь сделать игру Snake, используя алгоритм geneti c и 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 у меня есть NN Keras, но я бы хотел передать сгенерированные мной веса в 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 (weights) возвращает это исключение:

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

У нас есть 24 входных * 16 нейронов на скрытом слое один, затем 16 нейронов * 16 нейронов на скрытом слое 2 и, наконец, 16 нейронов скрытый слой 2 * 3 входа = 24 * 16 + 16 * 16 + 16 * 3 = 688

И

print(weights.shape[0])

- это 688. Так почему я не могу установить правильные веса?

Впервые я делаю проект с использованием ИИ, так что я, возможно, совершенно не понял, как это работает

1 Ответ

0 голосов
/ 03 мая 2020

Я уверен, что есть несоответствие формы весам модели и предоставленным вами весам. Вы должны предоставить веса, соответствующие каждому слою, как показано в примере ниже.

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)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...