tensorflow 在使用imagedatagenerator时,有没有办法更改类的数量?

iyfjxgzm  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(144)

我目前正在使用我自己的数据集,其中有4类(猫,狗,老鼠,金枪鱼),到目前为止,我能够在这4类之间进行相当好的分类。
我现在想把这个问题改为“哺乳动物和非哺乳动物之间的分类”,但我找不到一种方法来做到这一点,而不改变图像存储在每个文件夹上的方式。
我想出了一个不是很有效的方法:

def to2Clases(image_generator,batch_size):
  noMammal= (0,0,0,1,)
  for x, y in image_generator:
    for i in range(len(y)):
      
      if all(y[i]==noMammal): y[i] = (0,1,0,0,)
      else: y[i] = (1,0,0,0,)
  yield x, y

例如,我可以使用原始类进行预测,并在需要时转换预测,但我认为这将是我从一开始就一直在处理的同一个问题
有人知道更好的方法吗?

其他方法

唯一的“解决方案”,我能够找到使用Mnist数据集,并将问题转换为二进制分类(偶数/奇数)

even=[0,2,4,6,8]

        #Converting Train labels from numbers to even/odd
        Y_trainbinary= np.empty(Y_train.shape[0],dtype=object)     
        for idx, item in enumerate(Y_train):                     
              if np.nonzero(item)[0] in even:
                    Y_trainbinary[idx] = 0     # even number
              else:
                    Y_trainbinary[idx] = 1     # odd number

        Y_trainmodel = np_utils.to_categorical(Y_trainbinary)

这个解决方案并不适合我,因为MNIST使用标签编码,而我的train生成器使用one-hot编码。

其他信息

这是我定义train_generator的方式

train_datagen = ImageDataGenerator(
    rescale = 1./255,
    horizontal_flip = True,
    vertical_flip = True,
    validation_split = 0.1)

train_generator = train_datagen.flow_from_directory(
    data_train,
    target_size = (img_height, img_width),
    batch_size = batch_size,
    shuffle = True,
    class_mode = 'categorical',
    subset = 'training',
    seed = 42)

这里我打印y来查看它的形状:

x,y = train_generator.next()

print(len(y))
print(len(y[0]))
print(y[0])

输出如下:
32(批量)
4(班级数
[0. 1. 0. 0.](元组)

oaxa6hgo

oaxa6hgo1#

我能够来一个解决方案,我想张贴它的情况下,有人有同样的问题。
首先,在创建生成器时,您必须忘记使用“从目录流动”,而是使用“从数据框架流动”。
要创建 Dataframe ,可以使用以下代码:

lst = list(data_train.glob("*/*.tiff"))
newLst = list() 
print(lst[0])
for l in lst:
    if l.parent == data_train / "bird":
      type="Not Mammal"
    else:
      type="Mammal"
    newLst.append((str(l),type))

df = pd.DataFrame(newLst, columns = ['path', 'category'])
print(df)

通过这种方式,您可以更改类别的名称(这是使用目录时无法做到的一件事)。
然后使用(几乎)相同的代码初始化生成器:

train_datagen = ImageDataGenerator(
    rescale = 1./255,
    horizontal_flip = True,
    vertical_flip = True,
    validation_split = 0.1)

train_generator = train_datagen.flow_from_dataframe(
    df,
    x_col = "path",
    y_col="category"
    target_size = (img_height, img_width),
    batch_size = batch_size,
    shuffle = True,
    class_mode = 'binary', 
    subset = 'training',
    seed = 42)

到目前为止,它的工作方式与从目录流相同。

相关问题