Skip to content

Commit 4b97264

Browse files
committed
refactor: rename variables and classes / feat: add a FMNIST classifier
1 parent 989d075 commit 4b97264

File tree

14 files changed

+106
-107
lines changed

14 files changed

+106
-107
lines changed

DeepHyperion-FMNIST/README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# DeepHyperion-MNIST #
1+
# DeepHyperion-FMNIST #
22

33
Input test generator using illumination search algorithm
44

@@ -8,7 +8,7 @@ This tool is developed in Python on top of the DEAP evolutionary computation fra
88

99
## Dependencies ##
1010

11-
> NOTE: If you want to use DeepHyperion-MNIST easily without configuring your environment from scratch, you can also see [__Getting Started__](../documentation/getting_started.md)
11+
> NOTE: If you want to use DeepHyperion-FMNIST easily without configuring your environment from scratch, you can also see [__Getting Started__](../documentation/getting_started.md)
1212
1313
### Configuring Ubuntu ###
1414
Pull an Ubuntu Docker image, run and configure it by typing in the terminal:
@@ -29,11 +29,11 @@ apt install -y git
2929

3030
### Copy the project into the docker container ###
3131

32-
To copy DeepHyperion-MNIST inside the docker container, open another console and run:
32+
To copy DeepHyperion-FMNIST inside the docker container, open another console and run:
3333

3434
```
3535
cd <DEEP_HYPERION_HOME>
36-
docker cp DeepHyperion-MNIST/ <DOCKER_ID>:/
36+
docker cp DeepHyperion-FMNIST/ <DOCKER_ID>:/
3737
```
3838

3939
Where `<DEEP_HYPERION_HOME>` is the location in which you downloaded the artifact and `<DOCKER_ID>` is the ID of the ubuntu docker image just started.
@@ -93,7 +93,7 @@ apt install -y python3-venv
9393
Create the python virtual environment:
9494

9595
```
96-
cd /DeepHyperion-MNIST
96+
cd /DeepHyperion-FMNIST
9797
python3 -m venv .venv
9898
```
9999

@@ -134,23 +134,23 @@ apt install -y libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev g
134134
This tool has other dependencies, including `tensorflow` and `deap`, that can be installed via `pip`:
135135

136136
```
137-
cd /DeepHyperion-MNIST
137+
cd /DeepHyperion-FMNIST
138138
pip install -r requirements.txt
139139
```
140140

141141
## Usage ##
142142
### Input ###
143143

144144
* A trained model in h5 format. The default one is in the folder `models`;
145-
* A list of seeds used for the input generation. In this implementation, the seeds are indexes of elements of the MNIST dataset. The default list is in the file `bootstraps_five`;
145+
* A list of seeds used for the input generation. In this implementation, the seeds are indexes of elements of the FMNIST dataset. The default list is in the file `bootstraps_five`;
146146
* `properties.py` containing the configuration of the tool selected by the user.
147147

148148
### Run the Tool ###
149149

150150
To run the command execute:
151151

152152
```
153-
python mapelites_mnist.py
153+
python mapelites_fmnist.py
154154
```
155155

156156
### Output ###
@@ -164,7 +164,7 @@ When the run is finished, the tool produces the following outputs in the `logs`
164164

165165
### Generate Processed Data and Rescaled Maps ###
166166

167-
* [__DeepHyperion-MNIST/report_generator__](../DeepHyperion-MNIST/report_generator/README.md)
167+
* [__DeepHyperion-FMNIST/report_generator__](../DeepHyperion-FMNIST/report_generator/README.md)
168168

169169

170170
## Troubleshooting ##

DeepHyperion-FMNIST/digit_input.py renamed to DeepHyperion-FMNIST/clothes_input.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
import numpy as np
99

1010

11-
class Digit:
11+
class Clothes:
1212
COUNT = 0
1313

