tensorbored 2.21.0rc1769983804__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. tensorbored/__init__.py +112 -0
  2. tensorbored/_vendor/__init__.py +0 -0
  3. tensorbored/_vendor/bleach/__init__.py +125 -0
  4. tensorbored/_vendor/bleach/_vendor/__init__.py +0 -0
  5. tensorbored/_vendor/bleach/_vendor/html5lib/__init__.py +35 -0
  6. tensorbored/_vendor/bleach/_vendor/html5lib/_ihatexml.py +289 -0
  7. tensorbored/_vendor/bleach/_vendor/html5lib/_inputstream.py +918 -0
  8. tensorbored/_vendor/bleach/_vendor/html5lib/_tokenizer.py +1735 -0
  9. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/__init__.py +5 -0
  10. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/_base.py +40 -0
  11. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/py.py +67 -0
  12. tensorbored/_vendor/bleach/_vendor/html5lib/_utils.py +159 -0
  13. tensorbored/_vendor/bleach/_vendor/html5lib/constants.py +2946 -0
  14. tensorbored/_vendor/bleach/_vendor/html5lib/filters/__init__.py +0 -0
  15. tensorbored/_vendor/bleach/_vendor/html5lib/filters/alphabeticalattributes.py +29 -0
  16. tensorbored/_vendor/bleach/_vendor/html5lib/filters/base.py +12 -0
  17. tensorbored/_vendor/bleach/_vendor/html5lib/filters/inject_meta_charset.py +73 -0
  18. tensorbored/_vendor/bleach/_vendor/html5lib/filters/lint.py +93 -0
  19. tensorbored/_vendor/bleach/_vendor/html5lib/filters/optionaltags.py +207 -0
  20. tensorbored/_vendor/bleach/_vendor/html5lib/filters/sanitizer.py +916 -0
  21. tensorbored/_vendor/bleach/_vendor/html5lib/filters/whitespace.py +38 -0
  22. tensorbored/_vendor/bleach/_vendor/html5lib/html5parser.py +2795 -0
  23. tensorbored/_vendor/bleach/_vendor/html5lib/serializer.py +409 -0
  24. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/__init__.py +30 -0
  25. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/genshi.py +54 -0
  26. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/sax.py +50 -0
  27. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/__init__.py +88 -0
  28. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/base.py +417 -0
  29. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/dom.py +239 -0
  30. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree.py +343 -0
  31. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree_lxml.py +392 -0
  32. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/__init__.py +154 -0
  33. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/base.py +252 -0
  34. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/dom.py +43 -0
  35. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree.py +131 -0
  36. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree_lxml.py +215 -0
  37. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/genshi.py +69 -0
  38. tensorbored/_vendor/bleach/_vendor/parse.py +1078 -0
  39. tensorbored/_vendor/bleach/callbacks.py +32 -0
  40. tensorbored/_vendor/bleach/html5lib_shim.py +757 -0
  41. tensorbored/_vendor/bleach/linkifier.py +633 -0
  42. tensorbored/_vendor/bleach/parse_shim.py +1 -0
  43. tensorbored/_vendor/bleach/sanitizer.py +638 -0
  44. tensorbored/_vendor/bleach/six_shim.py +19 -0
  45. tensorbored/_vendor/webencodings/__init__.py +342 -0
  46. tensorbored/_vendor/webencodings/labels.py +231 -0
  47. tensorbored/_vendor/webencodings/mklabels.py +59 -0
  48. tensorbored/_vendor/webencodings/x_user_defined.py +325 -0
  49. tensorbored/assets.py +36 -0
  50. tensorbored/auth.py +102 -0
  51. tensorbored/backend/__init__.py +0 -0
  52. tensorbored/backend/application.py +604 -0
  53. tensorbored/backend/auth_context_middleware.py +38 -0
  54. tensorbored/backend/client_feature_flags.py +113 -0
  55. tensorbored/backend/empty_path_redirect.py +46 -0
  56. tensorbored/backend/event_processing/__init__.py +0 -0
  57. tensorbored/backend/event_processing/data_ingester.py +276 -0
  58. tensorbored/backend/event_processing/data_provider.py +535 -0
  59. tensorbored/backend/event_processing/directory_loader.py +142 -0
  60. tensorbored/backend/event_processing/directory_watcher.py +272 -0
  61. tensorbored/backend/event_processing/event_accumulator.py +950 -0
  62. tensorbored/backend/event_processing/event_file_inspector.py +463 -0
  63. tensorbored/backend/event_processing/event_file_loader.py +292 -0
  64. tensorbored/backend/event_processing/event_multiplexer.py +521 -0
  65. tensorbored/backend/event_processing/event_util.py +68 -0
  66. tensorbored/backend/event_processing/io_wrapper.py +223 -0
  67. tensorbored/backend/event_processing/plugin_asset_util.py +104 -0
  68. tensorbored/backend/event_processing/plugin_event_accumulator.py +721 -0
  69. tensorbored/backend/event_processing/plugin_event_multiplexer.py +522 -0
  70. tensorbored/backend/event_processing/reservoir.py +266 -0
  71. tensorbored/backend/event_processing/tag_types.py +29 -0
  72. tensorbored/backend/experiment_id.py +71 -0
  73. tensorbored/backend/experimental_plugin.py +51 -0
  74. tensorbored/backend/http_util.py +263 -0
  75. tensorbored/backend/json_util.py +70 -0
  76. tensorbored/backend/path_prefix.py +67 -0
  77. tensorbored/backend/process_graph.py +74 -0
  78. tensorbored/backend/security_validator.py +202 -0
  79. tensorbored/compat/__init__.py +69 -0
  80. tensorbored/compat/proto/__init__.py +0 -0
  81. tensorbored/compat/proto/allocation_description_pb2.py +35 -0
  82. tensorbored/compat/proto/api_def_pb2.py +82 -0
  83. tensorbored/compat/proto/attr_value_pb2.py +80 -0
  84. tensorbored/compat/proto/cluster_pb2.py +58 -0
  85. tensorbored/compat/proto/config_pb2.py +271 -0
  86. tensorbored/compat/proto/coordination_config_pb2.py +45 -0
  87. tensorbored/compat/proto/cost_graph_pb2.py +87 -0
  88. tensorbored/compat/proto/cpp_shape_inference_pb2.py +70 -0
  89. tensorbored/compat/proto/debug_pb2.py +65 -0
  90. tensorbored/compat/proto/event_pb2.py +149 -0
  91. tensorbored/compat/proto/full_type_pb2.py +74 -0
  92. tensorbored/compat/proto/function_pb2.py +157 -0
  93. tensorbored/compat/proto/graph_debug_info_pb2.py +111 -0
  94. tensorbored/compat/proto/graph_pb2.py +41 -0
  95. tensorbored/compat/proto/histogram_pb2.py +39 -0
  96. tensorbored/compat/proto/meta_graph_pb2.py +254 -0
  97. tensorbored/compat/proto/node_def_pb2.py +61 -0
  98. tensorbored/compat/proto/op_def_pb2.py +81 -0
  99. tensorbored/compat/proto/resource_handle_pb2.py +48 -0
  100. tensorbored/compat/proto/rewriter_config_pb2.py +93 -0
  101. tensorbored/compat/proto/rpc_options_pb2.py +35 -0
  102. tensorbored/compat/proto/saved_object_graph_pb2.py +193 -0
  103. tensorbored/compat/proto/saver_pb2.py +38 -0
  104. tensorbored/compat/proto/step_stats_pb2.py +116 -0
  105. tensorbored/compat/proto/struct_pb2.py +144 -0
  106. tensorbored/compat/proto/summary_pb2.py +111 -0
  107. tensorbored/compat/proto/tensor_description_pb2.py +38 -0
  108. tensorbored/compat/proto/tensor_pb2.py +68 -0
  109. tensorbored/compat/proto/tensor_shape_pb2.py +46 -0
  110. tensorbored/compat/proto/tfprof_log_pb2.py +307 -0
  111. tensorbored/compat/proto/trackable_object_graph_pb2.py +90 -0
  112. tensorbored/compat/proto/types_pb2.py +105 -0
  113. tensorbored/compat/proto/variable_pb2.py +62 -0
  114. tensorbored/compat/proto/verifier_config_pb2.py +38 -0
  115. tensorbored/compat/proto/versions_pb2.py +35 -0
  116. tensorbored/compat/tensorflow_stub/__init__.py +38 -0
  117. tensorbored/compat/tensorflow_stub/app.py +124 -0
  118. tensorbored/compat/tensorflow_stub/compat/__init__.py +131 -0
  119. tensorbored/compat/tensorflow_stub/compat/v1/__init__.py +20 -0
  120. tensorbored/compat/tensorflow_stub/dtypes.py +692 -0
  121. tensorbored/compat/tensorflow_stub/error_codes.py +169 -0
  122. tensorbored/compat/tensorflow_stub/errors.py +507 -0
  123. tensorbored/compat/tensorflow_stub/flags.py +124 -0
  124. tensorbored/compat/tensorflow_stub/io/__init__.py +17 -0
  125. tensorbored/compat/tensorflow_stub/io/gfile.py +1011 -0
  126. tensorbored/compat/tensorflow_stub/pywrap_tensorflow.py +285 -0
  127. tensorbored/compat/tensorflow_stub/tensor_shape.py +1035 -0
  128. tensorbored/context.py +129 -0
  129. tensorbored/data/__init__.py +0 -0
  130. tensorbored/data/grpc_provider.py +365 -0
  131. tensorbored/data/ingester.py +46 -0
  132. tensorbored/data/proto/__init__.py +0 -0
  133. tensorbored/data/proto/data_provider_pb2.py +517 -0
  134. tensorbored/data/proto/data_provider_pb2_grpc.py +374 -0
  135. tensorbored/data/provider.py +1365 -0
  136. tensorbored/data/server_ingester.py +301 -0
  137. tensorbored/data_compat.py +159 -0
  138. tensorbored/dataclass_compat.py +224 -0
  139. tensorbored/default.py +124 -0
  140. tensorbored/errors.py +130 -0
  141. tensorbored/lazy.py +99 -0
  142. tensorbored/main.py +48 -0
  143. tensorbored/main_lib.py +62 -0
  144. tensorbored/manager.py +487 -0
  145. tensorbored/notebook.py +441 -0
  146. tensorbored/plugin_util.py +266 -0
  147. tensorbored/plugins/__init__.py +0 -0
  148. tensorbored/plugins/audio/__init__.py +0 -0
  149. tensorbored/plugins/audio/audio_plugin.py +229 -0
  150. tensorbored/plugins/audio/metadata.py +69 -0
  151. tensorbored/plugins/audio/plugin_data_pb2.py +37 -0
  152. tensorbored/plugins/audio/summary.py +230 -0
  153. tensorbored/plugins/audio/summary_v2.py +124 -0
  154. tensorbored/plugins/base_plugin.py +367 -0
  155. tensorbored/plugins/core/__init__.py +0 -0
  156. tensorbored/plugins/core/core_plugin.py +981 -0
  157. tensorbored/plugins/custom_scalar/__init__.py +0 -0
  158. tensorbored/plugins/custom_scalar/custom_scalars_plugin.py +320 -0
  159. tensorbored/plugins/custom_scalar/layout_pb2.py +85 -0
  160. tensorbored/plugins/custom_scalar/metadata.py +35 -0
  161. tensorbored/plugins/custom_scalar/summary.py +79 -0
  162. tensorbored/plugins/debugger_v2/__init__.py +0 -0
  163. tensorbored/plugins/debugger_v2/debug_data_multiplexer.py +631 -0
  164. tensorbored/plugins/debugger_v2/debug_data_provider.py +634 -0
  165. tensorbored/plugins/debugger_v2/debugger_v2_plugin.py +504 -0
  166. tensorbored/plugins/distribution/__init__.py +0 -0
  167. tensorbored/plugins/distribution/compressor.py +158 -0
  168. tensorbored/plugins/distribution/distributions_plugin.py +116 -0
  169. tensorbored/plugins/distribution/metadata.py +19 -0
  170. tensorbored/plugins/graph/__init__.py +0 -0
  171. tensorbored/plugins/graph/graph_util.py +129 -0
  172. tensorbored/plugins/graph/graphs_plugin.py +336 -0
  173. tensorbored/plugins/graph/keras_util.py +328 -0
  174. tensorbored/plugins/graph/metadata.py +42 -0
  175. tensorbored/plugins/histogram/__init__.py +0 -0
  176. tensorbored/plugins/histogram/histograms_plugin.py +144 -0
  177. tensorbored/plugins/histogram/metadata.py +63 -0
  178. tensorbored/plugins/histogram/plugin_data_pb2.py +34 -0
  179. tensorbored/plugins/histogram/summary.py +234 -0
  180. tensorbored/plugins/histogram/summary_v2.py +292 -0
  181. tensorbored/plugins/hparams/__init__.py +14 -0
  182. tensorbored/plugins/hparams/_keras.py +93 -0
  183. tensorbored/plugins/hparams/api.py +130 -0
  184. tensorbored/plugins/hparams/api_pb2.py +208 -0
  185. tensorbored/plugins/hparams/backend_context.py +606 -0
  186. tensorbored/plugins/hparams/download_data.py +158 -0
  187. tensorbored/plugins/hparams/error.py +26 -0
  188. tensorbored/plugins/hparams/get_experiment.py +71 -0
  189. tensorbored/plugins/hparams/hparams_plugin.py +206 -0
  190. tensorbored/plugins/hparams/hparams_util_pb2.py +69 -0
  191. tensorbored/plugins/hparams/json_format_compat.py +38 -0
  192. tensorbored/plugins/hparams/list_metric_evals.py +57 -0
  193. tensorbored/plugins/hparams/list_session_groups.py +1040 -0
  194. tensorbored/plugins/hparams/metadata.py +125 -0
  195. tensorbored/plugins/hparams/metrics.py +41 -0
  196. tensorbored/plugins/hparams/plugin_data_pb2.py +69 -0
  197. tensorbored/plugins/hparams/summary.py +205 -0
  198. tensorbored/plugins/hparams/summary_v2.py +597 -0
  199. tensorbored/plugins/image/__init__.py +0 -0
  200. tensorbored/plugins/image/images_plugin.py +232 -0
  201. tensorbored/plugins/image/metadata.py +65 -0
  202. tensorbored/plugins/image/plugin_data_pb2.py +34 -0
  203. tensorbored/plugins/image/summary.py +159 -0
  204. tensorbored/plugins/image/summary_v2.py +130 -0
  205. tensorbored/plugins/mesh/__init__.py +14 -0
  206. tensorbored/plugins/mesh/mesh_plugin.py +292 -0
  207. tensorbored/plugins/mesh/metadata.py +152 -0
  208. tensorbored/plugins/mesh/plugin_data_pb2.py +37 -0
  209. tensorbored/plugins/mesh/summary.py +251 -0
  210. tensorbored/plugins/mesh/summary_v2.py +214 -0
  211. tensorbored/plugins/metrics/__init__.py +0 -0
  212. tensorbored/plugins/metrics/metadata.py +17 -0
  213. tensorbored/plugins/metrics/metrics_plugin.py +623 -0
  214. tensorbored/plugins/pr_curve/__init__.py +0 -0
  215. tensorbored/plugins/pr_curve/metadata.py +75 -0
  216. tensorbored/plugins/pr_curve/plugin_data_pb2.py +34 -0
  217. tensorbored/plugins/pr_curve/pr_curves_plugin.py +241 -0
  218. tensorbored/plugins/pr_curve/summary.py +574 -0
  219. tensorbored/plugins/profile_redirect/__init__.py +0 -0
  220. tensorbored/plugins/profile_redirect/profile_redirect_plugin.py +49 -0
  221. tensorbored/plugins/projector/__init__.py +67 -0
  222. tensorbored/plugins/projector/metadata.py +26 -0
  223. tensorbored/plugins/projector/projector_config_pb2.py +54 -0
  224. tensorbored/plugins/projector/projector_plugin.py +795 -0
  225. tensorbored/plugins/projector/tf_projector_plugin/index.js +32 -0
  226. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.html +524 -0
  227. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.js +15536 -0
  228. tensorbored/plugins/scalar/__init__.py +0 -0
  229. tensorbored/plugins/scalar/metadata.py +60 -0
  230. tensorbored/plugins/scalar/plugin_data_pb2.py +34 -0
  231. tensorbored/plugins/scalar/scalars_plugin.py +181 -0
  232. tensorbored/plugins/scalar/summary.py +109 -0
  233. tensorbored/plugins/scalar/summary_v2.py +124 -0
  234. tensorbored/plugins/text/__init__.py +0 -0
  235. tensorbored/plugins/text/metadata.py +62 -0
  236. tensorbored/plugins/text/plugin_data_pb2.py +34 -0
  237. tensorbored/plugins/text/summary.py +114 -0
  238. tensorbored/plugins/text/summary_v2.py +124 -0
  239. tensorbored/plugins/text/text_plugin.py +288 -0
  240. tensorbored/plugins/wit_redirect/__init__.py +0 -0
  241. tensorbored/plugins/wit_redirect/wit_redirect_plugin.py +49 -0
  242. tensorbored/program.py +910 -0
  243. tensorbored/summary/__init__.py +35 -0
  244. tensorbored/summary/_output.py +124 -0
  245. tensorbored/summary/_tf/__init__.py +14 -0
  246. tensorbored/summary/_tf/summary/__init__.py +178 -0
  247. tensorbored/summary/_writer.py +105 -0
  248. tensorbored/summary/v1.py +51 -0
  249. tensorbored/summary/v2.py +25 -0
  250. tensorbored/summary/writer/__init__.py +13 -0
  251. tensorbored/summary/writer/event_file_writer.py +291 -0
  252. tensorbored/summary/writer/record_writer.py +50 -0
  253. tensorbored/util/__init__.py +0 -0
  254. tensorbored/util/encoder.py +116 -0
  255. tensorbored/util/grpc_util.py +311 -0
  256. tensorbored/util/img_mime_type_detector.py +40 -0
  257. tensorbored/util/io_util.py +20 -0
  258. tensorbored/util/lazy_tensor_creator.py +110 -0
  259. tensorbored/util/op_evaluator.py +104 -0
  260. tensorbored/util/platform_util.py +20 -0
  261. tensorbored/util/tb_logging.py +24 -0
  262. tensorbored/util/tensor_util.py +617 -0
  263. tensorbored/util/timing.py +122 -0
  264. tensorbored/version.py +21 -0
  265. tensorbored/webfiles.zip +0 -0
  266. tensorbored-2.21.0rc1769983804.dist-info/METADATA +49 -0
  267. tensorbored-2.21.0rc1769983804.dist-info/RECORD +271 -0
  268. tensorbored-2.21.0rc1769983804.dist-info/WHEEL +5 -0
  269. tensorbored-2.21.0rc1769983804.dist-info/entry_points.txt +6 -0
  270. tensorbored-2.21.0rc1769983804.dist-info/licenses/LICENSE +739 -0
  271. tensorbored-2.21.0rc1769983804.dist-info/top_level.txt +1 -0
