Error in function - signal experiment

Hi all, apologies in advacne it is my first post. i am trying an experiment with new data and i getting an error i was wondering if somebody could please assist.

import math

import cvxpy as cp
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import torch
from cvxpylayers.torch import CvxpyLayer

import latexify
latexify.latexify()

torch.set_default_tensor_type(torch.DoubleTensor)
%matplotlib inline


N_train=1000




test=yf.download("SPY", start="2012-01-01", end="2017-04-30")['Close'].to_numpy()
outputs=torch.from_numpy(test)
inputs=np.linspace(1,100,len(outputs))
inputs=torch.from_numpy(inputs)

X_train = inputs[:N_train]
Y_train = outputs[:N_train]

X_val = inputs[N_train:]
Y_val = outputs[N_train:]


len(X_val)
len(Y_val)

def create_layer():
   y_cp = cp.Variable(n)
   x_minus_y = cp.Variable(n)
   
   x_param = cp.Parameter(n)
   theta_param = cp.Parameter((n, n))
   lambda_param = cp.Parameter(pos=True)
   objective = (
       cp.sum_squares(theta_param @ x_minus_y) +
       lambda_param*cp.sum_squares(cp.diff(y_cp))
   )
   constraints = [
       x_minus_y == x_param - y_cp
   ]
   problem = cp.Problem(cp.Minimize(objective), constraints)
   layer = CvxpyLayer(
       problem,
       parameters=[x_param, theta_param, lambda_param],
       variables=[y_cp])
   return layer
   

layer = create_layer()

import torch
from torch.utils.data import TensorDataset, DataLoader
import numpy as np
from cvxpylayers.torch import CvxpyLayer

torch.set_default_dtype(torch.double)

from tqdm.notebook import tqdm


def fit(loss, params, X, Y, Xval, Yval, batch_size=128, lr=1e-3, epochs=100, verbose=False, print_every=1, callback=None):
   """

   Arguments:
       loss: given x and y in batched form, evaluates loss.
       params: list of parameters to optimize.
       X: input data, torch tensor.
       Y: output data, torch tensor.
       Xval: input validation data, torch tensor.
       Yval: output validation data, torch tensor.
   """

   train_dset = TensorDataset(X, Y)
   train_loader = DataLoader(train_dset, batch_size=batch_size, shuffle=True)
   opt = torch.optim.Adam(params, lr=lr)

   train_losses = []
   val_losses = []
   for epoch in tqdm(range(epochs)):
       if callback is not None:
           callback()
           
       with torch.no_grad():
           val_losses.append(loss(Xval, Yval).item())
       if verbose and epoch % print_every == 0:
           print("val loss %03d | %3.5f" % (epoch + 1, val_losses[-1]))

       batch = 1
       train_losses.append([])
       for Xbatch, Ybatch in train_loader:
           opt.zero_grad()
           l = loss(Xbatch, Ybatch)
           l.backward()
           opt.step()
           train_losses[-1].append(l.item())
           if verbose and epoch % print_every == 0:
               print("batch %03d / %03d | %3.5f" %
                     (batch, len(train_loader), np.mean(train_losses[-1])))
           batch += 1
   return val_losses, train_losses

theta_tch = torch.eye(n, requires_grad=True)
lambda_tch = torch.tensor(0.5, requires_grad=True)
params = [theta_tch, lambda_tch]

def loss_fn(X, actual):
   preds = layer(X, theta_tch, lambda_tch)[0]
   mse_per_example = (preds - actual).pow(2).mean(axis=1)
   return mse_per_example.mean()


val_losses, train_losses =  fit(
   loss_fn, params, X_train, Y_train, X_val, Y_val, lr=1e-2, batch_size=8,
   epochs=15, verbose=True, print_every=1)

The above is the code taken from - https://github.com/cvxgrp/cvxpylayers/blob/master/examples/torch/signal_denoising.ipynb

