Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/ops/summary_op_util.py: 34%

29 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2017 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14#============================================================================== 

15"""Contains utility functions used by summary ops.""" 

16 

17import contextlib 

18import re 

19 

20from tensorflow.python.framework import ops 

21from tensorflow.python.platform import tf_logging 

22 

23 

24def collect(val, collections, default_collections): 

25 """Adds keys to a collection. 

26 

27 Args: 

28 val: The value to add per each key. 

29 collections: A collection of keys to add. 

30 default_collections: Used if collections is None. 

31 """ 

32 if collections is None: 

33 collections = default_collections 

34 for key in collections: 

35 ops.add_to_collection(key, val) 

36 

37 

38_INVALID_TAG_CHARACTERS = re.compile(r'[^-/\w\.]') 

39 

40 

41def clean_tag(name): 

42 """Cleans a tag. Removes illegal characters for instance. 

43 

44 Args: 

45 name: The original tag name to be processed. 

46 

47 Returns: 

48 The cleaned tag name. 

49 """ 

50 # In the past, the first argument to summary ops was a tag, which allowed 

51 # arbitrary characters. Now we are changing the first argument to be the node 

52 # name. This has a number of advantages (users of summary ops now can 

53 # take advantage of the tf name scope system) but risks breaking existing 

54 # usage, because a much smaller set of characters are allowed in node names. 

55 # This function replaces all illegal characters with _s, and logs a warning. 

56 # It also strips leading slashes from the name. 

57 if name is not None: 

58 new_name = _INVALID_TAG_CHARACTERS.sub('_', name) 

59 new_name = new_name.lstrip('/') # Remove leading slashes 

60 if new_name != name: 

61 tf_logging.info('Summary name %s is illegal; using %s instead.' % 

62 (name, new_name)) 

63 name = new_name 

64 return name 

65 

66 

67@contextlib.contextmanager 

68def summary_scope(name, family=None, default_name=None, values=None): 

69 """Enters a scope used for the summary and yields both the name and tag. 

70 

71 To ensure that the summary tag name is always unique, we create a name scope 

72 based on `name` and use the full scope name in the tag. 

73 

74 If `family` is set, then the tag name will be '<family>/<scope_name>', where 

75 `scope_name` is `<outer_scope>/<family>/<name>`. This ensures that `family` 

76 is always the prefix of the tag (and unmodified), while ensuring the scope 

77 respects the outer scope from this summary was created. 

78 

79 Args: 

80 name: A name for the generated summary node. 

81 family: Optional; if provided, used as the prefix of the summary tag name. 

82 default_name: Optional; if provided, used as default name of the summary. 

83 values: Optional; passed as `values` parameter to name_scope. 

84 

85 Yields: 

86 A tuple `(tag, scope)`, both of which are unique and should be used for the 

87 tag and the scope for the summary to output. 

88 """ 

89 name = clean_tag(name) 

90 family = clean_tag(family) 

91 # Use family name in the scope to ensure uniqueness of scope/tag. 

92 scope_base_name = name if family is None else '{}/{}'.format(family, name) 

93 with ops.name_scope( 

94 scope_base_name, default_name, values, skip_on_eager=False) as scope: 

95 if family is None: 

96 tag = scope.rstrip('/') 

97 else: 

98 # Prefix our scope with family again so it displays in the right tab. 

99 tag = '{}/{}'.format(family, scope.rstrip('/')) 

100 # Note: tag is not 100% unique if the user explicitly enters a scope with 

101 # the same name as family, then later enter it again before summaries. 

102 # This is very contrived though, and we opt here to let it be a runtime 

103 # exception if tags do indeed collide. 

104 yield (tag, scope)