@@ -0,0 +1,463 @@
1
+ # Copyright 2015 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
+
16
+ """Logic for TensorBoard inspector to help humans investigate event files.
17
+
18
+ Example usages:
19
+ tensorbored --inspect --event_file myevents.out
20
+ tensorbored --inspect --event_file myevents.out --tag loss
21
+ tensorbored --inspect --logdir mylogdir
22
+ tensorbored --inspect --logdir mylogdir --tag loss
23
+
24
+
25
+ This script runs over a logdir and creates an InspectionUnit for every
26
+ subdirectory with event files. If running over an event file, it creates only
27
+ one InspectionUnit. One block of output is printed to console for each
28
+ InspectionUnit.
29
+
30
+ The primary content of an InspectionUnit is the dict field_to_obs that maps
31
+ fields (e.g. "scalar", "histogram", "session_log:start", etc.) to a list of
32
+ Observations for the field. Observations correspond one-to-one with Events in an
33
+ event file but contain less information because they only store what is
34
+ necessary to generate the final console output.
35
+
36
+ The final output is rendered to console by applying some aggregating function
37
+ to the lists of Observations. Different functions are applied depending on the
38
+ type of field. For instance, for "scalar" fields, the inspector shows aggregate
39
+ statistics. For other fields like "session_log:start", all observed steps are
40
+ printed in order to aid debugging.
41
+
42
+
43
+ [1] Query a logdir or an event file for its logged tags and summary statistics
44
+ using --logdir or --event_file.
45
+
46
+ [[event_file]] contains these tags:
47
+ histograms
48
+ binary/Sign/Activations
49
+ binary/nn_tanh/act/Activations
50
+ binary/nn_tanh/biases
51
+ binary/nn_tanh/biases:gradient
52
+ binary/nn_tanh/weights
53
+ binary/nn_tanh/weights:gradient
54
+ images
55
+ input_images/image/0
56
+ input_images/image/1
57
+ input_images/image/2
58
+ scalars
59
+ Learning Rate
60
+ Total Cost
61
+ Total Cost (raw)
62
+
63
+ Debug output aggregated over all tags:
64
+ graph
65
+ first_step 0
66
+ last_step 0
67
+ max_step 0
68
+ min_step 0
69
+ num_steps 1
70
+ outoforder_steps []
71
+ histograms
72
+ first_step 491
73
+ last_step 659823
74
+ max_step 659823
75
+ min_step 491
76
+ num_steps 993
77
+ outoforder_steps []
78
+ images -
79
+ scalars
80
+ first_step 0
81
+ last_step 659823
82
+ max_step 659823
83
+ min_step 0
84
+ num_steps 1985
85
+ outoforder_steps []
86
+ sessionlog:checkpoint
87
+ first_step 7129
88
+ last_step 657167
89
+ max_step 657167
90
+ min_step 7129
91
+ num_steps 99
92
+ outoforder_steps []
93
+ sessionlog:start
94
+ outoforder_steps []
95
+ steps [0L]
96
+ sessionlog:stop -
97
+
98
+
99
+ [2] Drill down into a particular tag using --tag.
100
+
101
+ Debug output for binary/Sign/Activations:
102
+ histograms
103
+ first_step 491
104
+ last_step 659823
105
+ max_step 659823
106
+ min_step 491
107
+ num_steps 993
108
+ outoforder_steps []
109
+ """
110
+
111
+ import dataclasses
112
+ import itertools
113
+ import os
114
+
115
+ from typing import Any, Generator, Mapping
116
+
117
+ from tensorbored.backend.event_processing import event_accumulator
118
+ from tensorbored.backend.event_processing import event_file_loader
119
+ from tensorbored.backend.event_processing import io_wrapper
120
+ from tensorbored.compat import tf
121
+ from tensorbored.compat.proto import event_pb2
122
+
123
+ # Map of field names within summary.proto to the user-facing names that this
124
+ # script outputs.
125
+ SUMMARY_TYPE_TO_FIELD = {
126
+ "simple_value": "scalars",
127
+ "histo": "histograms",
128
+ "image": "images",
129
+ "audio": "audio",
130
+ }
131
+ for summary_type in event_accumulator.SUMMARY_TYPES:
132
+ if summary_type not in SUMMARY_TYPE_TO_FIELD:
133
+ SUMMARY_TYPE_TO_FIELD[summary_type] = summary_type
134
+
135
+ # Types of summaries that we may want to query for by tag.
136
+ TAG_FIELDS = list(SUMMARY_TYPE_TO_FIELD.values())
137
+
138
+ # Summaries that we want to see every instance of.
139
+ LONG_FIELDS = ["sessionlog:start", "sessionlog:stop"]
140
+
141
+ # Summaries that we only want an abridged digest of, since they would
142
+ # take too much screen real estate otherwise.
143
+ SHORT_FIELDS = ["graph", "sessionlog:checkpoint"] + TAG_FIELDS
144
+
145
+ # All summary types that we can inspect.
146
+ TRACKED_FIELDS = SHORT_FIELDS + LONG_FIELDS
147
+
148
+ PRINT_SEPARATOR = "=" * 70 + "\n"
149
+
150
+
151
+ @dataclasses.dataclass(frozen=True)
152
+ class Observation:
153
+ """Contains the data within each Event file that the inspector cares about.
154
+
155
+ The inspector accumulates Observations as it processes events.
156
+
157
+ Attributes:
158
+ step: Global step of the event.
159
+ wall_time: Timestamp of the event in seconds.
160
+ tag: Tag name associated with the event.
161
+ """
162
+
163
+ step: int
164
+ wall_time: float
165
+ tag: str
166
+
167
+
168
+ @dataclasses.dataclass(frozen=True)
169
+ class InspectionUnit:
170
+ """Created for each organizational structure in the event files.
171
+
172
+ An InspectionUnit is visible in the final terminal output. For instance, one
173
+ InspectionUnit is created for each subdirectory in logdir. When asked to inspect
174
+ a single event file, there may only be one InspectionUnit.
175
+
176
+ Attributes:
177
+ name: Name of the organizational unit that will be printed to console.
178
+ generator: A generator that yields `Event` protos.
179
+ field_to_obs: A mapping from string fields to `Observations` that the inspector
180
+ creates.
181
+ """
182
+
183
+ name: str
184
+ generator: Generator[event_pb2.Event, Any, Any]
185
+ field_to_obs: Mapping[str, Observation]
186
+
187
+
188
+ def get_field_to_observations_map(generator, query_for_tag=""):
189
+ """Return a field to `Observations` dict for the event generator.
190
+
191
+ Args:
192
+ generator: A generator over event protos.
193
+ query_for_tag: A string that if specified, only create observations for
194
+ events with this tag name.
195
+
196
+ Returns:
197
+ A dict mapping keys in `TRACKED_FIELDS` to an `Observation` list.
198
+ """
199
+
200
+ def increment(stat, event, tag=""):
201
+ assert stat in TRACKED_FIELDS
202
+ field_to_obs[stat].append(
203
+ dataclasses.asdict(
204
+ Observation(step=event.step, wall_time=event.wall_time, tag=tag)
205
+ )
206
+ )
207
+
208
+ field_to_obs = dict([(t, []) for t in TRACKED_FIELDS])
209
+
210
+ for event in generator:
211
+ ## Process the event
212
+ if event.HasField("graph_def") and (not query_for_tag):
213
+ increment("graph", event)
214
+ if event.HasField("session_log") and (not query_for_tag):
215
+ status = event.session_log.status
216
+ if status == event_pb2.SessionLog.START:
217
+ increment("sessionlog:start", event)
218
+ elif status == event_pb2.SessionLog.STOP:
219
+ increment("sessionlog:stop", event)
220
+ elif status == event_pb2.SessionLog.CHECKPOINT:
221
+ increment("sessionlog:checkpoint", event)
222
+ elif event.HasField("summary"):
223
+ for value in event.summary.value:
224
+ if query_for_tag and value.tag != query_for_tag:
225
+ continue
226
+
227
+ for proto_name, display_name in SUMMARY_TYPE_TO_FIELD.items():
228
+ if value.HasField(proto_name):
229
+ increment(display_name, event, value.tag)
230
+ return field_to_obs
231
+
232
+
233
+ def get_unique_tags(field_to_obs):
234
+ """Returns a dictionary of tags that a user could query over.
235
+
236
+ Args:
237
+ field_to_obs: Dict that maps string field to `Observation` list.
238
+
239
+ Returns:
240
+ A dict that maps keys in `TAG_FIELDS` to a list of string tags present in
241
+ the event files. If the dict does not have any observations of the type,
242
+ maps to an empty list so that we can render this to console.
243
+ """
244
+ return {
245
+ field: sorted(set([x.get("tag", "") for x in observations]))
246
+ for field, observations in field_to_obs.items()
247
+ if field in TAG_FIELDS
248
+ }
249
+
250
+
251
+ def print_dict(d, show_missing=True):
252
+ """Prints a shallow dict to console.
253
+
254
+ Args:
255
+ d: Dict to print.
256
+ show_missing: Whether to show keys with empty values.
257
+ """
258
+ for k, v in sorted(d.items()):
259
+ if (not v) and show_missing:
260
+ # No instances of the key, so print missing symbol.
261
+ print("{} -".format(k))
262
+ elif isinstance(v, list):
263
+ # Value is a list, so print each item of the list.
264
+ print(k)
265
+ for item in v:
266
+ print(" {}".format(item))
267
+ elif isinstance(v, dict):
268
+ # Value is a dict, so print each (key, value) pair of the dict.
269
+ print(k)
270
+ for kk, vv in sorted(v.items()):
271
+ print(" {:<20} {}".format(kk, vv))
272
+
273
+
274
+ def get_dict_to_print(field_to_obs):
275
+ """Transform the field-to-obs mapping into a printable dictionary.
276
+
277
+ Args:
278
+ field_to_obs: Dict that maps string field to `Observation` list.
279
+
280
+ Returns:
281
+ A dict with the keys and values to print to console.
282
+ """
283
+
284
+ def compressed_steps(steps):
285
+ return {
286
+ "num_steps": len(set(steps)),
287
+ "min_step": min(steps),
288
+ "max_step": max(steps),
289
+ "last_step": steps[-1],
290
+ "first_step": steps[0],
291
+ "outoforder_steps": get_out_of_order(steps),
292
+ }
293
+
294
+ def full_steps(steps):
295
+ return {"steps": steps, "outoforder_steps": get_out_of_order(steps)}
296
+
297
+ output = {}
298
+ for field, observations in field_to_obs.items():
299
+ if not observations:
300
+ output[field] = None
301
+ continue
302
+
303
+ steps = [x["step"] for x in observations]
304
+ if field in SHORT_FIELDS:
305
+ output[field] = compressed_steps(steps)
306
+ if field in LONG_FIELDS:
307
+ output[field] = full_steps(steps)
308
+
309
+ return output
310
+
311
+
312
+ def get_out_of_order(list_of_numbers):
313
+ """Returns elements that break the monotonically non-decreasing trend.
314
+
315
+ This is used to find instances of global step values that are "out-of-order",
316
+ which may trigger TensorBoard event discarding logic.
317
+
318
+ Args:
319
+ list_of_numbers: A list of numbers.
320
+
321
+ Returns:
322
+ A list of tuples in which each tuple are two elements are adjacent, but the
323
+ second element is lower than the first.
324
+ """
325
+ # TODO: Consider changing this to only check for out-of-order
326
+ # steps within a particular tag.
327
+ result = []
328
+ # pylint: disable=consider-using-enumerate
329
+ for i in range(len(list_of_numbers)):
330
+ if i == 0:
331
+ continue
332
+ if list_of_numbers[i] < list_of_numbers[i - 1]:
333
+ result.append((list_of_numbers[i - 1], list_of_numbers[i]))
334
+ return result
335
+
336
+
337
+ def generators_from_logdir(logdir):
338
+ """Returns a list of event generators for subdirectories with event files.
339
+
340
+ The number of generators returned should equal the number of directories
341
+ within logdir that contain event files. If only logdir contains event files,
342
+ returns a list of length one.
343
+
344
+ Args:
345
+ logdir: A log directory that contains event files.
346
+
347
+ Returns:
348
+ List of event generators for each subdirectory with event files.
349
+ """
350
+ subdirs = io_wrapper.GetLogdirSubdirectories(logdir)
351
+ generators = [
352
+ itertools.chain(
353
+ *[
354
+ generator_from_event_file(os.path.join(subdir, f))
355
+ for f in tf.io.gfile.listdir(subdir)
356
+ if io_wrapper.IsTensorFlowEventsFile(os.path.join(subdir, f))
357
+ ]
358
+ )
359
+ for subdir in subdirs
360
+ ]
361
+ return generators
362
+
363
+
364
+ def generator_from_event_file(event_file):
365
+ """Returns a generator that yields events from an event file."""
366
+ return event_file_loader.LegacyEventFileLoader(event_file).Load()
367
+
368
+
369
+ def get_inspection_units(logdir="", event_file="", tag=""):
370
+ """Returns a list of InspectionUnit objects given either logdir or
371
+ event_file.
372
+
373
+ If logdir is given, the number of InspectionUnits should equal the
374
+ number of directories or subdirectories that contain event files.
375
+
376
+ If event_file is given, the number of InspectionUnits should be 1.
377
+
378
+ Args:
379
+ logdir: A log directory that contains event files.
380
+ event_file: Or, a particular event file path.
381
+ tag: An optional tag name to query for.
382
+
383
+ Returns:
384
+ A list of InspectionUnit objects.
385
+ """
386
+ if logdir:
387
+ subdirs = io_wrapper.GetLogdirSubdirectories(logdir)
388
+ inspection_units = []
389
+ for subdir in subdirs:
390
+ generator = itertools.chain(
391
+ *[
392
+ generator_from_event_file(os.path.join(subdir, f))
393
+ for f in tf.io.gfile.listdir(subdir)
394
+ if io_wrapper.IsTensorFlowEventsFile(
395
+ os.path.join(subdir, f)
396
+ )
397
+ ]
398
+ )
399
+ inspection_units.append(
400
+ InspectionUnit(
401
+ name=subdir,
402
+ generator=generator,
403
+ field_to_obs=get_field_to_observations_map(generator, tag),
404
+ )
405
+ )
406
+ if inspection_units:
407
+ print(
408
+ "Found event files in:\n{}\n".format(
409
+ "\n".join([u.name for u in inspection_units])
410
+ )
411
+ )
412
+ elif io_wrapper.IsTensorFlowEventsFile(logdir):
413
+ print(
414
+ "It seems that {} may be an event file instead of a logdir. If this "
415
+ "is the case, use --event_file instead of --logdir to pass "
416
+ "it in.".format(logdir)
417
+ )
418
+ else:
419
+ print("No event files found within logdir {}".format(logdir))
420
+ return inspection_units
421
+ elif event_file:
422
+ generator = generator_from_event_file(event_file)
423
+ return [
424
+ InspectionUnit(
425
+ name=event_file,
426
+ generator=generator,
427
+ field_to_obs=get_field_to_observations_map(generator, tag),
428
+ )
429
+ ]
430
+ return []
431
+
432
+
433
+ def inspect(logdir="", event_file="", tag=""):
434
+ """Main function for inspector that prints out a digest of event files.
435
+
436
+ Args:
437
+ logdir: A log directory that contains event files.
438
+ event_file: Or, a particular event file path.
439
+ tag: An optional tag name to query for.
440
+
441
+ Raises:
442
+ ValueError: If neither logdir and event_file are given, or both are given.
443
+ """
444
+ print(
445
+ PRINT_SEPARATOR
446
+ + "Processing event files... (this can take a few minutes)\n"
447
+ + PRINT_SEPARATOR
448
+ )
449
+ inspection_units = get_inspection_units(logdir, event_file, tag)
450
+
451
+ for unit in inspection_units:
452
+ if tag:
453
+ print("Event statistics for tag {} in {}:".format(tag, unit.name))
454
+ else:
455
+ # If the user is not inspecting a particular tag, also print the list of
456
+ # all available tags that they can query.
457
+ print("These tags are in {}:".format(unit.name))
458
+ print_dict(get_unique_tags(unit.field_to_obs))
459
+ print(PRINT_SEPARATOR)
460
+ print("Event statistics for {}:".format(unit.name))
461
+
462
+ print_dict(get_dict_to_print(unit.field_to_obs), show_missing=(not tag))
463
+ print(PRINT_SEPARATOR)