首页 > 解决方案 > CNNLSTM2D 实现

问题描述

有 2550 张图像作为训练集,1530 张图像作为测试集。为了将这些图像分为两类,使用了混合深度学习模型,但在运行代码时出现错误,如下所示。我想知道是否有人帮助我知道错误的原因。谢谢你

错误:

检查输入时:预期 conv_lst_m2d_39_input 有 5 个维度,但得到了形状为 (32, 64, 64, 3) 的数组

    # importing libraries
    from keras.models import Sequential
    from keras.layers import Convolution2D
    from keras.layers import MaxPooling2D
    from keras.layers import Flatten
    from keras.layers import Dense
    import tensorflow as tf
    from keras.layers.convolutional_recurrent import ConvLSTM2D
    from keras.layers.normalization import BatchNormalization
    
    #Data_Prprocessing
    from keras.preprocessing.image import ImageDataGenerator
    train_datagen = ImageDataGenerator(
                                        rescale=1./255,
                                        shear_range=0.2,
                                        zoom_range=0.2,
                                        horizontal_flip=True)
    test_datagen = ImageDataGenerator(rescale=1./255)
    training_set = train_datagen.flow_from_directory(
                                        'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Training_set',
                                        target_size=(64, 64),
                                        batch_size=32,
                                        class_mode='binary')
    test_set = test_datagen.flow_from_directory(
                                        'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Test_set',
                                        target_size=(64, 64),
                                        batch_size=32,
                                        class_mode='binary')
    
    #initializing the CNN
    classifier = Sequential()
    
    classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),input_shape=(None, 64, 64, 3),  padding='same', return_sequences=True))
    
    classifier.add(BatchNormalization())
    
    classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                       padding='same', return_sequences=True))
    classifier.add(BatchNormalization())
    
    classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                       padding='same'))
    
    #Full Connection
    classifier.add(Dense(output_dim = 128, activation = 'relu'))
    classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
    
    #compiling the CNN
    classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    
    #Fitting the CNN to the images
    
    history = classifier.fit_generator(training_set,
                             steps_per_epoch=2550,
                             epochs=25,
                             validation_data= test_set,
                             validation_steps=510)
    
    
    import matplotlib.pyplot as plt
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(1, len(acc) + 1)
    plt.plot(epochs, acc, 'r', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.legend()
    plt.figure()
    plt.plot(epochs, loss, 'r', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.plot()
    plt.legend()
    plt.show()
    test_loss, test_acc = classifier.evaluate(test_set)
    print('test_acc:', test_acc)

ERROR:
ValueError: Input 0 is incompatible with layer conv_lst_m2d_23: expected ndim=5, found ndim=6

新错误: 在此处输入图像描述

import numpy as np
import glob
from PIL import Image
import tensorflow as tf

images_png = glob.glob("*.png")
images = []
for pic in images_png:
    image = tf.read_file(pic)
    image = tf.image.decode_png(image, channels=3, dtype=tf.uint16)
    image = tf.cast(image, tf.float32)
    image = image / 256.0
    images.append(image)

img_seq_list = []
for i in range(0, len(images) - 5, 5): 
    j = i+5       
    img_seq = np.stack(images[i:j], axis=0)
    img_seq_list.append(img_seq)
    
labels = np.zeros((2,len(img_seq_list) + 1), dtype=int)
labels = np.transpose(labels)
length = len(img_seq_list)/2
length = int(length)
for i in range(0, 255):
    if i <= 127:
        labels[i][0] = 1
    elif i > 127 :
        labels[i][1] = 1

        
  

import tensorflow as tf
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization

classifier = Sequential()

classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),input_shape=(5, 64, 64, 3),  padding='same', return_sequences=True))

classifier.add(BatchNormalization())

classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   padding='same', return_sequences=True))
classifier.add(BatchNormalization())

classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   padding='same'))

#Full Connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))

#compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

train_data = tf.data.Dataset.from_tensor_slices((img_seq_list[0:127], labels[0:127]))
train_data = train_data.shuffle(100).batch(10) 

test_data = tf.data.Dataset.from_tensor_slices((img_seq_list[128:254], labels[128:254]))
test_data = train_data.shuffle(100).batch(10)


history = classifier.fit(train_data, validation_data=test_data)

import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'r', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.plot()
plt.legend()
plt.show()

test_loss, test_acc = classifier.evaluate(test_data)
print('test_acc:', test_acc)





     

标签: pythontensorflow

解决方案


我认为问题在于卷积 LSTM 层需要一个时间序列的图像,所以它必须有 5 个维度,包括批量维度,所以有一些形状(B, T, H, W, C)。您已将输入形状(忽略批次尺寸)定义为(None, 64, 64, 3),因此您需要输入形状的批次张量(batch, timesteps, 64, 64, 3)

另外,我认为fit_generator()不赞成将生成器传递给fit().

编辑:如果您有来自视频流的一系列帧,您可以将它们堆叠成一个多维数组。您必须以正确的顺序从目录中手动获取图像,然后创建一个数据迭代器:

images = <ordered list of 3-D numpy arrays>
img_seq = np.stack(images, axis=0)

# Do the above for each sequence of images in the training data to get N sequences
sequences = <list of sequences of images of length N>
labels = <array of labels of length N>

train_data = tf.data.Dataset.from_tensor_slices((sequence, labels))
train_data = train_data.shuffle(1000).batch(batch_size)
# Do similar for test data

然后,您可以使用tf.data.Datasetin fit()

model.fit(train_data, validation_data=test_data)

推荐阅读