Skip to content

Commit

Permalink
Merge pull request BVLC#7 from BVLC/master
Browse files Browse the repository at this point in the history
update from up stream
  • Loading branch information
bittnt committed May 5, 2016
2 parents 2f0d001 + af04325 commit 4bea310
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ endif
ifeq ($(OSX), 1)
CXX := /usr/bin/clang++
ifneq ($(CPU_ONLY), 1)
CUDA_VERSION := $(shell $(CUDA_DIR)/bin/nvcc -V | grep -o 'release \d' | grep -o '\d')
CUDA_VERSION := $(shell $(CUDA_DIR)/bin/nvcc -V | grep -o 'release [0-9.]*' | grep -o '[0-9.]*')
ifeq ($(shell echo | awk '{exit $(CUDA_VERSION) < 7.0;}'), 1)
CXXFLAGS += -stdlib=libstdc++
LINKFLAGS += -stdlib=libstdc++
Expand Down
1 change: 1 addition & 0 deletions Makefile.config.example
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib
# (Usually not necessary -- OpenCV libraries are normally installed in one of the above $LIBRARY_DIRS.)
# USE_PKG_CONFIG := 1

# N.B. both build and distribute dirs are cleared on `make clean`
BUILD_DIR := build
DISTRIBUTE_DIR := distribute

Expand Down
2 changes: 1 addition & 1 deletion docker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ docker_files: standalone_files

standalone_files: standalone/cpu/Dockerfile standalone/gpu/Dockerfile

FROM_GPU = "nvidia/cuda:cudnn"
FROM_GPU = "nvidia/cuda:7.5-cudnn4-devel-ubuntu14.04"
FROM_CPU = "ubuntu:14.04"
GPU_CMAKE_ARGS = -DUSE_CUDNN=1
CPU_CMAKE_ARGS = -DCPU_ONLY=1
Expand Down
2 changes: 1 addition & 1 deletion docker/standalone/gpu/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM nvidia/cuda:cudnn
FROM nvidia/cuda:7.5-cudnn4-devel-ubuntu14.04
MAINTAINER caffe-maint@googlegroups.com

RUN apt-get update && apt-get install -y --no-install-recommends \
Expand Down
1 change: 1 addition & 0 deletions include/caffe/layers/python_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class PythonLayer : public Layer<Dtype> {
}
self_.attr("param_str") = bp::str(
this->layer_param_.python_param().param_str());
self_.attr("phase") = static_cast<int>(this->phase_);
self_.attr("setup")(bottom, top);
}
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
Expand Down
21 changes: 17 additions & 4 deletions python/caffe/_caffe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@
#define PyArray_SetBaseObject(arr, x) (PyArray_BASE(arr) = (x))
#endif

/* Fix to avoid registration warnings in pycaffe (#3960) */
#define BP_REGISTER_SHARED_PTR_TO_PYTHON(PTR) do { \
const boost::python::type_info info = \
boost::python::type_id<shared_ptr<PTR > >(); \
const boost::python::converter::registration* reg = \
boost::python::converter::registry::query(info); \
if (reg == NULL) { \
bp::register_ptr_to_python<shared_ptr<PTR > >(); \
} else if ((*reg).m_to_python == NULL) { \
bp::register_ptr_to_python<shared_ptr<PTR > >(); \
} \
} while (0)

namespace bp = boost::python;

