我正在尝试使用相同的数据集在Keras中重现面部形状分类(https://github.com/adonistio/inception-face-shape-classifier/blob/master/Paper%20v3.pdf) . 该数据集由500个5类(每组100个)的图像组成:心形,椭圆形,椭圆形,圆形和方形 . 图像有不同的尺寸,但面部是对齐的 .

示例图片:heart_agreene_003.jpg . 类:心形 .

不幸的是,我无法训练一个好的模型,我的准确率停留在20%(roc_auc_score = 0.5) . 在这一刻,有些反馈会非常好 .

我尝试了各种CNN架构,批量大小,学习率,优化器和数据增强 .

import os
import cv2
import numpy as np
import pandas as pd
from sklearn.model_selection import KFold, train_test_split
import matplotlib.pyplot as plt

from sklearn import metrics
import keras
from keras.models import Model
from keras.optimizers import SGD
from keras.applications.inception_v3 import InceptionV3
from keras.layers import Dense, Input, Flatten, Dropout, GlobalAveragePooling2D
from keras.layers.normalization import BatchNormalization
from keras.preprocessing.image import ImageDataGenerator
from keras.utils import np_utils

path = '...'

folders = next(os.walk(path))[1]

filepaths = []
labels = []

for i, cls in enumerate(folders):
    files = next(os.walk(path + cls + '/'))[2]

    for file in files:
        filepaths.append(path + cls + '/' + file)

        labels.append(i)

# convert to dummies
labels = np_utils.to_categorical(labels)

fps_train, fps_test, labels_train, labels_test = train_test_split(filepaths, labels, test_size=0.2, random_state=2018)

img_height = 299
img_width = 299
img_channels = 3
img_dim = (img_height, img_width, img_channels)
img_size = (img_height, img_width)

datagen = ImageDataGenerator(
        rescale=1./255,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.15,
        zoom_range=0.15,
        horizontal_flip=True)

def arc(img_dim=img_dim):
    base_model = InceptionV3(weights="imagenet", include_top=False, input_shape=img_dim)

    for l in base_model.layers:
            l.trainable = False

    x = base_model.output
    x = Flatten()(x)
    x = Dense(2048, activation="relu")(x)
    x = Dropout(0.5)(x)
    predictions = Dense(len(folders), activation="softmax")(x)

    # creating the final model 
    model = Model(inputs = base_model.input, outputs = predictions)

    return model

model = arc()

batch_size = 16
epochs = 100
n_folds = 3

preds_test = 0
train_scores = []; valid_scores = []

kf = KFold(n_splits=n_folds, random_state=10, shuffle=True)

history = []

for i, (train_index, test_index) in enumerate(kf.split(fps_train)):
        x_train = [fps_train[j] for j in train_index]; x_valid = [fps_train[j] for j in test_index]
        y_train = labels_train[train_index]; y_valid = labels_train[test_index]

        def train_generator():
            while 1:
                for start in range(0, len(x_train), batch_size):
                    x_batch = []
                    end = min(start + batch_size, len(x_train))
                    train_batch = x_train[start:end]
                    for filepath in train_batch:
                        img = cv2.imread(filepath)
                        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                        img = cv2.resize(img, img_size)

                        # data augmentation
                        img = np.expand_dims(img, axis=0)
                        img = next(datagen.flow(img, batch_size=1))[0]

                        x_batch.append(img)

                    y_batch = y_train[start:end]

                    x_batch = np.array(x_batch, np.float32)
                    y_batch = np.array(y_batch, np.uint8)
                    yield x_batch, y_batch

        def valid_generator():
            while 1:
                for start in range(0, len(x_valid), batch_size):
                    x_batch = []
                    end = min(start + batch_size, len(x_valid))
                    valid_batch = x_valid[start:end]
                    for filepath in valid_batch:
                        img = cv2.imread(filepath)
                        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                        img = cv2.resize(img, img_size)

                        # data augmentation
                        img = np.expand_dims(img, axis=0)
                        img = next(datagen.flow(img, batch_size=1))[0]

                        x_batch.append(img)

                    y_batch = y_train[start:end]     

                    x_batch = np.array(x_batch, np.float32)
                    y_batch = np.array(y_batch, np.uint8)
                    yield x_batch, y_batch

        def test_generator():
            while 1:
                for start in range(0, len(labels_test), batch_size):
                    x_batch = []
                    end = min(start + batch_size, len(labels_test))
                    test_batch = fps_test[start:end]
                    for filepath in test_batch:
                        img = cv2.imread(filepath)
                        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                        img = cv2.resize(img, img_size)
                        x_batch.append(img)
                    x_batch = np.array(x_batch, np.float32)
                    yield x_batch

        train_steps = len(x_train) / batch_size
        valid_steps = len(x_valid) / batch_size
        test_steps = len(labels_test) / batch_size

        model = model

        model.compile(optimizer=SGD(lr=0.00001, momentum=0.9), loss='categorical_crossentropy', 
                      metrics = ['accuracy'])

        # sparse_categorical_crossentropy
        history.append(model.fit_generator(train_generator(), 
                            train_steps, 
                            epochs=epochs, 
                            verbose=1, 
                            validation_data=valid_generator(), 
                            validation_steps=valid_steps,
                            shuffle=True))

        preds_valid = model.predict_generator(generator=valid_generator(),
                                      steps=valid_steps, verbose=1)

        preds_train = model.predict_generator(generator=train_generator(),
                                      steps=train_steps, verbose=1)

        preds_test_fold = model.predict_generator(generator=test_generator(),
                                              steps=test_steps, verbose=1)

        valid_score = metrics.roc_auc_score(y_valid, preds_valid)
        train_score = metrics.roc_auc_score(y_train, preds_train)

        print('valid score:{} for fold {}'.format(valid_score, i))
        print('train score: {} for fold {}'.format(train_score, i))

        valid_scores.append(valid_score)
        train_scores.append(train_score)

        print('avg valid score:{0:0.5f} after {1:0.5f} folds'.format(np.mean(valid_scores), i))
        print('avg train score:{0:0.5f} after {1:0.5f} folds'.format(np.mean(train_scores), i))

        preds_test += preds_test_fold

preds_test /= n_folds

test_score = metrics.roc_auc_score(labels_test, preds_test)
print(test_score)

.

Epoch 1/100
13/12 [===============================] - 114s 9s/step - loss: 1.7377 - acc: 0.2696 - val_loss: 1.7597 - val_acc: 0.2300
Epoch 2/100
13/12 [===============================] - 110s 8s/step - loss: 1.6934 - acc: 0.3023 - val_loss: 1.8588 - val_acc: 0.1550
Epoch 3/100
13/12 [===============================] - 111s 9s/step - loss: 1.7105 - acc: 0.3643 - val_loss: 1.7486 - val_acc: 0.2500
Epoch 4/100
13/12 [===============================] - 111s 9s/step - loss: 1.6023 - acc: 0.3164 - val_loss: 1.8622 - val_acc: 0.1950
Epoch 5/100
13/12 [===============================] - 119s 9s/step - loss: 1.6091 - acc: 0.3316 - val_loss: 1.7544 - val_acc: 0.2100
Epoch 6/100
13/12 [===============================] - 119s 9s/step - loss: 1.6923 - acc: 0.2882 - val_loss: 1.7124 - val_acc: 0.2600
Epoch 7/100
13/12 [===============================] - 118s 9s/step - loss: 1.6071 - acc: 0.3602 - val_loss: 1.8326 - val_acc: 0.2100
Epoch 8/100
13/12 [===============================] - 110s 8s/step - loss: 1.6666 - acc: 0.2882 - val_loss: 1.7460 - val_acc: 0.2250
Epoch 9/100
13/12 [===============================] - 107s 8s/step - loss: 1.5762 - acc: 0.3684 - val_loss: 1.7904 - val_acc: 0.1850
Epoch 10/100
13/12 [===============================] - 106s 8s/step - loss: 1.6371 - acc: 0.3550 - val_loss: 1.8316 - val_acc: 0.2000
Epoch 11/100
13/12 [===============================] - 105s 8s/step - loss: 1.5918 - acc: 0.3602 - val_loss: 1.6973 - val_acc: 0.2650
Epoch 12/100
13/12 [===============================] - 106s 8s/step - loss: 1.5225 - acc: 0.3987 - val_loss: 1.7811 - val_acc: 0.2100
Epoch 13/100
13/12 [===============================] - 105s 8s/step - loss: 1.6055 - acc: 0.3561 - val_loss: 1.8557 - val_acc: 0.1450
Epoch 14/100
13/12 [===============================] - 108s 8s/step - loss: 1.5136 - acc: 0.3368 - val_loss: 1.8463 - val_acc: 0.1650
Epoch 15/100
13/12 [===============================] - 108s 8s/step - loss: 1.5672 - acc: 0.3654 - val_loss: 1.7392 - val_acc: 0.2050
Epoch 16/100
13/12 [===============================] - 109s 8s/step - loss: 1.5112 - acc: 0.3939 - val_loss: 1.7721 - val_acc: 0.2200
Epoch 17/100
13/12 [===============================] - 106s 8s/step - loss: 1.3944 - acc: 0.4614 - val_loss: 1.7274 - val_acc: 0.2200
Epoch 18/100
13/12 [===============================] - 106s 8s/step - loss: 1.3603 - acc: 0.4559 - val_loss: 1.7671 - val_acc: 0.2050
Epoch 19/100
13/12 [===============================] - 107s 8s/step - loss: 1.4985 - acc: 0.3843 - val_loss: 1.7367 - val_acc: 0.2150
Epoch 20/100
13/12 [===============================] - 107s 8s/step - loss: 1.4073 - acc: 0.4180 - val_loss: 1.8292 - val_acc: 0.1700
Epoch 21/100
13/12 [===============================] - 111s 9s/step - loss: 1.4495 - acc: 0.3743 - val_loss: 1.8178 - val_acc: 0.2050
Epoch 22/100
13/12 [===============================] - 108s 8s/step - loss: 1.3810 - acc: 0.4704 - val_loss: 1.8049 - val_acc: 0.2000
Epoch 23/100
13/12 [===============================] - 105s 8s/step - loss: 1.3556 - acc: 0.4366 - val_loss: 1.7813 - val_acc: 0.2050
Epoch 24/100
13/12 [===============================] - 111s 9s/step - loss: 1.3139 - acc: 0.4614 - val_loss: 1.8184 - val_acc: 0.2000
Epoch 25/100
13/12 [===============================] - 111s 9s/step - loss: 1.4152 - acc: 0.4421 - val_loss: 1.8859 - val_acc: 0.1300
Epoch 26/100
13/12 [===============================] - 110s 8s/step - loss: 1.3630 - acc: 0.4577 - val_loss: 1.7652 - val_acc: 0.2250
Epoch 27/100
13/12 [===============================] - 110s 8s/step - loss: 1.3347 - acc: 0.4521 - val_loss: 1.7304 - val_acc: 0.2200
Epoch 28/100
13/12 [===============================] - 107s 8s/step - loss: 1.2981 - acc: 0.5048 - val_loss: 1.8108 - val_acc: 0.2200
Epoch 29/100
 2/12 [===>..........................] - ETA: 52s - loss: 1.5823 - acc: 0.3125