【问题标题】:Attribute error when I am try to modify a loaded LSTM model parameter on Colab当我尝试在 Colab 上修改加载的 LSTM 模型参数时出现属性错误
【发布时间】:2023-12-11 21:08:02
【问题描述】:

我正在尝试从 Colab 上的 Keras 加载 LSTM 模型并更改其单位,但我收到以下错误:“AttributeError:无法设置属性“单位”,可能是因为它与现有的只读冲突对象的@property。请选择其他名称”。我尝试修改其他图层参数,效果很好。我能做些什么来解决它?

我用来加载模型并修改它的代码:

model = keras.models.load_model('model.h5')
model.summary() #the model is composed by embedding, dropout, LSTM, dropout then dense layer

model.layers[2].units = 100
new_model = model_from_json(model.to_json())

我用来生成初始模型的代码:

def lstm(vocab_size, tokenizer, X_train, X_validation, y_train, y_validation):

  model = Sequential()

  model.add(Embedding(input_dim=vocab_size,
                      output_dim=embedding_dim,
                      input_length=length_size,
                      name='embedding'))
  
  #droupout layer
  model.add(Dropout(rate = first_dropout_rate))

  #lstm layer
  model.add(LSTM(units = units))

  #dropout layer
  model.add(Dropout(rate = last_dropout_rate))

  #output layer
  model.add(Dense(units=1, activation='sigmoid'))

  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
  #model_random.summary()

  history_random = model.fit(X_train, 
                             y_train,
                             batch_size=batch_size,
                             epochs=epochs,
                             validation_data=(X_validation, y_validation))
    
  return model

【问题讨论】:

    标签: python tensorflow keras lstm


    【解决方案1】:

    错误信息有些误导。 您不能直接更改参数,例如 LSTM 中的单元数,因为这会更改层权重的大小。
    您将必须构建一个与第一个模型具有相同结构的新模型,但 LSTM 层的单元数量不同。然后你需要复制模型权重,除了 LSTM 层和下一层(因为 LSTM 输出的大小发生了变化)。

    下面是一些代码(参数的值是任意的):

    from tensorflow.keras.layers import Embedding, Dropout, LSTM, Dense 
    from tensorflow.keras import Sequential
    
    vocab_size = 41
    embedding_dim = 100
    length_size = 50
    
    first_dropout_rate=0.2
    last_dropout_rate = 0.2
    units=2
    
    def create_lstm_model(vocab_size, embedding_dim, length_size, first_dropout_rate, last_dropout_rate, units):
        model = Sequential()
        model.add(Embedding(input_dim=vocab_size,
                        output_dim=embedding_dim,
                        input_length=length_size,
                        name='embedding'))
        #droupout layer
        model.add(Dropout(rate=first_dropout_rate))
        #lstm layer
        model.add(LSTM(units=units, name='mylstm'))  # give a name to the layer
    
        #dropout layer
        model.add(Dropout(rate=last_dropout_rate))
    
        #output layer
        model.add(Dense(units=1, activation='sigmoid', name='mydense'))  # give a name to the layer
        return model
    
    # create and compile model with 2 LSTM units
    model = create_lstm_model(vocab_size, embedding_dim, length_size, first_dropout_rate, last_dropout_rate, units=2)
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.summary()
    
    # do model.fit
    
    # create a new model with 3 LSTM units
    new_model = create_lstm_model(vocab_size, embedding_dim, length_size, first_dropout_rate, last_dropout_rate, units=3)
    
    # copy weights
    for count, (layer, new_layer) in enumerate(zip(model.layers, new_model.layers)): 
        if layer.name in ['mylstm', 'mydense']:  # the weights of these two layers have different sizes in the two models 
            continue
        print(new_layer)
        new_layer.set_weights(layer.get_weights())
    
    new_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    new_model.summary()
    

    【讨论】:

    • 非常感谢您的回答!它对我有用。但我有一个问题:那是只出现在 LSTM 上的问题吗?我还有一个 CNN 模型,我可以使用帖子中提到的相同策略重新训练更改过滤器。对此有什么解释吗?我做了一些在线研究,但我找不到任何东西。再次感谢您的帮助!
    • 我认为大多数 Keras 层都会出现问题,尽管它不一定会引发错误。在构建层时似乎考虑了单元的数量或内核的大小,但之后层的结构并没有改变。您可以通过创建具有单个 Dense 或 Conv1D 层的简单模型并显示模型摘要、更改参数然后再次显示摘要来看到这一点。应该有相同数量的参数和相同的输出大小。
    最近更新 更多