Closed giobus75 closed 3 years ago
When you use a CS_GPU then you have two networks one in CPU and a clone in GPU. EDDL internally keeps this clone by copying the weights from GPU (where training is performed) back to CPU and so on... When you put zeros to some weight on CPU then you only put in CPU but not in GPU. Then the "update_weights" are only updating weights in the CPU side. This is part of the internals of EDDL and i see that it could lead to misunderstanding.
In any case i do not know if there is any reason to do this. And just in case that exists a need please open and issue with the particular functionality you require and we will provide an implementation.
In case that you want to use these low-level methods (perfect) you can. In fact this clone network in GPU is in the following net member:
net.snets[0] // is the GPU network and snets[1] the second if you use more than one GPU etc...
layers = net.snets[0].layers
etc...
Thank you for the quick reply @RParedesPalacios.
I have to admit that I'm a bit confused, sorry :-). The problem is: If I'm working with the GPU and I want to set parameters by using some initialization tensors (e.g. the ImageNet ones) only on a subset of the network (for example the convolutional one), is it mandatory to use the low-level methods?
I mean, is the high-level API update_weighs
method useless if CS_GPU is set?
Thank you
you can use update_weights as you are doing but then we would need an extra function to sync_weights with the device (GPU/FPGA). Then I am going to provide such functionality asap.
Rigtht now you can do:
l.update_weights(w_np_t, b_np_t)
distributeTensor(l,"param",0); //weight
distributeTensor(l,"param",1); //bias
try it and let me know
Edit: Not sure if this functionality is available in python.
Also as a shortcut you can use:
distributeParams(l);
but it is in develop branch
Hi @RParedesPalacios, I tried the workaround by using distributeParams(l)
and it works fine both in C++ and Python. However, to check the outputs of the layers I had to access the net->snets[0]->layers
, maybe there is an easier way, I don't know.
By the way, during my C++ tests, I found out that if I call the API function getParams(layer, p)
using a layer without parameters (like the Input or maxpool ones), I get a segfault. I think it would be nice to get something like a null value to manage the exception and prevent the program exit in that way. What do you think about it?
Thank you again.
Giovanni
Hi @RParedesPalacios, I tried the workaround by using
distributeParams(l)
and it works fine both in C++ and Python. However, to check the outputs of the layers I had to access thenet->snets[0]->layers
, maybe there is an easier way, I don't know.
Tensor* getOutput(layer l1);
this function "collect" the tensor from devices. see for instance this example:
By the way, during my C++ tests, I found out that if I call the API function
getParams(layer, p)
using a layer without parameters (like the Input or maxpool ones), I get a segfault. I think it would be nice to get something like a null value to manage the exception and prevent the program exit in that way. What do you think about it?
well since this function requires a parameter it is assumed that the user knows the range of that parameter.
with vector<Tensor*> getParams(layer l1); (develop)
the user only has to provide a layer and the function returns a vector (could be void) with all the params
Thank you again. Giovanni
CC: @simleo
Hi, Trying to update the network parameters by using the layer
update_weights
method, I came across some problems so I tried to check if everything was fine by using a code able to set to zero or one weights (and/or bias) ad feeding the network with an ones-filled tensor (shape 3, 256, 256). Setting both weights and bias to zero and running on the CPU I got what expected: every layer outputs were 0.0 and the output of the softmax was 0.5. The weird behavior happened as soon as I switched to the GPU. I got something like this:The same output of GPU persists setting only bias to one. On the contrary, by using the CPU I still got what expected (intermediate layer outputs equal to 1.0 and 0.5 for the softmax output ).
Is that something I have to worry about? Thank you Giovanni
This is the code I used: