1

我编写了自己的参数搜索实现,主要是因为我不需要 scikit-learn 的 GridSearch 和 RandomizedSearch 的交叉验证

我使用 dask 来提供最佳的分布式性能。

这是我所拥有的:

from scipy.stats import uniform
class Params(object):
    def __init__(self,fixed,loc=0.0,scale=1.0):
        self.fixed=fixed
        self.sched=uniform(loc=loc,scale=scale)

    def _getsched(self,i,size):
        return self.sched.rvs(size=size,random_state=i)

    def param(self,i,size=None):
        tmp=self.fixed.copy()
        if size is None:
            size=tmp['niter']
        tmp.update({'schd':self._getsched(i,size)})
        return tmp    

class Mymodel(object):
    def __init__(self,func,params_object,score,ntries,client):
        self.params=params_object
        self.func=func
        self.score=score
        self.ntries=ntries
        self.client=client

    def _run(self,params,train,test):
        return self.func(params,train,test,self.score)

    def build(self,train,test):
        res=[]
        for i in range(self.ntries):
            cparam=self.params.param(i)
            res.append( (cparam, self.client.submit(self._run, cparam, train,test)) )
        self._results=res
        return res

    def compute_optimal(self,res=None):
        from operator import itemgetter
        if res is None:
            res=self._results
        self._sorted=sorted(self.client.compute(res),key=itemgetter(1))

        return self._sorted[0]


def score(test,correct):
    return np.linalg.norm(test-correct)

def myfunc(params,ldata,data,score):
    schd=params['schd']
    niter=len(schd)
    #here I do some magic after which ldata is changing
    return score(test=ldata,correct=data)

在我开始 dask.distributed 之后:

from distributed import Client
scheduler_host='myhostname:8786'
cli=Client(scheduler_host)

我这样运行它:

%%time
params=Params({'niter':50},loc=1.0e-06,scale=1.0)
model=Mymodel(myfunc,params,score,100,cli)
ptdata=bad_data_example.copy()
graph=model.build(ptdata,good_data)

得到这个:

distributed.protocol.pickle - INFO - Failed to serialize
<bound method Mymodel._run of <__main__.Mymodel object at 0x2b8961903050>>.
Exception: can't pickle thread.lock objects

你能帮我了解发生了什么以及如何解决这个问题吗?

我也很好奇如何在所有参数结果中找到最小值。有没有更好的方法来使用 Dask?

我相当快地编写了这段代码,从未尝试过串行。我正在与许多其他主题(机器学习、gpu 编程、Numba、Python OOP 等)一起学习 Dask,所以这段代码无论如何都不是最优的......

PS要实际执行它,我使用此调用:model.compute_optimal()。还没有到这里 - 由于上面的错误。

4

2 回答 2

1

解决眼前的问题:Mymodel有一个属性client,因为客户端不能被序列化。如果必须,请使用而不是client作为属性。distributed.get_client

我将在我的工作中明确使用 dask-searchcv - 当我需要交叉验证时 - 但现在它实际上只是对最佳解决方案的简单搜索 - 所以必须创建我自己的实现......

Dask-ML 还有很多超参数搜索能力。这是一个很好的概述:https ://ml.dask.org/hyper-parameter-search.html

默认情况下,这些搜索中的很多都不会进行繁重的交叉验证,因为它们假定数据很大(请参阅 参考资料IncrementalSearchCV)。其中一些搜索具有减少计算量的奇特方法(请参阅 参考资料HyperbandSearchCV)。

于 2020-04-19T15:12:45.430 回答
0

看起来主要问题是由于我试图映射函数的方法。我也有类似的问题joblib。所以我重新编码了问题并删除了所有类。

此处发布了以下有​​关优化的问题:使用 dask 进行参数搜索

我将明确地dask-searchcv在我的工作中使用——当我需要交叉验证时——但现在它实际上只是对最佳解决方案的简单搜索——所以必须创建我自己的实现......

于 2017-07-09T05:06:29.107 回答