首页 > 解决方案 > 为 keras 实现生成器会导致更糟糕的结果

问题描述

我正在对大约 3000 张图像的数据集进行多标签图像分类。因为这是我工作内存的限制并且数据集会增加,所以我尝试实现自己的生成器,因为我也在解析来自在线资源的图像。该网络达到了 25% 的准确度,其中三个准确度最高的标签可以很好地表示图像。

正常批次的形状为 (32, 64, 64, 3),标签的形状为 (32, 57)。我的模型看起来像:

def createModel(shape, classes):
    x = shape[0]
    y = shape[1]
    z = shape[2]
    model = Sequential()
    model.add(Conv2D(32, (2, 2), padding='same',input_shape=(x,y,z)))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Conv2D(32, (2, 1), padding='same'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Conv2D(32, (1, 2), padding='same'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides = 2))

    model.add(Conv2D(48, (2, 2), padding='same'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides = 2))

    model.add(Conv2D(80, (2, 2), padding='same'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides = 2))

    model.add(Flatten())
    model.add(Dense(classes, activation = 'sigmoid'))

其中类为 57,x、y、z 为 64、64、3。

我的发电机看起来像:

def generator(data, urls, labels, batch_size):
    counter = 0
    X_train = []
    Y_train = []

    while 1:
        for i in range(len(data)):
            if counter == batch_size:
                yield (np.array(X_train), np.array(Y_train))
                X_train = []
                Y_train = []
                counter = 0
            try:
                ID = data[i][0]
                if random.uniform(0,1) > 0.5:
                    X_train.append(getImage(64, urls[ID]))
                else:
                    X_train.append(np.flip(getImage(64, urls[ID]),1))
                Y_train.append(labels[i])
                counter+=1
            except:
                continue

其中 data 是带有图像 ID 和标签的列表,urls 是带有图像 ID 和用于查找图像的 url 的列表,标签是由 MultiLabelBinarizer() (.fit_transform) 和 batch_size 转换的标签。getImage() 函数产生一个 np.array() ,其中 64 给出了形状。

主要调用:

epochs = 60
lr = 1e-6

mlc = model.createModel((64,64,3), 57)

opt = Adam(lr=lr, decay=lr / epochs)

trainGenerator = data.generator(structuredData, urls, mlb_labels, 32)
validationGenerator = data.generator(structuredData, urls, mlb_labels, 32)

mlc.compile(loss="categorical_crossentropy", optimizer=opt, metrics= 
["accuracy"])

mlc.fit_generator(trainGenerator, steps_per_epoch = 10, epochs=epochs, 
validation_steps = 1, validation_data=validationGenerator)

mlc.save("datagenerator_test.h5")

此外,如果我不使用生成器,网络因此已经可以工作并进行训练,使用生成器似乎可以得到 1% 到 3% 之间的随机准确度。我希望这提供了足够的信息。

编辑:我需要大约 90 秒来准备一批 32 张图像。培训是否等待批次准备好?

标签: pythonkeras

解决方案


推荐阅读