设置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 供您参考。
我正在尝试使用遗传算法和 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 供您参考。