-
Notifications
You must be signed in to change notification settings - Fork 81
/
damage_inference.py
155 lines (122 loc) · 6.41 KB
/
damage_inference.py
1
2
3
4
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#####################################################################################################################################################################
# xView2 #
# Copyright 2019 Carnegie Mellon University. #
# NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO #
# WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, #
# EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, #
# TRADEMARK, OR COPYRIGHT INFRINGEMENT. #
# Released under a MIT (SEI)-style license, please see LICENSE.md or contact permission@sei.cmu.edu for full terms. #
# [DISTRIBUTION STATEMENT A] This material has been approved for public release and unlimited distribution. Please see Copyright notice for non-US Government use #
# and distribution. #
# This Software includes and/or makes use of the following Third-Party Software subject to its own license: #
# 1. SpaceNet (https://github.com/motokimura/spacenet_building_detection/blob/master/LICENSE) Copyright 2017 Motoki Kimura. #
# DM19-0988 #
#####################################################################################################################################################################
from PIL import Image
import time
import numpy as np
import pandas as pd
from tqdm import tqdm
import os
import math
import random
import argparse
import logging
import json
from sys import exit
import cv2
import datetime
import shapely.wkt
import shapely
from shapely.geometry import Polygon
from collections import defaultdict
import tensorflow as tf
import keras
from model import *
from keras import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense
from model import *
# Configurations
NUM_WORKERS = 4
NUM_CLASSES = 4
BATCH_SIZE = 64
NUM_EPOCHS = 120
LEARNING_RATE = 0.0001
RANDOM_SEED = 123
LOG_DIR = '/tmp/inference/classification_log_' + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
damage_intensity_encoding = dict()
damage_intensity_encoding[3] = 'destroyed'
damage_intensity_encoding[2] = 'major-damage'
damage_intensity_encoding[1] = 'minor-damage'
damage_intensity_encoding[0] = 'no-damage'
###
# Creates data generator for validation set
###
def create_generator(test_df, test_dir, output_json_path):
gen = keras.preprocessing.image.ImageDataGenerator(
rescale=1.4)
try:
gen_flow = gen.flow_from_dataframe(dataframe=test_df,
directory=test_dir,
x_col='uuid',
batch_size=BATCH_SIZE,
shuffle=False,
seed=RANDOM_SEED,
class_mode=None,
target_size=(128, 128))
except:
# No polys detected so write out a blank json
blank = {}
with open(output_json_path , 'w') as outfile:
json.dump(blank, outfile)
exit(0)
return gen_flow
# Runs inference on given test data and pretrained model
def run_inference(test_data, test_csv, model_weights, output_json_path):
model = generate_xBD_baseline_model()
model.load_weights(model_weights)
adam = keras.optimizers.Adam(lr=LEARNING_RATE,
beta_1=0.9,
beta_2=0.999,
epsilon=None,
decay=0.0,
amsgrad=False)
model.compile(loss=ordinal_loss, optimizer=adam, metrics=['accuracy'])
df = pd.read_csv(test_csv)
test_gen = create_generator(df, test_data, output_json_path)
test_gen.reset()
samples = df["uuid"].count()
steps = np.ceil(samples/BATCH_SIZE)
tensorboard_callbacks = keras.callbacks.TensorBoard(log_dir=LOG_DIR, histogram_freq=1)
predictions = model.predict_generator(generator=test_gen,
callbacks=[tensorboard_callbacks],
verbose=1)
predicted_indices = np.argmax(predictions, axis=1)
predictions_json = dict()
for i in range(samples):
filename_raw = test_gen.filenames[i]
filename = filename_raw.split(".")[0]
predictions_json[filename] = damage_intensity_encoding[predicted_indices[i]]
with open(output_json_path , 'w') as outfile:
json.dump(predictions_json, outfile)
def main():
parser = argparse.ArgumentParser(description='Run Building Damage Classification Training & Evaluation')
parser.add_argument('--test_data',
required=True,
metavar="/path/to/xBD_test_dir",
help="Full path to the parent dataset directory")
parser.add_argument('--test_csv',
required=True,
metavar="/path/to/xBD_test_csv",
help="Full path to the parent dataset directory")
parser.add_argument('--model_weights',
default=None,
metavar='/path/to/input_model_weights',
help="Path to input weights")
parser.add_argument('--output_json',
required=True,
metavar="/path/to/output_json")
args = parser.parse_args()
run_inference(args.test_data, args.test_csv, args.model_weights, args.output_json)
if __name__ == '__main__':
main()