【问题标题】:Keras ValueError related to input shape in 1D Convolutional Neural Network与 1D 卷积神经网络中的输入形状相关的 Keras ValueError
【发布时间】:2021-11-23 17:44:21
【问题描述】:

当我尝试在 7 波段光谱数据上运行 1D CNN 时出现以下错误。类标签是二进制的,我想要一个输出。我附上代码和输出。显然,Conv1D 似乎在摄取 7 个输入波段时遇到了一些问题。我尝试查看已经发布的帖子,但没有取得多大成功。


import numpy as np
import rasterio
from rasterio.plot import show
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from tensorflow import keras
from sklearn.metrics import confusion_matrix, precision_score, recall_score
from tensorflow.keras.utils import plot_model
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Dense, Conv1D, MaxPooling1D
from tensorflow.keras.layers import Concatenate
from spectral import *
import pysptools.spectro as spectro
import copy
import os
import matplotlib
from sklearn.preprocessing import OneHotEncoder
import pandas as pd
import shutil


#%% DEFINE THE 1D CNN MODEL ARCHITECTURE
filters=4
kernel_size=4

visible = Input(shape=(7,1))
hidden1 = Conv1D (filters=filters, kernel_size=kernel_size, input_shape=(7,1), activation='relu', name="L1")(visible)
hidden2 = MaxPooling1D()(hidden1)
hidden3 = Dense(2, activation='relu', name="L3")(hidden2)
# hidden4 = Dense(2, activation='relu', name="L4")(hidden3)
output = Dense(1, activation='softmax', name="Output")(hidden3)
model = Model(inputs=visible, outputs=output)

# Shapes of the input data and label

print("\n7 band spectral data shape:", ern_T_c_d_v.shape) 
print("Class labels shape:", ern_Mask_c_d_v.shape)
            
# Split into test and train
            
xTrain, xTest, yTrain, yTest = train_test_split(ern_T_c_d_v, ern_Mask_c_d_v, test_size=0.5, random_state=42)
# Note that I have transposed the arrays...

print("\nBefore reshaping")

print("xTrain:", xTrain.shape)
print("yTrain", yTrain.shape)

print("xTest:",xTest.shape)
print("yTest:",yTest.shape)

xTrain = np.reshape(xTrain, (xTrain.shape[0],  1, xTrain.shape[1]))
xTest = np.reshape(xTest, (xTest.shape[0], 1, xTest.shape[1]))

# xTrain=np.expand_dims(xTrain, axis=1)
# xTest=np.expand_dims(xTrain, axis=1)

print("\nReshaped...")
print("xTrain:", xTrain.shape)
print("yTrain:", yTrain.shape)

print("xTest:", xTest.shape)
print("yTest:",yTest.shape)

#%%

# Define the accuracy metrics and parameters
# opt=keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer='adam', loss="binary_crossentropy", metrics=["accuracy"])

# Run the model
history = model.fit(xTrain, yTrain, epochs=1500)
pd.DataFrame(history.history).plot(figsize=(6,4))
plt.savefig(path+os.sep+'History')
plt.show()
print(history.params)

#%%

# Predict for test data 
yTestPredicted = model.predict(xTest)

而且,这就是我得到的:

Warning 1: TIFFReadDirectoryCheckOrder:Invalid TIFF directory; tags are not sorted in ascending order
Warning 1: TIFFReadDirectory:Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples.
Model: "model_15"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_19 (InputLayer)        [(None, 7, 1)]            0         
_________________________________________________________________
L1 (Conv1D)                  (None, 4, 6)              30        
_________________________________________________________________
max_pooling1d_15 (MaxPooling (None, 2, 6)              0         
_________________________________________________________________
L3 (Dense)                   (None, 2, 4)              28        
_________________________________________________________________
Output (Dense)               (None, 2, 1)              5         
=================================================================
Total params: 63
Trainable params: 63
Non-trainable params: 0
_________________________________________________________________
None

7 band spectral data shape: (1201, 7)
Class labels shape: (1201,)

Before reshaping
xTrain: (600, 7)
yTrain (600,)
xTest: (601, 7)
yTest: (601,)

Reshaped...
xTrain: (600, 1, 7)
yTrain: (600,)
xTest: (601, 1, 7)
yTest: (601,)
Traceback (most recent call last):

  File "/Volumes/256GB/Ceres_Red_FC/NN_Codes/NN_Functional_CNN_1.py", line 181, in <module>
    history = model.fit(xTrain, yTrain, epochs=1500)

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 728, in fit
    use_multiprocessing=use_multiprocessing)

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 224, in fit
    distribution_strategy=strategy)

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 547, in _process_training_inputs
    use_multiprocessing=use_multiprocessing)

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 594, in _process_inputs
    steps=steps)

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 2472, in _standardize_user_data
    exception_prefix='input')

  File "/Users/pragya/opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_utils.py", line 574, in standardize_input_data
    str(data_shape))

