Keras вы пытаетесь загрузить файл весов, содержащий 2 слоя в модель с 1 слоями - PullRequest
6 голосов
/ 01 октября 2019

Я тренировал модель CNN с использованием Keras и сохранял вес. Когда я пытаюсь загрузить их обратно в ту же модель, я получаю следующую ошибку:

ValueError: Вы пытаетесь загрузить файл весов, содержащий 2 слоя, в модель с 1 слоем.

Я выяснил, что это распространенная ошибка. Тем не менее, предложенные средства правовой защиты, похоже, не работают для меня. Я попытался понизить мою текущую версию Keras 2.2.4 до 2.1.6. Моя модель выглядит так:

def build_model(self):

    model = Sequential()
    #pdb.set_trace()
    model.add(Dense(128 * 7 * 7, activation="relu", input_shape=(None, self.latent_dim)))
    model.add(Reshape((7, 7, 128)))
    model.add(UpSampling2D())
    model.add(Conv2D(128, kernel_size=4, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))
    model.add(UpSampling2D())
    model.add(Conv2D(64, kernel_size=4, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))

    model.add(UpSampling2D(size=(1, 2)))
    model.add(Conv2D(64, kernel_size=4, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))

    model.add(UpSampling2D(size=(1, 2)))
    model.add(Conv2D(64, kernel_size=4, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))

    model.add(Conv2D(self.channels, kernel_size=4, padding="same"))
    model.add(Activation("tanh"))

    model.summary()

    noise = Input(shape=(self.latent_dim,))
    img = model(noise)

    return Model(noise, img)

Затем для загрузки весов я делаю что-то вроде:

self.my_model = self.build_model()

input = Input(shape=(self.latent_dim,))
img = self.my_model(input)
output = self.my_critic(img)

self.the_model = Model(input, output)
self.the_model.compile(loss= self.wasserstein_loss,optimizer=optimizer)    

self.the_model.compile(...) # the same options as in case of training
self.the_model.load_weights('models/stored_weights') 

РЕДАКТИРОВАТЬ:

Iпроверил более тщательно мой код, и я понял, что моя проблема была чем-то другим и более сложным. Мой код соответствует реализации Вассерштейна GAN. Модель, которую я тренирую, напрямую не строится с использованием только build_model. Однако это комбинация этой модели и критика (следовательно, комбинация этих двух моделей). Во-первых, я определяю свою модель (это мой генератор) self.my_model = self.build_model(), а затем у меня есть self.the_model = Model (input, output), где input - это вход my_model: input = Input(shape=(self.latent_dim,)), а output - выход критика:

img = self.my_model(input)
output = self.my_critic(img)

Поэтому я не тренирую и не храню веса my_model, а только веса the_model (так как я хочу тренировать my_model и критика одновременно).

Таким образом, япопытался сделать: self.the_model.load_weights('models/gen_vv_face_feats__') вместо my_model.load_weights

Теперь я получаю следующую ошибку:

ValueError: оси не соответствуют массиву

1 Ответ

5 голосов
/ 04 октября 2019

Часть проблемы может заключаться в Model(noise, img), где img - это целая модель Sequential, которая может обрабатываться как однослойный при загрузке весов (см. Ниже) - в зависимости от как веса были сохранены.

Чтобы лучше понять проблему, было бы полезно увидеть ваш save код - поскольку ваш код предоставлен как есть (с добавленным кодом сохранения)) работает для меня. Обходное решение, которое вы можете попробовать, см. Ниже.


Возможная проблема:

model = build_model()
model.summary()

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 12)                0         
_________________________________________________________________
sequential_1 (Sequential)    (None, 28, 112, 16)       623824    
=================================================================
Total params: 623,824
Trainable params: 623,184
Non-trainable params: 640

Что сработало для меня :

model_to_save = build_model()
model_to_save.compile()
model_to_save.save_weights(path)

model_to_load = build_model()
model_to_load.compile()
model_to_load.load_weights(path)

Обходной путь + подсказка :

Чтобы исправить, как есть, отбросьте строки noise =, image = и Model(...)полностью и просто выполните return model: ваш исходный Input уже должен делать то, что вы собираетесь с noise =.

Кроме того, если вам требуется расширенная функциональность с несколькими входами / выходами, используйте Model,Намного легче работать - и не смешивайте Model w / Sequential, если только по очень конкретным причинам.

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