【问题标题】:How to fix tensorflow "InvalidArgumentError: Shapes of all inputs must match"如何修复张量流“InvalidArgumentError:所有输入的形状必须匹配”
【发布时间】:2019-11-30 22:27:17
【问题描述】:

我正在尝试通过顺序 Keras 神经网络运行小波重建数据集。为了从训练中获得更好的结果,我正在尝试构建一个只关注波形的某些指标的自定义损失函数。我打算创建一个神经网络来对截断的波形进行插值,所以我只希望神经网络通过将波形的截断段与实际输出进行比较来计算损失。

我已经尝试为我的自定义损失函数创建一个包装器,以便我可以传入一个额外的输入参数。然后,我使用此输入参数来查找裁剪数据点的索引,并尝试从 y_pred 和 y_true 收集这些索引。

这是模型实例化和训练的地方:

x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.7)
_dim = len(x_train[0])

# define the keras model
model = Sequential()

# tanh activation allows for vals between -1 and 1 unlike relu
model.add(Dense(_dim*2, input_dim=_dim, activation=_activation))
model.add(Dense(_dim*2, activation=_activation))
model.add(Dense(_dim, activation=_activation))
# model.compile(loss=_loss, optimizer=_optimizer)
model.compile(loss=_loss, optimizer=_optimizer, metrics=[custom_loss_wrapper_2(x_train)])

print(model.summary())

# The patience parameter is the amount of epochs to check for improvement
early_stop = EarlyStopping(monitor='val_loss', patience=5)

# fit the model
history = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=150, batch_size=15, callbacks=[early_stop])

这就是我的自定义损失函数所在的位置:

def custom_loss_wrapper_2(inputs):
# source: https://stackoverflow.com/questions/55445712/custom-loss-function-in-keras-based-on-the-input-data
# 2nd source: http://stackoverflow.com/questions.55597335/how-to-use-tf-gather-in-batch
def reindex(tensor_tuple):
    # unpack tensor tuple
    y_true = tensor_tuple[0]
    y_pred = tensor_tuple[1]
    t_inputs = K.cast(tensor_tuple[2], dtype='int64')
    t_max_indices = K.tf.where(K.tf.equal(t_inputs, K.max(t_inputs)))

    # gather the values from y_true and y_pred
    y_true_gathered = K.gather(y_true, t_max_indices)
    y_pred_gathered = K.gather(y_pred, t_max_indices)

    print(K.mean(K.square(y_true_gathered - y_pred_gathered)))

    return K.mean(K.square(y_true_gathered - y_pred_gathered))

def custom_loss(y_true, y_pred):
    # Step 1: "tensorize" the previous list
    t_inputs = K.variable(inputs)

    # Step 2: Stack tensors
    tensor_tuple = K.stack([y_true, y_pred, t_inputs], axis=1)

    vals = K.map_fn(reindex, tensor_tuple, dtype='float32')
    print('vals: ', vals)

    return K.mean(vals)

return custom_loss

我在尝试自定义损失函数时收到以下错误消息:

Using TensorFlow backend.
WARNING: Logging before flag parsing goes to stderr.
W0722 15:28:20.239395 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py:74: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.

W0722 15:28:20.252325 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py:517: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.

W0722 15:28:20.253353 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py:4138: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.

W0722 15:28:20.280281 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\optimizers.py:790: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.

W0722 15:28:20.293246 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py:1521: The name tf.log is deprecated. Please use tf.math.log instead.

W0722 15:28:20.366046 17232 deprecation.py:323] From C:\Users\Madison\PycharmProjects\MSTS\Seismic_Analysis\ML\custom_loss.py:83: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where
Tensor("metrics/custom_loss/map/while/Mean:0", shape=(), dtype=float32)
vals:  Tensor("metrics/custom_loss/map/TensorArrayStack/TensorArrayGatherV3:0", shape=(1228,), dtype=float32)
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 1002)              503004    
_________________________________________________________________
dense_2 (Dense)              (None, 1002)              1005006   
_________________________________________________________________
dense_3 (Dense)              (None, 501)               502503    
=================================================================
Total params: 2,010,513
Trainable params: 2,010,513
Non-trainable params: 0
_________________________________________________________________
None
W0722 15:28:20.467779 17232 deprecation_wrapper.py:119] From C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py:986: The name tf.assign_add is deprecated. Please use tf.compat.v1.assign_add instead.

Train on 1228 samples, validate on 527 samples
Epoch 1/150
2019-07-22 15:28:20.606792: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
Traceback (most recent call last):
  File "C:/Users/Madison/PycharmProjects/MSTS/Seismic_Analysis/ML/clipping_ml.py", line 172, in <module>
    main()
  File "C:/Users/Madison/PycharmProjects/MSTS/Seismic_Analysis/ML/clipping_ml.py", line 168, in main
    run_general()
  File "C:/Users/Madison/PycharmProjects/MSTS/Seismic_Analysis/ML/clipping_ml.py", line 156, in run_general
    _loss=_loss, _activation=_activation, _optimizer=_optimizer)
  File "C:/Users/Madison/PycharmProjects/MSTS/Seismic_Analysis/ML/clipping_ml.py", line 59, in build_clipping_model
    history = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=150, batch_size=15, callbacks=[early_stop])
  File "C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\engine\training.py", line 1039, in fit
    validation_steps=validation_steps)
  File "C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\engine\training_arrays.py", line 199, in fit_loop
    outs = f(ins_batch)
  File "C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py", line 2715, in __call__
    return self._call(inputs)
  File "C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\keras\backend\tensorflow_backend.py", line 2675, in _call
    fetched = self._callable_fn(*array_vals)
  File "C:\Users\Madison\PycharmProjects\MSTS\venv\lib\site-packages\tensorflow\python\client\session.py", line 1458, in __call__
    run_metadata_ptr)
