当我在 Keras 中传递参数时函数的一种非常奇怪的行为

A very strange behavior of a function when I pass arguments in Keras

我创建了一个函数来训练和评估 keras2、tensorflow2 中的模型。

这是我的代码:

def f_compile_fit_evaluate_model1(filters1, kernel_size1, filters2 , kernel_size2, epochs):

    setting1 = Input(shape = (10,8), name = 'setting1')
    setting2 = Input(shape = (10,8), name = 'setting2')
    s2 = Input(shape = (10,8), name = 's2')
    s3 = Input(shape = (10,8), name = 's3')
    s6 = Input(shape = (10,8), name = 's6')
    s7 = Input(shape = (10,8), name = 's7')
    s8 = Input(shape = (10,8), name = 's8')
    s9 = Input(shape = (10,8), name = 's9')
    s11 = Input(shape = (10,8), name = 's11')
    s12 = Input(shape = (10,8), name = 's12')
    s13 = Input(shape = (10,8), name = 's13')
    s14 = Input(shape = (10,8), name = 's14')
    s15 = Input(shape = (10,8), name = 's15')
    s17 = Input(shape = (10,8), name = 's17')
    s20 = Input(shape = (10,8), name = 's20')
    s21 = Input(shape = (10,8), name = 's21')

    setting1_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(setting1)
    setting2_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(setting2)
    s2_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s2)
    s3_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s3)
    s6_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s6)
    s7_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s7)
    s8_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s8)
    s9_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s9)
    s11_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s11)
    s12_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s12)
    s13_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s13)
    s14_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s14)
    s15_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s15)
    s17_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s17)
    s20_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s20)
    s21_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s21)

    x = Concatenate()([setting1_, setting2_, s2_, s3_, s6_, s7_, s8_, s9_, s11_, s12_, s13_, s14_, s15_, s17_, s20_, s21_])

    x = Conv1D(filters =filters2, kernel_size = kernel_size2, activation = 'relu')(x)

    x = GlobalMaxPooling1D()(x)

    preds = Dense(1, activation = 'relu')(x)

    model = Model(inputs = [setting1, setting2, s2, s3, s6, s7, s8, s9, s11, s12, s13, s14, s15, s17, s20, s21], outputs = preds)

    model.compile(loss = 'mean_squared_error',  optimizer = 'Adam', metrics = ['MAPE'])

    history = model.fit(x = [setting1_train_, setting2_train_, s2_train_, s3_train_, s6_train_, s7_train_, s8_train_, s9_train_, s11_train_, s12_train_, s13_train_, s14_train_, s15_train_,
                  s17_train_, s20_train_, s21_train_], y = target_train_, validation_data = ([setting1_dev_, setting2_dev_, s2_dev_, s3_dev_, s6_dev_, s7_dev_, s8_dev_, s9_dev_,
                    s11_dev_, s12_dev_, s13_dev_, s14_dev_, s15_dev_,s17_dev_, s20_dev_, s21_dev_], target_dev_), epochs = epochs)
    
    evaluation = model.evaluate(x = [setting1_dev_, setting2_dev_, s2_dev_, s3_dev_, s6_dev_, s7_dev_, s8_dev_, s9_dev_, s11_dev_, s12_dev_, s13_dev_, s14_dev_, s15_dev_,
              s17_dev_, s20_dev_, s21_dev_], y = target_dev_)
    
    #preds = model.predict(x = [setting1_dev_, setting2_dev_, s2_dev_, s3_dev_, s6_dev_, s7_dev_, s8_dev_, s9_dev_, s11_dev_, s12_dev_, s13_dev_, s14_dev_, s15_dev_,
    #          s17_dev_, s20_dev_, s21_dev_])
    
    #pd.Series(target_dev_).plot()
    #pd.Series(preds1.ravel()).plot(color= 'red')
    
    Experiment_results = {}
    
    Experiment_results['model'] = model
    Experiment_results['history'] = history
    Experiment_results['evaluation'] = evaluation
    
    return(Experiment_results)

当我将数字传递给参数时,一切正常:

