Provide mean pixel values to Caffe's python classify.py - pickle

I'd like to test a Caffe model with the Python wrapper:
python classify.py --model_del ./deploy.prototxt --pretrained_model ./mymodel.caffemodel input.png output
Is there a simple way to give mean_pixel values to the python wrapper? It seems to only support a mean_file argument?

The code makes use of args.mean_file variable to read a numpy format data to a variable mean. The easiest method will be to bring on a new parser argument named args.mean_pixel which has a single mean value, store it a mean_pixel variable, then create an array called mean which has the same dimensions as that of input data and copy the mean_pixel value to all the elements in the array. The rest of the code will function as normal.
parser.add_argument(
"--mean_pixel",
type=float,
default=128.0,
help="Enter the mean pixel value to be subtracted."
)
The above code segment will try to take a command line argument called mean_pixel.
Replace the code segment:
if args.mean_file:
mean = np.load(args.mean_file)
with:
if args.mean_file:
mean = np.load(args.mean_file)
elif args.mean_pixel:
mean_pixel = args.mean_pixel
mean = np.array([image_dims[0],image_dims[1],channels]) #where channels is the number of channels of the image
mean.fill(mean_pixel)
This will make the code to pick the mean_pixel value passed on as an argument, if mean_file is not passed as an argument. The above code will create an array with the dimensions as that of the image and fill it with the mean_pixel value.
The rest of the code needn't be changed.

Related

Construct object on function ccall in Julia

I am trying to simplify some binding to C but I am not sure if this is even possible, what I am trying to do is pass an array and expect to receive in a function so an object can be constructed by the type specified in the parameter or by ccall calling the correct convert function and initialize a struct object.
Previous code, the bindings are full of Vector3(v...) and Color(c...), is there a way to avoid this be automatic handling?
drawline(startPos, endPos, color) = ccall((:DrawLine3D, "my_lib"), Cvoid, (Vector3,Vector3,Color), Vector3(startPos...), Vector3(endPos...), Color(color...))
drawpoint([10,10,10],[100,100,100],[155,155,155,255]) # call example
Is it possible to reduce the code with something like this?:
struct Vector3
x::Cfloat
y::Cfloat
z::Cfloat
Vector3((x,y,z))=new(x,y,z)
end
#first attempt
#trying to call the Vector3 constructor without calling explicitly
drawpoint(startpos::Vector3,endpos::Vector3,color::Color) = ccall((:DrawPoint3D, "my_lib"), Cvoid, (Vector3,Vector3,Color), startpos,endpos,color)
#second attempt (should be the simplest way to go)
#trying to receive arrays so ccall can convert from list or tuple to Struct object
drawpoint(startpos,endpos,color) = ccall((:DrawPoint3D, "my_lib"), Cvoid, (Vector3,Vector3,Color), startpos,endpos,color)
Is something like this even possible in Julia?
You just need to define the appropriate conversion. ccall will call this for you. I think this should do it:
Base.convert(::Type{Vector3}, x::AbstractVector) = Vector3(x)
You'll probably want to add some length checks and such, and I'd probably recommend using tuples or StaticArrays instead of Vectors for efficiency's sake.

how to ensure that matlab's jsonencode always outputs a vector

Json encodes a vector with square brackets. A scalar has no square brackets. Of course, a scalar can be seen as a special case of a vector with length=1.
Is there an argument I can pass to matlab's jsonencode to ensure that a variable is always encoded as a vector? In the following example, I would like both xe and ye to have square brackets:
x.data = [0];
y.data = [0 1];
xe = jsonencode(x) % '{"data":0}' ..... I want '{"data":[0]}'
ye = jsonencode(y) % '{"data":[0,1]}'
Interestingly, matlab already classes x.data as a vector (isvector returns 1, as do isscalar and ismatrix).
I am exporting the data to a json file which is read in by a parser belonging to another project. The parser expects a vector and trips up when it tries to loop through the elements. I will have a look at improving the robustness of the parser, but that won't be trivial, and there might be an easy option in matlab's jsonencode.
Interestingly, from the documentation there does not seem to be a name value-pair which allows for that. However, if you wrap the scalar in a cell the output generated is the one you are looking for.
x.data = {[0]};
y.data = [0 1];
xe = jsonencode(x)
ye = jsonencode(y)
>>xe
'{"data":[0]}'
>>ye
'{"data":[0,1]}'
Therefore you will need to check the size of the data field in the structure, and according to whether it's a single value wrap it in a cell.

Pickling a dictionary that contains pygame.Surface objects

