提交 dbb323ae authored 作者: Frederic Bastien's avatar Frederic Bastien

warn that axis=None behavior will change and the default for axis will change…

warn that axis=None behavior will change and the default for axis will change for fct min,max,argmin,argmax,max_and_argmax.
上级 f59a1dae
...@@ -6,6 +6,7 @@ import __builtin__ ...@@ -6,6 +6,7 @@ import __builtin__
import sys # for sys.maxint import sys # for sys.maxint
from theano.configparser import config, AddConfigVar, BoolParam from theano.configparser import config, AddConfigVar, BoolParam
import traceback #for overriding Op.__call__ import traceback #for overriding Op.__call__
import warnings
import numpy, theano import numpy, theano
#from copy import copy as python_copy #from copy import copy as python_copy
...@@ -1396,10 +1397,14 @@ class MaxAndArgmax(Op): ...@@ -1396,10 +1397,14 @@ class MaxAndArgmax(Op):
def __hash__(self): def __hash__(self):
return hash(type(self)) return hash(type(self))
def make_node(self, x, axis=None): def make_node(self, x, axis='DEFAULT'):
x = _as_tensor_variable(x) x = _as_tensor_variable(x)
if axis is None: if axis=='DEFAULT':
axis=x.type.ndim - 1
warnings.warn("The default axis of MaxAndArgmax will change! Now we return the max and the armax over the last dimensions. It will change to be the same as numpy: the max and argmax over all dimensions. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. MaxAndArgmax currently support axis over only 1 dimensions, so you must flatten the tensor to have the futur behavior.")
elif axis is None:
axis = x.type.ndim - 1 axis = x.type.ndim - 1
warnings.warn("The behavior of MaxAndArgmax when axis==None will change! Now we return the max and argmax over the last dimensions. It will change to the max and argmax over all dimensions as numpy. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. MaxAndArgmax currently support axis over only 1 dimensions, so you must flatten the tensor to have the futur behavior.")
if isinstance(axis,int): if isinstance(axis,int):
axis = [axis] axis = [axis]
elif isinstance(axis,(tuple,list)): elif isinstance(axis,(tuple,list)):
...@@ -1462,15 +1467,21 @@ def max_and_argmax(a): ...@@ -1462,15 +1467,21 @@ def max_and_argmax(a):
@constructor @constructor
def max(x, axis=None): def max(x, axis='DEFAULT'):
""" """
Return maximum elements obtained by iterating over given axis Return maximum elements obtained by iterating over given axis
Default axis is the last one. Default axis is the last one. This will change.
:note: we return an error as numpy when we reduce a dim with a shape of 0 :note: we return an error as numpy when we reduce a dim with a shape of 0
:note2: see MaxAndArgmax note for a difference between numpy and theano when axis==None :note2: see MaxAndArgmax note for a difference between numpy and theano when axis==None
""" """
if axis=='DEFAULT':
axis = x.type.ndim - 1
warnings.warn("The default axis of max will change! Now we return the max over the last dimensions. It will change to be the same as numpy: the max over all dimensions. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior set axis to range(nb dim), but this don't support the grad. To have the grad, you must flatten the tensor before calling max().")
elif axis is None:
axis = x.type.ndim - 1
warnings.warn("The behavior of max when axis==None will change! Now we return the max over the last dimensions. It will change to the max over all dimensions as numpy. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior set axis to range(nb dim), but this don't support the grad. To have the grad, you must flatten the tensor before calling max().")
if isinstance(axis,(list,tuple)) and len(axis)>1: if isinstance(axis,(list,tuple)) and len(axis)>1:
return CAReduce(scal.maximum,axis)(x) return CAReduce(scal.maximum,axis)(x)
try: try:
...@@ -1480,19 +1491,31 @@ def max(x, axis=None): ...@@ -1480,19 +1491,31 @@ def max(x, axis=None):
return max_and_argmax(x,axis)[0] return max_and_argmax(x,axis)[0]
@constructor @constructor
def argmax(x, axis=None): def argmax(x, axis='DEFAULT'):
""" """
Return indexes of maximum elements obtained by iterating over given axis Return indexes of maximum elements obtained by iterating over given axis
Default axis is the last one. Default axis is the last one. This will change.
""" """
if axis=='DEFAULT':
axis = x.type.ndim - 1
warnings.warn("The default axis of argmax will change! Now we return the argmax over the last dimensions. It will change to be the same as numpy: the argmax over all dimensions. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior, you must flatten the tensor before calling max().")
elif axis is None:
axis = x.type.ndim - 1
warnings.warn("The behavior of argmax when axis==None will change! Now we return the argmax over the last dimensions. It will change to the argmax over all dimensions as numpy. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior, you must flatten the tensor before calling argmax().")
# In python (using MaxAndArgmax.perform()) this leads to an wasteful # In python (using MaxAndArgmax.perform()) this leads to an wasteful
# implementation that goes through the data twice instead of once # implementation that goes through the data twice instead of once
# but when Argmax.c_impl() is in place, it should be fine. # but when Argmax.c_impl() is in place, it should be fine.
return max_and_argmax(x,axis)[1] return max_and_argmax(x,axis)[1]
@constructor @constructor
def min(x, axis=None): def min(x, axis='DEFAULT'):
if axis=='DEFAULT':
axis = x.type.ndim - 1
warnings.warn("The default axis of min will change! Now we return the min over the last dimensions. It will change to be the same as numpy: the min over all dimensions. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior set axis to range(nb dim), but this don't support the grad. To have the grad, you must flatten the tensor before calling min().")
elif axis is None:
axis = x.type.ndim - 1
warnings.warn("The behavior of min when axis==None will change! Now we return the min over the last dimensions. It will change to the min over all dimensions as numpy. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior set axis to range(nb dim), but this don't support the grad. To have the grad, you must flatten the tensor before calling min().")
str_x_type = str(x.dtype) str_x_type = str(x.dtype)
if str_x_type.startswith('float') or str_x_type.startswith('int'): if str_x_type.startswith('float') or str_x_type.startswith('int'):
return -max(-x, axis=axis) return -max(-x, axis=axis)
...@@ -1501,7 +1524,13 @@ def min(x, axis=None): ...@@ -1501,7 +1524,13 @@ def min(x, axis=None):
raise NotImplementedError() raise NotImplementedError()
@constructor @constructor
def argmin(x, axis=None): def argmin(x, axis='DEFAULT'):
if axis=='DEFAULT':
axis = x.type.ndim - 1
warnings.warn("The default axis of argmin will change! Now we return the argmin over the last dimensions. It will change to be the same as numpy: the argmin over all dimensions. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior, you must flatten the axis before calling argmin.")
elif axis is None:
axis = x.type.ndim - 1
warnings.warn("The behavior of argmin when axis==None will change! Now we return the argmin over the last dimensions. It will change to the argmin over all dimensions as numpy. To hide this warning and be compatible with the future behavior, set axis to -1 to have the current behavior. To have the futur behavior, you must flatten the axis before calling argmin.")
str_x_type = str(x.dtype) str_x_type = str(x.dtype)
if str_x_type.startswith('float') or str_x_type.startswith('int'): if str_x_type.startswith('float') or str_x_type.startswith('int'):
return argmax(-x, axis=axis) return argmax(-x, axis=axis)
...@@ -4222,6 +4251,9 @@ def verify_grad(fun, pt, n_tests=2, rng=None, eps=None, abs_tol=None, rel_tol=No ...@@ -4222,6 +4251,9 @@ def verify_grad(fun, pt, n_tests=2, rng=None, eps=None, abs_tol=None, rel_tol=No
g_cost = cast(g_cost, o_output.dtype) g_cost = cast(g_cost, o_output.dtype)
symbolic_grad = grad(cost, tensor_pt, g_cost) symbolic_grad = grad(cost, tensor_pt, g_cost)
#if o_output.dtype in ['float32','float64']:
# assert all([x.dtype == o_output.dtype for x in symbolic_grad]),("Expected grad of type %s, got %s "%( symbolic_grad.dtype, o_output.dtyp))
grad_fn = function(tensor_pt, symbolic_grad) grad_fn = function(tensor_pt, symbolic_grad)
for test_num in xrange(n_tests): for test_num in xrange(n_tests):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论