【问题标题】:ValueError: A target array with shape (72148, 23) was passed for an output of shape (None, 826, 23) while using as loss `categorical_crossentropy`ValueError: 形状为 (72148, 23) 的目标数组被传递为形状 (None, 826, 23) 的输出,同时用作损失`categorical_crossentropy`
【发布时间】:2020-06-10 18:06:44
【问题描述】:

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

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

但是,使用这些形状拟合模型会导致一个错误,这让我特别困惑,因为“对于形状的输出 (None, 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)

【问题讨论】:

  • 您必须减少网络内部的维度...您必须从 3d 传递到 2d 才能匹配您的目标。您可以使用 globalpooling 或 flatten layer 来做到这一点。如果你有兴趣,我可以给你一些例子
  • @MarcoCerliani 感谢您的快速回答!我以前见过展平层,但我不知道我必须在网络中的哪个点插入一个。请你给我解释一下好吗?

标签: python tensorflow keras conv-neural-network


【解决方案1】:

这些是从 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)

【讨论】:

  • 非常感谢!短短的一行代码又是如何改变一切的……
猜你喜欢
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2021-02-26
  • 2021-04-08
  • 2022-08-03
  • 1970-01-01
相关资源
最近更新 更多