and the error i am getting

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-58-0b0fb50d4406> in <module>
----> 1 val_losses, train_losses =  fit(
     2     loss_fn, params, X_train, Y_train, X_val, Y_val, lr=1e-2, batch_size=8,
     3     epochs=15, verbose=True, print_every=1)

<ipython-input-56-f19c59cb9b44> in fit(loss, params, X, Y, Xval, Yval, batch_size, lr, epochs, verbose, print_every, callback)
    32 
    33         with torch.no_grad():
---> 34             val_losses.append(loss(Xval, Yval).item())
    35         if verbose and epoch % print_every == 0:
    36             print("val loss %03d | %3.5f" % (epoch + 1, val_losses[-1]))

<ipython-input-57-0aead751c22d> in loss_fn(X, actual)
     4 
     5 def loss_fn(X, actual):
----> 6     preds = layer(X, theta_tch, lambda_tch)[0]
     7     mse_per_example = (preds - actual).pow(2).mean(axis=1)
     8     return mse_per_example.mean()

~/miniconda3/envs/myenv1/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   720             result = self._slow_forward(*input, **kwargs)
   721         else:
--> 722             result = self.forward(*input, **kwargs)
   723         for hook in itertools.chain(
   724                 _global_forward_hooks.values(),

~/cvxpylayers/cvxpylayers/torch/cvxpylayer.py in forward(self, solver_args, *params)
   150             info=info,
   151         )
--> 152         sol = f(*params)
   153         self.info = info
   154         return sol

~/cvxpylayers/cvxpylayers/torch/cvxpylayer.py in forward(ctx, *params)
   224                 p_shape = p.shape if batch_size == 0 else p.shape[1:]
   225                 if not np.all(p_shape == param_order[i].shape):
--> 226                     raise ValueError(
   227                         "Inconsistent parameter shapes passed in. "
   228                         "Expected parameter {} to have non-batched shape of "

ValueError: Inconsistent parameter shapes passed in. Expected parameter 0 to have non-batched shape of (100,) but got torch.Size([339]).

Tensor shape incorrect, evidently:

 to have non-batched shape of (100,) but got torch.Size([339])

How do I reshape to provide the code with the correct format. @ptrblck @smth was wondering if you would be able to assist. Thank you in advance.
Andrew

I’m unfortunately not familiar with cvxpylayers, but as @iffiX mentioned, the input shape of Xval and/or Yval seems to be wrong.
Based on your code it seems tou are trying to pass these tensors directly to the loss function, i.e. without a DataLoader. Could the batch size be missing? If not, I would recommend to check the shapes and make sure which shapes are expected.

Ah Thank you @ptrblck !! That was very helpful!! im still getting used to pytorch :),
i just assumed i could pass the dataset straight in.

The example is below works but i am a little unsure about how to fit it with new data.

Do you have any thoughts about how i could fit new data with the current example.

Kind regards ,
Andrew

So my next plan was to try a few different ways to format the data correctly.
I have not tried this but please observe the below.

import yfinance as yf
data = yf.download("SPY", start="2008-01-01", end="2017-04-30")['Close']
dd=data.to_numpy()
s=int(np.ceil(len(dd)/100))
s

def strided_app(a, L, S ):  # Window len = L, Stride len/stepsize = S
    nrows = ((a.size-L)//S)+1
    n = a.strides[0]
    return np.lib.stride_tricks.as_strided(a, shape=(nrows,L), strides=(S*n,n))

ddd= strided_app(dd, 100, s)



def f(x):
    # return math.sqrt(x)
    return torch.from_numpy(np.array(x))


ffxx=list(map(f, ddd))
torch.stack(ffxx)

Based on the previous post it seems that your code is already working with another dataset and the error is raised, if you are trying to use a new dataset?
If that’s the case, could you print the shape of the input tensor as well as some intermediate tensors?

Since your code is not executable, I can just speculate what might be wrong. :wink: