Почему RandomForestClassifier на CPU (с использованием SKLearn) и на GPU (с использованием RAPID) получает разные оценки, очень разные? - PullRequest
0 голосов
/ 12 марта 2020

Я использую RandomForestClassifier на процессоре с SKLearn и на GPU с использованием RAPID. Я делаю эталонный тест между этими двумя библиотеками на предмет ускорения и оценки с использованием набора данных Iris (это попытка, в будущем я изменю набор данных для лучшего сравнения, я начинаю с этих двух библиотек).

Проблема в том, что когда я измеряю счет на CPU, всегда получаю значение 1,0, но когда я пытаюсь измерить счет на GPU, я получаю переменное значение от 0,2 до 1,0, и я не понимаю, почему это могло произойти.

Прежде всего, используемые мной версии библиотек:

NumPy Version: 1.17.5
Pandas Version: 0.25.3
Scikit-Learn Version: 0.22.1
cuPY Version: 6.7.0
cuDF Version: 0.12.0
cuML Version: 0.12.0
Dask Version: 2.10.1
DaskCuda Version: 0+unknown
DaskCuDF Version: 0.12.0
MatPlotLib Version: 3.1.3
SeaBorn Version: 0.10.0

Код, который я использую для SKLearn RandomForestClassifier:

# Read data in host memory
host_s_csv = pd.read_csv('./DataSet/iris.csv', header = 0, delimiter = ',') # Get complete CSV
host_s_data = host_s_csv.iloc[:, [0, 1, 2, 3]].astype('float32') # Get data columns
host_s_labels = host_s_csv.iloc[:, 4].astype('category').cat.codes # Get labels column

# Plot data
#sns.pairplot(host_s_csv, hue = 'variety');

# Split train and test data
host_s_data_train, host_s_data_test, host_s_labels_train, host_s_labels_test = sk_train_test_split(host_s_data, host_s_labels, test_size = 0.2, random_state = 0)

# Create RandomForest model
sk_s_random_forest = skRandomForestClassifier(n_estimators = 40,
                                             max_depth = 16,
                                             max_features = 1.0,
                                             random_state = 10, 
                                             n_jobs = 1)

# Fit data in RandomForest
sk_s_random_forest.fit(host_s_data_train, host_s_labels_train)

# Predict data
sk_s_random_forest_labels_predicted = sk_s_random_forest.predict(host_s_data_test)

# Check score
print('accuracy_score: ', sk_accuracy_score(host_s_labels_test, sk_s_random_forest_labels_predicted))

Код, который я использую для RAPID RandomForestClassifier:

# Read data in device memory
device_s_csv = cudf.read_csv('./DataSet/iris.csv', header = 0, delimiter = ',') # Get complete CSV
device_s_data = device_s_csv.iloc[:, [0, 1, 2, 3]].astype('float32') # Get data columns
device_s_labels = device_s_csv.iloc[:, 4].astype('category').cat.codes # Get labels column

# Plot data
#sns.pairplot(device_s_csv.to_pandas(), hue = 'variety');

# Split train and test data
device_s_data_train, device_s_data_test, device_s_labels_train, device_s_labels_test = cu_train_test_split(device_s_data, device_s_labels, train_size = 0.8, shuffle = True, random_state = 0)

# Use same data as host
#device_s_data_train = cudf.DataFrame.from_pandas(host_s_data_train)
#device_s_data_test = cudf.DataFrame.from_pandas(host_s_data_test)
#device_s_labels_train = cudf.Series.from_pandas(host_s_labels_train).astype('int32')
#device_s_labels_test = cudf.Series.from_pandas(host_s_labels_test).astype('int32')

# Create RandomForest model
cu_s_random_forest = cusRandomForestClassifier(n_estimators = 40,
                                               max_depth = 16,
                                               max_features = 1.0,
                                               n_streams = 1)

# Fit data in RandomForest
cu_s_random_forest.fit(device_s_data_train, device_s_labels_train)

# Predict data
cu_s_random_forest_labels_predicted = cu_s_random_forest.predict(device_s_data_test)

# Check score
print('accuracy_score: ', cu_accuracy_score(device_s_labels_test, cu_s_random_forest_labels_predicted))

И пример набора данных радужной оболочки, который я использую:

Iris dataset example

Знаете ли вы, почему могли это происходит? Обе модели установлены равными, одинаковые параметры ... Я понятия не имею, почему такая большая разница между оценками.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Это вызвано известной проблемой в нашем коде предсказания, которая была исправлена ​​в 0.13 с предупреждением и откатом к ЦП в мультиклассовых классификациях. В версии 0.12 у нас не было предупреждений или откатов, поэтому, если вы не знали, использовать predict_model="CPU' в многоклассовой классификации, вы получите [намного] более низкий балл прогнозирования, чем при использовании модель, которая вам подходит.

Смотрите вопрос здесь: https://github.com/rapidsai/cuml/issues/1623

Вот код, который поможет вам и другим. Он был изменен, так что в будущем другим будет немного легче. Я получаю ~ 0,9333 на GV100 и RAPIDS 0,12 стабильной.

import cudf as cu
from cuml.ensemble import RandomForestClassifier as cusRandomForestClassifier
from cuml.metrics import accuracy_score as cu_accuracy_score
from cuml.preprocessing.model_selection import train_test_split as cu_train_test_split
import numpy as np

# data link: https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/639388c2cbc2120a14dcf466e85730eb8be498bb/iris.csv

# Read data
df = cu.read_csv('./iris.csv', header = 0, delimiter = ',') # Get complete CSV

# Prep data
X = df.iloc[:, [0, 1, 2, 3]].astype(np.float32) # Get data columns.  Must be float32 for our Classifier
y = df.iloc[:, 4].astype('category').cat.codes # Get labels column.  Will convert to int32

cu_s_random_forest = cusRandomForestClassifier(
                                           n_bins = 16, 
                                           n_estimators = 40,
                                           max_depth = 16,
                                           max_features = 1.0,
                                           n_streams = 1)

train_data, test_data, train_label, test_label = cu_train_test_split(X, y, train_size=0.8)

# Fit data in RandomForest
cu_s_random_forest.fit(train_data,train_label)

# Predict data
predict = cu_s_random_forest.predict(test_data, predict_model="CPU") # use CPU to do multi-class classifications
print(predict)

# Check score
print('accuracy_score: ', cu_accuracy_score(test_label, predict))
0 голосов
/ 12 марта 2020

Я попробовал это из вашего примера выше, преобразовал вещи в numpy, и это сработало

import numpy as np
train_label_np = host_s_labels_train.as_matrix().astype(np.int32)
train_data_np = host_s_data_train.as_matrix().astype(np.float32)
test_label_np = host_s_labels_test.as_matrix().astype(np.int32)
test_data_np = host_s_data_test.as_matrix().astype(np.float32)

cu_s_random_forest = cusRandomForestClassifier(n_estimators = 40,
                                           max_depth = 16, n_bins =16,
                                           max_features = 1.0,
                                           n_streams = 1)

# Fit data in RandomForest
cu_s_random_forest.fit(train_data_np,train_label_np)

# Predict data (GPU does not predict for multi-class at the moment. Fixed in 0.13)
predict_np = cu_s_random_forest.predict(test_data_np, predict_model='CPU')

# Check score
print('accuracy_score: ', sk_accuracy_score(test_label_np, predict_np))
...