Tôi có một bộ 2000 cây hồi quy ngẫu nhiên được huấn luyện (từ Random Forest Regressor của scikit learn with n_estimators=1
). Đào tạo cây song song (50 lõi) trên một tập dữ liệu lớn (~ 100000 * 700000 = 70GB @ 8-bit) sử dụng multiprocessing
và bộ nhớ dùng chung hoạt động như một nét duyên dáng. Lưu ý, tôi không sử dụng hỗ trợ đa lõi sẵn có của RF kể từ khi tôi đang làm tính năng lựa chọn trước.hiểu scikit tìm hiểu Yêu cầu bộ nhớ rừng ngẫu nhiên để dự đoán
Vấn đề: khi thử nghiệm một ma trận lớn (~ 20000 * 700000) song song tôi luôn luôn hết bộ nhớ (tôi có quyền truy cập vào máy chủ có 500 GB RAM).
Chiến lược của tôi là có ma trận thử nghiệm trong bộ nhớ và chia sẻ nó trong tất cả các quy trình. Theo yêu cầu statement by one of the developers yêu cầu bộ nhớ để thử nghiệm là 2 * n_jobs * sizeof (X), và trong trường hợp của tôi, một yếu tố khác của * 4 là có liên quan, vì các mục ma trận 8 bit được truyền lên float32 trong RF.
Bằng số, tôi nghĩ để thử nghiệm tôi cần:
14GB để giữ ma trận kiểm tra trong bộ nhớ + 50 (= n_jobs) * 20000 (N_SAMPLES) * 700 (= n_features) * 4 (upcasting nổi) * 2 bytes = 14 gb + 5.6 gb = ~ 21GB bộ nhớ.
Tuy nhiên, nó luôn thổi lên hàng trăm GB. Tôi thiếu gì ở đây? (Tôi đang trên phiên bản mới nhất của scikit-học, vì vậy các vấn đề bộ nhớ cũ cần được giải quyết)
Một quan sát:
Chạy trên một lõi duy nhất sử dụng bộ nhớ để thử nghiệm dao động từ 30 đến 100 GB (được đo bởi free
)
mã của tôi:
#----------------
#helper functions
def initializeRFtest(*args):
global df_test, pt_test #initialize test data and test labels as globals in shared memory
df_test, pt_test = args
def star_testTree(model_featidx):
return predTree(*model_featidx)
#end of helper functions
#-------------------
def RFtest(models, df_test, pt_test, features_idx, no_trees):
#test trees in parallel
ncores = 50
p = Pool(ncores, initializer=initializeRFtest, initargs=(df_test, pt_test))
args = itertools.izip(models, features_idx)
out_list = p.map(star_testTree, args)
p.close()
p.join()
return out_list
def predTree(model, feat_idx):
#get all indices of samples that meet feature subset requirement
nan_rows = np.unique(np.where(df_test.iloc[:,feat_idx] == settings.nan_enc)[0])
all_rows = np.arange(df_test.shape[0])
rows = all_rows[np.invert(np.in1d(all_rows, nan_rows))] #discard rows with missing values in the given features
#predict
pred = model.predict(df_test.iloc[rows,feat_idx])
return predicted
#main program
out = RFtest(models, df_test, pt_test, features_idx, no_trees)
Edit: quan sát khác: Khi chunking dữ liệu thử nghiệm chương trình chạy s một cách nhẹ nhàng với mức sử dụng bộ nhớ giảm nhiều. Đây là những gì tôi sử dụng để làm cho chương trình chạy.
Đoạn mã cho cập nhật predTree
chức năng:
def predTree(model, feat_idx):
# get all indices of samples that meet feature subset requirement
nan_rows = np.unique(np.where(test_df.iloc[:,feat_idx] == settings.nan_enc)[0])
all_rows = np.arange(test_df.shape[0])
rows = all_rows[np.invert(np.in1d(all_rows, nan_rows))] #discard rows with missing values in the given features
# predict height per valid sample
chunksize = 500
n_chunks = np.int(math.ceil(np.float(rows.shape[0])/chunksize))
pred = []
for i in range(n_chunks):
if n_chunks == 1:
pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:], feat_idx])
pred.append(pred_chunked)
break
if i == n_chunks-1:
pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:], feat_idx])
else:
pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:(i+1)*chunksize], feat_idx])
print pred_chunked.shape
pred.append(pred_chunked)
pred = np.concatenate(pred)
# populate matrix
predicted = np.empty(test_df.shape[0])
predicted.fill(np.nan)
predicted[rows] = pred
return predicted
Có bao nhiêu bộ nhớ mà các cây hồi quy ngẫu nhiên được huấn luyện năm 2000 của bạn? Chúng có được sao chép cho mỗi lõi trong số 50 lõi không? –
@ BrianO'Donnell bạn có phải là kích thước của mô hình không? Tôi không có quyền truy cập vào mô hình nữa, nhưng nó chắc chắn có thể quản lý được. – Dahlai
Có, kích thước của mô hình. –