Exemple #1
0
    def run_node(cls,
                 node,
                 inputs,
                 device='CPU',
                 opset_version=_known_opset_version):
        super(Caffe2Backend, cls).run_node(node, inputs, device)

        device_option = get_device_option(Device(device))
        with Workspace(), core.DeviceScope(device_option):  # temporary!
            if isinstance(inputs, dict):
                for key, value in inputs.items():
                    workspace.FeedBlob(key, value)
            else:
                assert len(node.input) == len(
                    inputs), "{}: expected {} but got {}".format(
                        node.op_type, len(node.input), len(inputs))
                for key, value in zip(node.input, inputs):
                    workspace.FeedBlob(key, value)

            cls._inplace_rewrite([node])
            init_ops, ops, _ = cls._onnx_node_to_caffe2_op(
                None, None, node, opset_version or cls._known_opset_version)
            ops = init_ops + ops
            for op in ops:
                op.device_option.CopyFrom(device_option)
            workspace.RunOperatorsOnce(ops)
            output_values = [workspace.FetchBlob(name) for name in node.output]
            return namedtupledict('Outputs', node.output)(*output_values)
 def GetLossAndGrad(self, op, grad_ops, x, input_name, grad_name,
                    outputs_with_grads):
     # First, feed in the current input. Note that we are not changing
     # anything else, so we don't need to feed in others.
     workspace.FeedBlob(input_name, x, self._device_option)
     # Run.
     workspace.RunOperatorOnce(op)
     loss = 0.
     # Get Loss and feed in the gradients, run gradient ops.
     for idx in outputs_with_grads:
         name = op.output[idx]
         arr = workspace.FetchBlob(name)
         loss += (arr**2).sum()
         workspace.FeedBlob(name + '_grad', arr, self._device_option)
     loss /= 2.
     # Run gradient ops
     workspace.RunOperatorsOnce(grad_ops)
     # Get gradients
     if isinstance(grad_name, core.GradientSlice):
         workspace.FeedBlob('zeros', np.zeros_like(x, dtype=np.float32))
         workspace.FeedBlob('one', np.ones(1, dtype=np.float32))
         sparse_to_dense_op = core.CreateOperator(
             'ScatterWeightedSum',
             ['zeros', 'one', grad_name.indices, grad_name.values, 'one'],
             'zeros')
         workspace.RunOperatorOnce(sparse_to_dense_op)
         grad = workspace.FetchBlob('zeros')
     else:
         grad = workspace.FetchBlob(grad_name)
     return loss, grad
