多输入卷积神经网络用于图像分类。

3
我是深度学习的初学者,想在Keras中创建一个多输入卷积神经网络(CNN)模型,用于图像分类。我正在努力创建一个CNN模型,它可以接收两个图像作为输入,并输出一个代表这两个图像类别的输出。我有两个数据集:Type1和Type2,每个数据集都包含相同的类别,但是在Type1数据集中,每个类别的图像数量要高于Type2数据集。模型应该从Type1数据集中取一个图像,从Type2数据集中取另一个图像,然后将这些图像分类到一个类别(ClassA或ClassB或------)。以下是数据集的结构。
Type1 dataset
|Train
              |ClassA
                             |image1
                             |image2
                             |image3
                             |image4
                            -----
              |ClassB
                             |image1
                             |image2
                             |image3
                             |image4
                            -----
              |ClassC
                             |image1
                             |image2
                             |image3
                             |image4
                            -----
              |ClassD
                             |image1
                             |image2
                             |image3
                             |image4
                            -----
       ----------------
|Validate
            -----------
|Test
           --------------

Type2 dataset
|Train
              |ClassA
                             |image1
                             |image2
                            -----
              |ClassB
                             |image1
                             |image2
                            -----
              |ClassC
                             |image1
                             |image2
                            -----
              |ClassD
                             |image1
                             |image2
                            -----
       ----------------
|Validate
            -----------
|Test
           --------------

这个模型与图像中的模型非常相似,但在扁平化层之前有更多的层。

Multi-input

我创建了一个自定义生成器,输入两个图像(来自类型1和2),并且每个类型1的图像都与属于相同类别(标签)的类型2的所有图像配对。
问题是在执行fit_generator时,会出现无限循环,如下所示:
  Found *** images belonging to 100 classes.

    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes.
    Found *** images belonging to 100 classes. ......
.................................................................

这是我的自定义生成器代码:

input_imgen = ImageDataGenerator( 
                                  rotation_range=10,
                                  shear_range=0.2,
                                  zoom_range=0.1,
                                  width_shift_range=0.1,
                                  height_shift_range=0.1
                                  )



test_imgen = ImageDataGenerator()



def generate_generator_multiple(generator,dir1, dir2, batch_size, img_height,img_width):


    genX1 = generator.flow_from_directory(dir1,
                                          target_size = (img_height,img_width),
                                          class_mode = 'categorical',
                                          batch_size = batch_size,
                                          shuffle=False, 
                                          seed=7)

    genX2 = generator.flow_from_directory(dir2,
                                          target_size = (img_height,img_width),
                                          class_mode = 'categorical',
                                          batch_size = batch_size,
                                          shuffle=False, 
                                          seed=7)
    while True:
      X2i = genX2.next() 
      Type1 = []
      Type2 = []
      image1 = []
      image2 = []

      while True:
        X1i = genX1.next() 
        for i in range(len(X2i[1])): #Type2
          for j in range(len(X1i[1])): #Type1
            if all(X2i[1][i]) == all(X1i[1][j]): # have same label
              image1.append(X1i[0][j]) # add image
              image1.append(X1i[1][j]) # add label
              image2.append(X2i[0][i]) # add image
              image2.append(X2i[1][i]) # add label
      Type1.append(image1)
      Type2.append(image2)
      yield [Type1 [0], Type2 [0]], Type2 [1]  #Yield both images and their mutual label


inputgenerator=generate_generator_multiple(generator=input_imgen,
                                           dir1=train_iris_data,
                                           dir2=train_face_data,
                                           batch_size=32,
                                           img_height=224,
                                           img_width=224)       

validgenerator=generate_generator_multiple(generator=test_imgen,
                                          dir1=valid_iris_data,
                                          dir2=valid_face_data,
                                          batch_size=32,
                                          img_height=224,
                                          img_width=224) 

testgenerator=generate_generator_multiple(generator=test_imgen,
                                          dir1=test_face_data,
                                          dir2=test_face_data,
                                          batch_size=32,
                                          img_height=224,
                                          img_width=224)


    # compile the model
    multi_model.compile(
            loss='categorical_crossentropy',
            optimizer=Adam(lr=0.0001),
            metrics=['accuracy']
        )


# train the model and save the history
history = multi_model.fit_generator(
inputgenerator,
steps_per_epoch=len(train_data) // batch_size,
epochs=10,
verbose=1,
validation_data=validgenerator,
validation_steps=len(valid_data) // batch_size,
use_multiprocessing=True,
shuffle=False
)

你能帮我解决这个问题并创建自定义生成器吗?


1
由于您已经了解每个数据集的结构和文件名,因此可以创建一个文件名元组列表,这些元组属于相同的类别但来自不同类型,然后使用生成器从这些文件名读取图像并产生图像和标签。 - kvish
谢谢您的建议。如果我采用这个建议,我需要在数据集中复制图像,而且我有很多图像。您认为复制图像的数量比创建自定义的“fit_generator”更好吗? - Noran
1
如果您有大量的图像,那么也许您可以考虑对数据进行采样,以便您可以提供足够数量的图像。可能并不需要使用这些图像的每个组合。我看到您当前方法的主要问题是将生成器嵌套在生成器中,并保存从每个生成器获取的图像数据会消耗大量内存。生成器非常高效,因为您只在需要时使用较小的内存量。 - kvish
1个回答

0
class MultipleInputGenerator(Sequence):
    def __init__(self, dir_train_01, dir_train_02, batch_size):
        # Keras生成器
        self.generator = ImageDataGenerator(rotation_range=15, 
                                            width_shift_range=0.2,
                                            height_shift_range=0.2,
                                            shear_range=0.2,
                                            zoom_range=0.2,
                                            horizontal_flip=True, 
                                            fill_mode='nearest')
# 实时多输入数据增强 self.genX1 = self.generator.flow_from_directory( dir_train_01, target_size = IMG_SIZE, batch_size = BATCH_SIZE, class_mode = 'categorical', color_mode = 'rgb', # 转换为RGB seed = SEED ) self.genX2 = self.generator.flow_from_directory( dir_train_02, target_size = IMG_SIZE, batch_size = BATCH_SIZE, class_mode = 'categorical', color_mode = 'rgb', # 转换为RGB seed = SEED )
def __len__(self): """在Keras序列中实现它是强制性的""" return self.genX1.__len__()
def __getitem__(self, index): """从两个生成器中获取项目并打包它们""" X1_batch, Y_batch = self.genX1.__getitem__(index) X2_batch, Y_batch = self.genX2.__getitem__(index)
X_batch = [X1_batch, X2_batch]
return X_batch, Y_batch

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接