namespace caffe {
Expand Down Expand Up @@ -255,7 +268,7 @@ BOOST_PYTHON_MODULE(_caffe) {
.def("_set_input_arrays", &Net_SetInputArrays,
bp::with_custodian_and_ward<1, 2, bp::with_custodian_and_ward<1, 3> >())
.def("save", &Net_Save);
bp::register_ptr_to_python<shared_ptr<Net<Dtype> > >();
BP_REGISTER_SHARED_PTR_TO_PYTHON(Net<Dtype>);

bp::class_<Blob<Dtype>, shared_ptr<Blob<Dtype> >, boost::noncopyable>(
"Blob", bp::no_init)
Expand All @@ -275,7 +288,7 @@ BOOST_PYTHON_MODULE(_caffe) {
NdarrayCallPolicies()))
.add_property("diff", bp::make_function(&Blob<Dtype>::mutable_cpu_diff,
NdarrayCallPolicies()));
bp::register_ptr_to_python<shared_ptr<Blob<Dtype> > >();
BP_REGISTER_SHARED_PTR_TO_PYTHON(Blob<Dtype>);

bp::class_<Layer<Dtype>, shared_ptr<PythonLayer<Dtype> >,
boost::noncopyable>("Layer", bp::init<const LayerParameter&>())
Expand All @@ -284,7 +297,7 @@ BOOST_PYTHON_MODULE(_caffe) {
.def("setup", &Layer<Dtype>::LayerSetUp)
.def("reshape", &Layer<Dtype>::Reshape)
.add_property("type", bp::make_function(&Layer<Dtype>::type));
bp::register_ptr_to_python<shared_ptr<Layer<Dtype> > >();
BP_REGISTER_SHARED_PTR_TO_PYTHON(Layer<Dtype>);

bp::class_<LayerParameter>("LayerParameter", bp::no_init);

Expand All @@ -299,7 +312,7 @@ BOOST_PYTHON_MODULE(_caffe) {
.def("step", &Solver<Dtype>::Step)
.def("restore", &Solver<Dtype>::Restore)
.def("snapshot", &Solver<Dtype>::Snapshot);
bp::register_ptr_to_python<shared_ptr<Solver<Dtype> > >();
BP_REGISTER_SHARED_PTR_TO_PYTHON(Solver<Dtype>);

bp::class_<SGDSolver<Dtype>, bp::bases<Solver<Dtype> >,
shared_ptr<SGDSolver<Dtype> >, boost::noncopyable>(
Expand Down
1 change: 1 addition & 0 deletions python/caffe/classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def predict(self, inputs, oversample=True):
-self.crop_dims / 2.0,
self.crop_dims / 2.0
])
crop = crop.astype(int)
input_ = input_[:, crop[0]:crop[2], crop[1]:crop[3], :]

# Classify
Expand Down
2 changes: 1 addition & 1 deletion python/caffe/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def get_pydot_graph(caffe_net, rankdir, label_edges=True):
-------
pydot graph object
"""
pydot_graph = pydot.Dot(caffe_net.name,
pydot_graph = pydot.Dot(caffe_net.name if caffe_net.name else 'Net',
graph_type='digraph',
rankdir=rankdir)
pydot_nodes = {}
Expand Down
2 changes: 1 addition & 1 deletion python/caffe/net_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def param_name_dict():
# get all parameter names (typically underscore case) and corresponding
# type names (typically camel case), which contain the layer names
# (note that not all parameters correspond to layers, but we'll ignore that)
param_names = [s for s in dir(layer) if s.endswith('_param')]
param_names = [f.name for f in layer.DESCRIPTOR.fields if f.name.endswith('_param')]
param_type_names = [type(getattr(layer, s)).__name__ for s in param_names]
# strip the final '_param' or 'Parameter'
param_names = [s[:-len('_param')] for s in param_names]
Expand Down
26 changes: 26 additions & 0 deletions python/caffe/test/test_python_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ def forward(self, bottom, top):
def backward(self, top, propagate_down, bottom):
self.blobs[0].diff[0] = 1

class PhaseLayer(caffe.Layer):
"""A layer for checking attribute `phase`"""

def setup(self, bottom, top):
pass

def reshape(self, bootom, top):
top[0].reshape()

def forward(self, bottom, top):
top[0].data[()] = self.phase

def python_net_file():
with tempfile.NamedTemporaryFile(mode='w+', delete=False) as f:
f.write("""name: 'pythonnet' force_backward: true
Expand Down Expand Up @@ -76,6 +88,14 @@ def parameter_net_file():
""")
return f.name

def phase_net_file():
with tempfile.NamedTemporaryFile(mode='w+', delete=False) as f:
f.write("""name: 'pythonnet' force_backward: true
layer { type: 'Python' name: 'layer' top: 'phase'
python_param { module: 'test_python_layer' layer: 'PhaseLayer' } }
""")
return f.name


@unittest.skipIf('Python' not in caffe.layer_type_list(),
'Caffe built without Python layer support')
Expand Down Expand Up @@ -140,3 +160,9 @@ def test_parameter(self):
self.assertEqual(layer.blobs[0].data[0], 1)

os.remove(net_file)

def test_phase(self):
net_file = phase_net_file()
for phase in caffe.TRAIN, caffe.TEST:
net = caffe.Net(net_file, phase)
self.assertEqual(net.forward()['phase'], phase)
2 changes: 1 addition & 1 deletion scripts/download_model_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def valid_dirname(dirname):

# Closure-d function for checking SHA1.
def model_checks_out(filename=model_filename, sha1=frontmatter['sha1']):
with open(filename, 'r') as f:
with open(filename, 'rb') as f:
return hashlib.sha1(f.read()).hexdigest() == sha1

# Check if model exists.
Expand Down
2 changes: 1 addition & 1 deletion src/caffe/proto/caffe.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ message ReshapeParameter {
// reshape_param { shape { dim: 2 dim: 2 dim: 4 } }
// reshape_param { shape { dim: 0 dim: 2 dim: 4 } }
// reshape_param { shape { dim: 0 dim: 2 dim: -1 } }
// reshape_param { shape { dim: -1 dim: 0 dim: 2 } }
// reshape_param { shape { dim: 0 dim:-1 dim: 4 } }
//
optional BlobShape shape = 1;

Expand Down
26 changes: 15 additions & 11 deletions tools/extra/plot_training_log.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import matplotlib.legend as lgd
import matplotlib.markers as mks

def get_log_parsing_script():
dirname = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
dirname = os.path.dirname(os.path.abspath(inspect.getfile(
inspect.currentframe())))
return dirname + '/parse_log.sh'

def get_log_file_suffix():
Expand Down Expand Up @@ -61,16 +62,17 @@ def get_data_file_type(chart_type):
return data_file_type

def get_data_file(chart_type, path_to_log):
return os.path.basename(path_to_log) + '.' + get_data_file_type(chart_type).lower()
return (os.path.basename(path_to_log) + '.' +
get_data_file_type(chart_type).lower())

def get_field_descriptions(chart_type):
description = get_chart_type_description(chart_type).split(
get_chart_type_description_separator())
y_axis_field = description[0]
x_axis_field = description[1]
return x_axis_field, y_axis_field
return x_axis_field, y_axis_field

def get_field_indecies(x_axis_field, y_axis_field):
def get_field_indices(x_axis_field, y_axis_field):
data_file_type = get_data_file_type(chart_type)
fields = create_field_index()[0][data_file_type]
return fields[x_axis_field], fields[y_axis_field]
Expand Down Expand Up @@ -111,7 +113,7 @@ def plot_chart(chart_type, path_to_png, path_to_log_list):
os.system('%s %s' % (get_log_parsing_script(), path_to_log))
data_file = get_data_file(chart_type, path_to_log)
x_axis_field, y_axis_field = get_field_descriptions(chart_type)
x, y = get_field_indecies(x_axis_field, y_axis_field)
x, y = get_field_indices(x_axis_field, y_axis_field)
data = load_data(data_file, x, y)
## TODO: more systematic color cycle for lines
color = [random.random(), random.random(), random.random()]
Expand All @@ -138,8 +140,8 @@ def plot_chart(chart_type, path_to_png, path_to_log_list):
plt.legend(loc = legend_loc, ncol = 1) # ajust ncol to fit the space
plt.title(get_chart_type_description(chart_type))
plt.xlabel(x_axis_field)
plt.ylabel(y_axis_field)
plt.savefig(path_to_png)
plt.ylabel(y_axis_field)
plt.savefig(path_to_png)
plt.show()

def print_help():
Expand All @@ -160,28 +162,30 @@ Supported chart types:""" % (len(get_supported_chart_types()) - 1,
num = len(supported_chart_types)
for i in xrange(num):
print ' %d: %s' % (i, supported_chart_types[i])
exit
sys.exit()

def is_valid_chart_type(chart_type):
return chart_type >= 0 and chart_type < len(get_supported_chart_types())

if __name__ == '__main__':
if len(sys.argv) < 4:
print_help()
else:
chart_type = int(sys.argv[1])
if not is_valid_chart_type(chart_type):
print '%s is not a valid chart type.' % chart_type
print_help()
path_to_png = sys.argv[2]
if not path_to_png.endswith('.png'):
print 'Path must ends with png' % path_to_png
exit
sys.exit()
path_to_logs = sys.argv[3:]
for path_to_log in path_to_logs:
if not os.path.exists(path_to_log):
print 'Path does not exist: %s' % path_to_log
exit
sys.exit()
if not path_to_log.endswith(get_log_file_suffix()):
print 'Log file must end in %s.' % get_log_file_suffix()
print_help()
## plot_chart accpets multiple path_to_logs
plot_chart(chart_type, path_to_png, path_to_logs)

0 comments on commit 4bea310

Please sign in to comment.