Newer
Older
import autoaug.child_networks as cn
from autoaug.autoaugment_learners.AaLearner import AaLearner
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import random
class Genetic_learner(AaLearner):
def __init__(self,
# search space settings
sp_num=5,
p_bins=11,
m_bins=10,
discrete_p_m=False,
exclude_method=[],
# child network settings
learning_rate=1e-1,
max_epochs=float('inf'),
early_stop_num=20,
batch_size=8,
toy_size=1,
num_offspring=1,
):
super().__init__(
sp_num=sp_num,
p_bins=p_bins,
m_bins=m_bins,
discrete_p_m=discrete_p_m,
batch_size=batch_size,
toy_size=toy_size,
learning_rate=learning_rate,
max_epochs=max_epochs,
early_stop_num=early_stop_num,
exclude_method=exclude_method
)
self.bin_to_aug = {}
for idx, augmentation in enumerate(self.augmentation_space):
bin_rep = '{0:b}'.format(idx)
while len(bin_rep) < len('{0:b}'.format(len(self.augmentation_space))):
bin_rep = '0' + bin_rep
self.bin_to_aug[bin_rep] = augmentation[0]
self.just_augs = [x[0] for x in self.augmentation_space]
self.mag_to_bin = {
'0': "0000",
'1': '0001',
'2': '0010',
'3': '0011',
'4': '0100',
'5': '0101',
'6': '0110',
'7': '0111',
'8' : '1000',
'9': '1001',
'10': '1010',
}
self.prob_to_bin = {
'0': "0000",
'0.0' : '0000',
'0.1': '0001',
'0.2': '0010',
'0.3': '0011',
'0.4': '0100',
'0.5': '0101',
'0.6': '0110',
'0.7': '0111',
'0.8' : '1000',
'0.9': '1001',
'1.0': '1010',
'1' : '1010',
}
self.bin_to_prob = dict((value, key) for key, value in self.prob_to_bin.items())
self.bin_to_mag = dict((value, key) for key, value in self.mag_to_bin.items())
self.aug_to_bin = dict((value, key) for key, value in self.bin_to_aug.items())
self.num_offspring = num_offspring
"""
Generates a random subpolicy using the reduced augmentation_space
Returns
--------
subpolicy -> ((transformation, probability, magnitude), (trans., prob., mag.))
"""
choose_items = [x[0] for x in self.augmentation_space]
trans1 = str(random.choice(choose_items))
trans2 = str(random.choice(choose_items))
prob1 = float(random.randrange(0, 11, 1) / 10)
prob2 = float(random.randrange(0, 11, 1) / 10)
if self.aug_space_dict[trans1]:
mag1 = int(random.randrange(0, 10, 1))
else:
mag1 = None
if self.aug_space_dict[trans2]:
mag2 = int(random.randrange(0, 10, 1))
else:
mag2 = None
subpol = ((trans1, prob1, mag1), (trans2, prob2, mag2))
return subpol
"""
Generates a random policy, consisting of sp_num subpolicies
Returns
------------
policy -> [subpolicy, subpolicy, ...]
"""
pol = []
for _ in range(self.sp_num):
pol.append(self.gen_random_subpol())
return pol
"""
Converts a binary string representation of a subpolicy to a subpolicy
Parameters
------------
subpol_bin -> str
Binary representation of a subpolicy
Returns
-----------
policy -> [(subpolicy)]
"""
if subpol_bin[idx*12:(idx*12)+4] in self.bin_to_aug:
trans = self.bin_to_aug[subpol_bin[idx*12:(idx*12)+4]]
else:
trans = random.choice(self.just_augs)
mag_is_none = not self.aug_space_dict[trans]
if subpol_bin[(idx*12)+4: (idx*12)+8] in self.bin_to_prob:
prob = float(self.bin_to_prob[subpol_bin[(idx*12)+4: (idx*12)+8]])
else:
prob = float(random.randrange(0, 11, 1) / 10)
if subpol_bin[(idx*12)+8:(idx*12)+12] in self.bin_to_mag:
mag = int(self.bin_to_mag[subpol_bin[(idx*12)+8:(idx*12)+12]])
else:
mag = int(random.randrange(0, 10, 1))
if mag_is_none:
mag = None
pol.append((trans, prob, mag))
pol = [tuple(pol)]
return pol
"""
Converts a subpolicy to its binary representation
Parameters
------------
subpol -> ((transforamtion, probability, magnitude), (trans., prob., mag.))
Returns
------------
bin_pol -> str
Binary representation of the subpolicy
"""
bin_pol = ''
trans1, prob1, mag1 = subpol[0]
trans2, prob2, mag2 = subpol[1]
bin_pol += self.aug_to_bin[trans1] + self.prob_to_bin[str(prob1)]
bin_pol += self.aug_to_bin[trans2] + self.prob_to_bin[str(prob2)]
def _choose_parents(self, parents, parents_weights):
"""
Chooses parents from which the next policy will be generated from
Parameters
------------
parents -> [policy, policy, ...]
parents_weights -> [float, float, ...]
Returns
------------
(parent1, parent2) -> (policy, policy)
"""
parent1 = random.choices(parents, parents_weights, k=1)[0][0]
parent2 = random.choices(parents, parents_weights, k=1)[0][0]
while parent2 == parent1:
parent2 = random.choices(parents, parents_weights, k=1)[0][0]
parent1 = self.subpol_to_bin(parent1)
parent2 = self.subpol_to_bin(parent2)
return (parent1, parent2)
"""
Generates children via the random crossover method
Returns
------------
new_pols -> [child_policy, child_policy, ...]
"""
parent_acc = sorted(self.history, key = lambda x: x[1], reverse=True)
parents = [x[0] for x in parent_acc]
parents_weights = [x[1] for x in parent_acc]
new_pols = []
for _ in range(self.num_offspring):
parent1, parent2 = self.choose_parents(parents, parents_weights)
cross_over = random.randrange(1, int(len(parent2)/2), 1)
cross_over2 = random.randrange(int(len(parent2)/2), int(len(parent2)), 1)
child += parent2[cross_over:int(len(parent2)/2)]
child += parent1[int(len(parent2)/2):int(len(parent2)/2)+cross_over2]
child += parent2[int(len(parent2)/2)+cross_over2:]
def learn(self, train_dataset, test_dataset, child_network_architecture, iterations = 100):
"""
Generates policies through a genetic algorithm.
Parameters
------------
train_dataset -> torchvision.dataset
test_dataset -> torchvision.dataset
child_network_architecture ->
iterations -> int
number of iterations to run the instance for
"""
policy = [self.gen_random_subpol()]
else:
policy = self.bin_to_subpol(random.choice(self.generate_children()))
reward = self._test_autoaugment_policy(policy,
child_network_architecture,
train_dataset,
test_dataset)