def test_copy(self): shape0 = Shape((DimNames.BATCH, 16), (DimNames.CHANNEL, 3), (DimNames.HEIGHT, 48), (DimNames.WIDTH, 32), (DimNames.UNITS, 10), (DimNames.TIME, 13)) shape1 = shape0.__copy__() self.assertEqual(shape0, shape1) self.assertEqual(shape1, shape0) self.assertIsNot(shape0, shape1)
def test_state(self): shape0 = Shape((DimNames.BATCH, 16), (DimNames.CHANNEL, 3), (DimNames.HEIGHT, 48), (DimNames.WIDTH, 32), (DimNames.UNITS, 10), (DimNames.TIME, 13)) state = shape0.__getstate__() self.assertIsNotNone(state) shape1 = Shape.__new__(Shape) shape1.__setstate__(state) self.assertEqual(shape0, shape1) self.assertEqual(shape1, shape0)
def test_hash(self): shape0 = Shape((DimNames.BATCH, 16), (DimNames.CHANNEL, 3), (DimNames.HEIGHT, 48), (DimNames.WIDTH, 32), (DimNames.UNITS, 10), (DimNames.TIME, 13)) hash0 = shape0.__hash__() shape1 = shape0.__copy__() hash1 = shape1.__hash__() self.assertIsInstance(hash0, int) self.assertIsInstance(hash1, int) self.assertEqual(hash0, hash1) self.assertEqual(hash1, hash0)
def max_transform(cls, nts): if nts.dtype not in cls.allowedTypes: return None s = Shape() result = TypeShape(nts.dtype, s) for _dim in nts.shape.dim: if _dim.name == DimNames.BATCH: s.dim.append(Shape.Dim(_dim.name, _dim.size)) elif _dim.name == DimNames.UNITS: s.dim.append(Shape.Dim(_dim.name, int(math.ceil(_dim.size * cls.__max_f)))) else: return None return result
def min_transform(cls, nts: TypeShape): if nts.dtype not in cls.allowedTypes: return None s = Shape((DimNames.UNITS, 1)) result = TypeShape(nts.dtype, s) idx = [ i for i, d in enumerate(nts.shape.dim) if d.name == DimNames.BATCH ] if len(idx) > 0: idx = idx[0] b = nts.shape.dim[idx].size if idx + 1 < len(nts.shape.dim) // 2: s.dim.insert(0, Shape.Dim(DimNames.BATCH, b)) else: s.dim.append((Shape.Dim(DimNames.BATCH, b))) return result
def possible_output_shapes(cls, input_ntss: Dict[str, TypeShape], target_output: TypeShape, is_reachable, max_possibilities: int = 10, **kwargs) -> \ List[Tuple[Dict[str, TypeShape], Dict[str, TypeShape], Dict[str, str]]]: target_shape = target_output.shape for label, nts in input_ntss.items(): if nts.dtype not in cls.allowedTypes: continue possible_sizes = [] names = [] invalid_dim = False for _dim in nts.shape.dim: target_size = target_shape[_dim.name] if _dim.name == DimNames.UNITS: lower_border = max(math.floor(_dim.size * cls.__min_f), (min(2, target_size) if target_size is not None else 2)) upper_border = math.ceil(_dim.size * cls.__max_f) pool = list(range(lower_border + 1, upper_border)) border_pool = list({lower_border, upper_border}) if target_size is None or not (lower_border < target_size < upper_border): pool = sample(pool, k=min(max(max_possibilities - len(border_pool), 0), len(pool))) else: pool.remove(target_size) pool = sample(pool, k=min(max(max_possibilities - len(border_pool) - 1, 0), len(pool))) + [target_size] pool = pool + border_pool elif _dim.name == DimNames.BATCH: pool = [_dim.size] else: invalid_dim = True break possible_sizes.append(pool) names.append(_dim.name) if invalid_dim: continue for dim_combination in Shape.random_dimension_product(possible_sizes): out_nts = TypeShape(nts.dtype, Shape(*zip(names, dim_combination))) if is_reachable(out_nts, target_output): yield ({}, {IOLabel.DENSE_OUT: out_nts}, {IOLabel.DENSE_IN: label})
def possible_output_shapes(cls, input_ntss: Dict[str, TypeShape], target_output: TypeShape, is_reachable, max_possibilities: int = 10, max_inputs: int = None, **kwargs) -> \ List[Tuple[Dict[str, TypeShape], Dict[str, TypeShape], Dict[str, str]]]: for label, nts in input_ntss.items(): if nts.dtype not in cls.allowedTypes: continue possible_sizes = [] names = [] invalid_dim = False for _dim in nts.shape.dim: if _dim.name == DimNames.UNITS and _dim.size == 1: pool = [1] elif _dim.name == DimNames.BATCH: pool = [_dim.size] else: invalid_dim = True break possible_sizes.append(pool) names.append(_dim.name) if invalid_dim: continue for comb in Shape.random_dimension_product(possible_sizes): out_nts = TypeShape(nts.dtype, Shape(*zip(names, comb))) if is_reachable(out_nts, target_output): yield ({ cls.get_in_label(i + 1): nts.__copy__() for i in range( round( np.random.beta(2, 5) * (10 if not isinstance(max_inputs, int) else max_inputs - 1))) }, { IOLabel.PERCEPTRON_OUT: out_nts }, { cls.get_in_label(0): label }) break
def min_transform(cls, nts): if nts.dtype not in cls.allowedTypes: return None s = Shape() result = TypeShape(nts.dtype, s) for _dim in nts.shape.dim: if _dim.name == DimNames.BATCH: s.dim.append(Shape.Dim(_dim.name, _dim.size)) elif _dim.name == DimNames.CHANNEL: s.dim.append( Shape.Dim(_dim.name, int(math.floor(_dim.size * cls.__min_f_c)))) elif _dim.name == DimNames.WIDTH or \ _dim.name == DimNames.HEIGHT: s.dim.append( Shape.Dim(_dim.name, int(math.floor(_dim.size * cls.__min_f_hw)))) else: return None return result
def test_as_dict(self): shape0 = Shape((DimNames.BATCH, 16), (DimNames.CHANNEL, 3), (DimNames.HEIGHT, 48), (DimNames.WIDTH, 32), (DimNames.UNITS, 10), (DimNames.TIME, 13)) ref = { DimNames.BATCH: 16, DimNames.CHANNEL: 3, DimNames.HEIGHT: 48, DimNames.WIDTH: 32, DimNames.UNITS: 10, DimNames.TIME: 13 } self.assertDictEqual(shape0.as_dict, ref) self.assertDictEqual(ref, shape0.as_dict)
def possible_output_shapes(cls, input_ntss: Dict[str, TypeShape], target_output: TypeShape, is_reachable, max_possibilities: int = 20, **kwargs) -> \ List[Tuple[Dict[str, TypeShape], Dict[str, TypeShape], Dict[str, str]]]: def valid_config(h_i, h_o, w_i, w_o): def stride_range(in_, out_): if out_ == 1: return [in_] else: lower_limit = math.ceil(in_ / out_) upper_limit = math.ceil(in_ / (out_ - 1)) - 1 if lower_limit == 0 or \ math.ceil(in_ / lower_limit) < out_ or \ upper_limit == 0 or \ math.ceil(in_ / upper_limit) > out_: return [] return list(range(lower_limit, upper_limit + 1)) def filter_range(in_, out_): lower_limit = 1 upper_limit = in_ - out_ + 1 return list(range(lower_limit, upper_limit + 1)) for s_h in stride_range(h_i, h_o): for s_w in stride_range(w_i, w_o): if s_h != s_w: continue return True for k_w in filter_range(w_i, w_o): for k_h in filter_range(h_i, h_o): if k_w != k_h: continue for s_h in stride_range(h_i - k_h + 1, h_o): for s_w in stride_range(w_i - k_w + 1, w_o): if s_h != s_w: continue return True return False target_shape = target_output.shape for label, nts in input_ntss.items(): _prev = time.time() if nts.dtype not in cls.allowedTypes: continue possible_sizes = [] names = [] invalid_dim = False for _dim in nts.shape.dim: target_size = target_shape[_dim.name] if _dim.name == DimNames.WIDTH or \ _dim.name == DimNames.HEIGHT: lower_border = max(math.floor(_dim.size * cls.__min_f_hw), (min(2, target_size) if target_size is not None else 2)) upper_border = math.ceil(_dim.size * cls.__max_f_hw) pool = list(range(lower_border + 1, upper_border)) border_pool = list({lower_border, upper_border}) if target_size is None or not (lower_border < target_size < upper_border): pool = sample( pool, k=min(max(max_possibilities - len(border_pool), 0), len(pool))) else: pool.remove(target_size) pool = sample( pool, k=min( max(max_possibilities - len(border_pool) - 1, 0), len(pool))) + [target_size] pool = pool + border_pool elif _dim.name == DimNames.CHANNEL: lower_border = max(math.floor(_dim.size * cls.__min_f_c), (min(2, target_size) if target_size is not None else 2)) upper_border = math.ceil(_dim.size * cls.__max_f_c) pool = list(range(lower_border + 1, upper_border)) border_pool = list({lower_border, upper_border}) if target_size is None or not (lower_border < target_size < upper_border): pool = sample( pool, k=min(max(max_possibilities - len(border_pool), 0), len(pool))) else: pool.remove(target_size) pool = sample( pool, k=min( max(max_possibilities - len(border_pool) - 1, 0), len(pool))) + [target_size] pool = pool + border_pool elif _dim.name == DimNames.BATCH: pool = [_dim.size] else: invalid_dim = True break possible_sizes.append(pool) names.append(_dim.name) if invalid_dim: continue in_w, in_h = nts.shape[DimNames.WIDTH], nts.shape[DimNames.HEIGHT] for comb in Shape.random_dimension_product(possible_sizes): out_nts = TypeShape(nts.dtype, Shape(*zip(names, comb))) out_w, out_h = out_nts.shape[DimNames.WIDTH], out_nts.shape[ DimNames.HEIGHT] if valid_config(in_h, out_h, in_w, out_w) and is_reachable( out_nts, target_output): yield ({}, { IOLabel.CONV2D_OUT: out_nts }, { IOLabel.CONV2D_IN: label })