-
Notifications
You must be signed in to change notification settings - Fork 92
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
Can GPU fit handle functions that returns vectors instead of a single value? #46
Comments
Can you be more specific? In general, a multidimensional fit can be reformulated as a normal, scalar fit, and solved accordingly. |
I meant something link: f(x_1,x_2,x_3 ; alpha_1, alpha_2) = {alpha_1x_1 + alpha_2x_2, alpha_1x_2 + alpha_2x_3, alpha_1alpha_2x_1 + e^alpha_2 x_3}; So my samples are point in 3D space and I have to fit those with that vector function. My actual case is much more complicated and doesn't have a simple closed form expression. You can also imagine the function has to be fit using a LSE minimizer. |
Is it possible to fit such a function? Or is there a workaround for that? |
Yes, it can but you have to use a customized model function and fit estimator. Writing your own model function and fit estimator you can easily fit functions with vectors as output in Gpufit. See: http://gpufit.readthedocs.io/en/latest/customization.html I guess using the built-in LSE estimator would have problems though because it assumes that the number of model values is equal to the number of independent variable values. |
According to the documentation I should...
How do I specify in this case, "the derivative is a matrix" and "the function should output three values" instead of one? I assume for the derivative I'll just address the array accordingly, it should be a problem.
For the estimator I guess I'll be asking something later, but should I essentially implement a specific LSE estimater for my vector function? Thx |
Hi, could anyone give me more details based on what I asked above? I can't figure out how to proper index the derivatives and function values in my case. The documentation doesn't help much... |
Hi, I think what you're asking for is already possible using the existing Gpufit framework. Your function returns a vector of values, let's say 3 values, and you are fitting data that has three data values per coordinate. In this situation you can treat the problem as a simultaneous fit to multiple datasets, with shared parameters. For example, let's say your data values are a 3 x N array (a vector of 3 values for N coordinates) with a value [Y1,Y2,Y3] at each coordinate N. You could concatenate these values into a long 1D array [Y1(x1), Y1(x2), Y1(x3)...... Y2(x1), Y2(x2), Y2(x3).... Y3(x1), Y3(x2), Y3(x3), .... ] for sending to Gpufit. Next, write your model function to return the appropriate value, depending on which element it is working on - i.e. if your model function is working on a point in the Y1 section of the array, then it should return the first element of the vector, if it is in the Y2 section, then the second element, and so on. The same is true for the derivative values. The function is always using the same parameter set, however. The existing LSE or MLE estimators should already work for this case, without modification. Does this solution address your question? |
I fully agree with superchromix. The existing LSE and MLE estimators will work with vector-valued functions as long as the number of data points per fit is the number of x coordinates times number of values per fit. Just for completeness: an alternative ordering would be [Y1(x1) Y2(x1) Y3(x1) Y1(x2) Y2(x2) Y3(x3) ...]. The task reduces to implement a custom model function. Me might not yet have an example for that case. Might be good to have one. |
Hi superchromix, jkfindeisen. Because there's no example that would expound the details of what you're proposing I'd need you to guide me... So please bear with me.
So far I'm with you...
For the examples provided with GPUFit the generation of the samples is implemented in a separate function. In the case of the
According to the templates in the customization page, what parameter/parameters of the model function would tell me on what section of the array I'd be working on?
About the derivatives/hessians, I'm understanding that in this case the derivative would be a a matrix, while the hessian would be a 3D array in theory (though I'd re-index a 1D array to reproduce the same structure) is this correct? |
It's up to you if you want to create such a unit test
The "point index" tells you which element you are working on. Your model function would contain something like a switch statement, returning a different value depending on the point index.
The derivatives are also returned as a 1D array, of length n_parameters * n_points. In the example I gave above for each parameter and data point you have three derivatives, and you need to return them with the same ordering as how you choose to organize the input data. |
Continuing with the example, the final size of your derivatives array would be n_parameters * n_points * length_of_function_vector (three in this case). |
To see how to organize the derivatives, you can look into e.g. the Gaussian model function code. e.g. http://github.com/gpufit/Gpufit/blob/master/Gpufit/models/gauss_1d.cuh |
But in my case that 1D array will represent the Jacobian of my model right? How about the hessian instead? In the example of the 1D gaussian function (which dependes on 4 parameters) your 1D array of derivatives represents the gradient of the model with respect to the parameters to be fitted. This means if I had two components that 1D array should represent a matrix. Is that right? (It will still be a 1D array, but it's the interpretation that changes). Unless, again, I'm missing something. |
You don't need to calculate the Hessian - you only want the derivative of the function with respect to each of the parameters. You are essentially treating your function, which returns a vector (of e.g. length three) as three separate functions. |
I won't need the hessian because the estimator won't change, right? I'll re-use the ones already available. |
Yes, you can use the standard estimator. |
Everything boils down to just create a new model with the features you mentioned then, if this is true I'll follow the guidelines you just gave me. I'll eventually post the example I have in mind, if it is of any interest. |
Great. Yes that would be helpful - we could add it to the docs. Post back here if you need any more guidance. You might want to create a simple toy model function to get a feeling for this first, before implementing your specific function. |
I'll try. Thank you. |
Hi, I've this toy example.
Now, did you mean something like this? Also if you could clarify how do I take into account that some parameters are shared that would be helpful. |
I think it should be something more like this. This really depends on how you are passing the data into Gpufit. Below, I assume that the data is interleaved - i.e. [Y1(0), Y2(0), Y1(1), Y2(1), ...] . I also removed the parts involving user_info, since it's not strictly necessary to use custom x values.
` |
How about the shared parameters part? (You forgot to remove the array indices in the second component by the way). Still confused how is that supposed to be done. Moreover it seems to me you used the same coordinate x to compute the function value, but the function depends from three scalar values and returns two components. Basically as I said in the comment I'm trying to implement:
|
So, if your function is f(x,y,z) = (P0 * x + P1 * y, P0 * y + P2 * z) Then you just have to choose how you want to organize the X, Y, and Z coordinates, and the two values of the function, in the input array. The same thing is done in the 2D Gaussian example. one possible organization: [Y0(x0,y0,z0),Y1(x0,y0,z0),Y0(x1,y0,z0),Y1(x1,y0,z0),........] it's up to you to decide this. |
If you have unequal numbers of X, Y, and Z values, then you would also have to specify the number of X, Y, and Z points to the model function, via user_info for example, or the function has no way of knowing what the x,y,z coordinates are. |
No, the function is f(x,y,z) = (P0x + P1y,P0y + P2z); For the coordinates organization I'm assuming this x[0],y[0],z[0],x[1],y[1],z[1],...,x[i],y[i],z[i],.... If N are my samples, as you said I need an array 'v' of size 3*N, therefore I can retrive the coordinates x,y,z of the i-th sample as (x,y,z) = (v[3i],v[3i+1],v[3*i+2]). |
If your function lives in a three dimensional space, then the total data size must be N_x * N_y * N_z, where N_x is the number of X coordinates, etc. Unless, that is, your data is unevenly sampled, in which case you need to use the user_info parameter to pass in the coordinates. |
I'm assuming N_x = N_y = N_y, so I'll have a total of N_x^3 samples. Also I've modified my function model as follows
The reason for this bit:
It's because given that I have N^3 samples then the the the indexing in the linear array follows the formula
The reason for this bit:
It's because the gauss 2D function does something similar, not sure why though. |
The multi-dimensionality makes this "toy" model more complicated, but I think this is what you want.
|
And how do I use this for the fitting now? Should I fit just one function? or two?
|
Note that my modified example may not be the fastest solution - it is meant for illustrating the point. Also, the modulo operator is supposedly slow in CUDA. |
Doesn't matter for now, as long as it works for now. I'll work out some of those details later. |
I have to leave this for now. Hopefully you can see the point that this is all about deciding how to organize the multiple dimensions and multiple elements of the function in memory. Each thread on the GPU needs to know what it is responsible for computing, which X, Y, and Z coordinates it represents and which element of the function it will calculate. That's all that you need to do. When passing the data and initial parameters into Gpufit, you need to organize them in the same way that your model function is expecting them. You also need to conform to the definitions of n_fits, n_points, and n_parameters, so that Gpufit knows how large the various arrays are. |
I'm still missing the shared parameters bit. According to the code of the gauss2d example I can see that for each fit we have a different parameters vector, and each fit will use such vector independently. In my case Thank you for you help anyway, I appreciate it. |
I rewrote your calling function. See my changes below.
|
Hi again, this is the output I'm getting:
Which seems to be correct. I need to understand a bit how the whole thing works because I have many more parameters. I post the two functions then: model to be fit:
test case:
|
Leaving this open as a reminder to add this case to the examples library and documentation. |
Hi,
I have a function that returns more than value that I have to fit, like a f : R^3 -> R^3. I was wondering if GPUFit can handle such cases as well, but it doesn't seem to do so.
Regards
The text was updated successfully, but these errors were encountered: