Beispiel #1
0
    def testCallingEnableRepeatedlyWithDifferentTensorDebugMode(self):
        """Assert that calling enable_dumping() with different tensor-debug modes.

    It should lead to overwriting of the previously-configured mode.
    """
        writer = dumping_callback.enable_dumping(self.dump_root,
                                                 tensor_debug_mode="NO_TENSOR")

        @def_function.function
        def add_1_divide_by_2(x):
            return (x + 1.0) / 2.0

        self.assertAllClose(add_1_divide_by_2(constant_op.constant(4.0)), 2.5)
        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()
        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        context_ids, _, _ = self._readAndCheckGraphsFile(stack_frame_by_id)
        _, _, _, _, tensor_values = self._readAndCheckExecutionFile()
        self.assertEqual(tensor_values, [[]])
        (_, _, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        self.assertLen(tensor_values, 2)
        for tensor_value in tensor_values:
            self.assertEqual(tensor_value.dtype, np.float32)
            self.assertEqual(tensor_value.shape, (0, ))

        with self.assertRaisesRegexp(
                ValueError,
                r"already.*NO_TENSOR.*FULL_TENSOR.*not be honored"):
            dumping_callback.enable_dumping(self.dump_root,
                                            tensor_debug_mode="FULL_TENSOR")
Beispiel #2
0
 def testInvalidTensorDebugModeCausesError(self):
     with self.assertRaisesRegexp(
             ValueError,
             r"Invalid value in tensor_debug_mode \(\'NONSENSICAL\'\).*"
             r"Valid options.*NO_TENSOR.*"):
         dumping_callback.enable_dumping(self.dump_root,
                                         tensor_debug_mode="NONSENSICAL")
Beispiel #3
0
    def testCallingEnableTracingTwiceWithDifferentDumpRootsOverwrites(self):
        dumping_callback.enable_dumping(self.dump_root)
        new_dump_root = self.dump_root + "_new_dump_root"
        writer = dumping_callback.enable_dumping(new_dump_root)

        x = constant_op.constant([10.0, 12.0, 10.0])
        for _ in range(2):
            array_ops.unique(x)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        reader = debug_events_reader.DebugEventsDir(new_dump_root)
        execution_iter = reader.execution_iterator()
        for _ in range(2):
            debug_event = next(execution_iter)
            self.assertGreater(debug_event.wall_time, 0)
            execution = debug_event.execution
            self.assertEqual(execution.op_type, "Unique")
            self.assertEqual(execution.num_outputs, 2)
            self.assertTrue(execution.code_location)
        with self.assertRaises(StopIteration):
            next(execution_iter)

        old_dump_root_reader = debug_events_reader.DebugEventsDir(
            self.dump_root)
        execution_iter = old_dump_root_reader.execution_iterator()
        # The old dump root shouldn't have been written to.
        with self.assertRaises(StopIteration):
            next(execution_iter)
Beispiel #4
0
    def testSimpleKerasRecurrentModelPredict(self, tensor_debug_mode):
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)
        model = _create_simple_recurrent_keras_model([3, 4])
        batch_size = 5
        xs = np.ones([batch_size, 3, 4])
        self.assertAllClose(model.predict(xs), np.zeros([batch_size, 1]))

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        (context_ids, op_types,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)
        # Simply assert that graph are recorded and refrain from asserting on the
        # internal details of the Keras model.
        self.assertTrue(context_ids)
        self.assertTrue(op_types)
        self.assertTrue(op_name_to_op_type)

        if context.executing_eagerly():
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, hence it doesn't get logged to the
            # .execution file.
            (executed_op_types, _, _, _,
             tensor_values) = self._readAndCheckExecutionFile()
            self.assertTrue(executed_op_types)

            for value_list in tensor_values:
                if tensor_debug_mode == "NO_TENSOR":
                    self.assertFalse(value_list)

        (op_names, _, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        # These are the ops that we can safely assume to have been executed during
        # the model prediction.
        self.assertIn("MatMul", executed_op_types)
        self.assertIn("BiasAdd", executed_op_types)
        # On the GPU, CudnnRNN is used in lieu of the default op-by-op
        # implementation.
        self.assertTrue(
            ("Sigmoid" in executed_op_types and "Tanh" in executed_op_types
             or "CudnnRNN" in executed_op_types))
        # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought to
        # be an empty float32 tensor.
        if tensor_debug_mode == "NO_TENSOR":
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
        else:
            # Refrain from asserting the internal implementation details of the LSTM
            # layer.
            concrete_tensor_values = [
                value for value in tensor_values
                if value is not None and value.size > 0
            ]
            self.assertTrue(concrete_tensor_values)
Beispiel #5
0
    def testSimpleKerasRecurrentModelFit(self, tensor_debug_mode):
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)
        model = _create_simple_recurrent_keras_model([3, 4])
        xs = np.ones([5, 3, 4])
        ys = np.ones([5, 1])

        history = model.fit(xs, ys, epochs=3, verbose=0)
        self.assertAllClose(history.history["loss"],
                            [1.0, 0.9603999853134155, 0.9223681688308716])

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        (context_ids, op_types,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)
        # Simply assert that graph are recorded and refrain from asserting on the
        # internal details of the Keras model.
        self.assertTrue(context_ids)
        self.assertTrue(op_types)
        self.assertTrue(op_name_to_op_type)

        if context.executing_eagerly():
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, hence it doesn't get logged to the
            # .execution file.
            (executed_op_types, _, _, _,
             tensor_values) = self._readAndCheckExecutionFile()
            self.assertTrue(executed_op_types)
            if tensor_debug_mode == "NO_TENSOR":
                for value_list in tensor_values:
                    self.assertFalse(value_list)

        (op_names, _, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        # These are the ops that we can safely assume to have been executed during
        # the recurrent model's fit() call.
        self.assertIn("MatMul", executed_op_types)
        self.assertIn("BiasAdd", executed_op_types)
        # On the GPU, CudnnRNN is used in lieu of the default op-by-op
        # implementation.
        self.assertTrue(
            ("Sigmoid" in executed_op_types and "Tanh" in executed_op_types
             or "CudnnRNN" in executed_op_types))
        self.assertTrue(("SigmoidGrad" in executed_op_types
                         and "TanhGrad" in executed_op_types
                         or "CudnnRNNBackprop" in executed_op_types))
        if tensor_debug_mode == "NO_TENSOR":
            # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought
            # to be an empty float32 tensor.
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
Beispiel #6
0
    def testMultiThreadedExecution(self, tensor_debug_mode):
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)
        x = variables.Variable(10.0, dtype=dtypes.float32)
        y = variables.Variable(3.0, dtype=dtypes.float32)

        @def_function.function
        def increase_x():
            return x.assign_add(y * 2.0)

        increase_x()

        num_threads = 3
        threads = []
        for _ in range(num_threads):
            threads.append(threading.Thread(target=increase_x))
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()
        # 10 --> 16 --> 22 --> 28 --> 34.
        self.assertAllClose(x.read_value(), 34.0)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        reader = debug_events_reader.DebugEventsDir(self.dump_root)
        execution_iter = reader.execution_iterator()
        prev_wall_time = 1
        for debug_event in execution_iter:
            self.assertGreaterEqual(debug_event.wall_time, prev_wall_time)
            prev_wall_time = debug_event.wall_time

        (context_ids, _,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)

        (op_names, _, output_slots, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        self.assertEqual(executed_op_types.count("Mul"), 1 + num_threads)
        self.assertEqual(executed_op_types.count("ReadVariableOp"),
                         2 * (1 + num_threads))
        for output_slot in output_slots:
            self.assertEqual(output_slot, 0)
        if tensor_debug_mode == "NO_TENSOR":
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
        elif tensor_debug_mode == "FULL_TENSOR":
            mul_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Mul"
            ]
            self.assertAllClose(mul_values, [6.0, 6.0, 6.0, 6.0])