1414
def __init__(self, desc, label, seed):
1515
self.timestamp, self.elapsed_time = Timer.get_timestamps()
16-
self.id = Digit.COUNT
16+
self.id = Clothes.COUNT
1717
self.run = RUN
1818
self.seed = seed
1919
# TODO
@@ -24,7 +24,7 @@ def __init__(self, desc, label, seed):
2424
self.expected_label = label
2525
self.predicted_label = None
2626
self.confidence = None
27-
Digit.COUNT += 1
27+
Clothes.COUNT += 1
2828

2929
def to_dict(self):
3030
return {'id': str(self.id),
@@ -78,5 +78,5 @@ def export(self, all=False):
7878
self.save_svg(dst)
7979

8080
def clone(self):
81-
clone_digit = Digit(self.xml_desc, self.expected_label, self.seed)
82-
return clone_digit
81+
clone_clothes = Clothes(self.xml_desc, self.expected_label, self.seed)
82+
return clone_clothes

DeepHyperion-FMNIST/digit_mutator.py renamed to DeepHyperion-FMNIST/clothes_mutator.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
import keras
99

1010

11-
class DigitMutator:
11+
class ClothesMutator:
1212
# load the FMNIST dataset
1313
fmnist = keras.datasets.fashion_mnist
1414
(_, _), (x_test, _) = fmnist.load_data()
1515

16-
def __init__(self, digit):
17-
self.digit = digit
16+
def __init__(self, clothes):
17+
self.clothes = clothes
1818

1919
def mutate(self):
2020
condition = True
@@ -35,30 +35,30 @@ def mutate(self):
3535
mutation = 4
3636

3737
counter_mutations += 1
38-
mutant_vector = mutation_manager.mutate(self.digit.xml_desc, mutation, counter_mutations/20)
38+
mutant_vector = mutation_manager.mutate(self.clothes.xml_desc, mutation, counter_mutations/20)
3939
mutant_xml_desc = vectorization_tools.create_svg_xml(mutant_vector)
40-
rasterized_digit = rasterization_tools.rasterize_in_memory(mutant_xml_desc)
40+
rasterized_clothes = rasterization_tools.rasterize_in_memory(mutant_xml_desc)
4141

42-
distance_inputs = get_distance(self.digit.purified, rasterized_digit)
42+
distance_inputs = get_distance(self.clothes.purified, rasterized_clothes)
4343

4444
if (TSHD_TYPE == '0'):
4545
if distance_inputs != 0:
4646
condition = False
4747
elif (TSHD_TYPE == '1'):
48-
seed_image = DigitMutator.x_test[int(self.digit.seed)]
48+
seed_image = ClothesMutator.x_test[int(self.clothes.seed)]
4949
xml_desc = vectorization_tools.vectorize(seed_image)
5050
seed = rasterization_tools.rasterize_in_memory(xml_desc)
51-
distance_seed = get_distance(seed, rasterized_digit)
51+
distance_seed = get_distance(seed, rasterized_clothes)
5252
if distance_inputs != 0 and distance_seed <= DISTANCE and distance_seed != 0:
5353
condition = False
5454
elif (TSHD_TYPE == '2'):
55-
seed = reshape(DigitMutator.x_test[int(self.digit.seed)])
56-
distance_seed = get_distance(seed, rasterized_digit)
55+
seed = reshape(ClothesMutator.x_test[int(self.clothes.seed)])
56+
distance_seed = get_distance(seed, rasterized_clothes)
5757
if distance_inputs != 0 and distance_seed <= DISTANCE_SEED and distance_seed != 0:
5858
condition = False
5959

60-
self.digit.xml_desc = mutant_xml_desc
61-
self.digit.purified = rasterized_digit
62-
self.digit.predicted_label = None
63-
self.digit.confidence = None
60+
self.clothes.xml_desc = mutant_xml_desc
61+
self.clothes.purified = rasterized_clothes
62+
self.clothes.predicted_label = None
63+
self.clothes.confidence = None
6464

DeepHyperion-FMNIST/features.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
NAMESPACE = '{http://www.w3.org/2000/svg}'
99

1010

11-
def bitmap_count(digit, threshold):
12-
image = deepcopy(digit.purified)
11+
def bitmap_count(clothes, threshold):
12+
image = deepcopy(clothes.purified)
1313
bw = np.asarray(image)
1414
#bw = bw / 255.0
1515
count = 0
@@ -19,8 +19,8 @@ def bitmap_count(digit, threshold):
1919
return count
2020

2121

22-
def move_distance(digit):
23-
root = ET.fromstring(digit.xml_desc)
22+
def move_distance(clothes):
23+
root = ET.fromstring(clothes.xml_desc)
2424
svg_path = root.find(NAMESPACE + 'path').get('d')
2525
pattern = re.compile('([\d\.]+),([\d\.]+)\sM\s([\d\.]+),([\d\.]+)')
2626
segments = pattern.findall(svg_path)
@@ -38,10 +38,10 @@ def move_distance(digit):
3838
return 0
3939

4040

41-
def orientation_calc(digit, threshold):
41+
def orientation_calc(clothes, threshold):
4242
x = []
4343
y = []
44-
image = deepcopy(digit.purified)
44+
image = deepcopy(clothes.purified)
4545
bw = np.asarray(image)
4646
for _, ix, iy, _ in np.ndindex(bw.shape):
4747
if bw[_, ix, iy, _] > threshold:

DeepHyperion-FMNIST/individual.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import predictor
2-
from digit_mutator import DigitMutator
2+
from clothes_mutator import ClothesMutator
33

44

55
class Individual(object):
@@ -27,6 +27,6 @@ def evaluate(self):
2727
return self.ff
2828

2929
def mutate(self):
30-
DigitMutator(self.member).mutate()
30+
ClothesMutator(self.member).mutate()
3131
self.reset()
3232

DeepHyperion-FMNIST/mapelites_mnist.py renamed to DeepHyperion-FMNIST/mapelites_fmnist.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from feature_dimension import FeatureDimension
1414
from features import move_distance, bitmap_count, orientation_calc
1515
import vectorization_tools
16-
from digit_input import Digit
16+
from clothes_input import Clothes
1717
from individual import Individual
1818
from properties import NGEN, \
1919
POPSIZE, EXPECTED_LABEL, INITIALPOP, \
@@ -33,16 +33,16 @@
3333
assert (len(starting_seeds) == POPSIZE)
3434

3535

36-
def generate_digit(seed):
36+
def generate_clothes(seed):
3737
seed_image = x_test[int(seed)]
3838
xml_desc = vectorization_tools.vectorize(seed_image)
39-
return Digit(xml_desc, EXPECTED_LABEL, seed)
39+
return Clothes(xml_desc, EXPECTED_LABEL, seed)
4040

4141

42-
class MapElitesMNIST(MapElites):
42+
class MapElitesFMNIST(MapElites):
4343

4444
def __init__(self, *args, **kwargs):
45-
super(MapElitesMNIST, self).__init__(*args, **kwargs)
45+
super(MapElitesFMNIST, self).__init__(*args, **kwargs)
4646

4747
def map_x_to_b(self, x):
4848
"""
@@ -100,8 +100,8 @@ def generate_random_solution(self):
100100
seed = starting_seeds[Individual.COUNT - 1]
101101
Individual.SEEDS.add(seed)
102102

103-
digit1 = generate_digit(seed)
104-
individual = Individual(digit1, seed)
103+
clothes1 = generate_clothes(seed)
104+
individual = Individual(clothes1, seed)
105105
individual.seed = seed
106106

107107
return individual
@@ -198,15 +198,15 @@ def main():
198198
utils.setup_logging(log_to, debug)
199199
print("Logging results to " + log_to)
200200

201-
map_E = MapElitesMNIST(NGEN, POPSIZE, log_dir_name, True)
202-
MapElitesMNIST.print_config()
201+
map_E = MapElitesFMNIST(NGEN, POPSIZE, log_dir_name, True)
202+
MapElitesFMNIST.print_config()
203203
map_E.run()
204204

205205
Individual.COUNT = 0
206206

207207
print("Exporting inputs ...")
208-
for digit in Exploration.all_inputs:
209-
digit.export(all=True)
208+
for clothes in Exploration.all_inputs:
209+
clothes.export(all=True)
210210

211211
print("Done")
212212

-13.8 MB
Binary file not shown.

DeepHyperion-FMNIST/properties.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class MissingEnvironmentVariable(Exception):
88
POPSIZE = int(os.getenv('DH_POPSIZE', '800'))
99
NGEN = int(os.getenv('DH_NGEN', '500000'))
1010

11-
RUNTIME = int(os.getenv('DH_RUNTIME', '180'))
11+
RUNTIME = int(os.getenv('DH_RUNTIME', '10'))
1212
INTERVAL = int(os.getenv('DH_INTERVAL', '60'))
1313

1414
# Mutation Hyperparameters
@@ -31,8 +31,7 @@ class MissingEnvironmentVariable(Exception):
3131

3232
INITIALPOP = os.getenv('DH_INITIALPOP', 'seeded')
3333

34-
MODEL = os.getenv('DH_MODEL', 'models/model_mnist.h5')
35-
#MODEL = os.getenv('DH_MODEL', 'models/cnnClassifierTest.h5')
34+
MODEL = os.getenv('DH_MODEL', 'models/fmnist_cnn.h5')
3635

3736
ORIGINAL_SEEDS = os.getenv('DH_ORIGINAL_SEEDS', 'bootstraps_five')
3837

DeepHyperion-FMNIST/report_generator/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ and compute metrics of interests (misbehaviors, density, etc.)
99

1010
We assume to have access to the raw data about each experiment, which consists in a `timestamped` folder that
1111
contains all the individuals (e.g., `npy` vectors) generated by the test generators and possibly the outcome of the
12-
test, i.e., misclassified digits for MNIST.
12+
test, i.e., misclassified clothes for FMNIST.
1313

1414
The steps to generate the maps are:
1515

1616
1. Process the output of the tools and generate an `info_<ID>.json` file for each sample. This file contains the features, and various metadata about the sample (timestamp, sample-id, file location, tool name, run id, etc.)
1717

18-
To do it, go to the root of the project (`./DeepHyperion-MNIST`) and run the following command to process a dataset folder (folders will be recursively checked):
18+
To do it, go to the root of the project (`./DeepHyperion-FMNIST`) and run the following command to process a dataset folder (folders will be recursively checked):
1919

2020
```
2121
export LC_ALL=C.UTF-8
@@ -25,7 +25,7 @@ The steps to generate the maps are:
2525
> NOTE: the set of features to be computed is predefined for each tool.
2626
2727

28-
2. Process all the json files corresponding to the samples of all the runs for all the tools, to extract the maps `extrema` for each feature. Go to the root of the project (`./DeepHyperion-MNIST`) and run the following command:
28+
2. Process all the json files corresponding to the samples of all the runs for all the tools, to extract the maps `extrema` for each feature. Go to the root of the project (`./DeepHyperion-FMNIST`) and run the following command:
2929

3030
```
3131
python report_generator/app.py extract-stats --parsable --feature <NAME> --feature <NAME> ./logs/run_XXX/archive

DeepHyperion-FMNIST/report_generator/app.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -177,22 +177,22 @@ def generate_samples(ctx, force_attribute, filter_samples_by_tshd, asfault_n_sec
177177
178178
"""
179179

180-
# --filter-samples-by-tshd applies only to MNIST
181-
mnist_filter = None
180+
# --filter-samples-by-tshd applies only to FMNIST
181+
fmnist_filter = None
182182
if filter_samples_by_tshd[0] is not None:
183183
# Make sure the import is done only if needed, this code is problematic if the libraries are not installed
184184
if ctx.obj['show-progress']:
185185
print("Filtering samples by TSHD, %s, %s" % (filter_samples_by_tshd))
186186
from report_generator.tshd_selection import is_valid_digit
187-
# Use the is_valid_digit and the input to create a partial function to filter the mnist inputs.
187+
# Use the is_valid_digit and the input to create a partial function to filter the fmnist inputs.
188188
# the partial function accepts now only ONE input, the sample, and is configured automatically with type
189189
# and val
190190
# The lambda makes sure that we apply partial correctly
191-
mnist_filter = partial( lambda tshd_type, tshd_val, sample :
191+
fmnist_filter = partial( lambda tshd_type, tshd_val, sample :
192192
is_valid_digit(sample, tshd_type, tshd_val),
193193
str(filter_samples_by_tshd[0]), float(filter_samples_by_tshd[1]))
194194
# Make sure we record the filter setting so we can store it inside th sample file
195-
setattr(mnist_filter, "filter_name", "-".join(["tshd",
195+
setattr(fmnist_filter, "filter_name", "-".join(["tshd",
196196
str(filter_samples_by_tshd[0]), str(filter_samples_by_tshd[1])]))
197197

198198
# Setup the generation. Select the
@@ -246,10 +246,10 @@ def generate_samples(ctx, force_attribute, filter_samples_by_tshd, asfault_n_sec
246246
if cast_as == "DLFuzz":
247247
sample = DLFuzzSample(os.path.splitext(sample_file)[0])
248248
# add validity and re-dump if necessaty
249-
if mnist_filter is not None:
250-
is_valid = mnist_filter(sample)
249+
if fmnist_filter is not None:
250+
is_valid = fmnist_filter(sample)
251251
sample.is_valid = is_valid
252-
sample.valid_according_to = mnist_filter.filter_name
252+
sample.valid_according_to = fmnist_filter.filter_name
253253
# We need this because dump is done automatically in the constructor,
254254
# BEFORE we can check for validity
255255
sample.dump()
@@ -259,10 +259,10 @@ def generate_samples(ctx, force_attribute, filter_samples_by_tshd, asfault_n_sec
259259
elif cast_as == "DeepJanus":
260260
sample = DeepJanusSample(os.path.splitext(sample_file)[0])
261261
# add validity and re-dump if necessaty
262-
if mnist_filter is not None:
263-
is_valid = mnist_filter(sample)
262+
if fmnist_filter is not None:
263+
is_valid = fmnist_filter(sample)
264264
sample.is_valid = is_valid
265-
sample.valid_according_to = mnist_filter.filter_name
265+
sample.valid_according_to = fmnist_filter.filter_name
266266
# We need this because dump is done automatically in the constructor,
267267
# BEFORE we can check for validity
268268
sample.dump()
@@ -271,10 +271,10 @@ def generate_samples(ctx, force_attribute, filter_samples_by_tshd, asfault_n_sec
271271
elif cast_as == "DeepHyperion":
272272
sample = DeepHyperionSample(os.path.splitext(sample_file)[0])
273273
# add validity and re-dump if necessaty
274-
if mnist_filter is not None:
275-
is_valid = mnist_filter(sample)
274+
if fmnist_filter is not None:
275+
is_valid = fmnist_filter(sample)
276276
sample.is_valid = is_valid
277-
sample.valid_according_to = mnist_filter.filter_name
277+
sample.valid_according_to = fmnist_filter.filter_name
278278
# We need this because dump is done automatically in the constructor,
279279
# BEFORE we can check for validity
280280
sample.dump()
@@ -320,7 +320,7 @@ def extract_stats(ctx, report_missing_features, parsable, feature, dataset_folde
320320
feature: the list of name of the features to consider during the analysis
321321
322322
dataset_folder: this is the root folder that contains all the results (i.e., samples as json) from all the
323-
tools considered in one analysis (e.g., MNIST, BeamNG)
323+
tools considered in one analysis (e.g., FMNIST, BeamNG)
324324
325325
parsable: a flag to generate an easy to parse data
326326

0 commit comments

Comments
 (0)