Python 3.x 我需要做什么才能为时间分布层获得正确的输入形状?
我已经建立了一个模型,由CNN向LSTM提供信息组成。我把有线电视新闻网包装在一个时间分发的包装里。我已将我的训练集(x值)配置为5D形状(批大小、步数、图像高度、图像宽度、通道)。在尝试训练模型时,我得到以下错误:ValueError:检查输入时出错:预期时间_分布_输入有5个维度,但得到了形状为(4,28,28,1)的数组 我尝试了许多不同的模型配置,并通过代码进行了调试。我可以看到ValueError被抛出的位置,但我看不到任何方法可以阻止这种情况发生。要遵循的代码详细信息 我的模型建筑代码:Python 3.x 我需要做什么才能为时间分布层获得正确的输入形状?,python-3.x,tensorflow,Python 3.x,Tensorflow,我已经建立了一个模型,由CNN向LSTM提供信息组成。我把有线电视新闻网包装在一个时间分发的包装里。我已将我的训练集(x值)配置为5D形状(批大小、步数、图像高度、图像宽度、通道)。在尝试训练模型时,我得到以下错误:ValueError:检查输入时出错:预期时间_分布_输入有5个维度,但得到了形状为(4,28,28,1)的数组 我尝试了许多不同的模型配置,并通过代码进行了调试。我可以看到ValueError被抛出的位置,但我看不到任何方法可以阻止这种情况发生。要遵循的代码详细信息 我的模型建筑代
def build_cnn(input_shape=None):
print('Building the CNN')
model = tfkm.Sequential()
if input_shape:
model.add(tfkl.Conv2D(64, (3, 3), activation='relu', input_shape=input_shape))
else:
model.add(tfkl.Conv2D(64, (3, 3), activation='relu'))
model.add(tfkl.MaxPooling2D((2, 2), strides=(1, 1)))
model.add(tfkl.Conv2D(128, (4, 4), activation='relu'))
model.add(tfkl.MaxPooling2D((2, 2), strides=(2, 2)))
model.add(tfkl.Conv2D(256, (4, 4), activation='relu'))
model.add(tfkl.MaxPooling2D((2, 2), strides=(2, 2)))
# extract features and dropout
model.add(tfkl.Flatten())
return model
def build_lstm(units, return_sequences, dropout):
print('Building the LSTM model')
model = tfkm.Sequential()
model.add(tfkl.LSTM(units, return_sequences=return_sequences, dropout=dropout))
return model
def build_classification_layer(num_classes):
print('Building the classification-layer model')
model = tfkm.Sequential()
# classifier with sigmoid activation for multilabel
model.add(tfkl.Dense(num_classes, activation='sigmoid'))
return model
cnn = build_cnn(input_shape=(28, 28, 1))
lstm = build_lstm(256, False, 0.5)
classification_layer = build_classification_layer(2)
combined_model = tfkm.Sequential()
#combined_model.add(tfkl.TimeDistributed(cnn, batch_input_shape=(20, 4, 28, 28, 1)))
#combined_model.add(tfkl.TimeDistributed(cnn, input_shape=(4, 28, 28, 1), batch_size=20))
combined_model.add(tfkl.TimeDistributed(cnn, input_shape=(4, 28, 28, 1)))
combined_model.add(lstm)
combined_model.add(classification_layer)
combined_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
.
.
.
data-set building: creating 20 individual records, each containing a sequence of 4 28x28x1 images and the associated labels list.
.
.
.
print('train_input shape: {} train_labels shape: {}'.format(np.array(train_input).shape, np.array(train_labels).shape))
print('Training the model')
combined_model.fit(train_input, train_labels, epochs=2)
培训尝试的输出:
train_input shape: (20, 4, 28, 28, 1) train_labels shape: (20,)
Training the model
Traceback (most recent call last):
File "/Users/scott/sandbox/CNN-LSTM-sandbox/build_and_train.py", line 184, in <module>
combined_model.fit(train_input, train_labels, epochs=2)
File "/anaconda3/envs/TF2_py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 806, in fit
shuffle=shuffle)
File "/anaconda3/envs/TF2_py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 2596, in _standardize_user_data
exception_prefix='input')
File "/anaconda3/envs/TF2_py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py", line 340, in standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking input: expected time_distributed_input to have 5 dimensions, but got array with shape (4, 28, 28, 1)
Process finished with exit code 1
调试器点击第336行时的状态为:
np.array(data).shape = <class 'tuple'>: (1, 4, 28, 28, 1)
data_shape = <class 'tuple'>: (4, 28, 28, 1)
name = <class 'list'>: ['time_distributed_input']
shapes = <class 'list'>: [(None, 4, 28, 28, 1)]
np.array(data.shape=:(1,4,28,28,1)
数据形状=:(4,28,28,1)
名称=:['time\u distributed\u input']
形状=:[(无、4、28、28、1)]
由此可以看出,到达这一点的数据形状是正确的,但代码从批处理中的第一条记录中取出数据,并将其形状与TimeDistributed层期望的形状进行比较。问题是TimeDistributed层希望在shape(无,4,28,28,1)
中有批表示,但它不在那里b/c代码只在该批位置提取输入记录数据\u shape=data[i]。shape
在我看来,批次维度不应该在用于为InputLayer建立预期数据形状的元组中表示,批次长度比较需要忽略形状元组中的
None
,或者如果len(np.array(data.shape)!=len(shape):鉴于最后一段中的三种情况都不太可能发生,我如何让代码识别我实际上发送了正确的形状?在这方面取得了一些进展。将指定的行添加到training_utils.py
中的以下代码块中,从第296行开始:如果形状不是无:data=np.expand_dims(data,0)#由SQ数据添加=[zip(data,shapes)中的(x,shape)的标准化单数组(x,shape)]其他:data=[standardardarized_单数组(x)对于数据中的x]
添加此行后,我可以训练模型。。。。我还没有验证它是否真的有效,但我不会再出现形状错误。考虑到最后一段中的三种情况都不太可能发生,我如何让代码识别我实际上发送了正确的形状?在这方面取得了一些进展。将指定的行添加到training_utils.py
中的以下代码块中,从第296行开始:如果形状不是无:data=np.expand_dims(data,0)#由SQ数据添加=[zip(data,shapes)中的(x,shape)的标准化单数组(x,shape)]其他:data=[standardardarized_单数组(x)对于数据中的x]
添加此行后,我可以训练模型。。。。我还没有验证它是否真的有效,但我不再得到形状错误。
np.array(data).shape = <class 'tuple'>: (1, 4, 28, 28, 1)
data_shape = <class 'tuple'>: (4, 28, 28, 1)
name = <class 'list'>: ['time_distributed_input']
shapes = <class 'list'>: [(None, 4, 28, 28, 1)]