首页 > 解决方案 > 用于图像分类的多输入卷积神经网络

问题描述

我是深度学习的初学者,我想在 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
           --------------

该模型与此图像中的模型非常相似,但在展平层之前它具有更多层。

多输入

我创建了一个自定义生成器,它输入两个图像(来自类型 1 和 2),并且来自 type1 的每个图像都与来自 type2 的每个图像配对,只要这些图像属于同一类(标签)

问题是执行时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
)

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

标签: tensorflowmachine-learningkerasdeep-learningcomputer-vision

解决方案


类MultipleInputGenerator(序列):
    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,
                                            剪切范围=0.2,
                                            缩放范围=0.2,
                                            水平翻转=真,
                                            填充模式='最近的')

        # 实时多输入数据增强
        self.genX1 = self.generator.flow_from_directory(
            dir_train_01,
            目标尺寸 = IMG_SIZE,
            批量大小 = 批量大小,
            class_mode = '分类',
            color_mode = 'rgb', # 转换为 rgb
            种子 = 种子
        )
        self.genX2 = self.generator.flow_from_directory(
            dir_train_02,
            目标尺寸 = IMG_SIZE,
            批量大小 = 批量大小,
            class_mode = '分类',
            color_mode = 'rgb', # 转换为 rgb
            种子 = 种子
        )

    def __len__(self):
        """必须在 Keras Sequence 上实现"""
        返回 self.genX1.__len__()

    def __getitem__(self, index):
        """从 2 个生成器中获取物品并打包"""
        X1_batch, Y_batch = self.genX1.__getitem__(index)
        X2_batch, Y_batch = self.genX2.__getitem__(index)

        X_batch = [X1_batch, X2_batch]

        返回 X_batch,Y_batch

推荐阅读