Beispiel #7
0
    def testNestedFunctionExecutionWithoutControlFlow(self, tensor_debug_mode):
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)

        @def_function.function
        def log_sum(x, y):
            return math_ops.log(x + y)

        @def_function.function
        def sin1p_log_sum(x, y):
            return math_ops.sin(1.0 + log_sum(x, y))

        x = constant_op.constant(2.0)
        y = constant_op.constant(3.0)
        self.assertAllClose(sin1p_log_sum(x, y), np.sin(1.0 + np.log(5.0)))
        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        if context.executing_eagerly():
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, so doesn't get logged to the
            # .execution file.
            executed_op_types, _, _, _, _ = self._readAndCheckExecutionFile()
            self.assertLen(executed_op_types, 1)
            self.assertIn("sin1p_log_sum", executed_op_types[0])

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        (context_ids, op_types,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)
        self.assertIn("AddV2", op_types)
        self.assertIn("Log", op_types)
        self.assertIn("Sin", op_types)

        (op_names, _, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        self.assertEqual(executed_op_types, ["AddV2", "Log", "AddV2", "Sin"])

        if tensor_debug_mode == "NO_TENSOR":
            # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought to
            # be an empty float32 tensor.
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
        elif tensor_debug_mode == "FULL_TENSOR":
            self.assertAllClose(tensor_values[0], 5.0)  # 1st AddV2 op.
            self.assertAllClose(tensor_values[1], np.log(5.0))  # Log op.
            self.assertAllClose(tensor_values[2],
                                np.log(5.0) + 1.0)  # 2nd AddV2 op.
            self.assertAllClose(tensor_values[3],
                                np.sin(np.log(5.0) + 1.0))  # Sin op.
Beispiel #8
0
    def testCallingEnableTracingTwiceWithTheSameDumpRootIsIdempotent(self):
        dumping_callback.enable_dumping(self.dump_root)
        writer = dumping_callback.enable_dumping(self.dump_root)

        x = constant_op.constant([10.0, 12.0, 10.0])
        for _ in range(2):
            array_ops.unique(x)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        reader = debug_events_reader.DebugEventsDir(self.dump_root)
        execution_iter = reader.execution_iterator()
        for _ in range(2):
            debug_event = next(execution_iter)
            self.assertGreater(debug_event.wall_time, 0)
            execution = debug_event.execution
            self.assertEqual(execution.op_type, "Unique")
            self.assertEqual(execution.num_outputs, 2)
            self.assertTrue(execution.code_location)
        with self.assertRaises(StopIteration):
            next(execution_iter)
Beispiel #9
0
    def testMobileNetV2Fit(self):
        """Test training Keras MobileNetV2 application works w/ check numerics."""
        # Use a large circular-buffer to make sure we capture all the executed ops.
        writer = dumping_callback.enable_dumping(self.dump_root,
                                                 circular_buffer_size=100000)
        model = mobilenet_v2.MobileNetV2(alpha=0.1, weights=None)

        xs = np.zeros([2] + list(model.input_shape[1:]))
        ys = np.zeros([2] + list(model.output_shape[1:]))
        model.compile(optimizer="sgd", loss="categorical_crossentropy")
        epochs = 1
        history = model.fit(xs, ys, epochs=epochs, verbose=0)
        self.assertEqual(len(history.history["loss"]), epochs)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        (context_ids, op_types,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)
        # Simply assert that graph are recorded and refrain from asserting on the
        # internal details of the Keras model.
        self.assertTrue(context_ids)
        self.assertTrue(op_types)
        self.assertTrue(op_name_to_op_type)

        if context.executing_eagerly():
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, hence it doesn't get logged to the
            # .execution file.
            executed_op_types, _, _, _ = self._readAndCheckExecutionFile()
            self.assertTrue(executed_op_types)

        (op_names, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        # These are the ops that we can safely assume to have been executed during
        # the model's fit() call.
        self.assertIn("Conv2D", executed_op_types)
        self.assertIn("Relu6", executed_op_types)
        self.assertIn("Conv2DBackpropFilter", executed_op_types)
        self.assertIn("Relu6Grad", executed_op_types)
        # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought to
        # be an empty float32 tensor.
        for tensor_value in tensor_values:
            self.assertEqual(tensor_value.dtype, np.float32)
            self.assertEqual(tensor_value.shape, (0, ))
Beispiel #10
0
    def testDisableTracingWorks(self):
        writer = dumping_callback.enable_dumping(self.dump_root)
        dumping_callback.disable_dumping()

        x = constant_op.constant([10.0, 12.0, 10.0])
        for _ in range(2):
            array_ops.unique(x)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        reader = debug_events_reader.DebugEventsDir(self.dump_root)
        source_files_iter = reader.source_files_iterator()
        stack_frames_iter = reader.stack_frames_iterator()
        execution_iter = reader.execution_iterator()
        # No source-file, stack-frame or execution data should have been dumped.
        with self.assertRaises(StopIteration):
            next(source_files_iter)
        with self.assertRaises(StopIteration):
            next(stack_frames_iter)
        with self.assertRaises(StopIteration):
            next(execution_iter)
Beispiel #11
0
    def testPureEagerOpExecution(self, tensor_debug_mode):
        """Test catching Infinity in eager op execution: float32."""
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)

        x = constant_op.constant(10.0)
        zero = constant_op.constant(0.0)
        one = constant_op.constant(1.0)
        two = constant_op.constant(2.0)
        three = constant_op.constant(3.0)
        # Use Collatz conjecture as a test case.
        while x > one:
            if math_ops.equal(x % two, zero):
                x = x / two
            else:
                x = x * three + one

        writer.FlushNonExecutionFiles()
        self._readAndCheckMetadataFile()
        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()

        # Before FlushExecutionFiles() is called, the .execution file should be
        # empty.
        reader = debug_events_reader.DebugEventsDir(self.dump_root)
        execution_iter = reader.execution_iterator()
        with self.assertRaises(StopIteration):
            next(execution_iter)

        # After the flushing, the .execution file should hold the appropriate
        # contents.
        writer.FlushExecutionFiles()
        execution_iter = reader.execution_iterator()
        prev_wall_time = 1
        executed_op_types = []
        tensor_values = collections.defaultdict(lambda: [])
        for debug_event in execution_iter:
            self.assertGreaterEqual(debug_event.wall_time, prev_wall_time)
            prev_wall_time = debug_event.wall_time
            execution = debug_event.execution
            executed_op_types.append(execution.op_type)
            self.assertTrue(execution.input_tensor_ids)
            self.assertTrue(execution.output_tensor_ids)
            if tensor_debug_mode == "NO_TENSOR":
                # Due to the NO_TENSOR tensor debug mode, tensor_protos ought to
                # be empty.
                self.assertFalse(execution.tensor_protos)
            elif tensor_debug_mode == "FULL_TENSOR":
                # Under the FULL_TENSOR mode, the value of the tensor should be
                # available through `tensor_protos`.
                tensor_value = float(
                    tensor_util.MakeNdarray(execution.tensor_protos[0]))
                tensor_values[execution.op_type].append(tensor_value)
            # Verify the code_location field.
            self.assertTrue(execution.code_location.stack_frame_ids)
            for stack_frame_id in execution.code_location.stack_frame_ids:
                self.assertIn(stack_frame_id, stack_frame_by_id)
        if tensor_debug_mode == "FULL_TENSOR":
            self.assertAllClose(tensor_values["Greater"],
                                [1, 1, 1, 1, 1, 1, 0])
            self.assertAllClose(tensor_values["RealDiv"], [5, 8, 4, 2, 1])
            self.assertAllClose(tensor_values["Mul"], [15])
            self.assertAllClose(tensor_values["AddV2"], [16])

        self.assertEqual(
            executed_op_types,
            [
                "Greater",
                "FloorMod",
                "Equal",
                "RealDiv",  # 10 --> 5
                "Greater",
                "FloorMod",
                "Equal",
                "Mul",
                "AddV2",  # 5 --> 16
                "Greater",
                "FloorMod",
                "Equal",
                "RealDiv",  # 16 --> 8
                "Greater",
                "FloorMod",
                "Equal",
                "RealDiv",  # 8 --> 4
                "Greater",
                "FloorMod",
                "Equal",
                "RealDiv",  # 4 --> 2
                "Greater",
                "FloorMod",
                "Equal",
                "RealDiv",  # 2 --> 1
                "Greater"
            ])

        # Due to the pure eager op execution, the .graph file and the
        # .graph_execution_traces file ought to be empty.
        graphs_iterator = reader.graphs_iterator()
        with self.assertRaises(StopIteration):
            next(graphs_iterator)
        graph_trace_iter = reader.graph_execution_traces_iterator()
        with self.assertRaises(StopIteration):
            next(graph_trace_iter)
Beispiel #12
0
    def testMobiletNetV2Fit(self, tensor_debug_mode):
        """Test training Keras MobileNetV2 works with dumping."""
        # Use a large circular-buffer to make sure we capture all the executed ops.
        writer = dumping_callback.enable_dumping(
            self.dump_root,
            tensor_debug_mode=tensor_debug_mode,
            circular_buffer_size=100000)
        model = mobilenet_v2.MobileNetV2(input_shape=(32, 32, 3),
                                         alpha=0.1,
                                         weights=None)
        y = model.layers[22].output
        y = core.Flatten()(y)
        y = core.Dense(1)(y)
        model = models.Model(inputs=model.inputs, outputs=y)

        batch_size = 2
        xs = np.zeros([batch_size] + list(model.input_shape[1:]))
        ys = np.zeros([batch_size] + list(model.output_shape[1:]))
        model.compile(optimizer="sgd", loss="mse")
        epochs = 1
        history = model.fit(xs, ys, epochs=epochs, verbose=0)
        self.assertLen(history.history["loss"], epochs)

        writer.FlushNonExecutionFiles()
        writer.FlushExecutionFiles()

        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()
        (context_ids, op_types,
         op_name_to_op_type) = self._readAndCheckGraphsFile(stack_frame_by_id)
        # Simply assert that graph are recorded and refrain from asserting on the
        # internal details of the Keras model.
        self.assertTrue(context_ids)
        self.assertTrue(op_types)
        self.assertTrue(op_name_to_op_type)

        if context.executing_eagerly():
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, hence it doesn't get logged to the
            # .execution file.
            executed_op_types, _, _, _, _ = self._readAndCheckExecutionFile()
            self.assertTrue(executed_op_types)

        (op_names, _, _, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        # These are the ops that we can safely assume to have been executed during
        # the model's fit() call.
        self.assertIn("Conv2D", executed_op_types)
        self.assertIn("Relu6", executed_op_types)
        self.assertIn("Conv2DBackpropFilter", executed_op_types)
        self.assertIn("Relu6Grad", executed_op_types)
        if tensor_debug_mode == "NO_TENSOR":
            # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought to
            # be an empty float32 tensor.
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
        elif tensor_debug_mode == "FULL_TENSOR":
            conv2d_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Conv2D"
            ]
            self.assertTrue(conv2d_values)
            for conv2d_value in conv2d_values:
                self.assertGreater(len(conv2d_value.shape), 1)
                self.assertEqual(conv2d_value.shape[0], batch_size)
            relu6_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Relu6"
            ]
            self.assertTrue(relu6_values)
            for relu6_value in relu6_values:
                self.assertGreater(len(relu6_value.shape), 1)
                self.assertEqual(relu6_value.shape[0], batch_size)
            conv2d_bp_filter_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Conv2DBackpropFilter"
            ]
            self.assertTrue(conv2d_bp_filter_values)
            for conv2d_bp_filter_value in conv2d_bp_filter_values:
                self.assertGreater(len(conv2d_bp_filter_value.shape), 1)
            relu6_grad_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Relu6Grad"
            ]
            self.assertTrue(relu6_grad_values)
            for relu6_grad_value in relu6_grad_values:
                self.assertGreater(len(relu6_grad_value.shape), 1)
Beispiel #13
0
    def testFunctionExecutionWithControlFlow(self, tensor_debug_mode):
        writer = dumping_callback.enable_dumping(
            self.dump_root, tensor_debug_mode=tensor_debug_mode)

        @def_function.function
        def iterative_doubling(x, times):
            i = constant_op.constant(0, dtype=dtypes.int32)
            while i < times:
                x = x * 2.0
                i += 1
            return x

        x = constant_op.constant(0.5, dtype=dtypes.float32)
        times = constant_op.constant(4, dtype=dtypes.int32)
        self.assertAllClose(self.evaluate(iterative_doubling(x, times)), 8.0)

        writer.FlushNonExecutionFiles()
        stack_frame_by_id = self._readAndCheckSourceFilesAndStackFrames()

        # Verify the content of the .graphs file.
        context_ids, op_types, op_name_to_op_type = (
            self._readAndCheckGraphsFile(stack_frame_by_id))
        self.assertIn("Less", op_types)
        self.assertIn("Mul", op_types)
        self.assertIn("AddV2", op_types)

        # Before FlushExecutionFiles() is called, the .execution and
        # .graph_execution_traces files should be both empty.
        reader = debug_events_reader.DebugEventsDir(self.dump_root)
        execution_iter = reader.execution_iterator()
        graph_execution_traces_iter = reader.graph_execution_traces_iterator()
        with self.assertRaises(StopIteration):
            next(execution_iter)
        with self.assertRaises(StopIteration):
            next(graph_execution_traces_iter)

        # TODO(cais): Backport execution instrumentation to tf.Session.
        writer.FlushExecutionFiles()
        # After the flushing, the .execution file should hold the appropriate
        # contents.
        if context.executing_eagerly():
            (executed_op_types, input_tensor_ids, output_tensor_ids,
             tensor_debug_modes,
             tensor_values) = self._readAndCheckExecutionFile()
            # NOTE(b/142486213): Execution of the TF function happens with
            # Session.run() in v1 graph mode, hence it doesn't get logged to the
            # .execution file.
            self.assertLen(executed_op_types, 1)
            self.assertIn("iterative_doubling", executed_op_types[0])
            self.assertLen(input_tensor_ids[0], 2)
            self.assertLen(output_tensor_ids[0], 1)
            self.assertEqual(
                tensor_debug_modes[0],
                debug_event_pb2.TensorDebugMode.Value(tensor_debug_mode))
            if tensor_debug_mode == "FULL_TENSOR":
                self.assertAllClose(tensor_values, [[8.0]])

        (op_names, _, output_slots, tensor_values
         ) = self._readAndCheckGraphExecutionTracesFile(context_ids)
        executed_op_types = [
            op_name_to_op_type[op_name] for op_name in op_names
        ]
        # The Less op should have been executed 5 times.
        self.assertEqual(executed_op_types.count("Less"), 5)
        # The last executed op should be Less.
        self.assertEqual(executed_op_types[-1], "Less")
        # The Mul op should have been executed 4 times.
        self.assertEqual(executed_op_types.count("Mul"), 4)
        # The AddV2 op should have been run, but we refrain from asserting on how
        # many times it's executed.
        self.assertIn("AddV2", executed_op_types)
        for output_slot in output_slots:
            self.assertEqual(output_slot, 0)
        if tensor_debug_mode == "NO_TENSOR":
            # Under the default NO_TENSOR tensor-debug mode, the tensor_proto ought to
            # be an empty float32 tensor.
            for tensor_value in tensor_values:
                self.assertEqual(tensor_value.dtype, np.float32)
                self.assertEqual(tensor_value.shape, (0, ))
        elif tensor_debug_mode == "FULL_TENSOR":
            less_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Less"
            ]
            self.assertAllClose(less_values, [True, True, True, True, False])
            mul_values = [
                tensor_values[i] for i, op_type in enumerate(executed_op_types)
                if op_type == "Mul"
            ]
            self.assertAllClose(mul_values, [1.0, 2.0, 4.0, 8.0])
