def __init__(self, shape: Union[None, TensorShape] = None, ndim: Union[None, int] = None, max_ndim: Union[None, int] = None, min_ndim: Union[None, int] = None, axes=None, dtype=None, object_type: Optional[ObjectType] = None, is_spatial=False, name=None): self._dtype = dtype if dtype is not None else None self._shape_tuple = None self.object_type = object_type self._name = name if shape is not None: if isinstance(shape, TensorShape): self.ndim = shape.ndims self._shape_tuple = tuple(shape.dims) self.shape = shape elif isinstance(shape, (list, tuple)) and all( [isinstance(item, numbers.Number) for item in shape]): self.ndim = len(shape) self._shape_tuple = (None, ) + tuple(shape) self.shape = TensorShape(shape) elif not is_tensor(shape) and isinstance(shape, numbers.Number): self.ndim = 0 self.shape = TensorShape([None, shape]) self._shape_tuple = (None, shape) elif is_tensor(shape) and 'int' in str(shape.dtype): self.ndim = len(shape) shape = to_list(to_numpy(shape)) self._shape_tuple = (None, ) + tuple(shape) self.shape = TensorShape(self._shape_tuple) else: print(shape) self.ndim = len(shape) shape = to_list(to_numpy(shape)) self._shape_tuple = (None, ) + tuple(shape) self.shape = TensorShape(self._shape_tuple) else: self.ndim = ndim self.shape = None self.max_ndim = max_ndim self.min_ndim = min_ndim try: axes = axes or {} self.axes = {int(k): axes[k] for k in axes} except (ValueError, TypeError): raise TypeError('The keys in axes must be integers.') if self.axes and (self.ndim is not None or self.max_ndim is not None): max_dim = (self.ndim if self.ndim else self.max_ndim) - 1 max_axis = max(self.axes) if max_axis > max_dim: raise ValueError( 'Axis {} is greater than the maximum allowed value: {}'. format(max_axis, max_dim))
def get_signature(fn, name=None): """ Args: name (): fn (): Returns: Examples: >>> get_signature(unpack_singleton) split_path( path:<class 'str'>) -> folder, filename, ext """ base_fn = fn base_signature = base_fn._signature if hasattr(fn, '_signature') else None if hasattr(fn, 'forward'): base_fn = fn.forward signature = Signature() sig = inspect.signature(base_fn) paras = list(sig.parameters.items()) returns = sig.return_annotation if sig.return_annotation is not inspect._empty: if isinstance(returns, str): signature.outputs[returns] = TensorSpec(TensorShape([None]), optional=False, name=returns) elif returns is Tensor: pass else: for i in range(len(returns)): signature.outputs['output_{0}'.format(i)] = TensorSpec(TensorShape([None]), optional=False, name='output_{0}'.format(i)) else: signature.outputs['output'] = TensorSpec(TensorShape([None]), optional=False, name='output') for k, v in paras: if k not in ['kwargs', 'self', 'args']: annotation = v.annotation _default = v.default if v.default != inspect.Parameter.empty else None _optional = _default is not None _dtype = type(_default) if _default is not None else annotation if not is_instance(annotation, str) else None _ndim = 0 if _dtype in [int, float, bool, str, numbers.Number, numbers.Integral] else None _shape = TensorShape([0]) if _dtype in [int, float, bool, str, numbers.Number, numbers.Integral] else None if annotation is Tensor: _dtype = dtype.float32 _shape = TensorShape([None]) _ndim = None signature.inputs[k] = TensorSpec(shape=_shape, ndim=_ndim, dtype=_dtype, optional=_optional, default=_default, name=k) if name is not None: signature.name = name else: signature.name = name if name is not None else fn.__class__.__name__ if is_instance(fn, 'Layer') else fn.__class__.__qualname__ # if hasattr(base_fn,'__code__'): # signature.__code__ = base_fn.__code__ return signature
def tensor_to_spec(cls, t: Tensor, object_type: ObjectType = None, need_exclude_batch_axis=True, is_singleton=False, optional=False, name=None): if isinstance(t,str): return cls(shape=TensorShape([None]), dtype=str, object_type=object_type, optional=optional, name=name) else: t = to_tensor(t) return cls(shape=tensor_to_shape(t, need_exclude_batch_axis=need_exclude_batch_axis, is_singleton=is_singleton), dtype=t.dtype, object_type=object_type, optional=optional, name=name)
def _make_recovery_model_include_top(recovery_model:Layer,default_shape=None,input_shape=None, include_top=True, classes=1000, freeze_features=False): size_change=False if default_shape is None: if recovery_model.built: default_shape=tuple(recovery_model._input_shape.dims[1:] if isinstance(recovery_model._input_shape,TensorShape) else recovery_model._input_shape) else: default_shape=(3,224,224) if get_backend() == 'pytorch' else (224,224,3) if input_shape is not None and input_shape !=default_shape: size_change=True dims = list(input_shape) dims.insert(0, None) if isinstance(recovery_model.signature, Signature): recovery_model._input_shape = TensorShape(dims) recovery_model.signature.inputs.value_list[0].shape = TensorShape(dims) recovery_model.signature.inputs.value_list[0].object_type=ObjectType.rgb if freeze_features: recovery_model.trainable=False idx=-1 while (len(recovery_model[idx]._parameters) == 0 or isinstance(recovery_model[idx], Dense))and len(recovery_model[idx].output_shape) >= 2: layer=recovery_model[idx] if layer.output_shape.rank>2: break if len(recovery_model[idx]._parameters) >0: recovery_model[idx].trainable=True idx-=1 if not include_top: while len(recovery_model[-1]._parameters)==0 or isinstance(recovery_model[-1],Dense) and len(recovery_model[-1].output_shape)>=2: layer = recovery_model[-1] if layer.output_shape.rank > 2: break recovery_model.remove_at(-1) recovery_model.class_names = [] elif size_change: new_layers=[] dims = list(input_shape) dims.insert(0, None) shp=TensorShape(dims) while len(recovery_model[-1]._parameters) == 0 or isinstance(recovery_model[-1], Dense) and len(recovery_model[-1].output_shape) >= 2: layer = recovery_model[-1] if layer.output_shape.rank > 2: break new_layer=copy.deepcopy(layer) if isinstance(layer,Dense) : if layer.num_filters==1000 and classes != 1000: new_layer=Dense((classes)) recovery_model.class_names = [] else: num_filters=new_layer.num_filters new_layer=Dense((num_filters)) new_layers.insert(0,new_layer) recovery_model.remove_at(-1) out=recovery_model(to_tensor(shp.get_dummy_tensor())) recovery_model[-1].output_shape=tensor_to_shape(out,need_exclude_batch_axis=True) fc_seq=0 for ly in new_layers: if isinstance(ly, Dense): recovery_model.add_module('fc' if fc_seq==0 else 'fc{0}'.format(fc_seq),ly) fc_seq += 1 else: recovery_model.add_module(ly.name, ly) if isinstance(recovery_model.signature, Signature): recovery_model.output_shape = TensorShape([None, classes]) recovery_model.signature.outputs.value_list[0].shape = TensorShape([None, classes]) recovery_model.signature.outputs.value_list[0].object_type = ObjectType.classification_label else: #include_top=True if classes != 1000: while len(recovery_model[-1]._parameters)==0 or isinstance(recovery_model[-1],Dense) and len(recovery_model[-1].output_shape)>=2: m=recovery_model[-1] if isinstance(m,Dense): recovery_model[-1]=Dense((classes)) recovery_model.add_module('softmax',SoftMax()) break else: recovery_model.remove_at(-1) if isinstance(recovery_model.signature, Signature): recovery_model.output_shape= TensorShape([None,classes]) recovery_model.signature.outputs.value_list[0].shape = TensorShape([None,classes]) recovery_model.signature.outputs.value_list[0].object_type = ObjectType.classification_label recovery_model.class_names = [] return recovery_model
def assert_spec_compatibility(input_spec: TensorSpec, other_spec: TensorSpec): """Checks compatibility between the layer and provided inputs. This checks that the tensor(s) `inputs` verify the input assumptions of a layer (if any). If not, a clear and actional exception gets raised. Arguments: input_spec: An InputSpec instance, list of InputSpec instances, a nested structure of InputSpec instances, or None. other_spec: Another InputSpec Raises: ValueError: in case of mismatch between the provided inputs and the expectations of the layer. """ if not input_spec: return False if isinstance(input_spec, (tuple, list)) and all( [isinstance(item, numbers.Integral) for item in input_spec]): input_spec = TensorSpec(shape=to_tensor(input_spec)) if isinstance(other_spec, (tuple, list)) and all( [isinstance(item, numbers.Integral) for item in other_spec]): other_spec = TensorSpec(shape=to_tensor(other_spec)) if (input_spec.ndim is not None or input_spec.min_ndim is not None or input_spec.max_ndim is not None): if other_spec.ndim is None: print('Other_spec ' + ' is incompatible with input_spec: ' 'its rank is undefined, but input_spec requires a ' 'defined rank.') return False # Check ndim. if input_spec.ndim is not None: ndim = other_spec.ndim if ndim != input_spec.ndim: print( 'Other_spec is incompatible with the input_spec: expected ndim=' + str(input_spec.ndim) + ', found ndim=' + str(ndim) + '. Full shape received: ' + str(other_spec._shape_tuple)) return False if input_spec.max_ndim is not None: ndim = other_spec.ndim if ndim is not None and ndim > input_spec.max_ndim: print( 'Other_spec is incompatible with the input_spec: expected max_ndim=' + str(input_spec.max_ndim) + ', found ndim=' + str(ndim)) return False if input_spec.min_ndim is not None: ndim = other_spec.ndim if ndim is not None and ndim < input_spec.min_ndim: print( 'Other_spec is incompatible with the input_spec: expected min_ndim=' + str(input_spec.min_ndim) + ', found ndim=' + str(ndim) + '. Full shape received: ' + str(other_spec._shape_tuple)) return False # Check dtype. if input_spec.dtype is not None: if other_spec.dtype != input_spec.dtype: print( 'Other_spec is incompatible with the input_spec: expected dtype=' + str(input_spec.dtype) + ', found dtype=' + str(other_spec.dtype)) return False # Check specific shape axes. if input_spec.axes: shape = other_spec._shape_tuple if shape is not None: for axis, value in input_spec.axes.items(): if hasattr(value, 'value'): value = value.value if value is not None and shape[int(axis)] not in {value, None}: print( 'Other_spec is incompatible with input_spec: expected axis ' + str(axis) + ' of input shape to have value ' + str(value) + ' but received input with shape ' + str(shape)) return False # Check shape. if input_spec.shape is not None: shape = other_spec._shape_tuple is_compatible = TensorShape(input_spec.shape).is_compatible_with( TensorShape(other_spec._shape_tuple)) if is_compatible: return is_compatible if shape is not None: for spec_dim, dim in zip(other_spec._shape_tuple, input_spec._shape_tuple): if spec_dim is not None and dim is not None: if spec_dim != dim: print( 'Other_spec is incompatible with input_spec: expected shape=' + str(input_spec._shape_tuple) + ', found shape=' + str(shape)) return False return True
def _make_recovery_model_include_top(recovery_model: Layer, default_shape=None, input_shape=None, include_top=True, classes=1000, freeze_features=True): size_change = False if default_shape is None: if recovery_model.built: default_shape = tuple( recovery_model._input_shape. dims[1:] if isinstance(recovery_model._input_shape, TensorShape ) else recovery_model._input_shape) else: default_shape = (3, 224, 224) if get_backend() == 'pytorch' else (224, 224, 3) if input_shape is not None and input_shape != default_shape: size_change = True if freeze_features: recovery_model.trainable = False idx = -1 is_last_dense = True while (len(recovery_model[idx]._parameters) == 0 or isinstance(recovery_model[idx], Dense)) and len( recovery_model[idx].output_shape) >= 2: layer = recovery_model[idx] if layer.output_shape.rank > 2: break elif len(recovery_model[idx]._parameters) > 0: if not include_top: recovery_model.remove_at(idx) idx += 1 elif size_change or (is_last_dense and classes != 1000 and isinstance(recovery_model[idx], Dense)): if hasattr( recovery_model[idx], 'num_filters' ) and recovery_model[idx].num_filters != classes: recovery_model[idx].num_filters = classes recovery_model[idx]._built = False recovery_model[idx]._parameters.clear() else: recovery_model[idx].trainable = True else: if not include_top: recovery_model.remove_at(idx) idx += 1 idx -= 1 dims = list(default_shape) dims.insert(0, None) new_tensorshape = TensorShape(dims) if size_change: dims = list(input_shape) dims.insert(0, None) new_tensorshape = TensorShape(dims) for module in recovery_model.modules(): module._input_shape = None module._output_shape = None recovery_model.to(get_device()) out = recovery_model( to_tensor(new_tensorshape.get_dummy_tensor(), device=get_device())) if isinstance(recovery_model.signature, Signature): recovery_model.signature.inputs.value_list[0].shape = TensorShape(dims) recovery_model.signature.inputs.value_list[ 0].object_type = ObjectType.rgb recovery_model.to(get_device()) return recovery_model
def __setattr__(self, name, value): object.__setattr__(self, name, value) if name in ['shape']: if value is not None and value != TensorShape([None]) and value != TensorShape([0]): self.ndim = self.shape.ndims self._shape_tuple = tuple(self.shape.dims)