So I have a dictionary called Images and it stores pygame.Surface objects. Instead of having to build this entire dictionary every time I run the code, I would just like to read it in from a file.
This is the code that I am trying to use to pickle and unpickle the dictionary:
with open('Images.pkl', 'wb') as output:
pickle.dump(Images, output, pickle.HIGHEST_PROTOCOL)
with open('Images.pkl', 'rb') as input:
Images = pickle.load(input)
Later on, I use this code:
class Survivor:
def __init__(self):
self.body_image=Images['Characters/Survivor/handgun/idle0']
self.body_rect=self.body_image.get_rect()
which gives me:
File "ZombieSurvival.py", line 1320, in init
self.body_rect=self.body_image.get_rect(center=self.vector)
pygame.error: display Surface quit
pygame.Surface objects are actually a wrapper around a SDL_Surface, which is a C structure handled by the SDL library. This structure must be created with a call to the SDL_CreateRGBSurface() function of the SDL library.
This is probably done somewhere in pygame.Surface.__init__().
But unpickling an instance does not initialize it in a normal way. As the pickle documentation says:
When a class instance is unpickled, its init() method is usually
not invoked
So the C structure is never initialized and everything goes wrong.
I was able to pickle the dictionary by first using pygame's pygame.image.tostring() function to convert every pygame.Surface in the dictionary Images, to a string, using pygame.image.tostring(). Then I pickled Images. Whenever I want to use Images, I unpickle it and convert every string in it back go a pygame.Surface using pygame.image.fromstring().
However, pygame.image.fromstring() requires us to tell it the size of the pygame.Surface that it is about to convert, so I saved the sizes of each pygame.Surface before I used the pyame.image.tostring() function.
On every occasion where I was about to call pygame.image.tostring() on a pygame.Surface, I first stored the pygame.Surface's key (it's location in Images) and its size in an instance of a class with fields key and size. I stored every instance of this class in a list called list_of_image_sizes, and pickled the list.
Now, when you use the pygame.image.fromstring() function, you can call it as such:
for data in list_of_image_sizes:
Images[data.key]=pygame.image.fromstring(Image[data.key], data.size, 'RGBA')
#RGBA is my particular argument, you can change it as you wish

Function in Python Setting Global Variables (without intent)

I don't know if this is a problem that others get, but I have code in python that goes like this:
def makemove(board,move,val):
new=board
new[move[0]][move[1]]=val
return new
My problem is that if I use this function by simply doing makemove(game,[0,1],-1) where game equals [[0,0,1],[0,1,0],[1,0,0]] the variable game becomes [[0, -1, 1], [0, 1, 0], [1, 0, 0]].
I have tried to look into functions setting global variables, but I have thus for not found a way to prevent makemove() from setting the variables that you put into it. Is there something obvious that I'm missing?
You need to clone board.
import
new = copy.deepcopy(board)
see https://stackoverflow.com/a/2612815/93910 for other ways of doing this.
Your code sets elements of a variable which is a "reference".
In other words, your variable new is really an array reference to board, i.e. it points to the same memory location. So when you change new, the original variable board gets changed.
Here's another answer on how to think about this: https://stackoverflow.com/a/9697367/93910
This is basically because assignment in Python doesn't mean what you think it does, and lists are mutable sequences.
Lists are Python objects. The name board is merely a label for or reference to that object.
So when you say new=board this means "let the name new reference the same object as the name board".
In Python every object has a unique identifier that you can retrieve using id(). Let's create a board, do the assignment and see what happens:
In [1]: board = [[0,0,1],[0,1,0],[1,0,0]]
In [2]: new = board
In [3]: id(new), id(board)
Out[3]: (34495504136, 34495504136)
new and board are referencing the same object.
Since a list is a mutable sequence you can change it without getting an error.
So if you want to play with any mutable sequence inside a function without modifying the original, you should use copy.deepcopy first to make a copy and modify that.

Seq2Seq in CNTK : Run Time Error Function Only supports 2 dynamic axis

I am trying to implement a basic translation model where input and output are sentences in different languages in CNTK using LSTMs.
To achieve this I am creating model as follows :
def create_model(x):
with c.layers.default_options():
m = c.layers.Recurrence(c.layers.LSTM(input_vocab_size))(x)
m = sequence.last(m)
y = c.layers.Recurrence(c.layers.LSTM(label_vocab_size))(m)
return m
batch_axis = Axis.default_batch_axis()
input_seq_axis = Axis('inputAxis')
input_dynamic_axes = [batch_axis, input_seq_axis]
raw_input = input_variable(shape = (input_vocab_dim), dynamic_axes = input_dynamic_axes, name = 'raw_input')
z= create_model(raw_input)
But I am getting following error :
RuntimeError: Currently PastValue/FutureValue Function only supports input operand with 2 dynamic axis (1 sequence-axis and 1 batch-axis)
As per I understand, dynamic axis are basically those axis which gets decided after data gets loaded, in this case batch size and length of input sentence. I don't think I am changing the dynamic axis of input anywhere.
Any help is highly appreciated.
The last() operation strips the dynamic axis, since it reduces the input sequence to a single value (the thought vector).
The thought vector should then become the initial state for the second recurrence. So it should not be passed as the data argument to the second recurrence.
In the current version, the initial_state argument of Recurrence() cannot be data dependent. This will be soon possible, it is already under code review and will be merged to master soon.
Until then, there is a more complicated way to pass a data-dependent initial state, where you manually construct the recurrence (without Recurrence() layer), and manually add the initial hidden state in the recurrence. It is illustrated in the sequence-2-sequence sample.
This might be :
input_dynamic_axes= [Axis.default_batch_axis(), Axis.default_dynamic_axis()]
The first one will be the number of sample in your minibatch, the second will be the sequence length automagically inferred by CNTK