ValueError: Error when checking input: expected input_19 to have shape (7, 1) but got array with shape (1, 7)

我无法理解为什么 Conv1D 不能接受 7 个输入波段。任何想法如何解决这个问题?提前谢谢...

【问题讨论】:

  • 尝试将您的输入重塑为(600, 7,1)
  • @Nachiket 我已经尝试过了。没用...
  • 好的,你能发布一个最小的可重现示例,包含所有数组,例如ern_T_c_d_v 已定义?如果您也可以减少依赖项的数量,那就太好了。
  • 看来您需要设置input_shape=(1,7) 而不是(7, 1)。我不确定您的数据是什么样的 - 但在我看来,每个波段都是一个特征或不同的列等。

标签: python tensorflow keras conv-neural-network valueerror


【解决方案1】:

以下内容对我有用

from tensorflow.keras.utils import plot_model
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Dense, Conv1D, MaxPooling1D
from tensorflow.keras.layers import Concatenate

import numpy as np

nexamples = 200
filters=4
kernel_size=4

xTrain = np.zeros((nexamples,7,1),dtype='float64')
yTrain = np.zeros((nexamples,),dtype='float64')

visible = Input(shape=(7,1))
hidden1 = Conv1D(filters=filters, kernel_size=kernel_size, input_shape=(7,1), activation='relu', name="L1")(visible)
hidden2 = MaxPooling1D()(hidden1)
hidden3 = Dense(2, activation='relu', name="L3")(hidden2)
# hidden4 = Dense(2, activation='relu', name="L4")(hidden3)
output = Dense(1, activation='softmax', name="Output")(hidden3)
model = Model(inputs=visible, outputs=output)

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

# Run the model
history = model.fit(xTrain, yTrain, epochs=1)

【讨论】:

  • 我在运行上面的代码时遇到了这个错误...ValueError: A target array with shape (200, 1) was passed for an output of shape (None, 2, 1) while using as loss `binary_crossentropy`. This loss expects targets to have the same shape as the output.
  • 我再次检查,它对我有用。我不确定为什么它不适合你。
  • 非常感谢您的帮助。我不明白:Pedro 的答案很有效,尽管它基本上是在做你建议的事情。
【解决方案2】:

如果你改变这一行

xTrain = np.reshape(xTrain, (xTrain.shape[0],  1, xTrain.shape[1]))
xTest = np.reshape(xTest, (xTest.shape[0], 1, xTest.shape[1]))

到这里

xTrain = np.reshape(xTrain, (xTrain.shape[0], xTrain.shape[1], 1))
xTest = np.reshape(xTest, (xTest.shape[0], xTest.shape[1], 1))

fit 函数有效。 为了更好地理解这一点,您需要知道卷积在形状上有一个通道,给您一个只有一个值的 7 通道示例,并且您试图将一个 4 大小的内核传递给这个单个输入, 它们是解决此问题的两种方法,您可以创建一个包含 7 个值且只有 1 个通道的输入,如上例所示,或者您可以在通道之间进行可分离的卷积。

【讨论】:

  • 这行得通,但是这两个代码不是在做完全相同的事情吗?您能否通过您提到的渠道进一步说明这一点。否则,请建议一个我可以了解更多信息的来源。非常感谢...
  • 您可以找到一篇很棒的文章 here 并查看图像的主要区别,但简单来说,您的数据具有以下形式 [batch_size, length, channels] 当您在卷积中定义内核时,内核需要比你的长度更小,并且库会创建与你拥有的通道一样多的内核
猜你喜欢
  • 2019-09-09
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 2017-07-30
  • 2017-08-31
  • 2020-05-26
  • 2018-06-16
  • 2020-03-16
相关资源
最近更新 更多