1# Copyright 2016 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"""Operators for concise TensorFlow parameter specifications.
16
17This module is used as an environment for evaluating expressions
18in the "params" DSL.
19
20Specifications are intended to assign simple numerical
21values. Examples:
22
23    --params "n=64; d=5" --spec "(Cr(n) | Mp([2, 2])) ** d | Fm"
24
25The random parameter primitives are useful for running large numbers
26of experiments with randomly distributed parameters:
27
28    --params "n=Li(5,500); d=Ui(1,5)" --spec "(Cr(n) | Mp([2, 2])) ** d | Fm"
29
30Internally, this might be implemented as follows:
31
32    params = specs.create_params(FLAGS.params, {})
33    logging.info(repr(params))
34    net = specs.create_net(FLAGS.spec, inputs, params)
35
36Note that separating the specifications into parameters and network
37creation allows us to log the random parameter values easily.
38
39The implementation of this will change soon in order to support
40hyperparameter tuning with steering. Instead of returning a number,
41the primitives below will return a class instance that is then
42used to generate a random number by the framework.
43"""
44from __future__ import absolute_import
45from __future__ import division
46from __future__ import print_function
47
48# Lint disabled because these are operators in the DSL, not regular
49# Python functions.
50# pylint: disable=invalid-name
51# pylint: disable=wildcard-import,unused-wildcard-import,redefining-builtin
52# pylint: disable=redefined-builtin,g-importing-member,no-member
53# make available all math expressions
54import math
55from math import *
56import random
57# pylint: enable=wildcard-import,unused-wildcard-import,redefining-builtin
58# pylint: enable=redefined-builtin,g-importing-member,no-member
59
60
61def Uf(lo=0.0, hi=1.0):
62  """Uniformly distributed floating number."""
63  return random.uniform(lo, hi)
64
65
66def Ui(lo, hi):
67  """Uniformly distributed integer, inclusive limits."""
68  return random.randint(lo, hi)
69
70
71def Lf(lo, hi):
72  """Log-uniform distributed floatint point number."""
73  return math.exp(random.uniform(math.log(lo), math.log(hi)))
74
75
76def Li(lo, hi):
77  """Log-uniform distributed integer, inclusive limits."""
78  return int(math.floor(math.exp(random.uniform(math.log(lo),
79                                                math.log(hi+1-1e-5)))))
80
81
82def Nt(mu, sigma, limit=3.0):
83  """Normally distributed floating point number with truncation."""
84  return min(max(random.gauss(mu, sigma), mu-limit*sigma), mu+limit*sigma)
85
86
87# pylint: enable=invalid-name
88