Skip to content

Commit 4edb30e

Browse files
author
Danqing Liu
authored
Add basic proto files and logic
2 parents 206a581 + 8acf1c3 commit 4edb30e

27 files changed

+1894
-1
lines changed

.travis.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
language: python
2+
python:
3+
- '2.7'
4+
- '3.5'
5+
- '3.6'
6+
install: make bootstrap
7+
script: make test
8+
branches:
9+
except:
10+
- /^v[0-9]/

Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.PHONY: protoc
2+
protoc:
3+
@protoc -I=tinyboard/proto --python_out=tinyboard/proto tinyboard/proto/*.proto
4+
5+
.PHONY: lint
6+
lint:
7+
@flake8 tinyboard
8+
9+
.PHONY: clean
10+
clean:
11+
@find . -type f -name '*.pyc' -delete
12+
13+
.PHONY: bootstrap
14+
bootstrap:
15+
@pip install -r requirements.txt
16+
@python setup.py develop
17+
18+
.PHONY: test
19+
test: lint
20+
py.test --cov-report term-missing --cov=tinyboard tests/

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
# tinyboard
1+
# TinyBoard
2+
3+
TinyBoard is TensorBoard for PyTorch and other popular deep learning frameworks.

setup.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from setuptools import setup, find_packages
2+
3+
__version__ = '0.1.0'
4+
5+
requires = [
6+
'numpy>=1.13.1',
7+
'pillow>=4.2.1',
8+
]
9+
10+
pytorch_requires = ['torch']
11+
12+
setup(
13+
name='tinyboard',
14+
version=__version__,
15+
description='Universal TensorBoard visualization library',
16+
author='TinyMind',
17+
author_email='[email protected]',
18+
url='https://github.com/mind/tinyboard',
19+
packages=find_packages(exclude=('tests', 'tests.*',)),
20+
install_requires=requires,
21+
extras_require={
22+
'pytorch': pytorch_requires,
23+
},
24+
license='Apache 2.0',
25+
classifiers=[
26+
'Development Status :: 4 - Beta',
27+
'License :: OSI Approved :: Apache Software License',
28+
'Programming Language :: Python :: 2.7',
29+
'Programming Language :: Python :: 3.5',
30+
'Programming Language :: Python :: 3.6',
31+
'Topic :: Scientific/Engineering :: Artificial Intelligence',
32+
]
33+
)

tests/__init__.py

Whitespace-only changes.

tests/core/test_compat.py

Whitespace-only changes.

tinyboard/__init__.py

Whitespace-only changes.

tinyboard/core/__init__.py

Whitespace-only changes.

tinyboard/core/audio.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
import io
4+
import struct
5+
import wave
6+
7+
from tinyboard.proto.summary_pb2 import Summary
8+
9+
10+
def audio(tag, tensor, sample_rate=44100):
11+
tensor_list = [int(32767.0 * x) for x in tensor]
12+
fio = io.BytesIO()
13+
Wave_write = wave.open(fio, 'wb')
14+
Wave_write.setnchannels(1)
15+
Wave_write.setsampwidth(2)
16+
Wave_write.setframerate(sample_rate)
17+
tensor_enc = b''
18+
for v in tensor_list:
19+
tensor_enc += struct.pack('<h', v)
20+
21+
Wave_write.writeframes(tensor_enc)
22+
Wave_write.close()
23+
audio_string = fio.getvalue()
24+
fio.close()
25+
audio = Summary.Audio(
26+
sample_rate=sample_rate,
27+
num_channels=1,
28+
length_frames=len(tensor_list),
29+
encoded_audio_string=audio_string,
30+
content_type='audio/wav',
31+
)
32+
33+
return Summary(value=[Summary.Value(tag=tag, audio=audio)])

tinyboard/core/compat.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
import logging
4+
import re
5+
6+
INVALID_TAG_CHARS = re.compile(r'[^-/\w\.]')
7+
8+
9+
def clean_tag(name):
10+
"""Convert old tag names (pre-TF 1.3) to new ones.
11+
12+
Historically, the first argument to summary ops was a tag, which allowed
13+
arbitrary characters. Now we are changing the first argument to be the node
14+
name. This function replaces all illegal characters with _s, and logs a
15+
warning. It also strips leading slashes from the name.
16+
17+
:param string name: The original name of the tag.
18+
:returns string: The cleaned tag name.
19+
"""
20+
if not name:
21+
return ''
22+
new_name = INVALID_TAG_CHARS.sub('_', name).lstrip('/')
23+
if new_name != name:
24+
logging.info('Summary name {} illegal; using {} instead.'.format(
25+
name, new_name,
26+
))
27+
return new_name

tinyboard/core/histogram.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
import numpy as np
4+
5+
from tinyboard.core.compat import clean_tag
6+
from tinyboard.proto.summary_pb2 import HistogramProto
7+
from tinyboard.proto.summary_pb2 import Summary
8+
9+
10+
def histogram(name, tensor, bins, collections=None):
11+
"""Prepare a summary proto containing a histogram.
12+
13+
:param string name: The name of the histogram.
14+
:param Tensor tensor: The tensor of the histogram. Can be of any shape.
15+
:param int|list<int> bins: If an int, it defines the number of equal-width
16+
bins in the given range. If a sequence, it defines the bin edges,
17+
including the rightmost edge, allowing for non-uniform bin widths.
18+
:param list<string> collections: Optional collections keys. The new summary
19+
will be added to these collections.
20+
:returns Summary: The summary proto containing the histogram.
21+
"""
22+
name = clean_tag(name)
23+
hist = _make_histogram(tensor.astype(float), bins)
24+
return Summary(value=[Summary.Value(tag=name, histo=hist)])
25+
26+
27+
def _make_histogram(values, bins):
28+
"""Convert values into a histogram proto.
29+
30+
:param array_like values: The values over which the histogram is computed.
31+
:param int|list<int> bins: If an int, it defines the number of equal-width
32+
bins in the given range. If a sequence, it defines the bin edges,
33+
including the rightmost edge, allowing for non-uniform bin widths.
34+
:returns HistogramProto: The histogram proto.
35+
"""
36+
values = values.reshape(-1)
37+
counts, limits = np.histogram(values, bins=bins)
38+
return HistogramProto(
39+
min=values.min(), max=values.max(),
40+
num=len(values),
41+
sum=values.sum(), sum_squares=values.dot(values),
42+
bucket_limit=limits[1:], bucket=counts,
43+
)

tinyboard/core/scalar.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
from tinyboard.core.compat import clean_tag
4+
from tinyboard.proto.summary_pb2 import Summary
5+
6+
7+
def scalar(name, scalar, collections=None):
8+
"""Prepare a summary proto containing a scalar value.
9+
10+
:param string name: The name of the scalar series.
11+
:param Tensor scalar: The scalar value. Should contain a single value.
12+
:param list<string> collections: Optional collections keys. The new summary
13+
will be added to these collections.
14+
:returns Summary: The summary proto containing the scalar value.
15+
:raises ValueError: If the incoming tensor has the wrong shape/type.
16+
"""
17+
name = clean_tag(name)
18+
return Summary(value=[Summary.Value(tag=name, simple_value=float(scalar))])

tinyboard/core/text.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
from tinyboard.proto.summary_pb2 import Summary, SummaryMetadata
4+
from tinyboard.proto.tensor_pb2 import TensorProto
5+
6+
7+
def text(name, text):
8+
"""Prepare a summary proto containing text.
9+
10+
:param string name: The name of the text.
11+
:param string text: The text.
12+
:returns Summary: The summary proto containing the text.
13+
"""
14+
plugin_data = [SummaryMetadata.PluginData(plugin_name='text')]
15+
meta = SummaryMetadata(plugin_data=plugin_data)
16+
tensor = TensorProto(
17+
dtype='DT_STRING', string_val=[text.encode(encoding='utf_8')],
18+
)
19+
return Summary(value=[
20+
Summary.Value(node_name=name, metadata=meta, tensor=tensor),
21+
])

tinyboard/proto/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# TensorBoard Protos
2+
3+
Protobuf definitions in this folder are mostly copied from the [TensorFlow framework](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/framework), Apache 2.0 licensed from TensorFlow authors.

tinyboard/proto/resource_handle.proto

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
syntax = "proto3";
2+
3+
package tinyboard;
4+
5+
option cc_enable_arenas = true;
6+
option java_outer_classname = "ResourceHandle";
7+
option java_multiple_files = true;
8+
option java_package = "ai.tinymind.tinyboard";
9+
10+
// Protocol buffer representing a handle to a tensorflow resource. Handles are
11+
// not valid across executions, but can be serialized back and forth from within
12+
// a single run.
13+
message ResourceHandleProto {
14+
// Unique name for the device containing the resource.
15+
string device = 1;
16+
17+
// Container in which this resource is placed.
18+
string container = 2;
19+
20+
// Unique name of this resource.
21+
string name = 3;
22+
23+
// Hash code for the type of the resource. Is only valid in the same device
24+
// and in the same execution.
25+
uint64 hash_code = 4;
26+
27+
// For debug-only, the name of the type pointed to by this handle, if
28+
// available.
29+
string maybe_type_name = 5;
30+
};

tinyboard/proto/resource_handle_pb2.py

+99
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)