tensorflow.python.framework.errors_impl.**InvalidArgumentError: Shapes of all inputs must match**: values[0].shape = [15,501] != values[2].shape = [1228,501]
     [[{{node metrics/custom_loss/stack}}]]

【问题讨论】:

    标签: python tensorflow machine-learning keras loss-function


    【解决方案1】:

    您能否分享一个可运行但失败的问题示例?即使只有几个数据点。现在看起来您的数据形状不一致。例如。一个小波比另一个长。批次需要是同质的。一种检查方法是:

    print(set(inp.shape for inp in inputs))
    

    如果该集合包含多个元素,您可能需要扩充数据。

    问题中 sn-ps 的示例代码

    import numpy as np
    from keras import backend as K
    from keras.callbacks import EarlyStopping
    from keras.layers import Dense, Activation
    from keras.models import Sequential
    from keras import optimizers
    from sklearn.model_selection import train_test_split
    
    _activation = Activation('softmax')
    _optimizer = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    
    def custom_loss_wrapper_2(inputs):
        print("inputs {}".format(inputs.shape))
        # source: https://stackoverflow.com/questions/55445712/custom-loss-function-in-keras-based-on-the-input-data
        # 2nd source: http://stackoverflow.com/questions.55597335/how-to-use-tf-gather-in-batch
        def reindex(tensor_tuple):
            # unpack tensor tuple
            y_true = tensor_tuple[0]
            y_pred = tensor_tuple[1]
            t_inputs = K.cast(tensor_tuple[2], dtype='int64')
            t_max_indices = K.tf.where(K.tf.equal(t_inputs, K.max(t_inputs)))
    
            # gather the values from y_true and y_pred
            print("y_true {}".format(y_true.shape))
            print("y_pred {}".format(y_pred.shape))
            y_true_gathered = K.gather(y_true, t_max_indices)
            y_pred_gathered = K.gather(y_pred, t_max_indices)
    
            print(K.mean(K.square(y_true_gathered - y_pred_gathered)))
    
            return K.mean(K.square(y_true_gathered - y_pred_gathered))
    
        def custom_loss(y_true, y_pred):
            print("y_true2 {}".format(y_true.shape))
            print("y_pred2 {}".format(y_pred.shape))
    
            # Step 1: "tensorize" the previous list
            t_inputs = K.variable(inputs)
    
            # Step 2: Stack tensors
            tensor_tuple = K.stack([y_true, y_pred, t_inputs], axis=1)
    
            vals = K.map_fn(reindex, tensor_tuple, dtype='float32')
            print('vals: {}'.format(vals.shape))
            print('kvals: {}'.format(K.mean(vals).shape))
            return K.mean(vals, keepdims=True)
    
        return custom_loss
    
    dataset_size = 100
    dim = 501
    X = np.random.rand(dataset_size, dim)
    Y = np.random.rand(dataset_size, dim)
    
    x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.7)
    print(x_train.shape)
    print(y_train.shape)
    
    print(x_test.shape)
    print(y_test.shape)
    
    _dim = len(x_train[0])
    print("_dim {}".format(_dim))
    # define the keras model
    model = Sequential()
    
    _loss = custom_loss_wrapper_2(x_train)
    _mmm = _loss
    
    # tanh activation allows for vals between -1 and 1 unlike relu
    model.add(Dense(_dim*2, input_shape=(_dim,), activation=_activation))
    model.add(Dense(_dim*2, activation=_activation))
    model.add(Dense(_dim, activation=_activation))
    # model.compile(loss=_loss, optimizer=_optimizer)
    model.compile(loss=_loss, optimizer=_optimizer, metrics=[_mmm])
    
    print(model.summary())
    
    # The patience parameter is the amount of epochs to check for improvement
    early_stop = EarlyStopping(monitor='val_loss', patience=5)
    
    # fit the model
    history = model.fit(
        x_train,
        y_train,
        validation_data=(x_test, y_test),
        epochs=150,
        batch_size=10,
        callbacks=[early_stop])
    
    
    

    【讨论】:

    • 我运行了那行代码,打印在我的数据集上的结果值为 {(501,)},因此看起来所有数据点至少具有相同的长度。我使用随机生成的 numpy 数组运行我的代码,并遇到了同样的问题。我使用以下内容来生成我的 X 和 Y,而不是像以前那样从 mat 文件中加载这些数组。 X = np.random.rand(44, 501) Y = np.random.rand(44, 501) 随着形状尺寸参数的变化,我得到了同样的错误。 values[0].shape = [15,501] != values[2].shape = [30,501].
    • 我没时间看这个,但问题是批量大小以某种方式进入了图形计算。如果您删除验证数据,似乎没有问题。但我怀疑有。我将我的形状调试代码粘贴到答案中。
    【解决方案2】:

    经过一番思考,我找到了原始问题的答案。我想我会把它贴在这里,以防将来它可能对某人有所帮助。我遇到的问题与我提供损失函数包装器的输入参数有关。当我应该只传递批处理输入时,我传递了整个输入数组。这是在函数调用期间通过发送 model.inputs 来完成的。所以新的编译行应该是这样的:

    model.compile(loss=_loss, optimizer=_optimizer, metrics=[custom_loss_wrapper_2(model.input)])
    

    【讨论】:

      猜你喜欢
      • 2021-11-10
      • 2020-07-14
      • 1970-01-01
      • 2022-11-26
      • 1970-01-01
      • 2021-08-11
      • 2019-12-19
      • 1970-01-01
      • 2018-06-10
      相关资源
      最近更新 更多