我想创建我自己的小神经网络估计器。我试图遵循这里提到的惯例,但我有一些问题。
假设我的类类似于
现在,我希望用户指定num_layers
和n_epochs
。
class NN(BaseEstimator, ClassifierMixin):
def __init__(self, num_layers=[10, 5], n_epochs=10):
self.num_layers = num_layers
self.n_epochs = n_epochs
我是否正确理解我应该而不是在__init__()
中设置网络架构?我有相当多的代码来做这个,它真的都应该在fit()
中吗?我认为这段代码应该放在__init__()
…
我还希望对变量名末尾的下划线进行一些澄清。我认为,例如,应该强调每一层中的权重,但是那些没有真正估计任何东西的额外辅助变量呢?scikit真的关心下划线吗,或者这纯粹是为了可读性的约定?
另外,如果我不提供score()
函数,但我提供了predict()
,如何计算分数?
也许你应该在scikit-learn邮件列表上问这些具体的问题,但我会尽力帮助你:
1)你可以在BaseEstimator类(base.py)中读取注释:
Base class for all estimators in scikit-learn
Notes
-----
All estimators should specify all the parameters that can be set
at the class level in their ``__init__`` as explicit keyword
arguments (no ``*args`` or ``**kwargs``).
我还可以添加GridSearch/BaseSearch以这样的方式工作,它直接在初始化模型上使用set_params设置参数,然后在每个估计器上调用fit()。这就是为什么应该将每个依赖变量初始化(从构造函数参数)从__init__
移到fit
。从__init__
参数中初始化的所有字段都应该与该参数完全相同,否则BaseEstimator
的get_params
方法将返回None而不是字段的正确值:
from sklearn import base
class Foo(base.BaseEstimator):
def __init__(self, parameter_a, parameter_b, parameter_c):
# Correct naming of internal fields
self.parameter_a = parameter_a
self.parameter_b = parameter_b
# Incorrect naming of internal fields
self.parameter_c_incorrect = parameter_c
p = Foo(1, 2, 3)
print(p.get_params())
# prints {'parameter_c': None, 'parameter_a': 1, 'parameter_b': 2}
在这种情况下克隆也会返回错误的结果。相关的问题。
2)我认为这是纯粹的传统,你可以读一下pep8。
3) ClassifierMixin
, RegressorMixin
等这些mixins是一种类,你可以将它们添加到你的类中以获得额外的功能,但它们本身不能做任何事情(你不能实例化它们)。看看它们在base.py中的实现。