mirror of
https://github.com/clearml/clearml
synced 2025-06-26 18:16:07 +00:00
Refactor examples
This commit is contained in:
3
examples/frameworks/tensorflow/legacy/requirements.txt
Normal file
3
examples/frameworks/tensorflow/legacy/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
trains
|
||||
tensorboard>=1.14.0
|
||||
tensorflow>=1.14.0
|
||||
238
examples/frameworks/tensorflow/legacy/tensorboard_pr_curve.py
Normal file
238
examples/frameworks/tensorflow/legacy/tensorboard_pr_curve.py
Normal file
@@ -0,0 +1,238 @@
|
||||
# TRAINS - Example of new tensorboard pr_curves model
|
||||
#
|
||||
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
"""Create sample PR curve summary data.
|
||||
We have 3 classes: R, G, and B. We generate colors within RGB space from 3
|
||||
normal distributions (1 at each corner of the color triangle: [255, 0, 0],
|
||||
[0, 255, 0], and [0, 0, 255]).
|
||||
The true label of each random color is associated with the normal distribution
|
||||
that generated it.
|
||||
Using 3 other normal distributions (over the distance each color is from a
|
||||
corner of the color triangle - RGB), we then compute the probability that each
|
||||
color belongs to the class. We use those probabilities to generate PR curves.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os.path
|
||||
from tempfile import gettempdir
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from six.moves import xrange # pylint: disable=redefined-builtin
|
||||
import tensorflow as tf
|
||||
from tensorboard.plugins.pr_curve import summary
|
||||
from trains import Task
|
||||
|
||||
task = Task.init(project_name='examples', task_name='tensorboard pr_curve')
|
||||
|
||||
tf.compat.v1.disable_v2_behavior()
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('logdir', os.path.join(gettempdir(), "pr_curve_demo"),
|
||||
"Directory into which to write TensorBoard data.")
|
||||
|
||||
flags.DEFINE_integer('steps', 10,
|
||||
'Number of steps to generate for each PR curve.')
|
||||
|
||||
|
||||
def start_runs(
|
||||
logdir,
|
||||
steps,
|
||||
run_name,
|
||||
thresholds,
|
||||
mask_every_other_prediction=False):
|
||||
"""Generate a PR curve with precision and recall evenly weighted.
|
||||
Arguments:
|
||||
logdir: The directory into which to store all the runs' data.
|
||||
steps: The number of steps to run for.
|
||||
run_name: The name of the run.
|
||||
thresholds: The number of thresholds to use for PR curves.
|
||||
mask_every_other_prediction: Whether to mask every other prediction by
|
||||
alternating weights between 0 and 1.
|
||||
"""
|
||||
tf.compat.v1.reset_default_graph()
|
||||
tf.compat.v1.set_random_seed(42)
|
||||
|
||||
# Create a normal distribution layer used to generate true color labels.
|
||||
distribution = tf.compat.v1.distributions.Normal(loc=0., scale=142.)
|
||||
|
||||
# Sample the distribution to generate colors. Lets generate different numbers
|
||||
# of each color. The first dimension is the count of examples.
|
||||
|
||||
# The calls to sample() are given fixed random seed values that are "magic"
|
||||
# in that they correspond to the default seeds for those ops when the PR
|
||||
# curve test (which depends on this code) was written. We've pinned these
|
||||
# instead of continuing to use the defaults since the defaults are based on
|
||||
# node IDs from the sequence of nodes added to the graph, which can silently
|
||||
# change when this code or any TF op implementations it uses are modified.
|
||||
|
||||
# TODO(nickfelt): redo the PR curve test to avoid reliance on random seeds.
|
||||
|
||||
# Generate reds.
|
||||
number_of_reds = 100
|
||||
true_reds = tf.clip_by_value(
|
||||
tf.concat([
|
||||
255 - tf.abs(distribution.sample([number_of_reds, 1], seed=11)),
|
||||
tf.abs(distribution.sample([number_of_reds, 2], seed=34))
|
||||
], axis=1),
|
||||
0, 255)
|
||||
|
||||
# Generate greens.
|
||||
number_of_greens = 200
|
||||
true_greens = tf.clip_by_value(
|
||||
tf.concat([
|
||||
tf.abs(distribution.sample([number_of_greens, 1], seed=61)),
|
||||
255 - tf.abs(distribution.sample([number_of_greens, 1], seed=82)),
|
||||
tf.abs(distribution.sample([number_of_greens, 1], seed=105))
|
||||
], axis=1),
|
||||
0, 255)
|
||||
|
||||
# Generate blues.
|
||||
number_of_blues = 150
|
||||
true_blues = tf.clip_by_value(
|
||||
tf.concat([
|
||||
tf.abs(distribution.sample([number_of_blues, 2], seed=132)),
|
||||
255 - tf.abs(distribution.sample([number_of_blues, 1], seed=153))
|
||||
], axis=1),
|
||||
0, 255)
|
||||
|
||||
# Assign each color a vector of 3 booleans based on its true label.
|
||||
labels = tf.concat([
|
||||
tf.tile(tf.constant([[True, False, False]]), (number_of_reds, 1)),
|
||||
tf.tile(tf.constant([[False, True, False]]), (number_of_greens, 1)),
|
||||
tf.tile(tf.constant([[False, False, True]]), (number_of_blues, 1)),
|
||||
], axis=0)
|
||||
|
||||
# We introduce 3 normal distributions. They are used to predict whether a
|
||||
# color falls under a certain class (based on distances from corners of the
|
||||
# color triangle). The distributions vary per color. We have the distributions
|
||||
# narrow over time.
|
||||
initial_standard_deviations = [v + FLAGS.steps for v in (158, 200, 242)]
|
||||
iteration = tf.compat.v1.placeholder(tf.int32, shape=[])
|
||||
red_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[0] - iteration,
|
||||
dtype=tf.float32))
|
||||
green_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[1] - iteration,
|
||||
dtype=tf.float32))
|
||||
blue_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[2] - iteration,
|
||||
dtype=tf.float32))
|
||||
|
||||
# Make predictions (assign 3 probabilities to each color based on each color's
|
||||
# distance to each of the 3 corners). We seek double the area in the right
|
||||
# tail of the normal distribution.
|
||||
examples = tf.concat([true_reds, true_greens, true_blues], axis=0)
|
||||
probabilities_colors_are_red = (1 - red_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([255., 0, 0]), axis=1))) * 2
|
||||
probabilities_colors_are_green = (1 - green_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([0, 255., 0]), axis=1))) * 2
|
||||
probabilities_colors_are_blue = (1 - blue_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([0, 0, 255.]), axis=1))) * 2
|
||||
|
||||
predictions = (
|
||||
probabilities_colors_are_red,
|
||||
probabilities_colors_are_green,
|
||||
probabilities_colors_are_blue
|
||||
)
|
||||
|
||||
# This is the crucial piece. We write data required for generating PR curves.
|
||||
# We create 1 summary per class because we create 1 PR curve per class.
|
||||
for i, color in enumerate(('red', 'green', 'blue')):
|
||||
description = ('The probabilities used to create this PR curve are '
|
||||
'generated from a normal distribution. Its standard '
|
||||
'deviation is initially %0.0f and decreases over time.' %
|
||||
initial_standard_deviations[i])
|
||||
|
||||
weights = None
|
||||
if mask_every_other_prediction:
|
||||
# Assign a weight of 0 to every even-indexed prediction. Odd-indexed
|
||||
# predictions are assigned a default weight of 1.
|
||||
consecutive_indices = tf.reshape(
|
||||
tf.range(tf.size(input=predictions[i])), tf.shape(input=predictions[i]))
|
||||
weights = tf.cast(consecutive_indices % 2, dtype=tf.float32)
|
||||
|
||||
summary.op(
|
||||
name=color,
|
||||
labels=labels[:, i],
|
||||
predictions=predictions[i],
|
||||
num_thresholds=thresholds,
|
||||
weights=weights,
|
||||
display_name='classifying %s' % color,
|
||||
description=description)
|
||||
merged_summary_op = tf.compat.v1.summary.merge_all()
|
||||
events_directory = os.path.join(logdir, run_name)
|
||||
sess = tf.compat.v1.Session()
|
||||
writer = tf.compat.v1.summary.FileWriter(events_directory, sess.graph)
|
||||
|
||||
for step in xrange(steps):
|
||||
feed_dict = {
|
||||
iteration: step,
|
||||
}
|
||||
merged_summary = sess.run(merged_summary_op, feed_dict=feed_dict)
|
||||
writer.add_summary(merged_summary, step)
|
||||
|
||||
writer.close()
|
||||
|
||||
|
||||
def run_all(logdir, steps, thresholds, verbose=False):
|
||||
"""Generate PR curve summaries.
|
||||
Arguments:
|
||||
logdir: The directory into which to store all the runs' data.
|
||||
steps: The number of steps to run for.
|
||||
verbose: Whether to print the names of runs into stdout during execution.
|
||||
thresholds: The number of thresholds to use for PR curves.
|
||||
"""
|
||||
# First, we generate data for a PR curve that assigns even weights for
|
||||
# predictions of all classes.
|
||||
run_name = 'colors'
|
||||
if verbose:
|
||||
print('--- Running: %s' % run_name)
|
||||
start_runs(
|
||||
logdir=logdir,
|
||||
steps=steps,
|
||||
run_name=run_name,
|
||||
thresholds=thresholds)
|
||||
|
||||
# Next, we generate data for a PR curve that assigns arbitrary weights to
|
||||
# predictions.
|
||||
run_name = 'mask_every_other_prediction'
|
||||
if verbose:
|
||||
print('--- Running: %s' % run_name)
|
||||
start_runs(
|
||||
logdir=logdir,
|
||||
steps=steps,
|
||||
run_name=run_name,
|
||||
thresholds=thresholds,
|
||||
mask_every_other_prediction=True)
|
||||
|
||||
|
||||
def main(_):
|
||||
print('Saving output to %s.' % FLAGS.logdir)
|
||||
run_all(FLAGS.logdir, FLAGS.steps, 50, verbose=True)
|
||||
print('Done. Output saved to %s.' % FLAGS.logdir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(main)
|
||||
83
examples/frameworks/tensorflow/legacy/tensorboard_toy.py
Normal file
83
examples/frameworks/tensorflow/legacy/tensorboard_toy.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# TRAINS - Example of tensorboard with tensorflow (without any actual training)
|
||||
#
|
||||
import os
|
||||
from tempfile import gettempdir
|
||||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
from trains import Task
|
||||
task = Task.init(project_name='examples', task_name='tensorboard toy example')
|
||||
|
||||
|
||||
k = tf.placeholder(tf.float32)
|
||||
|
||||
# Make a normal distribution, with a shifting mean
|
||||
mean_moving_normal = tf.random_normal(shape=[1000], mean=(5*k), stddev=1)
|
||||
# Record that distribution into a histogram summary
|
||||
tf.summary.histogram("normal/moving_mean", mean_moving_normal)
|
||||
tf.summary.scalar("normal/value", mean_moving_normal[-1])
|
||||
|
||||
# Make a normal distribution with shrinking variance
|
||||
variance_shrinking_normal = tf.random_normal(shape=[1000], mean=0, stddev=1-(k))
|
||||
# Record that distribution too
|
||||
tf.summary.histogram("normal/shrinking_variance", variance_shrinking_normal)
|
||||
tf.summary.scalar("normal/variance_shrinking_normal", variance_shrinking_normal[-1])
|
||||
|
||||
# Let's combine both of those distributions into one dataset
|
||||
normal_combined = tf.concat([mean_moving_normal, variance_shrinking_normal], 0)
|
||||
# We add another histogram summary to record the combined distribution
|
||||
tf.summary.histogram("normal/bimodal", normal_combined)
|
||||
tf.summary.scalar("normal/normal_combined", normal_combined[0])
|
||||
|
||||
# Add a gamma distribution
|
||||
gamma = tf.random_gamma(shape=[1000], alpha=k)
|
||||
tf.summary.histogram("gamma", gamma)
|
||||
|
||||
# And a poisson distribution
|
||||
poisson = tf.random_poisson(shape=[1000], lam=k)
|
||||
tf.summary.histogram("poisson", poisson)
|
||||
|
||||
# And a uniform distribution
|
||||
uniform = tf.random_uniform(shape=[1000], maxval=k*10)
|
||||
tf.summary.histogram("uniform", uniform)
|
||||
|
||||
# Finally, combine everything together!
|
||||
all_distributions = [mean_moving_normal, variance_shrinking_normal, gamma, poisson, uniform]
|
||||
all_combined = tf.concat(all_distributions, 0)
|
||||
tf.summary.histogram("all_combined", all_combined)
|
||||
|
||||
# Log text value
|
||||
tf.summary.text("this is a test", tf.make_tensor_proto("This is the content", dtype=tf.string))
|
||||
|
||||
# convert to 4d [batch, col, row, RGB-channels]
|
||||
image_open = Image.open(os.path.join("..", "..", "..", "reporting", "data_samples", "picasso.jpg"))
|
||||
image = np.asarray(image_open)
|
||||
image_gray = image[:, :, 0][np.newaxis, :, :, np.newaxis]
|
||||
image_rgba = np.concatenate((image, 255*np.atleast_3d(np.ones(shape=image.shape[:2], dtype=np.uint8))), axis=2)
|
||||
image_rgba = image_rgba[np.newaxis, :, :, :]
|
||||
image = image[np.newaxis, :, :, :]
|
||||
|
||||
tf.summary.image("test", image, max_outputs=10)
|
||||
tf.summary.image("test_gray", image_gray, max_outputs=10)
|
||||
tf.summary.image("test_rgba", image_rgba, max_outputs=10)
|
||||
|
||||
# Setup a session and summary writer
|
||||
summaries = tf.summary.merge_all()
|
||||
sess = tf.Session()
|
||||
|
||||
logger = task.get_logger()
|
||||
|
||||
# Use original FileWriter for comparison , run:
|
||||
# % tensorboard --logdir=/tmp/histogram_example
|
||||
writer = tf.summary.FileWriter(os.path.join(gettempdir(), "histogram_example"))
|
||||
|
||||
# Setup a loop and write the summaries to disk
|
||||
N = 40
|
||||
for step in range(N):
|
||||
k_val = step/float(N)
|
||||
summ = sess.run(summaries, feed_dict={k: k_val})
|
||||
writer.add_summary(summ, global_step=step)
|
||||
|
||||
print('Done!')
|
||||
355
examples/frameworks/tensorflow/legacy/tensorflow_eager.py
Normal file
355
examples/frameworks/tensorflow/legacy/tensorflow_eager.py
Normal file
@@ -0,0 +1,355 @@
|
||||
# TRAINS - Example of tensorflow eager mode, model logging and tensorboard
|
||||
#
|
||||
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
"""A deep MNIST classifier using convolutional layers.
|
||||
Sample usage:
|
||||
python mnist.py --help
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from tempfile import gettempdir
|
||||
|
||||
import tensorflow as tf
|
||||
from tensorflow.examples.tutorials.mnist import input_data
|
||||
|
||||
from trains import Task
|
||||
|
||||
tf.compat.v1.enable_eager_execution()
|
||||
|
||||
task = Task.init(project_name='examples', task_name='Tensorflow eager mode')
|
||||
|
||||
|
||||
FLAGS = tf.app.flags.FLAGS
|
||||
tf.app.flags.DEFINE_integer('data_num', 100, """Flag of type integer""")
|
||||
tf.app.flags.DEFINE_string('img_path', './img', """Flag of type string""")
|
||||
|
||||
|
||||
layers = tf.keras.layers
|
||||
FLAGS = None
|
||||
|
||||
|
||||
class Discriminator(tf.keras.Model):
|
||||
"""
|
||||
GAN Discriminator.
|
||||
A network to differentiate between generated and real handwritten digits.
|
||||
"""
|
||||
|
||||
def __init__(self, data_format):
|
||||
"""Creates a model for discriminating between real and generated digits.
|
||||
Args:
|
||||
data_format: Either 'channels_first' or 'channels_last'.
|
||||
'channels_first' is typically faster on GPUs while 'channels_last' is
|
||||
typically faster on CPUs. See
|
||||
https://www.tensorflow.org/performance/performance_guide#data_formats
|
||||
"""
|
||||
super(Discriminator, self).__init__(name='')
|
||||
if data_format == 'channels_first':
|
||||
self._input_shape = [-1, 1, 28, 28]
|
||||
else:
|
||||
assert data_format == 'channels_last'
|
||||
self._input_shape = [-1, 28, 28, 1]
|
||||
self.conv1 = layers.Conv2D(
|
||||
64, 5, padding='SAME', data_format=data_format, activation=tf.tanh)
|
||||
self.pool1 = layers.AveragePooling2D(2, 2, data_format=data_format)
|
||||
self.conv2 = layers.Conv2D(
|
||||
128, 5, data_format=data_format, activation=tf.tanh)
|
||||
self.pool2 = layers.AveragePooling2D(2, 2, data_format=data_format)
|
||||
self.flatten = layers.Flatten()
|
||||
self.fc1 = layers.Dense(1024, activation=tf.tanh)
|
||||
self.fc2 = layers.Dense(1, activation=None)
|
||||
|
||||
def call(self, inputs):
|
||||
"""Return two logits per image estimating input authenticity.
|
||||
Users should invoke __call__ to run the network, which delegates to this
|
||||
method (and not call this method directly).
|
||||
Args:
|
||||
inputs: A batch of images as a Tensor with shape [batch_size, 28, 28, 1]
|
||||
or [batch_size, 1, 28, 28]
|
||||
Returns:
|
||||
A Tensor with shape [batch_size] containing logits estimating
|
||||
the probability that corresponding digit is real.
|
||||
"""
|
||||
x = tf.reshape(inputs, self._input_shape)
|
||||
x = self.conv1(x)
|
||||
x = self.pool1(x)
|
||||
x = self.conv2(x)
|
||||
x = self.pool2(x)
|
||||
x = self.flatten(x)
|
||||
x = self.fc1(x)
|
||||
x = self.fc2(x)
|
||||
return x
|
||||
|
||||
|
||||
class Generator(tf.keras.Model):
|
||||
"""
|
||||
Generator of handwritten digits similar to the ones in the MNIST dataset.
|
||||
"""
|
||||
|
||||
def __init__(self, data_format):
|
||||
"""Creates a model for discriminating between real and generated digits.
|
||||
Args:
|
||||
data_format: Either 'channels_first' or 'channels_last'.
|
||||
'channels_first' is typically faster on GPUs while 'channels_last' is
|
||||
typically faster on CPUs. See
|
||||
https://www.tensorflow.org/performance/performance_guide#data_formats
|
||||
"""
|
||||
super(Generator, self).__init__(name='')
|
||||
self.data_format = data_format
|
||||
# We are using 128 6x6 channels as input to the first deconvolution layer
|
||||
if data_format == 'channels_first':
|
||||
self._pre_conv_shape = [-1, 128, 6, 6]
|
||||
else:
|
||||
assert data_format == 'channels_last'
|
||||
self._pre_conv_shape = [-1, 6, 6, 128]
|
||||
self.fc1 = layers.Dense(6 * 6 * 128, activation=tf.tanh)
|
||||
|
||||
# In call(), we reshape the output of fc1 to _pre_conv_shape
|
||||
|
||||
# Deconvolution layer. Resulting image shape: (batch, 14, 14, 64)
|
||||
self.conv1 = layers.Conv2DTranspose(
|
||||
64, 4, strides=2, activation=None, data_format=data_format)
|
||||
|
||||
# Deconvolution layer. Resulting image shape: (batch, 28, 28, 1)
|
||||
self.conv2 = layers.Conv2DTranspose(
|
||||
1, 2, strides=2, activation=tf.nn.sigmoid, data_format=data_format)
|
||||
|
||||
def call(self, inputs):
|
||||
"""Return a batch of generated images.
|
||||
Users should invoke __call__ to run the network, which delegates to this
|
||||
method (and not call this method directly).
|
||||
Args:
|
||||
inputs: A batch of noise vectors as a Tensor with shape
|
||||
[batch_size, length of noise vectors].
|
||||
Returns:
|
||||
A Tensor containing generated images. If data_format is 'channels_last',
|
||||
the shape of returned images is [batch_size, 28, 28, 1], else
|
||||
[batch_size, 1, 28, 28]
|
||||
"""
|
||||
|
||||
x = self.fc1(inputs)
|
||||
x = tf.reshape(x, shape=self._pre_conv_shape)
|
||||
x = self.conv1(x)
|
||||
x = self.conv2(x)
|
||||
return x
|
||||
|
||||
|
||||
def discriminator_loss(discriminator_real_outputs, discriminator_gen_outputs):
|
||||
"""
|
||||
Original discriminator loss for GANs, with label smoothing.
|
||||
See `Generative Adversarial Nets` (https://arxiv.org/abs/1406.2661) for more
|
||||
details.
|
||||
Args:
|
||||
discriminator_real_outputs: Discriminator output on real data.
|
||||
discriminator_gen_outputs: Discriminator output on generated data. Expected
|
||||
to be in the range of (-inf, inf).
|
||||
Returns:
|
||||
A scalar loss Tensor.
|
||||
"""
|
||||
|
||||
loss_on_real = tf.compat.v1.losses.sigmoid_cross_entropy(
|
||||
tf.ones_like(discriminator_real_outputs),
|
||||
discriminator_real_outputs,
|
||||
label_smoothing=0.25)
|
||||
loss_on_generated = tf.compat.v1.losses.sigmoid_cross_entropy(
|
||||
tf.zeros_like(discriminator_gen_outputs), discriminator_gen_outputs)
|
||||
loss = loss_on_real + loss_on_generated
|
||||
tf.contrib.summary.scalar('discriminator_loss', loss)
|
||||
return loss
|
||||
|
||||
|
||||
def generator_loss(discriminator_gen_outputs):
|
||||
"""
|
||||
Original generator loss for GANs.
|
||||
L = -log(sigmoid(D(G(z))))
|
||||
See `Generative Adversarial Nets` (https://arxiv.org/abs/1406.2661)
|
||||
for more details.
|
||||
Args:
|
||||
discriminator_gen_outputs: Discriminator output on generated data. Expected
|
||||
to be in the range of (-inf, inf).
|
||||
Returns:
|
||||
A scalar loss Tensor.
|
||||
"""
|
||||
loss = tf.compat.v1.losses.sigmoid_cross_entropy(
|
||||
tf.ones_like(discriminator_gen_outputs), discriminator_gen_outputs)
|
||||
tf.contrib.summary.scalar('generator_loss', loss)
|
||||
return loss
|
||||
|
||||
|
||||
def train_one_epoch(generator, discriminator, generator_optimizer,
|
||||
discriminator_optimizer, dataset, step_counter,
|
||||
log_interval, noise_dim):
|
||||
"""
|
||||
Train `generator` and `discriminator` models on `dataset`.
|
||||
Args:
|
||||
generator: Generator model.
|
||||
discriminator: Discriminator model.
|
||||
generator_optimizer: Optimizer to use for generator.
|
||||
discriminator_optimizer: Optimizer to use for discriminator.
|
||||
dataset: Dataset of images to train on.
|
||||
step_counter: An integer variable, used to write summaries regularly.
|
||||
log_interval: How many steps to wait between logging and collecting
|
||||
summaries.
|
||||
noise_dim: Dimension of noise vector to use.
|
||||
"""
|
||||
|
||||
total_generator_loss = 0.0
|
||||
total_discriminator_loss = 0.0
|
||||
for (batch_index, images) in enumerate(dataset):
|
||||
with tf.device('/cpu:0'):
|
||||
tf.compat.v1.assign_add(step_counter, 1)
|
||||
with tf.contrib.summary.record_summaries_every_n_global_steps(
|
||||
log_interval, global_step=step_counter):
|
||||
current_batch_size = images.shape[0]
|
||||
noise = tf.random.uniform(
|
||||
shape=[current_batch_size, noise_dim],
|
||||
minval=-1.,
|
||||
maxval=1.,
|
||||
seed=batch_index)
|
||||
|
||||
# we can use 2 tapes or a single persistent tape.
|
||||
# Using two tapes is memory efficient since intermediate tensors can be
|
||||
# released between the two .gradient() calls below
|
||||
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
|
||||
generated_images = generator(noise)
|
||||
tf.contrib.summary.image(
|
||||
'generated_images',
|
||||
tf.reshape(generated_images, [-1, 28, 28, 1]),
|
||||
max_images=10)
|
||||
|
||||
discriminator_gen_outputs = discriminator(generated_images)
|
||||
discriminator_real_outputs = discriminator(images)
|
||||
discriminator_loss_val = discriminator_loss(discriminator_real_outputs,
|
||||
discriminator_gen_outputs)
|
||||
total_discriminator_loss += discriminator_loss_val
|
||||
|
||||
generator_loss_val = generator_loss(discriminator_gen_outputs)
|
||||
total_generator_loss += generator_loss_val
|
||||
|
||||
generator_grad = gen_tape.gradient(generator_loss_val,
|
||||
generator.variables)
|
||||
discriminator_grad = disc_tape.gradient(discriminator_loss_val,
|
||||
discriminator.variables)
|
||||
|
||||
generator_optimizer.apply_gradients(
|
||||
zip(generator_grad, generator.variables))
|
||||
discriminator_optimizer.apply_gradients(
|
||||
zip(discriminator_grad, discriminator.variables))
|
||||
|
||||
if log_interval and batch_index > 0 and batch_index % log_interval == 0:
|
||||
print('Batch #%d\tAverage Generator Loss: %.6f\tAverage Discriminator Loss: %.6f' %
|
||||
(batch_index, total_generator_loss / batch_index, total_discriminator_loss / batch_index))
|
||||
|
||||
|
||||
def main(_):
|
||||
(device, data_format) = ('/gpu:0', 'channels_first')
|
||||
if FLAGS.no_gpu or tf.contrib.eager.num_gpus() <= 0:
|
||||
(device, data_format) = ('/cpu:0', 'channels_last')
|
||||
print('Using device %s, and data format %s.' % (device, data_format))
|
||||
|
||||
# Load the datasets
|
||||
data = input_data.read_data_sets(FLAGS.data_dir)
|
||||
dataset = (
|
||||
tf.data.Dataset.from_tensor_slices(data.train.images[:1280]).shuffle(60000).batch(FLAGS.batch_size))
|
||||
|
||||
# Create the models and optimizers.
|
||||
model_objects = {
|
||||
'generator': Generator(data_format),
|
||||
'discriminator': Discriminator(data_format),
|
||||
'generator_optimizer': tf.compat.v1.train.AdamOptimizer(FLAGS.lr),
|
||||
'discriminator_optimizer': tf.compat.v1.train.AdamOptimizer(FLAGS.lr),
|
||||
'step_counter': tf.compat.v1.train.get_or_create_global_step(),
|
||||
}
|
||||
|
||||
# Prepare summary writer and checkpoint info
|
||||
summary_writer = tf.contrib.summary.create_file_writer(
|
||||
FLAGS.output_dir, flush_millis=1000)
|
||||
checkpoint_prefix = os.path.join(FLAGS.checkpoint_dir, 'ckpt')
|
||||
latest_cpkt = tf.train.latest_checkpoint(FLAGS.checkpoint_dir)
|
||||
if latest_cpkt:
|
||||
print('Using latest checkpoint at ' + latest_cpkt)
|
||||
checkpoint = tf.train.Checkpoint(**model_objects)
|
||||
# Restore variables on creation if a checkpoint exists.
|
||||
checkpoint.restore(latest_cpkt)
|
||||
|
||||
with tf.device(device):
|
||||
for _ in range(3):
|
||||
start = time.time()
|
||||
with summary_writer.as_default():
|
||||
train_one_epoch(dataset=dataset, log_interval=FLAGS.log_interval,
|
||||
noise_dim=FLAGS.noise, **model_objects)
|
||||
end = time.time()
|
||||
checkpoint.save(checkpoint_prefix)
|
||||
print('\nTrain time for epoch #%d (step %d): %f' %
|
||||
(checkpoint.save_counter.numpy(), checkpoint.step_counter.numpy(), end - start))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'--data-dir',
|
||||
type=str,
|
||||
default=os.path.join(gettempdir(), 'tensorflow', 'mnist', 'input_data'),
|
||||
help='Directory for storing input data (default /tmp/tensorflow/mnist/input_data)')
|
||||
parser.add_argument(
|
||||
'--batch-size',
|
||||
type=int,
|
||||
default=16,
|
||||
metavar='N',
|
||||
help='input batch size for training (default: 128)')
|
||||
parser.add_argument(
|
||||
'--log-interval',
|
||||
type=int,
|
||||
default=1,
|
||||
metavar='N',
|
||||
help='number of batches between logging and writing summaries (default: 100)')
|
||||
parser.add_argument(
|
||||
'--output_dir',
|
||||
type=str,
|
||||
default=os.path.join(gettempdir(), 'tensorflow'),
|
||||
metavar='DIR',
|
||||
help='Directory to write TensorBoard summaries (defaults to none)')
|
||||
parser.add_argument(
|
||||
'--checkpoint_dir',
|
||||
type=str,
|
||||
default=os.path.join(gettempdir(), 'tensorflow', 'mnist', 'checkpoints'),
|
||||
metavar='DIR',
|
||||
help='Directory to save checkpoints in (once per epoch) (default /tmp/tensorflow/mnist/checkpoints/)')
|
||||
parser.add_argument(
|
||||
'--lr',
|
||||
type=float,
|
||||
default=0.001,
|
||||
metavar='LR',
|
||||
help='learning rate (default: 0.001)')
|
||||
parser.add_argument(
|
||||
'--noise',
|
||||
type=int,
|
||||
default=100,
|
||||
metavar='N',
|
||||
help='Length of noise vector for generator input (default: 100)')
|
||||
parser.add_argument(
|
||||
'--no-gpu',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='disables GPU usage even if a GPU is available')
|
||||
|
||||
FLAGS, unparsed = parser.parse_known_args()
|
||||
|
||||
tf.compat.v1.app.run(main=main, argv=[sys.argv[0]] + unparsed)
|
||||
@@ -0,0 +1,219 @@
|
||||
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
"""A simple MNIST classifier which displays summaries in TensorBoard.
|
||||
|
||||
This is an unimpressive MNIST model, but it is a good example of using
|
||||
tf.name_scope to make a graph legible in the TensorBoard graph explorer, and of
|
||||
naming summary tags so that they are grouped meaningfully in TensorBoard.
|
||||
|
||||
It demonstrates the functionality of every TensorBoard dashboard.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorflow.examples.tutorials.mnist import input_data
|
||||
from trains import Task
|
||||
|
||||
FLAGS = None
|
||||
task = Task.init(project_name='examples', task_name='Tensorflow mnist with summaries example')
|
||||
|
||||
|
||||
def train():
|
||||
# Import data
|
||||
mnist = input_data.read_data_sets(FLAGS.data_dir, fake_data=FLAGS.fake_data)
|
||||
|
||||
sess = tf.InteractiveSession()
|
||||
# Create a multilayer model.
|
||||
|
||||
# Input placeholders
|
||||
with tf.name_scope('input'):
|
||||
x = tf.placeholder(tf.float32, [None, 784], name='x-input')
|
||||
y_ = tf.placeholder(tf.int64, [None], name='y-input')
|
||||
|
||||
with tf.name_scope('input_reshape'):
|
||||
image_shaped_input = tf.reshape(x, [-1, 28, 28, 1])
|
||||
tf.summary.image('input', image_shaped_input, 10)
|
||||
|
||||
# We can't initialize these variables to 0 - the network will get stuck.
|
||||
def weight_variable(shape):
|
||||
"""Create a weight variable with appropriate initialization."""
|
||||
initial = tf.truncated_normal(shape, stddev=0.1)
|
||||
return tf.Variable(initial)
|
||||
|
||||
def bias_variable(shape):
|
||||
"""Create a bias variable with appropriate initialization."""
|
||||
initial = tf.constant(0.1, shape=shape)
|
||||
return tf.Variable(initial)
|
||||
|
||||
def variable_summaries(var):
|
||||
"""Attach a lot of summaries to a Tensor (for TensorBoard visualization)."""
|
||||
with tf.name_scope('summaries'):
|
||||
mean = tf.reduce_mean(var)
|
||||
tf.summary.scalar('mean', mean)
|
||||
with tf.name_scope('stddev'):
|
||||
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
|
||||
tf.summary.scalar('stddev', stddev)
|
||||
tf.summary.scalar('max', tf.reduce_max(var))
|
||||
tf.summary.scalar('min', tf.reduce_min(var))
|
||||
tf.summary.histogram('histogram', var)
|
||||
|
||||
def nn_layer(input_tensor, input_dim, output_dim, layer_name, act=tf.nn.relu):
|
||||
"""Reusable code for making a simple neural net layer.
|
||||
|
||||
It does a matrix multiply, bias add, and then uses ReLU to nonlinearize.
|
||||
It also sets up name scoping so that the resultant graph is easy to read,
|
||||
and adds a number of summary ops.
|
||||
"""
|
||||
# Adding a name scope ensures logical grouping of the layers in the graph.
|
||||
with tf.name_scope(layer_name):
|
||||
# This Variable will hold the state of the weights for the layer
|
||||
with tf.name_scope('weights'):
|
||||
weights = weight_variable([input_dim, output_dim])
|
||||
variable_summaries(weights)
|
||||
with tf.name_scope('biases'):
|
||||
biases = bias_variable([output_dim])
|
||||
variable_summaries(biases)
|
||||
with tf.name_scope('Wx_plus_b'):
|
||||
preactivate = tf.matmul(input_tensor, weights) + biases
|
||||
tf.summary.histogram('pre_activations', preactivate)
|
||||
activations = act(preactivate, name='activation')
|
||||
tf.summary.histogram('activations', activations)
|
||||
return activations
|
||||
|
||||
hidden1 = nn_layer(x, 784, 500, 'layer1')
|
||||
|
||||
with tf.name_scope('dropout'):
|
||||
keep_prob = tf.placeholder(tf.float32)
|
||||
tf.summary.scalar('dropout_keep_probability', keep_prob)
|
||||
dropped = tf.nn.dropout(hidden1, keep_prob)
|
||||
|
||||
# Do not apply softmax activation yet, see below.
|
||||
y = nn_layer(dropped, 500, 10, 'layer2', act=tf.identity)
|
||||
|
||||
with tf.name_scope('cross_entropy'):
|
||||
# The raw formulation of cross-entropy,
|
||||
#
|
||||
# tf.reduce_mean(-tf.reduce_sum(y_ * tf.math.log(tf.softmax(y)),
|
||||
# reduction_indices=[1]))
|
||||
#
|
||||
# can be numerically unstable.
|
||||
#
|
||||
# So here we use tf.compat.v1.losses.sparse_softmax_cross_entropy on the
|
||||
# raw logit outputs of the nn_layer above, and then average across
|
||||
# the batch.
|
||||
with tf.name_scope('total'):
|
||||
cross_entropy = tf.losses.sparse_softmax_cross_entropy(
|
||||
labels=y_, logits=y)
|
||||
tf.summary.scalar('cross_entropy', cross_entropy)
|
||||
|
||||
with tf.name_scope('train'):
|
||||
train_step = tf.train.AdamOptimizer(FLAGS.learning_rate).minimize(
|
||||
cross_entropy)
|
||||
|
||||
with tf.name_scope('accuracy'):
|
||||
with tf.name_scope('correct_prediction'):
|
||||
correct_prediction = tf.equal(tf.argmax(y, 1), y_)
|
||||
with tf.name_scope('accuracy'):
|
||||
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
|
||||
tf.summary.scalar('accuracy', accuracy)
|
||||
|
||||
# Merge all the summaries and write them out to
|
||||
# /tmp/tensorflow/mnist/logs/mnist_with_summaries (by default)
|
||||
merged = tf.summary.merge_all()
|
||||
train_writer = tf.summary.FileWriter(os.path.join(FLAGS.log_dir, 'train'), sess.graph)
|
||||
test_writer = tf.summary.FileWriter(os.path.join(FLAGS.log_dir, 'test'))
|
||||
|
||||
tf.global_variables_initializer().run()
|
||||
|
||||
# Train the model, and also write summaries.
|
||||
# Every 10th step, measure test-set accuracy, and write test summaries
|
||||
# All other steps, run train_step on training data, & add training summaries
|
||||
|
||||
def feed_dict(train):
|
||||
"""Make a TensorFlow feed_dict: maps data onto Tensor placeholders."""
|
||||
if train or FLAGS.fake_data:
|
||||
xs, ys = mnist.train.next_batch(FLAGS.batch_size, fake_data=FLAGS.fake_data)
|
||||
k = FLAGS.dropout
|
||||
else:
|
||||
xs, ys = mnist.test.images, mnist.test.labels
|
||||
k = 1.0
|
||||
return {x: xs, y_: ys, keep_prob: k}
|
||||
|
||||
saver = tf.train.Saver()
|
||||
for i in range(FLAGS.max_steps):
|
||||
if i % 10 == 0: # Record summaries and test-set accuracy
|
||||
summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False))
|
||||
test_writer.add_summary(summary, i)
|
||||
print('Accuracy at step %s: %s' % (i, acc))
|
||||
else: # Record train set summaries, and train
|
||||
if i % FLAGS.batch_size == FLAGS.batch_size - 1: # Record execution stats
|
||||
run_metadata = tf.RunMetadata()
|
||||
summary, _ = sess.run([merged, train_step],
|
||||
feed_dict=feed_dict(True),
|
||||
run_metadata=run_metadata)
|
||||
train_writer.add_run_metadata(run_metadata, 'step%04d' % i)
|
||||
train_writer.add_summary(summary, i)
|
||||
print('Adding run metadata for', i)
|
||||
else: # Record a summary
|
||||
summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True))
|
||||
# train_writer.add_summary(summary, i)
|
||||
|
||||
save_path = saver.save(sess, FLAGS.save_path)
|
||||
print("Saved model: %s" % save_path)
|
||||
print('Flushing all images, this may take a couple of minutes')
|
||||
train_writer.close()
|
||||
test_writer.close()
|
||||
print('Finished storing all metrics & images')
|
||||
|
||||
|
||||
def main(_):
|
||||
if tf.gfile.Exists(FLAGS.log_dir):
|
||||
tf.gfile.DeleteRecursively(FLAGS.log_dir)
|
||||
tf.gfile.MakeDirs(FLAGS.log_dir)
|
||||
with tf.Graph().as_default():
|
||||
train()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--fake_data', nargs='?', const=True, type=bool,
|
||||
default=False,
|
||||
help='If true, uses fake data for unit testing.')
|
||||
parser.add_argument('--max_steps', type=int, default=300,
|
||||
help='Number of steps to run trainer.')
|
||||
parser.add_argument('--learning_rate', type=float, default=0.001,
|
||||
help='Initial learning rate')
|
||||
parser.add_argument('--dropout', type=float, default=0.9,
|
||||
help='Keep probability for training dropout.')
|
||||
parser.add_argument('--data_dir', type=str,
|
||||
default=os.path.join(tempfile.gettempdir(), 'tensorflow', 'mnist', 'input_data'),
|
||||
help='Directory for storing input data')
|
||||
parser.add_argument('--log_dir', type=str,
|
||||
default=os.path.join(tempfile.gettempdir(),
|
||||
'tensorflow', 'mnist', 'logs', 'mnist_with_summaries'),
|
||||
help='Summaries log directory')
|
||||
parser.add_argument('--save_path', default=os.path.join(tempfile.gettempdir(), "model.ckpt"),
|
||||
help='Save the trained model under this path')
|
||||
parser.add_argument('--batch_size', default=100,
|
||||
help='Batch size for training')
|
||||
FLAGS, unparsed = parser.parse_known_args()
|
||||
tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
|
||||
42
examples/frameworks/tensorflow/manual_model_upload.py
Normal file
42
examples/frameworks/tensorflow/manual_model_upload.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# TRAINS - Example of manual model configuration and uploading
|
||||
#
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import tensorflow as tf
|
||||
from trains import Task
|
||||
|
||||
task = Task.init(project_name='examples', task_name='Model configuration and upload')
|
||||
|
||||
model = tf.Module()
|
||||
|
||||
# Connect a local configuration file
|
||||
config_file = os.path.join('..', '..', 'reporting', 'data_samples', 'sample.json')
|
||||
config_file = task.connect_configuration(config_file)
|
||||
# then read configuration as usual, the backend will contain a copy of it.
|
||||
# later when executing remotely, the returned `config_file` will be a temporary file
|
||||
# containing a new copy of the configuration retrieved form the backend
|
||||
# # model_config_dict = json.load(open(config_file, 'rt'))
|
||||
|
||||
# Or Store dictionary of definition for a specific network design
|
||||
model_config_dict = {
|
||||
'value': 13.37,
|
||||
'dict': {'sub_value': 'string', 'sub_integer': 11},
|
||||
'list_of_ints': [1, 2, 3, 4],
|
||||
}
|
||||
model_config_dict = task.connect_configuration(model_config_dict)
|
||||
|
||||
# We now update the dictionary after connecting it, and the changes will be tracked as well.
|
||||
model_config_dict['new value'] = 10
|
||||
model_config_dict['value'] *= model_config_dict['new value']
|
||||
|
||||
# store the label enumeration of the training model
|
||||
labels = {'background': 0, 'cat': 1, 'dog': 2}
|
||||
task.connect_label_enumeration(labels)
|
||||
|
||||
# storing the model, it will have the task network configuration and label enumeration
|
||||
print('Any model stored from this point onwards, will contain both model_config and label_enumeration')
|
||||
|
||||
tempdir = tempfile.mkdtemp()
|
||||
tf.saved_model.save(model, os.path.join(tempdir, "model"))
|
||||
print('Model saved')
|
||||
3
examples/frameworks/tensorflow/requirements.txt
Normal file
3
examples/frameworks/tensorflow/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
tensorboard>=2.0
|
||||
tensorflow>=2.0
|
||||
trains
|
||||
279
examples/frameworks/tensorflow/tensorboard_pr_curve.py
Normal file
279
examples/frameworks/tensorflow/tensorboard_pr_curve.py
Normal file
@@ -0,0 +1,279 @@
|
||||
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
"""Create sample PR curve summary data.
|
||||
We have 3 classes: R, G, and B. We generate colors within RGB space from 3
|
||||
normal distributions (1 at each corner of the color triangle: [255, 0, 0],
|
||||
[0, 255, 0], and [0, 0, 255]).
|
||||
The true label of each random color is associated with the normal distribution
|
||||
that generated it.
|
||||
Using 3 other normal distributions (over the distance each color is from a
|
||||
corner of the color triangle - RGB), we then compute the probability that each
|
||||
color belongs to the class. We use those probabilities to generate PR curves.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os.path
|
||||
|
||||
from tempfile import gettempdir
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from six.moves import xrange # pylint: disable=redefined-builtin
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorboard.plugins.pr_curve import summary
|
||||
from trains import Task
|
||||
|
||||
|
||||
task = Task.init(project_name='examples', task_name='tensorboard pr_curve')
|
||||
|
||||
tf.compat.v1.disable_v2_behavior()
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
flags.DEFINE_string(
|
||||
"logdir",
|
||||
os.path.join(gettempdir(), "pr_curve_demo"),
|
||||
"Directory into which to write TensorBoard data.",
|
||||
)
|
||||
|
||||
flags.DEFINE_integer(
|
||||
"steps", 10, "Number of steps to generate for each PR curve."
|
||||
)
|
||||
|
||||
|
||||
def start_runs(
|
||||
logdir, steps, run_name, thresholds, mask_every_other_prediction=False
|
||||
):
|
||||
"""Generate a PR curve with precision and recall evenly weighted.
|
||||
Arguments:
|
||||
logdir: The directory into which to store all the runs' data.
|
||||
steps: The number of steps to run for.
|
||||
run_name: The name of the run.
|
||||
thresholds: The number of thresholds to use for PR curves.
|
||||
mask_every_other_prediction: Whether to mask every other prediction by
|
||||
alternating weights between 0 and 1.
|
||||
"""
|
||||
tf.compat.v1.reset_default_graph()
|
||||
tf.compat.v1.set_random_seed(42)
|
||||
|
||||
# Create a normal distribution layer used to generate true color labels.
|
||||
distribution = tf.compat.v1.distributions.Normal(loc=0.0, scale=142.0)
|
||||
|
||||
# Sample the distribution to generate colors. Lets generate different numbers
|
||||
# of each color. The first dimension is the count of examples.
|
||||
|
||||
# The calls to sample() are given fixed random seed values that are "magic"
|
||||
# in that they correspond to the default seeds for those ops when the PR
|
||||
# curve test (which depends on this code) was written. We've pinned these
|
||||
# instead of continuing to use the defaults since the defaults are based on
|
||||
# node IDs from the sequence of nodes added to the graph, which can silently
|
||||
# change when this code or any TF op implementations it uses are modified.
|
||||
|
||||
# TODO(nickfelt): redo the PR curve test to avoid reliance on random seeds.
|
||||
|
||||
# Generate reds.
|
||||
number_of_reds = 100
|
||||
true_reds = tf.clip_by_value(
|
||||
tf.concat(
|
||||
[
|
||||
255 - tf.abs(distribution.sample([number_of_reds, 1], seed=11)),
|
||||
tf.abs(distribution.sample([number_of_reds, 2], seed=34)),
|
||||
],
|
||||
axis=1,
|
||||
),
|
||||
0,
|
||||
255,
|
||||
)
|
||||
|
||||
# Generate greens.
|
||||
number_of_greens = 200
|
||||
true_greens = tf.clip_by_value(
|
||||
tf.concat(
|
||||
[
|
||||
tf.abs(distribution.sample([number_of_greens, 1], seed=61)),
|
||||
255
|
||||
- tf.abs(distribution.sample([number_of_greens, 1], seed=82)),
|
||||
tf.abs(distribution.sample([number_of_greens, 1], seed=105)),
|
||||
],
|
||||
axis=1,
|
||||
),
|
||||
0,
|
||||
255,
|
||||
)
|
||||
|
||||
# Generate blues.
|
||||
number_of_blues = 150
|
||||
true_blues = tf.clip_by_value(
|
||||
tf.concat(
|
||||
[
|
||||
tf.abs(distribution.sample([number_of_blues, 2], seed=132)),
|
||||
255
|
||||
- tf.abs(distribution.sample([number_of_blues, 1], seed=153)),
|
||||
],
|
||||
axis=1,
|
||||
),
|
||||
0,
|
||||
255,
|
||||
)
|
||||
|
||||
# Assign each color a vector of 3 booleans based on its true label.
|
||||
labels = tf.concat(
|
||||
[
|
||||
tf.tile(tf.constant([[True, False, False]]), (number_of_reds, 1)),
|
||||
tf.tile(tf.constant([[False, True, False]]), (number_of_greens, 1)),
|
||||
tf.tile(tf.constant([[False, False, True]]), (number_of_blues, 1)),
|
||||
],
|
||||
axis=0,
|
||||
)
|
||||
|
||||
# We introduce 3 normal distributions. They are used to predict whether a
|
||||
# color falls under a certain class (based on distances from corners of the
|
||||
# color triangle). The distributions vary per color. We have the distributions
|
||||
# narrow over time.
|
||||
initial_standard_deviations = [v + FLAGS.steps for v in (158, 200, 242)]
|
||||
iteration = tf.compat.v1.placeholder(tf.int32, shape=[])
|
||||
red_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.0,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[0] - iteration, dtype=tf.float32
|
||||
),
|
||||
)
|
||||
green_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.0,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[1] - iteration, dtype=tf.float32
|
||||
),
|
||||
)
|
||||
blue_predictor = tf.compat.v1.distributions.Normal(
|
||||
loc=0.0,
|
||||
scale=tf.cast(
|
||||
initial_standard_deviations[2] - iteration, dtype=tf.float32
|
||||
),
|
||||
)
|
||||
|
||||
# Make predictions (assign 3 probabilities to each color based on each color's
|
||||
# distance to each of the 3 corners). We seek double the area in the right
|
||||
# tail of the normal distribution.
|
||||
examples = tf.concat([true_reds, true_greens, true_blues], axis=0)
|
||||
probabilities_colors_are_red = (
|
||||
1
|
||||
- red_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([255.0, 0, 0]), axis=1)
|
||||
)
|
||||
) * 2
|
||||
probabilities_colors_are_green = (
|
||||
1
|
||||
- green_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([0, 255.0, 0]), axis=1)
|
||||
)
|
||||
) * 2
|
||||
probabilities_colors_are_blue = (
|
||||
1
|
||||
- blue_predictor.cdf(
|
||||
tf.norm(tensor=examples - tf.constant([0, 0, 255.0]), axis=1)
|
||||
)
|
||||
) * 2
|
||||
|
||||
predictions = (
|
||||
probabilities_colors_are_red,
|
||||
probabilities_colors_are_green,
|
||||
probabilities_colors_are_blue,
|
||||
)
|
||||
|
||||
# This is the crucial piece. We write data required for generating PR curves.
|
||||
# We create 1 summary per class because we create 1 PR curve per class.
|
||||
for i, color in enumerate(("red", "green", "blue")):
|
||||
description = (
|
||||
"The probabilities used to create this PR curve are "
|
||||
"generated from a normal distribution. Its standard "
|
||||
"deviation is initially %0.0f and decreases over time."
|
||||
% initial_standard_deviations[i]
|
||||
)
|
||||
|
||||
weights = None
|
||||
if mask_every_other_prediction:
|
||||
# Assign a weight of 0 to every even-indexed prediction. Odd-indexed
|
||||
# predictions are assigned a default weight of 1.
|
||||
consecutive_indices = tf.reshape(
|
||||
tf.range(tf.size(input=predictions[i])),
|
||||
tf.shape(input=predictions[i]),
|
||||
)
|
||||
weights = tf.cast(consecutive_indices % 2, dtype=tf.float32)
|
||||
|
||||
summary.op(
|
||||
name=color,
|
||||
labels=labels[:, i],
|
||||
predictions=predictions[i],
|
||||
num_thresholds=thresholds,
|
||||
weights=weights,
|
||||
display_name="classifying %s" % color,
|
||||
description=description,
|
||||
)
|
||||
merged_summary_op = tf.compat.v1.summary.merge_all()
|
||||
events_directory = os.path.join(logdir, run_name)
|
||||
sess = tf.compat.v1.Session()
|
||||
writer = tf.compat.v1.summary.FileWriter(events_directory, sess.graph)
|
||||
|
||||
for step in xrange(steps):
|
||||
feed_dict = {
|
||||
iteration: step,
|
||||
}
|
||||
merged_summary = sess.run(merged_summary_op, feed_dict=feed_dict)
|
||||
writer.add_summary(merged_summary, step)
|
||||
|
||||
writer.close()
|
||||
|
||||
|
||||
def run_all(logdir, steps, thresholds, verbose=False):
|
||||
"""Generate PR curve summaries.
|
||||
Arguments:
|
||||
logdir: The directory into which to store all the runs' data.
|
||||
steps: The number of steps to run for.
|
||||
verbose: Whether to print the names of runs into stdout during execution.
|
||||
thresholds: The number of thresholds to use for PR curves.
|
||||
"""
|
||||
# First, we generate data for a PR curve that assigns even weights for
|
||||
# predictions of all classes.
|
||||
run_name = "colors"
|
||||
if verbose:
|
||||
print("--- Running: %s" % run_name)
|
||||
start_runs(
|
||||
logdir=logdir, steps=steps, run_name=run_name, thresholds=thresholds
|
||||
)
|
||||
|
||||
# Next, we generate data for a PR curve that assigns arbitrary weights to
|
||||
# predictions.
|
||||
run_name = "mask_every_other_prediction"
|
||||
if verbose:
|
||||
print("--- Running: %s" % run_name)
|
||||
start_runs(
|
||||
logdir=logdir,
|
||||
steps=steps,
|
||||
run_name=run_name,
|
||||
thresholds=thresholds,
|
||||
mask_every_other_prediction=True,
|
||||
)
|
||||
|
||||
|
||||
def main(unused_argv):
|
||||
print("Saving output to %s." % FLAGS.logdir)
|
||||
run_all(FLAGS.logdir, FLAGS.steps, 50, verbose=True)
|
||||
print("Done. Output saved to %s." % FLAGS.logdir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(main)
|
||||
76
examples/frameworks/tensorflow/tensorboard_toy.py
Normal file
76
examples/frameworks/tensorflow/tensorboard_toy.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# TRAINS - Example of tensorboard with tensorflow (without any actual training)
|
||||
#
|
||||
import os
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from tempfile import gettempdir
|
||||
from PIL import Image
|
||||
|
||||
from trains import Task
|
||||
|
||||
|
||||
def generate_summary(k, step):
|
||||
# Make a normal distribution, with a shifting mean
|
||||
mean_moving_normal = tf.random.normal(shape=[1000], mean=(5 * k), stddev=1)
|
||||
# Record that distribution into a histogram summary
|
||||
tf.summary.histogram("normal/moving_mean", mean_moving_normal, step=step)
|
||||
tf.summary.scalar("normal/value", mean_moving_normal[-1], step=step)
|
||||
|
||||
# Make a normal distribution with shrinking variance
|
||||
variance_shrinking_normal = tf.random.normal(shape=[1000], mean=0, stddev=1-k)
|
||||
# Record that distribution too
|
||||
tf.summary.histogram("normal/shrinking_variance", variance_shrinking_normal, step=step)
|
||||
tf.summary.scalar("normal/variance_shrinking_normal", variance_shrinking_normal[-1], step=step)
|
||||
|
||||
# Let's combine both of those distributions into one dataset
|
||||
normal_combined = tf.concat([mean_moving_normal, variance_shrinking_normal], 0)
|
||||
# We add another histogram summary to record the combined distribution
|
||||
tf.summary.histogram("normal/bimodal", normal_combined, step=step)
|
||||
tf.summary.scalar("normal/normal_combined", normal_combined[0], step=step)
|
||||
|
||||
# Add a gamma distribution
|
||||
gamma = tf.random.gamma(shape=[1000], alpha=k)
|
||||
tf.summary.histogram("gamma", gamma, step=step)
|
||||
|
||||
# And a poisson distribution
|
||||
poisson = tf.random.poisson(shape=[1000], lam=k)
|
||||
tf.summary.histogram("poisson", poisson, step=step)
|
||||
|
||||
# And a uniform distribution
|
||||
uniform = tf.random.uniform(shape=[1000], maxval=k*10)
|
||||
tf.summary.histogram("uniform", uniform, step=step)
|
||||
|
||||
# Finally, combine everything together!
|
||||
all_distributions = [mean_moving_normal, variance_shrinking_normal, gamma, poisson, uniform]
|
||||
all_combined = tf.concat(all_distributions, 0)
|
||||
tf.summary.histogram("all_combined", all_combined, step=step)
|
||||
|
||||
# Log text value
|
||||
tf.summary.text("this is a test", "This is the content", step=step)
|
||||
|
||||
# convert to 4d [batch, col, row, RGB-channels]
|
||||
image_open = Image.open(os.path.join('..', '..', 'reporting', 'data_samples', 'picasso.jpg'))
|
||||
image = np.asarray(image_open)
|
||||
image_gray = image[:, :, 0][np.newaxis, :, :, np.newaxis]
|
||||
image_rgba = np.concatenate((image, 255*np.atleast_3d(np.ones(shape=image.shape[:2], dtype=np.uint8))), axis=2)
|
||||
image_rgba = image_rgba[np.newaxis, :, :, :]
|
||||
image = image[np.newaxis, :, :, :]
|
||||
|
||||
tf.summary.image("test", image, max_outputs=10, step=step)
|
||||
tf.summary.image("test_gray", image_gray, max_outputs=10, step=step)
|
||||
tf.summary.image("test_rgba", image_rgba, max_outputs=10, step=step)
|
||||
|
||||
|
||||
task = Task.init(project_name='examples', task_name='tensorboard toy example')
|
||||
|
||||
# create the tensorboard file writer in a temp folder
|
||||
writer = tf.summary.create_file_writer(os.path.join(gettempdir(), "toy_tb_example"))
|
||||
|
||||
# Setup a loop and write the summaries to disk
|
||||
N = 40
|
||||
for step in range(N):
|
||||
k_val = step/float(N)
|
||||
with writer.as_default():
|
||||
generate_summary(k_val, tf.cast(step, tf.int64))
|
||||
|
||||
print('Tensorboard toy example done')
|
||||
134
examples/frameworks/tensorflow/tensorflow_mnist.py
Normal file
134
examples/frameworks/tensorflow/tensorflow_mnist.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
from tempfile import gettempdir
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorflow.keras.layers import Dense, Flatten, Conv2D
|
||||
from tensorflow.keras import Model
|
||||
|
||||
from trains import Task
|
||||
|
||||
|
||||
task = Task.init(project_name='examples',
|
||||
task_name='Tensorflow v2 mnist with summaries')
|
||||
|
||||
|
||||
# Load and prepare the MNIST dataset.
|
||||
mnist = tf.keras.datasets.mnist
|
||||
|
||||
(x_train, y_train), (x_test, y_test) = mnist.load_data()
|
||||
x_train, x_test = x_train / 255.0, x_test / 255.0
|
||||
|
||||
# Add a channels dimension
|
||||
x_train = x_train[..., tf.newaxis].astype('float32')
|
||||
x_test = x_test[..., tf.newaxis].astype('float32')
|
||||
|
||||
# Use tf.data to batch and shuffle the dataset
|
||||
train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(10000).batch(32)
|
||||
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
|
||||
|
||||
|
||||
# Build the tf.keras model using the Keras model subclassing API
|
||||
class MyModel(Model):
|
||||
def __init__(self):
|
||||
super(MyModel, self).__init__()
|
||||
self.conv1 = Conv2D(32, 3, activation='relu', dtype=tf.float32)
|
||||
self.flatten = Flatten()
|
||||
self.d1 = Dense(128, activation='relu', dtype=tf.float32)
|
||||
self.d2 = Dense(10, activation='softmax', dtype=tf.float32)
|
||||
|
||||
def call(self, x):
|
||||
x = self.conv1(x)
|
||||
x = self.flatten(x)
|
||||
x = self.d1(x)
|
||||
return self.d2(x)
|
||||
|
||||
|
||||
# Create an instance of the model
|
||||
model = MyModel()
|
||||
|
||||
# Choose an optimizer and loss function for training
|
||||
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
|
||||
optimizer = tf.keras.optimizers.Adam()
|
||||
|
||||
# Select metrics to measure the loss and the accuracy of the model.
|
||||
# These metrics accumulate the values over epochs and then print the overall result.
|
||||
train_loss = tf.keras.metrics.Mean(name='train_loss', dtype=tf.float32)
|
||||
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
|
||||
|
||||
test_loss = tf.keras.metrics.Mean(name='test_loss', dtype=tf.float32)
|
||||
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')
|
||||
|
||||
|
||||
# Use tf.GradientTape to train the model
|
||||
@tf.function
|
||||
def train_step(images, labels):
|
||||
with tf.GradientTape() as tape:
|
||||
predictions = model(images)
|
||||
loss = loss_object(labels, predictions)
|
||||
gradients = tape.gradient(loss, model.trainable_variables)
|
||||
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
|
||||
|
||||
train_loss(loss)
|
||||
train_accuracy(labels, predictions)
|
||||
|
||||
|
||||
# Test the model
|
||||
@tf.function
|
||||
def test_step(images, labels):
|
||||
predictions = model(images)
|
||||
t_loss = loss_object(labels, predictions)
|
||||
|
||||
test_loss(t_loss)
|
||||
test_accuracy(labels, predictions)
|
||||
|
||||
|
||||
# Set up summary writers to write the summaries to disk in a different logs directory
|
||||
train_log_dir = os.path.join(gettempdir(), 'logs', 'gradient_tape', 'train')
|
||||
test_log_dir = os.path.join(gettempdir(), 'logs', 'gradient_tape', 'test')
|
||||
train_summary_writer = tf.summary.create_file_writer(train_log_dir)
|
||||
test_summary_writer = tf.summary.create_file_writer(test_log_dir)
|
||||
|
||||
# Set up checkpoints manager
|
||||
ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=optimizer, net=model)
|
||||
manager = tf.train.CheckpointManager(ckpt, os.path.join(gettempdir(), 'tf_ckpts'), max_to_keep=3)
|
||||
ckpt.restore(manager.latest_checkpoint)
|
||||
if manager.latest_checkpoint:
|
||||
print("Restored from {}".format(manager.latest_checkpoint))
|
||||
else:
|
||||
print("Initializing from scratch.")
|
||||
|
||||
# Start training
|
||||
EPOCHS = 5
|
||||
for epoch in range(EPOCHS):
|
||||
for images, labels in train_ds:
|
||||
train_step(images, labels)
|
||||
with train_summary_writer.as_default():
|
||||
tf.summary.scalar('loss', train_loss.result(), step=epoch)
|
||||
tf.summary.scalar('accuracy', train_accuracy.result(), step=epoch)
|
||||
|
||||
ckpt.step.assign_add(1)
|
||||
if int(ckpt.step) % 1 == 0:
|
||||
save_path = manager.save()
|
||||
print("Saved checkpoint for step {}: {}".format(int(ckpt.step), save_path))
|
||||
|
||||
for test_images, test_labels in test_ds:
|
||||
test_step(test_images, test_labels)
|
||||
with test_summary_writer.as_default():
|
||||
tf.summary.scalar('loss', test_loss.result(), step=epoch)
|
||||
tf.summary.scalar('accuracy', test_accuracy.result(), step=epoch)
|
||||
|
||||
template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}'
|
||||
print(template.format(epoch+1,
|
||||
train_loss.result(),
|
||||
train_accuracy.result()*100,
|
||||
test_loss.result(),
|
||||
test_accuracy.result()*100))
|
||||
|
||||
# Reset the metrics for the next epoch
|
||||
train_loss.reset_states()
|
||||
train_accuracy.reset_states()
|
||||
test_loss.reset_states()
|
||||
test_accuracy.reset_states()
|
||||
Reference in New Issue
Block a user