在每个特定间隔后训练ML模型时出现内存使用问题

时间:2018-11-08 11:56:19

标签: python machine-learning memory-management apscheduler

我正在尝试每隔1小时运行一次ML训练脚本,但是每隔一小时,内存使用率将增加大约20%,3-4小时后,内存使用率将达到90%,然后此脚本抛出内存错误。 我想知道为什么火车功能完成后没有释放内存。

尽管如果我手动运行训练函数(通过不使用任何类型的线程调度程序并两次调用训练函数或一次又三次调用训练函数),则不会显示此行为。

任何在每个特定间隔后训练模型的建议。

这是代码。

import pickle
import pandas as pd
from pymongo import MongoClient
import datetime
from apscheduler.schedulers.blocking import BlockingScheduler

def train():

    client = MongoClient(databaseURI)
    db = client['mydb']

    movie_data = []
    for index, obj in enumerate(db.movies.find({})):
        movie_obj = {}

        movie_obj['_id'] = obj['_id']
        movie_obj['title'] = obj['title']
        movie_obj['rating'] = obj['rating']
        movie_data.append(movie_obj)


    user_data = []
    for index, obj in enumerate(db.users.find({})):
        user_obj = {}

        user_obj['_id'] = obj['_id']
        user_obj['username'] = obj['username']
        user_obj['movie_id'] = obj['movie_id']
        user_obj['rating'] = obj['rating']
        user_data.append(user_obj)


    movie_data_df = pd.DataFrame(movie_data)
    user_data_df = pd.DataFrame(user_data)

    # some ML training ALGO
    trainedModel = algo.train(user_data_df, movie_data_df)

    trained.to_pickle('files/trained.pkl')


scheduler = BlockingScheduler()
scheduler.add_job(train, 'interval', hours=1, next_run_time=datetime.datetime.now())
scheduler.start()

1 个答案:

答案 0 :(得分:1)

  

作业商店存放计划的作业。 默认作业存储只是   将作业保存在内存中,但其他人将其存储在各种类型的   数据库。作业的数据保存到永久文件后会序列化   作业存储,然后从存储中反序列化。作业店   (默认值以外的其他)不会将作业数据保留在内存中,但是   充当中间人以保存,加载,更新和搜索作业   后端。

我建议尝试以下解决方案之一:

  1. jobstore从默认值(即内存)更改为某个持久位置(Example)。

  2. 或尝试将参数replace_existing设置为True,默认值为False )。

    scheduler.add_job(train, 'interval', hours=1, 
                      next_run_time=datetime.datetime.now(), replace_existing=True)
    

旁注:

我认为可能还有另一种 ugly 修复它的方法(我没有尝试过!),以便您添加Listener来监听崩溃并重新启动整个过程处理! (如果您可以尝试并以更Python化的方式对其进行修改!)

scheduler = BlockingScheduler()
scheduler.add_job(train, 'interval', hours=1, next_run_time=datetime.datetime.now())

def my_listener(event):
    if event.exception:       
        global scheduler
        scheduler.shutdown()
        gc.collect()
        scheduler = BlockingScheduler()
        scheduler.add_job(train, 'interval', hours=1, next_run_time=datetime.datetime.now())
        scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
        scheduler.start()

scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
scheduler.start()