ValueError:将形状为(72148,23)的目标数组传递为形状为(None,826,23)的输出,同时将其用作损耗`categorical_crossentropy`

时间:2020-06-10 09:25:02

标签: python tensorflow keras cnn

我正在尝试在心跳数据上训练一维CNN,以对病理性心跳进行分类。输入和输出形状为

X_train = np.zeros((72148, 828, 1))
y_train = np.zeros((72148, 23))

但是,使用这些形状拟合模型会导致一个错误,这特别使我感到困惑,因为“对于形状的输出(无,826,23)”。任何关于为什么发生这种情况的建议将不胜感激! 完整的错误代码:

Traceback (most recent call last):
  File "C:/1SchoolProjects/2019-2020/Term4/NN/NNHeartbeats/CNN_heatbeats.py", line 81, in <module>
    model.fit(X_train, y_train, epochs=3, batch_size= batch_size)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 819, in fit
    use_multiprocessing=use_multiprocessing)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 235, in fit
    use_multiprocessing=use_multiprocessing)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 593, in _process_training_inputs
    use_multiprocessing=use_multiprocessing)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 646, in _process_inputs
    x, y, sample_weight=sample_weights)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2383, in _standardize_user_data
    batch_size=batch_size)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2489, in _standardize_tensors
    y, self._feed_loss_fns, feed_output_shapes)
  File "C:\Miniconda\envs\tensorflow-gpu-cuda10\lib\site-packages\tensorflow_core\python\keras\engine\training_utils.py", line 810, in check_loss_and_target_compatibility
    ' while using as loss `' + loss_name + '`. '
ValueError: A target array with shape (72148, 23) was passed for an output of shape (None, 826, 23) while using as loss `categorical_crossentropy`. This loss expects targets to have the same shape as the output.

模型摘要:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d (Conv1D)              (None, 826, 512)          2048      
_________________________________________________________________
dense (Dense)                (None, 826, 256)          131328    
_________________________________________________________________
dropout (Dropout)            (None, 826, 256)          0         
_________________________________________________________________
dense_1 (Dense)              (None, 826, 23)           5911      
=================================================================
Total params: 139,287
Trainable params: 139,287
Non-trainable params: 0
_________________________________________________________________

代码:

import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split

def create_model(n_timesteps, n_features, n_outputs):
    tf.keras.backend.set_floatx('float16')
    dtype='float16'

    model = tf.keras.models.Sequential([
        tf.keras.layers.Conv1D(input_shape=(n_timesteps, n_features), kernel_size=3, filters=512),
        #tf.keras.layers.Dense(input_shape=(828,1), units=828, activation='relu', dtype=dtype),
        #tf.keras.layers.Dropout(0.2, dtype=dtype),
        tf.keras.layers.Dense(256, activation='relu', dtype=dtype),
        tf.keras.layers.Dropout(0.2, dtype=dtype),
        tf.keras.layers.Dense(n_outputs, activation='softmax', dtype=dtype)
    ])

    return model



if __name__ == "__main__":
    X_train = np.zeros((72148, 828, 1))
    y_train = np.zeros((72148, 23))
    n_timesteps, n_features, n_outputs = X_train.shape[1], X_train.shape[2], y_train.shape[1]
    model = create_model(n_timesteps, n_features, n_outputs)
    #optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
    #loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
    #model.compile(loss=loss_fn, optimizer=optimizer)
    model.compile(optimizer='adam',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    print(model.summary())



    batch_size = 32

    model.fit(X_train, y_train, epochs=3, batch_size= batch_size)

1 个答案:

答案 0 :(得分:0)

这些是从3d传递到2d的示例

使用Flatten ...,您可以将其放在输出层之前的网络中

n_timesteps, n_features, n_outputs = 826, 1, 23
n_samples = 1000

X = np.random.uniform(0,1, (n_samples, n_timesteps, n_features))
y = pd.get_dummies(np.random.randint(0,n_outputs, n_samples)).values

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv1D(input_shape=(n_timesteps, n_features), kernel_size=3, filters=16),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(n_outputs, activation='softmax')
])
model.compile('adam', 'categorical_crossentropy')

model.fit(X,y, epochs=3)

具有压缩时间维度的GlobalPooling层

n_timesteps, n_features, n_outputs = 826, 1, 23
n_samples = 1000

X = np.random.uniform(0,1, (n_samples, n_timesteps, n_features))
y = pd.get_dummies(np.random.randint(0,n_outputs, n_samples)).values

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv1D(input_shape=(n_timesteps, n_features), kernel_size=3, filters=16),
    tf.keras.layers.GlobalAveragePooling1D(), # also GlobalMaxPooling1D() is ok
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(n_outputs, activation='softmax')
])
model.compile('adam', 'categorical_crossentropy')

model.fit(X,y, epochs=3)