【问题标题】:set_model() missing 1 required positional argument: 'model'set_model() 缺少 1 个必需的位置参数:“模型”
【发布时间】:2018-09-07 03:12:35
【问题描述】:

我已经创建了一个 Keras 序列模型,并且正在使用 Adam 优化器。我希望在每个 epoch 之后获得学习率。这个stackoverflow question 似乎回答了我的问题。但是,当我按照提到的解决方案进行操作时,出现以下错误

set_model() missing 1 required positional argument: 'model'

这是我创建模型的代码:

model = Sequential()

model.add(Conv2D(64, (5, 5), input_shape=(IMG_HEIGHT, IMG_WIDTH, 3), activation='relu'))

model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.2))

model.add(Conv2D(128, (5, 5), activation='relu'))
model.add(Conv2D(128, (5, 5), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.2))

model.add(Conv2D(256, (5, 5), activation='relu'))
model.add(Conv2D(256, (5, 5), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(BatchNormalization(axis=3))
model.add(Dropout(0.2))

model.add(Flatten())
model.add(Dense(256, activation='relu'))

model.add(Dropout(0.5))

model.add(Dense(256, activation='relu'))

model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.4, 
                                            min_lr=0.0001)
csvlogger = CSVLogger("solution.csv", separator='\t')
checkpoint = ModelCheckpoint("models/best_model5.h5", monitor="val_acc", save_best_only=True, mode='max')
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.4, 
                                            min_lr=0.00001)

class MyCallback(keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        lr = self.model.optimizer.lr
        decay = self.model.optimizer.decay
        iterations = self.model.optimizer.iterations
        lr_with_decay = lr / (1. + decay * K.cast(iterations, K.dtype(decay)))
        print(K.eval(lr_with_decay))

model.fit_generator(datagen.flow(x_train, y_train, batch_size=75), 
                           epochs=10, validation_data=(x_validation, y_test),verbose=1, 
                           steps_per_epoch=x_train.shape[0], callbacks=[csvlogger, checkpoint, MyCallback])

如何解决此错误“set_model() 缺少 1 个必需的位置参数:'model' " 下面是堆栈跟踪

TypeError                                 Traceback (most recent call last)
<ipython-input-12-1826a19039cd> in <module>()
    128 model.fit_generator(datagen.flow(x_train, y_train, batch_size=75), 
    129                            epochs=10, validation_data=(x_validation, y_test),verbose=1,
--> 130                            steps_per_epoch=x_train.shape[0], callbacks=[csvlogger, checkpoint, MyCallback])
    131 model.save('trained_model5.h5')
    132 

/usr/local/lib/python3.6/dist-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name +
     90                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

/usr/local/lib/python3.6/dist-packages/keras/models.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   1274                                         use_multiprocessing=use_multiprocessing,
   1275                                         shuffle=shuffle,
-> 1276                                         initial_epoch=initial_epoch)
   1277 
   1278     @interfaces.legacy_generator_methods_support

/usr/local/lib/python3.6/dist-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name +
     90                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   2131         else:
   2132             callback_model = self
-> 2133         callbacks.set_model(callback_model)
   2134         callbacks.set_params({
   2135             'epochs': epochs,

/usr/local/lib/python3.6/dist-packages/keras/callbacks.py in set_model(self, model)
     50     def set_model(self, model):
     51         for callback in self.callbacks:
---> 52             callback.set_model(model)
     53 
     54     def on_epoch_begin(self, epoch, logs=None):

TypeError: set_model() missing 1 required positional argument: 'model'

另外,我的另一个问题是,上述解决方案是否正确。This tensorflow link about Adam Optimizer 建议将学习率计算为:

lr_t

这似乎与其他链接中提到的解决方案完全不同。我错过了什么吗?

【问题讨论】:

  • 你能告诉你哪个函数(哪一行)调用会引发以下错误吗?关于 Adam:Tensorflow 中的方程描述了变量在每次反向传播中如何修改,而您的解决方案在每个 epoch 后实现学习率衰减。这是完全不同的事情。 TensorFlow 的方程根本不会改变学习率。
  • 是的,我在回调列表中传递 MyCallbackmodel.fit_generator() 函数。那么,我是否正确地相信 Tensorflow 链接中提到的方程在给我 t 时期的学习率方面是正确的? @Primoz
  • 我找不到您的问题的原因您可以尝试调试或至少提供跟踪吗?不,TF 方程并不是为了在 epoch 结束时修改学习率,这只是描述 Adam 工作原理的代码的一部分。它用于修改网络权重。修改学习率与优化器没有太大关系。对于该任务,可以使用更多策略。 stackoverflow.com/questions/47490834/… 中提供的策略是选项之一。
  • 我已修改问题以包含堆栈跟踪。

标签: python tensorflow deep-learning keras


【解决方案1】:

该错误意味着您没有在位置 1(从 0 开始)处为称为“模型”的参数提供值。调用者是 Tensorflow 本身,所以故障很可能不存在。

此错误表明您正在调用静态方法而不是对象上的方法,因此只传递了 1 个参数而不是 2。这是因为当您调用对象上的方法时,对象作为第一个参数传递而“model”将作为第二个参数传递。

简而言之,您的错误在于您的回调是“类”而不是“对象”。确保您提供的是回调类的实例,而不是类本身。

像这样(注意“MyCallback”后面的括号):

model.fit_generator(datagen.flow(x_train, y_train, batch_size=75), epochs=10, validation_data=(x_validation, y_test),verbose=1, steps_per_epoch=x_train.shape[0], callbacks=[csvlogger, checkpoint, MyCallback()])

【讨论】:

    【解决方案2】:

    实际上,在 model.fit_generator 方法的回调参数中,您传递的是类而不是该类的对象。

    应该是

    my_calback_object = MyCallback() # create an object of the MyCallback class
    
    model.fit_generator(datagen.flow(x_train, y_train, batch_size=75), 
                        epochs=10, validation_data=(x_validation, y_test),
                        verbose=1, steps_per_epoch=x_train.shape[0],
                        callbacks=[csvlogger, checkpoint, my_callback_object])
    

    【讨论】:

    • 谢谢,这真的很有帮助。
    【解决方案3】:

    这更像是一条评论,只是不合适。

    这很奇怪。 MyCallback 继承的set_model 的默认实现是:

    def set_model(self, model):
        self.model = model
    

    这正是根据堆栈跟踪调用它的方式:

    /usr/local/lib/python3.6/dist-packages/keras/callbacks.py in set_model(self, model)
         50     def set_model(self, model):
         51         for callback in self.callbacks:    
    ---> 52             callback.set_model(model)
    

    此时我唯一的猜测是您的系统上存在一些版本不匹配。您可能还有一些旧的 .pyc 文件。我会尝试通过直接编辑 /usr/local/lib/python3.6/dist-packages/keras/callbacks.py 来调试它。例如,在第 52 行之前添加一个打印语句,以确保此代码真正运行。然后,进入pdb(添加import pdb; pdb.set_trace)并检查它为什么抱怨。这是一个基本的python问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      相关资源
      最近更新 更多