-
Notifications
You must be signed in to change notification settings - Fork 18.7k
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
Python net specification #2086
Python net specification #2086
Conversation
0e79cef
to
22ef4fe
Compare
Python net specification
22ef4fe
to
23ee7ab
Compare
Python net specification
23ee7ab
to
cde046a
Compare
Python net specification
cde046a
to
6f6a67e
Compare
This should now support repeated I think that means you can now specify any |
6f6a67e
to
c64f6cf
Compare
Python net specification
uncamel('HDF5Data') wrongly returns 'hd_f5_data'. |
And uncamel('PReLU') wrongly returns 'p_relu'. I think 'HDF5Data' -> 'hdf5_data' is normal uncamelling but 'PReLU' -> 'prelu' is exceptional. Maybe we have to find some other way. |
@muupan The layers that break the rule could just be hardcoded in the "uncamel" function, e.g. with a dictionary. Something like this:
|
@longjon I am having an issue using this PR. Running the example: http://nbviewer.ipython.org/github/BVLC/caffe/blob/tutorial/examples/01-learning-lenet.ipynb gives me the following error:
Update I tried adding an import statement for caffe as well and the following happened:
causes this error:
Discussion: http://stackoverflow.com/questions/29774793/typeerror-python-class |
Python net specification
Hi @Shaunakde , you safe me hours of reading code so I felt that I should help you (sorry if you already noticed that). You should use the comment of seanbell for your example. I guess that the reason is that Thank you longjon for this tool. I have spent hours debugging prototxt without noticing minor difference such as layers instead of layer. |
@@ -0,0 +1,54 @@ | |||
from caffe import layers as L, params as P, to_proto |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking over this and from what I can tell the to_proto function from PR #1733 has moved
into NetSpec here.
In this case NetSpec should be imported and all layer variables should be defined to it. This would then also print the layers in their correct order.
The alexnet function would look as follows:
def alexnet(lmdb, batch_size=256, include_acc=False):
n = NetSpec()
n.data, n.label = L.Data(source=lmdb, backend=P.Data.LMDB, batch_size=batch_size, ntop=2,
transform_param=dict(crop_size=227, mean_value=[104, 117, 123], mirror=True))
# the net itself
n.conv1, n.relu1 = conv_relu(n.data, 11, 96, stride=4)
n.pool1 = max_pool(n.relu1, 3, stride=2)
n.norm1 = L.LRN(n.pool1, local_size=5, alpha=1e-4, beta=0.75)
n.conv2, n.relu2 = conv_relu(n.norm1, 5, 256, pad=2, group=2)
n.pool2 = max_pool(n.relu2, 3, stride=2)
n.norm2 = L.LRN(n.pool2, local_size=5, alpha=1e-4, beta=0.75)
n.conv3, n.relu3 = conv_relu(n.norm2, 3, 384, pad=1)
n.conv4, n.relu4 = conv_relu(n.relu3, 3, 384, pad=1, group=2)
n.conv5, n.relu5 = conv_relu(n.relu4, 3, 256, pad=1, group=2)
n.pool5 = max_pool(n.relu5, 3, stride=2)
n.fc6, n.relu6 = fc_relu(n.pool5, 4096)
n.drop6 = L.Dropout(n.relu6, in_place=True)
n.fc7, n.relu7 = fc_relu(n.drop6, 4096)
n.drop7 = L.Dropout(n.relu7, in_place=True)
n.fc8 = L.InnerProduct(n.drop7, num_output=1000)
n.loss = L.SoftmaxWithLoss(n.fc8, n.label)
if include_acc:
n.acc = L.Accuracy(n.fc8, n.label)
return n.to_proto()
BR, Max
Hi, I've been using this PR for a few days and I have been able to write all the models I wanted to using it. I am very pleased with it and Ty for writing it. 👍 @longjon The PR mentions that it fillers, but I don't see how these can be accessed from python, was this omitted from the PR? I was wondering if there is an easy way to specify parameters for python layers, here a few ideas came to mind:
So for this I was wondering if there is an easier way. Also in case it was overlooked, its worthwhile looking at the Theano version of this, called Mariana. |
See also Lasagne on Theano. |
Getting ready to update this; here's list of TODOs: Cleanups and fixes before first mergeable version, which should be considered basically a "protobuf wrapper/generator":
Desiderata and future work to come after merge (PRs welcome!):
|
9409178
to
1d9546e
Compare
TODOs all done for now; marking this ready for review! @muupan @seanbell and others, @Shaunakde, note that we generally aren't able to provide support for PRs, especially in-progress ones. You're welcome to contribute to the development discussion, but otherwise please use caffe-users or other venues. @BlGene, see the tests for an example of specifying fillers. Parameters for Python layers are a different (though related) issue; see, e.g., #2001. |
def max_pool(bottom, ks, stride=1): | ||
return L.Pooling(bottom, pool=P.Pooling.MAX, kernel_size=ks, stride=stride) | ||
|
||
def alexnet(lmdb, batch_size=256, include_acc=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trivial, but this should be called caffenet
since it has our usual inversion.
ed4ecaa
to
1cdad89
Compare
@longjon amended names and the |
Very helpful, thank you! How do I go about changing the decay_mult parameter? |
e.g.,
(untested, could be slightly wrong) |
Python net specification
Is it possible to specify dummy data with this? Based on caffenet.py, I would expect that it would be something like this: import caffe
from caffe import layers as L, params as P, to_proto
from caffe.proto import caffe_pb2
from __future__ import print_function
def gen_inputs():
data = L.DummyData(name="data",ntop=1,shape=dict(dim=[1,2,3]))
label = L.DummyData(name="label",ntop=1,shape=dict(dim=[1,2,3]))
return data,label
def caffenet(include_acc=False):
data,label=gen_inputs()
loss = L.SoftmaxWithLoss(data, label)
return to_proto(loss)
def make_net(output_dir='./',net_name='train'):
fname = os.path.join(output_dir,net_name+'.prototxt')
with open(fname, 'w') as f:
print(caffenet(), file=f)
make_net() this produces:
I've tried various other things using caffe_pb2 and caffe.params. def gen_inputs():
data = L.DummyData(name="data",ntop=1,dummy_data_param=dict(shape=dict(dim=[1,2,3])))
label = L.DummyData(name="label",ntop=1,dummy_data_param=dict(shape=dict(dim=[1,2,3])))
return data,label def gen_inputs():
data_shape = caffe_pb2.BlobShape()
data_shape.dim = [1,2,3]
data_param = caffe_pb2.DummyDataParameter()
data_param.shape = data_shape
data = L.DummyData(name="data",ntop=1,dummy_data_param=data_param)
label = L.DummyData(name="label",ntop=1,dummy_data_param=data_param)
return data,label Any thoughts? |
Maybe this?: from __future__ import print_function
import caffe
from caffe import layers as L, params as P, to_proto
from caffe.proto import caffe_pb2
import os
def gen_inputs():
data = L.DummyData(name="data", ntop=1,dummy_data_param=dict(shape=[dict(dim=[1,2,3])]))
label = L.DummyData(name="label",ntop=1,dummy_data_param=dict(shape=[dict(dim=[1,2,3])]))
return data,label
def caffenet(include_acc=False):
data,label=gen_inputs()
loss = L.SoftmaxWithLoss(data, label)
return to_proto(loss)
def make_net(output_dir='./',net_name='train'):
fname = os.path.join(output_dir,net_name+'.prototxt')
with open(fname, 'w') as f:
print(caffenet(), file=f)
make_net() BR, Max |
@BlGene is right. If bad parameters are being silently ignored, however (in current |
I can open it with this as a test case. It may be the name 'shape' which has meaning in some contexts? |
@longjon Does this caffenet example get all the weight_filler and bias_fillers correct? I'm not able to easily see that the default weight_filler is somehow gaussian with std = 0.01 here. Is this true? |
master
edition of #1733. Still rough, but should be usable by the intrepid.uncamel
which broke acronym names (e.g., LRN) (thanks @sontran).