Как сохранить / загрузить сериализованную модель tensorflow 2.3.1 (агент DoubleDuelingDQN) с пользовательскими аргументами?

#python #tensorflow #keras #agent #dqn

#python #тензорный поток #keras #агент #dqn

Вопрос:

После нескольких руководств и вопросов Stackoverflow мне удалось обучить моего агента Double Dueling DQN в моей пользовательской среде.

Теперь я не могу сохранить и загрузить сетевую модель моего агента с ее аргументом advantage() . Как мне сохранить и загрузить такие пользовательские сериализованные сети?

Python 3.8.5 Tensorflow 2.3.1 Keras 2.4.3

Мой подход до сих пор был простым:

 class DuelingDeepQNAgent():
    ....
    def load_model(self, model_name):
        self.q_network = load_model(model_name)
        self.target_network = load_model(model_name)

    def save_model(self, model_name):
        self.q_network.save(model_name, save_format='tf')
 

Загрузка сохраненной модели и продолжение обучения приводят к этой ошибке:

 agent = MyAgent.DuelingDeepQNAgent()
agent.load_model(model_name)
.... 
# within learning process
q_values = self.q_network.advantage(state)
 

Ошибка атрибута: объект ‘DuelingDeepQNetwork’ не имеет атрибута ‘преимущество’

Сеть:

 class DuelingDeepQNetwork(keras.Model):
    def __init__(self, input_shape, output_shape, n_filter=64, kernel_size=3, n_neurons1=256, n_neurons2=128):
        super(DuelingDeepQNetwork, self).__init__()

        self.input_layer = keras.layers.InputLayer(input_shape=(None, *input_shape))
        # self.lstm1 = keras.layers.LSTM(units=n_neurons1, activation='relu', stateful=True, return_state=True)
        self.conv1d1 = keras.layers.Conv1D(filters=n_filter, kernel_size=kernel_size, padding='same', activation='relu')
        self.pool1 = keras.layers.AvgPool1D(pool_size=2)
        self.conv1d2 = keras.layers.Conv1D(filters=n_filter, kernel_size=kernel_size, padding='same', activation='relu')
        self.pool2 = keras.layers.AvgPool1D(pool_size=2)
        self.flat1 = keras.layers.Flatten()
        self.dens_1 = keras.layers.Dense(n_neurons1, activation='relu')
        self.dens_2 = keras.layers.Dense(n_neurons2, activation='relu')

        self.V = keras.layers.Dense(1, activation=None)  # Value layer
        self.A = keras.layers.Dense(output_shape, activation=None)  # Advantage layer

    def call(self, state):
        x = self.input_layer(state)
        x = self.conv1d1(x)
        x = self.pool1(x)
        x = self.conv1d2(x)
        x = self.pool2(x)
        x = self.flat1(x)
        x = self.dens_1(x)
        x = self.dens_2(x)

        A = self.A(x)
        V = self.V(x)
        Q = V   (A - tf.math.reduce_mean(A, axis=1, keepdims=True))

        return Q

    def advantage(self, state):
        x = self.input_layer(state)
        x = self.conv1d1(x)
        x = self.pool1(x)
        x = self.conv1d2(x)
        x = self.pool2(x)
        x = self.flat1(x)
        x = self.dens_1(x)
        x = self.dens_2(x)

        A = self.A(x)
        return A
 

Ответ №1:

РЕДАКТИРОВАТЬ: в моем предыдущем ответе выдвигалась гипотеза о недостающей части кода, но я считаю, что приведенный ниже ответ на самом деле правильный.

На самом деле я немного поработал над аналогичной проблемой, проблема, с которой вы, вероятно, сталкиваетесь, заключается в том, что при загрузке сохраненной модели H5 она не загружает связанные функции пользовательского класса. Что вам нужно сделать, это сохранить / загрузить только веса, чтобы гарантировать сохранение методов класса.

 def save_model(self):
     self.q_network.save_weights("model_name") #no *.h5 extension
def load_model(self):
    self.q_network.load_weights("model_name")
 

Комментарии:

1. Спасибо за ваш совет! Сейчас я работаю над каким-то другим проектом. Когда я вернусь к своему проекту ML, я проверю ваш совет и отчитаюсь. В любом случае спасибо !! 🙂