Experiment_results1 = f_compile_fit_evaluate_model1(filters1 = 64, kernel_size1 = 5,  filters2 = 32, kernel_size2 = 5, epochs =2)
Train on 17331 samples, validate on 4691 samples
Epoch 1/2
17331/17331 [==============================] - 4s 216us/sample - loss: 2194.9158 - MAPE: 81.0938 - val_loss: 1699.8839 - val_MAPE: 32.2841
Epoch 2/2
17331/17331 [==============================] - 3s 157us/sample - loss: 1321.0965 - MAPE: 50.1694 - val_loss: 1666.8266 - val_MAPE: 29.3222
4691/4691 [==============================] - 0s 67us/sample - loss: 1666.8266 - MAPE: 29.3222

但是当我使用变量或函数将数字传递给它时,我得到了奇怪的结果:

Experiment_results2 = f_compile_fit_evaluate_model1(filters1 = np.random.choice([2**4, 2**5, 2**6, 2**7, 2**8, 2**9]), kernel_size1 = np.random.choice([2,3,5]),  
                                                    filters2 =  np.random.choice([2**4, 2**5, 2**6, 2**7, 2**8, 2**9]), kernel_size2 = np.random.choice([2,3,5]), epochs =2)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Roaming\Python\Python37\site-packages\tensorflow_core\python\keras\utils\conv_utils.py in normalize_tuple(value, n, name)
     71     try:
---> 72       value_tuple = tuple(value)
     73     except TypeError:

TypeError: 'numpy.int32' object is not iterable

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-48-778f42dc6d99> in <module>
      1 Experiment_results2 = f_compile_fit_evaluate_model1(filters1 = np.random.choice([2**4, 2**5, 2**6, 2**7, 2**8, 2**9]), kernel_size1 = np.random.choice([2,3,5]),  
----> 2                                                     filters2 =  np.random.choice([2**4, 2**5, 2**6, 2**7, 2**8, 2**9]), kernel_size2 = np.random.choice([2,3,5]), epochs =2)

<ipython-input-30-4ea336e18e58> in f_compile_fit_evaluate_model1(filters1, kernel_size1, filters2, kernel_size2, epochs)
     18     s21 = Input(shape = (10,8), name = 's21')
     19 
---> 20     setting1_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(setting1)
     21     setting2_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(setting2)
     22     s2_ = Conv1D(filters = filters1, kernel_size = kernel_size1, activation = 'relu')(s2)

~\AppData\Roaming\Python\Python37\site-packages\tensorflow_core\python\keras\layers\convolutional.py in __init__(self, filters, kernel_size, strides, padding, data_format, dilation_rate, activation, use_bias, kernel_initializer, bias_initializer, kernel_regularizer, bias_regularizer, activity_regularizer, kernel_constraint, bias_constraint, **kwargs)
    442         kernel_constraint=constraints.get(kernel_constraint),
    443         bias_constraint=constraints.get(bias_constraint),
--> 444         **kwargs)
    445 
    446 

~\AppData\Roaming\Python\Python37\site-packages\tensorflow_core\python\keras\layers\convolutional.py in __init__(self, rank, filters, kernel_size, strides, padding, data_format, dilation_rate, activation, use_bias, kernel_initializer, bias_initializer, kernel_regularizer, bias_regularizer, activity_regularizer, kernel_constraint, bias_constraint, trainable, name, **kwargs)
    127     self.filters = filters
    128     self.kernel_size = conv_utils.normalize_tuple(
--> 129         kernel_size, rank, 'kernel_size')
    130     self.strides = conv_utils.normalize_tuple(strides, rank, 'strides')
    131     self.padding = conv_utils.normalize_padding(padding)

~\AppData\Roaming\Python\Python37\site-packages\tensorflow_core\python\keras\utils\conv_utils.py in normalize_tuple(value, n, name)
     73     except TypeError:
     74       raise ValueError('The `' + name + '` argument must be a tuple of ' +
---> 75                        str(n) + ' integers. Received: ' + str(value))
     76     if len(value_tuple) != n:
     77       raise ValueError('The `' + name + '` argument must be a tuple of ' +

ValueError: The `kernel_size` argument must be a tuple of 1 integers. Received: 3

我该如何解决这个问题?

由于您的示例本身没有 运行,我只能测试它的一部分。但是您似乎正在尝试将不可迭代的值(numpy 类型)传递给内核大小参数。

尝试将值作为一维元组传递:

Experiment_results2 = f_compile_fit_evaluate_model1(filters1 = np.random.choice([2**4]), kernel_size1 = (np.random.choice([2]),),filters2=np.random.choice([2**4]), kernel_size2 = (np.random.choice([2]),), epochs =2)