TensorFlow Keras Оптимизация прогноза - PullRequest
0 голосов
/ 26 февраля 2019

Я использую тензорный поток и керас для прогнозирования чисел рукописного ввода.Для обучения я использую набор данных nmist.точность составляет около 98,8% после тренировки.но иногда в тесте путают между 4 и 9, 7 и 3, я alerady оптимизировать ввод изображения с помощью opencv, например, удалить шум, масштабирование, порог и т. д.
Что мне делать дальше, чтобы улучшить этот пунктточность?

Мой план состоит в том, чтобы добавить больше образца и изменить размер образца изображения с 28x28 до 56x56.
Повлияет ли это на точность?

Это моемодель для тренировки:

epoc=15, batch size=64

def build_model():
    model = Sequential()
    # add Convolutional layers
    model.add(Conv2D(filters=32, kernel_size=(3,3), activation='relu', padding='same', input_shape=input_shape))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same'))
    model.add(MaxPooling2D(pool_size=(2,2)))    
    model.add(Flatten())
    # Densely connected layers
    model.add(Dense(128, activation='relu'))

    # output layer
    model.add(Dense(10, activation='softmax'))

    # compile with adam optimizer & categorical_crossentropy loss function
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

    return model

1 Ответ

0 голосов
/ 11 июля 2019

Вы можете попытаться добавить регуляризацию:

def conv2d_bn(x,
              units,
              kernel_size=(3, 3),
              activation='relu',
              dropout=.5):
    y = Dropout(x)
    y = Conv2D(units, kernel_size=kernel_size, use_bias=False)(y)
    y = BatchNormalization(y)
    y = Activation(activation)(y)

    return y

def build_model(..., dropout=.5):
    x = Input(shape=[...])
    y = conv2d_bn(x, 32)
    y = MaxPooling2D(y)
    ...
    y = Dropout(dropout)(y)
    y = Dense(10, activation='softmax')

    model = Model(x, y)
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])

    return model

Вы можете настроить вес классов, чтобы заставить модель уделять больше внимания классам 3, 4, 7 и 9 во время обучения:

model.fit(..., class_weights={0: 1, 1: 1, 2:1, 3:2, 4:2, 5:1, 6:1, 7:2, 8:1, 9:2})

Если у вас есть время для записи, вы также можете попробовать grid или random-search гиперпараметры модели.Что-то в строках:

def build(conv_layers, dense_layers, dense_units, activation, dropout):
    y = x = Input(shape=[...])

    kernels = 32
    kernel_size = (2, 2)

    for i in range(conv_layers):
        y = conv2d_bn(y, kernel_size, kernels, activation, dropout)

        if i % 2 == 0:  # or 3 or 4.
            y = MaxPooling2D(y)
            kernels *= 2
            kernel_size = tuple(k+1 for k in kernel_size)

    y = GlobalAveragePooling2D()(y)

    for i in range(dense_layers):
        y = Dropout(dropout)(y)
        y = Dense(dense_units)(y)

    y = Dense(10, activation='softmax')(y)


model = KerasClassifier(build_model,
                        epochs=epochs,
                        validation_split=validation_split,
                        verbose=0,
                        ...)
params = dict(conv_layers=[2, 3, 4],
              dense_layers=[0, 1],
              activation=['relu', 'selu'],
              dropout=[.2, .3, .5],
              callbacks=[callbacks.EarlyStopping(patience=10,
                                                 restore_best_weights=True)])

grid = GridSearchCV(model, params,
                    scoring='balanced_accuracy_score',
                    verbose=2,
                    n_jobs=1)

Теперь объединить поиск гиперпарамов с NumpyArrayIterator немного сложно, потому что последний предполагает, что у нас есть все тренировочные образцы (и цели) под рукой до этапов обучения.Это все еще выполнимо, хотя:

g = ImageDataGenerator(...)
cv = StratifiedKFold(n_splits=3)
results = dict(params=[], valid_score=[])

for params in ParameterGrid(params):
    fold_scores = []

    for t, v in cv.split(train_data, train_labels):
        train = g.flow(train_data[t], train_labels[t], subset='training')
        nn_valid = g.flow(train_data[t], train_labels[t], subset='validation')
        fold_valid = g.flow(train_data[v], train_labels[v])

        nn = build_model(**params)
        nn.fit_generator(train, validation_data=nn_valid, ...)

        probabilities = nn.predict_generator(fold_valid, steps=...)
        p = np.argmax(probabilities, axis=1)

        fold_scores += [metrics.accuracy_score(valid.classes_, p)]

    results['params'] += [params]
    results['valid_score'] += [fold_scores]

best_ix = np.argmax(np.mean(results['valid_score'], axis=1))
best_params = results['params'][best_ix]

nn = build_model(**best_params)
nn.fit_generator(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...