Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export model to load in separate code #23

Open
Antorithms opened this issue Mar 2, 2024 · 4 comments
Open

Export model to load in separate code #23

Antorithms opened this issue Mar 2, 2024 · 4 comments

Comments

@Antorithms
Copy link

Hi everyone,
FIrst of all, thanks a lot for developing this amazing package.
I was wondering whether there is a way to export models after fitting on data to be able to then load from separate code and use it to transform.
Thanks for your help!

@ahwillia
Copy link
Owner

ahwillia commented Mar 2, 2024

I think it should be possible using pickle?

@Antorithms
Copy link
Author

I tried but i Get the error below

AttributeError: Can't pickle local object 'function..result'
Will try the solution at this link and update the issue! https://www.pythonpool.com/cant-pickle-local-object/

@Antorithms
Copy link
Author

I tried but without success... Most likely the probelm lies in the code below in _optimizers.py
Let me know if you have a fix.
Best,
Anto

def _construct_template_optimizer(loss):
    if loss == 'quadratic':
        # ------------------------------------------------- #
        # --- Template Update Rule Under Quadratic Loss --- #
        # ------------------------------------------------- #
        def f(x_knots, y_knots, template, data, smoothness_reg_scale, l2_reg_scale):
            K = data.shape[0]
            T = data.shape[1]

            # Initialize WtW with regularization term
            WtW = _diff_gramian(T, smoothness_reg_scale * K, l2_reg_scale * K)

            # Compute gramians.
            WtX = np.zeros((T, data.shape[-1]))
            _fast_template_grams(WtW[-2:], WtX, data, x_knots, y_knots)

            # Solve WtW * template = WtX
            return sci.linalg.solveh_banded(WtW, WtX)

    elif loss == 'poisson':
        # ----------------------------------------------- #
        # --- Template Update Rule Under Poisson Loss --- #
        # ----------------------------------------------- #
        def f(x_knots, y_knots, template, data, smoothness_reg_scale, l2_reg_scale):

            # Initialize template. Otherwise, warm-start from last result.
            if template is None:
                template = np.zeros(data.shape[1:])

            # Create objective.
            obj = PoissonObjective(data, smoothness_reg_scale, l2_reg_scale,
                                   x_knots=x_knots, y_knots=y_knots)

            opt = scipy.optimize.minimize(obj, template.ravel(),
                                          jac=True, method='L-BFGS-B',
                                          options=dict(maxiter=20))

            # # Fit using Newton's method
            # opt = scipy.optimize.minimize(obj, template.ravel(),
            #                               jac=True, hessp=obj.hessp,
            #                               method='newton-cg',
            #                               options=dict(maxiter=10))
            # print(opt.message)

            return (opt.x).reshape(template.shape)

    return f

@sjvenditto
Copy link

I got the same error when saving a PiecewiseWarping() model, and I believe the error is from pickle being unable to save nested function definitions, specifically coming from _construct_template_optimizer mentioned above. Un-nesting the functions as follows solved it for me:

def _construct_template_optimizer(loss):
    if loss == 'quadratic':
        return _quadratic_f
    elif loss == 'poisson':
        return _poisson_f

    # return f

def _quadratic_f(x_knots, y_knots, template, data, smoothness_reg_scale, l2_reg_scale):
    # ------------------------------------------------- #
    # --- Template Update Rule Under Quadratic Loss --- #
    # ------------------------------------------------- #

    K = data.shape[0]
    T = data.shape[1]

    # Initialize WtW with regularization term
    WtW = _diff_gramian(T, smoothness_reg_scale * K, l2_reg_scale * K)

    # Compute gramians.
    WtX = np.zeros((T, data.shape[-1]))
    _fast_template_grams(WtW[-2:], WtX, data, x_knots, y_knots)

    # Solve WtW * template = WtX
    return sci.linalg.solveh_banded(WtW, WtX)
     
def _poisson_f(x_knots, y_knots, template, data, smoothness_reg_scale, l2_reg_scale):
    # ----------------------------------------------- #
    # --- Template Update Rule Under Poisson Loss --- #
    # ----------------------------------------------- #

    # Initialize template. Otherwise, warm-start from last result.
    if template is None:
        template = np.zeros(data.shape[1:])

    # Create objective.
    obj = PoissonObjective(data, smoothness_reg_scale, l2_reg_scale,
                            x_knots=x_knots, y_knots=y_knots)

    opt = scipy.optimize.minimize(obj, template.ravel(),
                                    jac=True, method='L-BFGS-B',
                                    options=dict(maxiter=20))

    # # Fit using Newton's method
    # opt = scipy.optimize.minimize(obj, template.ravel(),
    #                               jac=True, hessp=obj.hessp,
    #                               method='newton-cg',
    #                               options=dict(maxiter=10))
    # print(opt.message)

    return (opt.x).reshape(template.shape)
    ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants