python: PEP8; changed docstring documentation style to NumPyDoc style
authorMartin Thoma <info@martin-thoma.de>
Mon, 11 May 2015 20:35:48 +0000 (22:35 +0200)
committerMartin Thoma <info@martin-thoma.de>
Mon, 11 May 2015 20:35:48 +0000 (22:35 +0200)
python/caffe/classifier.py
python/caffe/detector.py
python/caffe/draw.py
python/caffe/io.py
python/caffe/pycaffe.py
python/caffe/test/test_net.py
python/caffe/test/test_python_layer.py
python/caffe/test/test_solver.py

index 49f8003..7fb2ccc 100644 (file)
@@ -29,7 +29,7 @@ class Classifier(caffe.Net):
         in_ = self.inputs[0]
         self.transformer = caffe.io.Transformer(
             {in_: self.blobs[in_].data.shape})
-        self.transformer.set_transpose(in_, (2,0,1))
+        self.transformer.set_transpose(in_, (2, 0, 1))
         if mean is not None:
             self.transformer.set_mean(in_, mean)
         if input_scale is not None:
@@ -44,7 +44,6 @@ class Classifier(caffe.Net):
             image_dims = self.crop_dims
         self.image_dims = image_dims
 
-
     def predict(self, inputs, oversample=True):
         """
         Predict classification probabilities of inputs.
@@ -78,7 +77,7 @@ class Classifier(caffe.Net):
             input_ = input_[:, crop[0]:crop[2], crop[1]:crop[3], :]
 
         # Classify
-        caffe_in = np.zeros(np.array(input_.shape)[[0,3,1,2]],
+        caffe_in = np.zeros(np.array(input_.shape)[[0, 3, 1, 2]],
                             dtype=np.float32)
         for ix, in_ in enumerate(input_):
             caffe_in[ix] = self.transformer.preprocess(self.inputs[0], in_)
index a67b818..f72b548 100644 (file)
@@ -41,7 +41,7 @@ class Detector(caffe.Net):
         in_ = self.inputs[0]
         self.transformer = caffe.io.Transformer(
             {in_: self.blobs[in_].data.shape})
-        self.transformer.set_transpose(in_, (2,0,1))
+        self.transformer.set_transpose(in_, (2, 0, 1))
         if mean is not None:
             self.transformer.set_mean(in_, mean)
         if input_scale is not None:
@@ -53,17 +53,18 @@ class Detector(caffe.Net):
 
         self.configure_crop(context_pad)
 
-
     def detect_windows(self, images_windows):
         """
         Do windowed detection over given images and windows. Windows are
         extracted then warped to the input dimensions of the net.
 
-        Take
+        Parameters
+        ----------
         images_windows: (image filename, window list) iterable.
         context_crop: size of context border to crop in pixels.
 
-        Give
+        Returns
+        -------
         detections: list of {filename: image filename, window: crop coordinates,
             predictions: prediction vector} dicts.
         """
@@ -82,7 +83,7 @@ class Detector(caffe.Net):
         for ix, window_in in enumerate(window_inputs):
             caffe_in[ix] = self.transformer.preprocess(in_, window_in)
         out = self.forward_all(**{in_: caffe_in})
-        predictions = out[self.outputs[0]].squeeze(axis=(2,3))
+        predictions = out[self.outputs[0]].squeeze(axis=(2, 3))
 
         # Package predictions with images and windows.
         detections = []
@@ -97,16 +98,17 @@ class Detector(caffe.Net):
                 ix += 1
         return detections
 
-
     def detect_selective_search(self, image_fnames):
         """
         Do windowed detection over Selective Search proposals by extracting
         the crop and warping to the input dimensions of the net.
 
-        Take
+        Parameters
+        ----------
         image_fnames: list
 
-        Give
+        Returns
+        -------
         detections: list of {filename: image filename, window: crop coordinates,
             predictions: prediction vector} dicts.
         """
@@ -120,17 +122,18 @@ class Detector(caffe.Net):
         # Run windowed detection on the selective search list.
         return self.detect_windows(zip(image_fnames, windows_list))
 
-
     def crop(self, im, window):
         """
         Crop a window from the image for detection. Include surrounding context
         according to the `context_pad` configuration.
 
-        Take
+        Parameters
+        ----------
         im: H x W x K image ndarray to crop.
         window: bounding box coordinates as ymin, xmin, ymax, xmax.
 
-        Give
+        Returns
+        -------
         crop: cropped window.
         """
         # Crop window from the image.
@@ -175,14 +178,14 @@ class Detector(caffe.Net):
 
         return crop
 
-
     def configure_crop(self, context_pad):
         """
         Configure crop dimensions and amount of context for cropping.
         If context is included, make the special input mean for context padding.
 
-        Take
-        context_pad: amount of context for cropping.
+        Parameters
+        ----------
+        context_pad : amount of context for cropping.
         """
         # crop dimensions
         in_ = self.inputs[0]
@@ -204,8 +207,8 @@ class Detector(caffe.Net):
                 crop_mean = mean.copy().transpose(inv_transpose)
                 if channel_order is not None:
                     channel_order_inverse = [channel_order.index(i)
-                                            for i in range(crop_mean.shape[2])]
-                    crop_mean = crop_mean[:,:, channel_order_inverse]
+                                             for i in range(crop_mean.shape[2])]
+                    crop_mean = crop_mean[:, :, channel_order_inverse]
                 if raw_scale is not None:
                     crop_mean /= raw_scale
                 self.crop_mean = crop_mean
index 6a4dbd4..08b7c1d 100644 (file)
@@ -11,19 +11,23 @@ from google.protobuf import text_format
 import pydot
 
 # Internal layer and blob styles.
-LAYER_STYLE_DEFAULT = {'shape': 'record', 'fillcolor': '#6495ED',
-         'style': 'filled'}
-NEURON_LAYER_STYLE = {'shape': 'record', 'fillcolor': '#90EE90',
-         'style': 'filled'}
-BLOB_STYLE = {'shape': 'octagon', 'fillcolor': '#E0E0E0',
-        'style': 'filled'}
+LAYER_STYLE_DEFAULT = {'shape': 'record',
+                       'fillcolor': '#6495ED',
+                       'style': 'filled'}
+NEURON_LAYER_STYLE = {'shape': 'record',
+                      'fillcolor': '#90EE90',
+                      'style': 'filled'}
+BLOB_STYLE = {'shape': 'octagon',
+              'fillcolor': '#E0E0E0',
+              'style': 'filled'}
+
 
 def get_pooling_types_dict():
     """Get dictionary mapping pooling type number to type name
     """
     desc = caffe_pb2.PoolingParameter.PoolMethod.DESCRIPTOR
     d = {}
-    for k,v in desc.values_by_name.items():
+    for k, v in desc.values_by_name.items():
         d[v.number] = k
     return d
 
@@ -145,21 +149,24 @@ def get_pydot_graph(caffe_net, rankdir, label_edges=True):
                    label=edge['label']))
   return pydot_graph
 
+
 def draw_net(caffe_net, rankdir, ext='png'):
-  """Draws a caffe net and returns the image string encoded using the given
-  extension.
+    """Draws a caffe net and returns the image string encoded using the given
+    extension.
 
-  Input:
+    Parameters
+    ----------
     caffe_net: a caffe.proto.caffe_pb2.NetParameter protocol buffer.
     ext: the image extension. Default 'png'.
-  """
-  return get_pydot_graph(caffe_net, rankdir).create(format=ext)
+    """
+    return get_pydot_graph(caffe_net, rankdir).create(format=ext)
+
 
 def draw_net_to_file(caffe_net, filename, rankdir='LR'):
-  """Draws a caffe net, and saves it to file using the format given as the
-  file extension. Use '.raw' to output raw text that you can manually feed
-  to graphviz to draw graphs.
-  """
-  ext = filename[filename.rfind('.')+1:]
-  with open(filename, 'wb') as fid:
-    fid.write(draw_net(caffe_net, rankdir, ext))
+    """Draws a caffe net, and saves it to file using the format given as the
+    file extension. Use '.raw' to output raw text that you can manually feed
+    to graphviz to draw graphs.
+    """
+    ext = filename[filename.rfind('.')+1:]
+    with open(filename, 'wb') as fid:
+        fid.write(draw_net(caffe_net, rankdir, ext))
index 6ae2cf1..e5feff3 100644 (file)
@@ -8,16 +8,16 @@ try:
     from caffe.proto import caffe_pb2
 except:
     import sys
-    if sys.version_info >= (3,0):
+    if sys.version_info >= (3, 0):
         print("Failed to include caffe_pb2, things might go wrong!")
     else:
         raise
 
-## proto / datum / ndarray conversion
 
+## proto / datum / ndarray conversion
 def blobproto_to_array(blob, return_diff=False):
-    """Convert a blob proto to an array. In default, we will just return the data,
-    unless return_diff is True, in which case we will return the diff.
+    """Convert a blob proto to an array. In default, we will just return the
+    data, unless return_diff is True, in which case we will return the diff.
     """
     if return_diff:
         return np.array(blob.diff).reshape(
@@ -35,7 +35,7 @@ def array_to_blobproto(arr, diff=None):
     if arr.ndim != 4:
         raise ValueError('Incorrect array shape.')
     blob = caffe_pb2.BlobProto()
-    blob.num, blob.channels, blob.height, blob.width = arr.shape;
+    blob.num, blob.channels, blob.height, blob.width = arr.shape
     blob.data.extend(arr.astype(float).flat)
     if diff is not None:
         blob.diff.extend(diff.astype(float).flat)
@@ -81,7 +81,7 @@ def datum_to_array(datum):
     as one can easily get it by calling datum.label.
     """
     if len(datum.data):
-        return np.fromstring(datum.data, dtype = np.uint8).reshape(
+        return np.fromstring(datum.data, dtype=np.uint8).reshape(
             datum.channels, datum.height, datum.width)
     else:
         return np.array(datum.float_data).astype(float).reshape(
@@ -97,8 +97,9 @@ class Transformer:
     Note: this is mostly for illustrative purposes and it is likely better
     to define your own input preprocessing routine for your needs.
 
-    Take
-    net: a Net for which the input should be prepared
+    Parameters
+    ----------
+    net : a Net for which the input should be prepared
     """
     def __init__(self, inputs):
         self.inputs = inputs
@@ -108,13 +109,11 @@ class Transformer:
         self.mean = {}
         self.input_scale = {}
 
-
     def __check_input(self, in_):
         if in_ not in self.inputs:
             raise Exception('{} is not one of the net inputs: {}'.format(
                 in_, self.inputs))
 
-
     def preprocess(self, in_, data):
         """
         Format input for Caffe:
@@ -155,7 +154,6 @@ class Transformer:
             caffe_in *= input_scale
         return caffe_in
 
-
     def deprocess(self, in_, data):
         """
         Invert Caffe formatting; see preprocess().
@@ -179,7 +177,6 @@ class Transformer:
             decaf_in = decaf_in.transpose([transpose[t] for t in transpose])
         return decaf_in
 
-
     def set_transpose(self, in_, order):
         """
         Set the input channel order for e.g. RGB to BGR conversion
@@ -195,7 +192,6 @@ class Transformer:
                             'dimensions as the input.')
         self.transpose[in_] = order
 
-
     def set_channel_swap(self, in_, order):
         """
         Set the input channel order for e.g. RGB to BGR conversion
@@ -213,7 +209,6 @@ class Transformer:
                             'dimensions as the input channels.')
         self.channel_swap[in_] = order
 
-
     def set_raw_scale(self, in_, scale):
         """
         Set the scale of raw features s.t. the input blob = input * scale.
@@ -228,7 +223,6 @@ class Transformer:
         self.__check_input(in_)
         self.raw_scale[in_] = scale
 
-
     def set_mean(self, in_, mean):
         """
         Set the mean to subtract for centering the data.
@@ -254,7 +248,6 @@ class Transformer:
                 raise ValueError('Mean shape incompatible with input shape.')
         self.mean[in_] = mean
 
-
     def set_input_scale(self, in_, scale):
         """
         Set the scale of preprocessed inputs s.t. the blob = blob * scale.
@@ -359,7 +352,7 @@ def oversample(images, crop_dims):
 
     # Extract crops
     crops = np.empty((10 * len(images), crop_dims[0], crop_dims[1],
-                            im_shape[-1]), dtype=np.float32)
+                      im_shape[-1]), dtype=np.float32)
     ix = 0
     for im in images:
         for crop in crops_ix:
index 3c19261..e8a676a 100644 (file)
@@ -5,9 +5,9 @@ interface.
 
 from collections import OrderedDict
 try:
-       from itertools import izip_longest
+    from itertools import izip_longest
 except:
-       from itertools import zip_longest as izip_longest
+    from itertools import zip_longest as izip_longest
 import numpy as np
 
 from ._caffe import Net, SGDSolver
@@ -53,16 +53,19 @@ def _Net_forward(self, blobs=None, start=None, end=None, **kwargs):
     """
     Forward pass: prepare inputs and run the net forward.
 
-    Take
-    blobs: list of blobs to return in addition to output blobs.
-    kwargs: Keys are input blob names and values are blob ndarrays.
-            For formatting inputs for Caffe, see Net.preprocess().
-            If None, input is taken from data layers.
-    start: optional name of layer at which to begin the forward pass
-    end: optional name of layer at which to finish the forward pass (inclusive)
-
-    Give
-    outs: {blob name: blob ndarray} dict.
+    Parameters
+    ----------
+    blobs : list of blobs to return in addition to output blobs.
+    kwargs : Keys are input blob names and values are blob ndarrays.
+             For formatting inputs for Caffe, see Net.preprocess().
+             If None, input is taken from data layers.
+    start : optional name of layer at which to begin the forward pass
+    end : optional name of layer at which to finish the forward pass
+          (inclusive)
+
+    Returns
+    -------
+    outs : {blob name: blob ndarray} dict.
     """
     if blobs is None:
         blobs = []
@@ -99,14 +102,17 @@ def _Net_backward(self, diffs=None, start=None, end=None, **kwargs):
     """
     Backward pass: prepare diffs and run the net backward.
 
-    Take
-    diffs: list of diffs to return in addition to bottom diffs.
-    kwargs: Keys are output blob names and values are diff ndarrays.
+    Parameters
+    ----------
+    diffs : list of diffs to return in addition to bottom diffs.
+    kwargs : Keys are output blob names and values are diff ndarrays.
             If None, top diffs are taken from forward loss.
-    start: optional name of layer at which to begin the backward pass
-    end: optional name of layer at which to finish the backward pass (inclusive)
+    start : optional name of layer at which to begin the backward pass
+    end : optional name of layer at which to finish the backward pass
+        (inclusive)
 
-    Give
+    Returns
+    -------
     outs: {blob name: diff ndarray} dict.
     """
     if diffs is None:
@@ -146,13 +152,15 @@ def _Net_forward_all(self, blobs=None, **kwargs):
     """
     Run net forward in batches.
 
-    Take
-    blobs: list of blobs to extract as in forward()
-    kwargs: Keys are input blob names and values are blob ndarrays.
-            Refer to forward().
+    Parameters
+    ----------
+    blobs : list of blobs to extract as in forward()
+    kwargs : Keys are input blob names and values are blob ndarrays.
+             Refer to forward().
 
-    Give
-    all_outs: {blob name: list of blobs} dict.
+    Returns
+    -------
+    all_outs : {blob name: list of blobs} dict.
     """
     # Collect outputs from batches
     all_outs = {out: [] for out in set(self.outputs + (blobs or []))}
@@ -175,14 +183,16 @@ def _Net_forward_backward_all(self, blobs=None, diffs=None, **kwargs):
     """
     Run net forward + backward in batches.
 
-    Take
+    Parameters
+    ----------
     blobs: list of blobs to extract as in forward()
     diffs: list of diffs to extract as in backward()
     kwargs: Keys are input (for forward) and output (for backward) blob names
             and values are ndarrays. Refer to forward() and backward().
             Prefilled variants are called for lack of input or output blobs.
 
-    Give
+    Returns
+    -------
     all_blobs: {blob name: blob ndarray} dict.
     all_diffs: {blob name: diff ndarray} dict.
     """
@@ -229,11 +239,13 @@ def _Net_batch(self, blobs):
     """
     Batch blob lists according to net's batch size.
 
-    Take
+    Parameters
+    ----------
     blobs: Keys blob names and values are lists of blobs (of any length).
            Naturally, all the lists should have the same length.
 
-    Give (yield)
+    Yields
+    ------
     batch: {blob name: list of blobs} dict for a single batch.
     """
     num = len(blobs.itervalues().next())
index 62b407d..cc36747 100644 (file)
@@ -5,6 +5,7 @@ import numpy as np
 
 import caffe
 
+
 def simple_net_file(num_output):
     """Make a simple net prototxt, based on test_net.cpp, returning the name
     of the (temporary) file."""
@@ -31,6 +32,7 @@ def simple_net_file(num_output):
     f.close()
     return f.name
 
+
 class TestNet(unittest.TestCase):
     def setUp(self):
         self.num_output = 13
index dd99f6f..6fba491 100644 (file)
@@ -4,6 +4,7 @@ import os
 
 import caffe
 
+
 class SimpleLayer(caffe.Layer):
     """A layer that just multiplies by ten"""
 
@@ -19,6 +20,7 @@ class SimpleLayer(caffe.Layer):
     def backward(self, top, propagate_down, bottom):
         bottom[0].diff[...] = 10 * top[0].diff
 
+
 def python_net_file():
     with tempfile.NamedTemporaryFile(delete=False) as f:
         f.write("""name: 'pythonnet' force_backward: true
@@ -31,6 +33,7 @@ def python_net_file():
           python_param { module: 'test_python_layer' layer: 'SimpleLayer' } }""")
         return f.name
 
+
 class TestPythonLayer(unittest.TestCase):
     def setUp(self):
         net_file = python_net_file()
index d59f23d..09b974d 100644 (file)
@@ -6,6 +6,7 @@ import numpy as np
 import caffe
 from test_net import simple_net_file
 
+
 class TestSolver(unittest.TestCase):
     def setUp(self):
         self.num_output = 13