Exemple #3
0
    def run_node(cls, node, inputs, device='CPU', opset_version=_known_opset_version, outputs_info=None):
        super(Caffe2Backend, cls).run_node(node, inputs, device=device, outputs_info=outputs_info)

        device_option = get_device_option(Device(device))
        with Workspace(), core.DeviceScope(device_option):  # temporary!
            if isinstance(inputs, dict):
                for key, value in inputs.items():
                    workspace.FeedBlob(key, value)
            else:
                assert len(node.input) == len(inputs), "{}: expected {} but got {}".format(
                    node.op_type, len(node.input), len(inputs))
                for key, value in zip(node.input, inputs):
                    workspace.FeedBlob(key, value)

            ops = []
            cbackend = C.Caffe2Backend()
            ops_str = cbackend.convert_node(node.SerializeToString(), opset_version)
            for s in ops_str[0] + ops_str[1]:
                op = caffe2_pb2.OperatorDef()
                op.ParseFromString(s)
                op.device_option.CopyFrom(device_option)
                ops.append(op)
            # For testing
            if "ONNX_CAFFE2_DEBUG" in os.environ:
                init_ops, ops2, _ = cls._onnx_node_to_caffe2_op(
                    None, None, node, opset_version or cls._known_opset_version)
                ops2 = init_ops + ops2
                for op in ops2:
                    op.device_option.CopyFrom(device_option)
                print("\nC++:\n{}\nPython:\n{}".format(ops, ops2))
            workspace.RunOperatorsOnce(ops)
            output_values = [workspace.FetchBlob(name) for name in node.output]
            return namedtupledict('Outputs', node.output)(*output_values)
    def _assertGradReferenceChecks(
        self,
        op,
        inputs,
        ref_outputs,
        output_to_grad,
        grad_reference,
        threshold=1e-4,
    ):
        grad_blob_name = output_to_grad + '_grad'
        grad_ops, grad_map = core.GradientRegistry.GetBackwardPass(
            [op], {output_to_grad: grad_blob_name})
        output_grad = workspace.FetchBlob(output_to_grad)
        grad_ref_outputs = grad_reference(output_grad, ref_outputs, inputs)
        workspace.FeedBlob(grad_blob_name, workspace.FetchBlob(output_to_grad))
        workspace.RunOperatorsOnce(grad_ops)

        self.assertEqual(len(grad_ref_outputs), len(inputs))
        for (n, ref) in zip(op.input, grad_ref_outputs):
            grad_names = grad_map.get(n)
            if not grad_names:
                # no grad for this input
                self.assertIsNone(ref)
            else:
                if isinstance(grad_names, core.BlobReference):
                    # dense gradient
                    ref_vals = ref
                    ref_indices = None
                    val_name = grad_names
                else:
                    # sparse gradient
                    ref_vals, ref_indices = ref
                    val_name = grad_names.values
                vals = workspace.FetchBlob(str(val_name))
                np.testing.assert_allclose(
                    vals,
                    ref_vals,
                    atol=threshold,
                    rtol=threshold,
                    err_msg='Gradient {0} is not matching the reference'.
                    format(val_name, ),
                )
                if ref_indices is not None:
                    indices = workspace.FetchBlob(str(grad_names.indices))
                    np.testing.assert_allclose(indices,
                                               ref_indices,
                                               atol=1e-4,
                                               rtol=1e-4)
 def GetLossAndGrad(
     self, op, grad_ops, inputs, input_names, input_to_check, grad_name,
     outputs_with_grads
 ):
     for i in range(len(inputs)):
         workspace.FeedBlob(input_names[i], inputs[i],
                            self._input_device_options.get(
             input_names[i], self._device_option))
     x = inputs[input_to_check]
     # Run.
     workspace.RunOperatorOnce(op)
     loss = 0.
     # Get Loss and feed in the gradients, run gradient ops.
     for idx in outputs_with_grads:
         name = op.output[idx]
         arr = workspace.FetchBlob(name)
         loss += (arr**2).sum()
         workspace.FeedBlob(name + '_grad', arr, self._device_option)
     loss /= 2.
     # Run gradient ops
     workspace.RunOperatorsOnce(grad_ops)
     # Get gradients
     if isinstance(grad_name, core.GradientSlice):
         workspace.FeedBlob('zeros', np.zeros_like(x, dtype=np.float32))
         workspace.FeedBlob('ones', np.ones(1, dtype=np.float32))
         gv_cpu_op = core.CreateOperator(
             'EnsureCPUOutput', grad_name.values, grad_name.values + '_cpu',
             device_option=self._device_option
         )
         gi_cpu_op = core.CreateOperator(
             'EnsureCPUOutput', grad_name.indices, grad_name.indices + '_cpu',
             device_option=self._device_option
         )
         sparse_to_dense_op = core.CreateOperator(
             'ScatterWeightedSum',
             [
                 'zeros', 'ones', grad_name.indices + '_cpu',
                 grad_name.values + '_cpu', 'ones'
             ],
             'zeros',
         )
         workspace.RunOperatorOnce(gv_cpu_op)
         workspace.RunOperatorOnce(gi_cpu_op)
         workspace.RunOperatorOnce(sparse_to_dense_op)
         grad = workspace.FetchBlob('zeros')
     else:
         grad = workspace.FetchBlob(grad_name)
     return loss, grad
Exemple #6
0
    def run_node(cls, node, inputs, device='CPU'):
        super(Caffe2Backend, cls).run_node(node, inputs, device)

        device_option = get_device_option(Device(device))
        with Workspace(), core.DeviceScope(device_option):  # temporary!
            if isinstance(inputs, dict):
                for key, value in inputs.items():
                    workspace.FeedBlob(key, value)
            else:
                assert (len(node.input) == len(inputs))
                for key, value in zip(node.input, inputs):
                    workspace.FeedBlob(key, value)

            cls._inplace_rewrite([node])
            ops = cls._onnx_node_to_caffe2_op(node)
            for op in ops:
                op.device_option.CopyFrom(device_option)
            workspace.RunOperatorsOnce(ops)
            output_values = [workspace.FetchBlob(name) for name in node.output]
            return namedtupledict('Outputs', node.output)(*output_values)
Exemple #7
0
 def GetLossAndGrad(self, op, grad_ops, x, input_name, grad_name,
                    outputs_with_grads):
     # First, feed in the current input. Note that we are not changing
     # anything else, so we don't need to feed in others.
     workspace.FeedBlob(input_name, x, self._device_option)
     # Run.
     workspace.RunOperatorOnce(op)
     loss = 0.
     # Get Loss and feed in the gradients, run gradient ops.
     for idx in outputs_with_grads:
         name = op.output[idx]
         arr = workspace.FetchBlob(name)
         loss += (arr**2).sum()
         workspace.FeedBlob(name + '_grad', arr, self._device_option)
     loss /= 2.
     # Run gradient ops
     workspace.RunOperatorsOnce(grad_ops)
     # Get gradients
     grad = workspace.FetchBlob(grad_name)
     return loss, grad