XGBoost 速度问题

数据挖掘 机器学习 Python xgboost 机器学习模型 优化
2022-03-10 17:21:32

我正在尝试优化 XGBoost 的超参数,因此需要使用不同的参数多次运行它。然而,使用下面代码中提供的参数运行单个 XGBoost 所需的时间需要大量时间(因为优化需要大样本量的多次迭代)。

我的同事声称,对于 20 的样本大小和 13 次迭代(因此运行 XGBoost 需要 260 次),它需要 2h47'(167')(在 2 个内核上)。但是到目前为止,我无法看到这种速度。对我来说,提供的代码需要 ~4' 才能在我尝试过的所有机器上运行(总是 2 个核心机器并使用 2 个线程)。因此,总共 260 次 XGBoost 训练将花费我 1040 分钟(约 6 倍以上的时间)。

由于同事的代码使用的平均num_boost_round约为 250,所以我平均预计单次 XGBoost 训练需要 4 分钟以上。

由于运行 XGBoost 的快速版本是几个月前,计算机的配置可能会更改,因为我无法重现此速度。有谁知道可能是什么问题?您使用 xgboost 设置运行此代码段需要多长时间?

mnist-numbers 数据集可在此处下载:http: //yann.lecun.com/exdb/mnist/

我正在使用使用 pip: 安装的 XGBoost python 包pip install xgboost

使用的参数包含在代码片段中

编码:

import xgboost as xgb
import time
import os
import struct
import numpy as np

# Read MNIST files
def read_images(images_name):
    f = open(images_name, "rb")
    ds_images = []
    mw_32bit = f.read(4)
    n_numbers_32bit = f.read(4)
    n_rows_32bit = f.read(4)
    n_columns_32bit = f.read(4)
    mw = struct.unpack('>i', mw_32bit)[0]
    n_numbers = struct.unpack('>i', n_numbers_32bit)[0]
    n_rows = struct.unpack('>i', n_rows_32bit)[0]
    n_columns = struct.unpack('>i', n_columns_32bit)[0]
    try:
        for i in range(n_numbers):
            image = []
            for r in range(n_rows):
                for l in range(n_columns):
                    byte = f.read(1)
                    pixel = struct.unpack('B', byte)[0]
                    image.append(pixel)
            ds_images.append(image)
    finally:
        f.close()
    return ds_images


def read_labels(labels_name):
    f = open(labels_name, "rb")
    ds_labels = []
    mw_32bit = f.read(4)
    n_numbers_32bit = f.read(4)
    mw = struct.unpack('>i', mw_32bit)[0]
    n_numbers = struct.unpack('>i', n_numbers_32bit)[0]
    try:
        for i in range(n_numbers):
            byte = f.read(1)
            label = struct.unpack('B', byte)[0]
            ds_labels.append(label)
    finally:
        f.close()
    return ds_labels


def read_dataset(images_name, labels_name):
    images = read_images(images_name)
    labels = read_labels(labels_name)
    assert len(images) == len(labels)
    return (images, labels)


def create_datasets(sample_dir):
    image_file = os.path.join(sample_dir, 'train-images-idx3-ubyte')
    label_file = os.path.join(sample_dir, 'train-labels-idx1-ubyte')
    training_images, training_labels = read_dataset(image_file, label_file)
    image_file = os.path.join(sample_dir, 't10k-images-idx3-ubyte')
    label_file = os.path.join(sample_dir, 't10k-labels-idx1-ubyte')
    testing_images, testing_labels = read_dataset(image_file, label_file)
    dtrain = xgb.DMatrix(
        np.asmatrix(training_images),
        label=training_labels,
        nthread=2
    )
    dtest = xgb.DMatrix(
        np.asmatrix(testing_images),
        label=testing_labels,
        nthread=2
    )
    data_dict = {
        'dtrain': dtrain,
        'dtest': dtest,
        'training_labels': training_labels,
        'testing_labels': testing_labels
    }
    return data_dict


def main():
    data_dict = create_datasets("/path/to/mnist/numbers/sample")
    parameters = {
        'learning_rate': 0.1,
        'max_depth': 3,
        'gamma': 1,
        'min_child_weight': 20,
        'subsample': 0.8,
        'colsample_bytree': 0.4,
        'verbosity': 1,
        'objective': 'multi:softprob',
        'num_class': 10,
        'nthread': 2,
        'seed': 1,
    }
    start = time.time()
    model = xgb.train(
        parameters,
        data_dict['dtrain'],
        num_boost_round=100
    )
    end = time.time()
    print("Model training time: ", end-start)
    start2 = time.time()
    pred_train = model.predict(data_dict['dtrain'])
    end2 = time.time()
    print("Predict time: ", end2-start2)


if __name__ == '__main__':
    main()
1个回答

仔细检查您是否获得了基于线程的加速。变化nthread,看看增加核心是否会减少训练时间。

您只使用两个线程,nthread=2. 最好通过设置来使用所有可能的内核nthread=-1即使您当前机器上只有两个内核,它也可能会有所帮助。

然后转移到具有更多内核的机器上。