Beispiel #14
0
def main(_):
    if FLAGS.check_numerics and FLAGS.dump_dir:
        raise ValueError(
            "The --check_numerics and --dump_dir flags are mutually "
            "exclusive.")
    if FLAGS.check_numerics:
        tf.debugging.enable_check_numerics()
    elif FLAGS.dump_dir:
        dumping_callback.enable_dumping(
            FLAGS.dump_dir,
            tensor_debug_mode=FLAGS.dump_tensor_debug_mode,
            circular_buffer_size=FLAGS.dump_circular_buffer_size)

    # Import data
    if FLAGS.fake_data:
        imgs = tf.random.uniform(maxval=256,
                                 shape=(1000, 28, 28),
                                 dtype=tf.int32)
        labels = tf.random.uniform(maxval=10, shape=(1000, ), dtype=tf.int32)
        mnist_train = imgs, labels
        mnist_test = imgs, labels
    else:
        mnist_train, mnist_test = tf.keras.datasets.mnist.load_data()

    @tf.function
    def format_example(imgs, labels):
        """Formats each training and test example to work with our model."""
        imgs = tf.reshape(imgs, [-1, 28 * 28])
        imgs = tf.cast(imgs, tf.float32) / 255.0
        labels = tf.one_hot(labels, depth=10, dtype=tf.float32)
        return imgs, labels

    train_ds = tf.data.Dataset.from_tensor_slices(mnist_train).shuffle(
        FLAGS.train_batch_size * FLAGS.max_steps,
        seed=RAND_SEED).batch(FLAGS.train_batch_size)
    train_ds = train_ds.map(format_example)

    test_ds = tf.data.Dataset.from_tensor_slices(mnist_test).repeat().batch(
        len(mnist_test[0]))
    test_ds = test_ds.map(format_example)

    def get_dense_weights(input_dim, output_dim):
        """Initializes the parameters for a single dense layer."""
        initial_kernel = tf.keras.initializers.TruncatedNormal(mean=0.0,
                                                               stddev=0.1,
                                                               seed=RAND_SEED)
        kernel = tf.Variable(initial_kernel([input_dim, output_dim]))
        bias = tf.Variable(tf.constant(0.1, shape=[output_dim]))

        return kernel, bias

    @tf.function
    def dense_layer(weights, input_tensor, act=tf.nn.relu):
        """Runs the forward computation for a single dense layer."""
        kernel, bias = weights
        preactivate = tf.matmul(input_tensor, kernel) + bias

        activations = act(preactivate)
        return activations

    # init model
    hidden = get_dense_weights(IMAGE_SIZE**2, HIDDEN_SIZE)
    logits = get_dense_weights(HIDDEN_SIZE, NUM_LABELS)
    variables = hidden + logits

    @tf.function
    def model(x):
        """Feed forward function of the model.

    Args:
      x: a (?, 28*28) tensor consisting of the feature inputs for a batch of
        examples.

    Returns:
      A (?, 10) tensor containing the class scores for each example.
    """
        hidden_act = dense_layer(hidden, x)
        logits_act = dense_layer(logits, hidden_act, tf.identity)
        y = tf.nn.softmax(logits_act)
        return y

    @tf.function
    def loss(logits, labels):
        """Calculates cross entropy loss."""
        diff = -(labels * tf.math.log(logits))
        loss = tf.reduce_mean(diff)
        return loss

    train_batches = iter(train_ds)
    test_batches = iter(test_ds)
    optimizer = tf.optimizers.Adam(learning_rate=FLAGS.learning_rate)
    for i in range(FLAGS.max_steps):
        x_train, y_train = next(train_batches)
        x_test, y_test = next(test_batches)

        # Train Step
        with tf.GradientTape() as tape:
            y = model(x_train)
            loss_val = loss(y, y_train)
        grads = tape.gradient(loss_val, variables)

        optimizer.apply_gradients(zip(grads, variables))

        # Evaluation Step
        y = model(x_test)
        correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_test, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        print("Accuracy at step %d: %s" % (i, accuracy.numpy()))