Skip to content

Commit c24636d

Browse files
authored
Update ExtractDeepLearningInfoInLogFile.py
v1.10
1 parent f48699f commit c24636d

1 file changed

Lines changed: 102 additions & 38 deletions

File tree

Utilities/ExtractDeepLearningInfoInLogFile.py

Lines changed: 102 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import ctypes
44
import sys
55
from pathlib import Path
6+
67
parentFolder = str(Path(__file__).parent.parent)
78
activate_path = parentFolder + '\\env\\Scripts\\activate_this.py'
9+
810
if os.path.exists(activate_path):
911
exec(open(activate_path).read(), {'__file__': activate_path})
1012
print(f'Aivia virtual environment activated\nUsing python: {activate_path}')
@@ -21,7 +23,9 @@
2123

2224
import wx
2325
import matplotlib.pyplot as plt
26+
from matplotlib.widgets import RadioButtons
2427
import re
28+
import concurrent.futures
2529

2630
"""
2731
Extracts Deep Learning training info (epochs with their relative loss and validation loss values)
@@ -33,7 +37,7 @@
3337
scikit-image
3438
matplotlib
3539
re
36-
wxpython or pyside2 (needed for UI created by matplotlib)
40+
wxpython
3741
3842
Parameters
3943
----------
@@ -49,13 +53,19 @@
4953
"""
5054

5155

52-
def run():
56+
# [INPUT Name:inputPath Type:string DisplayName:'Any channel']
57+
# [OUTPUT Name:resultPath Type:string DisplayName:'Dummy to delete']
58+
def run(params):
5359
print("Running")
5460
# Setting colors for chart
5561
col1 = 'royalblue'
5662
col2 = 'r'
5763

64+
# GUI to select a log file
65+
print('Starting wxPython app')
66+
app = wx.App()
5867
logfile = pick_file()
68+
print('-- Selected file: {}--'.format(logfile))
5969

6070
# Check if log file is from local Aivia or Google Cloud Platform
6171
is_local = True
@@ -64,54 +74,107 @@ def run():
6474

6575
file = open(logfile, "r+")
6676
all_lines = file.read()
77+
list_n_epoch, list_i_epoch = [], []
6778
if is_local:
68-
(n_epoch, i_epoch) = extract_data(all_lines)
79+
print('-- Extracting local DL data --')
80+
indiv_data_blocks = extract_DL_runs(all_lines)
81+
82+
for data in indiv_data_blocks:
83+
list_n_epoch_tmp, list_i_epoch_tmp = extract_data(data)
84+
list_n_epoch.append(list_n_epoch_tmp)
85+
list_i_epoch.append(list_i_epoch_tmp)
86+
6987
else:
70-
(n_epoch, i_epoch) = extract_data_GCP(all_lines)
88+
print('-- Extracting Google Cloud DL data --')
89+
# (n_epoch, i_epoch) = extract_data_GCP(all_lines) # TODO: now n_epoch is a list of lists
7190

7291
# If nothing found, exit
73-
if n_epoch == 0:
74-
Mbox('No info found', 'No Deep Learning training info found in this log.', 0)
92+
if list_n_epoch is None:
93+
concurrent.futures.ThreadPoolExecutor().submit(Mbox, 'No info found',
94+
'No Deep Learning training info found in this log.', 0)
7595
sys.exit("No Deep Learning training info found in this log.")
7696

77-
n_epoch = list(map(int, n_epoch))
78-
79-
# extracting values from individual info
80-
if is_local:
81-
(all_v1, all_v2) = extract_epoch_val('\n'.join(i_epoch)+'\n')
82-
else:
83-
(all_v1, all_v2) = extract_epoch_val_GCP('\n'.join(i_epoch) + '\n')
84-
all_v1 = list(map(float, all_v1))
85-
all_v2 = list(map(float, all_v2))
86-
87-
ymax1 = max(all_v1) * 1.1
88-
ymax2 = max(all_v2) * 1.1
97+
print('-- Found {} DL training blocks --'.format(len(list_n_epoch)))
8998

90-
fig = plt.figure(figsize=plt.figaspect(0.5))
99+
# Init chart
100+
fig = plt.figure(figsize=plt.figaspect(0.4))
91101
ax1 = fig.add_subplot(111)
92102
ax1.set_xlabel('epochs')
93103
ax1.set_ylabel('loss', color=col1)
94104
ax1.tick_params(axis='y', labelcolor=col1)
95-
ax1.set_ylim(0, ymax1)
96-
# ax1.yaxis.set_major_locator(ticker.MultipleLocator(0.1))
97105

98106
# Create second axis
99107
ax2 = ax1.twinx()
100108
ax2.set_ylabel('validation_loss', color=col2)
101109
ax2.tick_params(axis='y', labelcolor=col2)
102-
ax2.set_ylim(0, ymax2)
103-
# ax2.yaxis.set_major_locator(ticker.MultipleLocator(1))
104110

105-
# Plot values
106-
all_v1_nonsci = [float('{:.4f}'.format(v)) for v in all_v1] # Remove scientific notation for loss value
107-
ax1.plot(n_epoch, all_v1_nonsci, color=col1, linewidth=1)
108-
ax2.plot(n_epoch, all_v2, color=col2, linewidth=1)
111+
# Create buttons to switch to another DL run
112+
# sub-plot for radio button with
113+
# left, bottom, width, height values
114+
plt.subplots_adjust(right=0.7)
115+
rax = plt.axes([0.8, 0.1, 0.16, 0.8])
116+
radio_button = RadioButtons(rax, tuple(['DL training no {}'.format(x) for x in range(1, len(list_n_epoch) + 1)]),
117+
active=len(list_n_epoch) - 1)
118+
119+
def get_values(run_index):
120+
run_index -= 1
121+
n_epoch = list(map(int, list_n_epoch[run_index]))
122+
i_epoch = list_i_epoch[run_index]
123+
124+
# extracting values from individual info
125+
if is_local:
126+
(all_v1, all_v2) = extract_epoch_val('\n'.join(i_epoch) + '\n')
127+
else:
128+
(all_v1, all_v2) = extract_epoch_val_GCP('\n'.join(i_epoch) + '\n')
129+
all_v1 = list(map(float, all_v1))
130+
all_v2 = list(map(float, all_v2))
131+
132+
all_v1_nonsci = [float('{:.4f}'.format(v)) for v in all_v1] # Remove scientific notation for loss value
133+
134+
ymax1 = max(all_v1) * 1.1
135+
ymax2 = max(all_v2) * 1.1
136+
137+
return n_epoch, all_v1_nonsci, all_v2, ymax1, ymax2
138+
139+
# Define function for the radio buttons
140+
def change_DL_run(label):
141+
run_no = int(str(label).split('no ')[-1])
142+
n_epoch, all_v1_nonsci, all_v2, ymax1, ymax2 = get_values(run_no)
143+
print('Selected DL run: {}'.format(run_no))
144+
145+
# Clear values
146+
ax1.cla()
147+
ax2.cla()
148+
149+
# Plot values
150+
ax1.plot(n_epoch, all_v1_nonsci, color=col1, linewidth=1)
151+
ax2.plot(n_epoch, all_v2, color=col2, linewidth=1)
152+
153+
ax1.set_ylim(0, ymax1)
154+
ax2.set_ylim(0, ymax2)
155+
156+
plt.draw() # Update plot
157+
158+
radio_button.on_clicked(change_DL_run)
159+
160+
# Process the last DL run
161+
run_index = len(list_n_epoch)
162+
change_DL_run(run_index)
109163

110164
plt.show()
111165

112166

113-
def extract_data(s): # TODO
114-
# The following regex is for the Worklog from the GCP - from restoration model (see PSNR)
167+
def extract_DL_runs(s):
168+
# To detect and extract all DL runs in the same log
169+
start_pattern = re.compile(r"(.+DeepLearning:Epoch\s+1/\d+.+\n)")
170+
str_split = start_pattern.split(s)
171+
blocks = [a + b for a, b in zip(str_split[1::2], str_split[2::2])]
172+
173+
return blocks
174+
175+
176+
def extract_data(s): # TODO
177+
# The following regex is for the log from Aivia - from restoration model (see PSNR)
115178
pattern = re.compile(r""".+DeepLearning:Epoch\s?(?P<epoch>\d*)\/(?P<totalEpochs>\d+) # First line
116179
\n(.*\n){0,20} # followed by several info lines
117180
(.*DeepLearning:.*\n){2,258} # lines for iterations
@@ -128,7 +191,7 @@ def extract_data(s): # TODO
128191
return n_epoc, i_epoc
129192

130193

131-
def extract_epoch_val(s): # TODO
194+
def extract_epoch_val(s): # TODO
132195
# The following regex is for the Worklog from Aivia - from restoration model (see PSNR)
133196
in_pattern = re.compile(r""".*\sloss:\s(?P<vloss>\d+\.?\d*e?-?\d*)
134197
\s.*-\sval_loss:\s(?P<vdloss>\d+\.?\d*e?-?\d*)
@@ -174,15 +237,12 @@ def extract_epoch_val_GCP(s):
174237

175238

176239
def pick_file():
177-
print('Starting wxPython app')
178-
app = wx.App()
179-
frame = wx.Frame(None, -1, 'File picker')
180-
181240
# Create open file dialog
182-
openFileDialog = wx.FileDialog(frame, "Select a log file to process", ".\\", "",
241+
openFileDialog = wx.FileDialog(None, "Select a log file to process", ".\\", "",
183242
"Log files (*.log)|*.log", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
184243

185-
openFileDialog.ShowModal()
244+
if openFileDialog.ShowModal() == wx.ID_CANCEL:
245+
sys.exit()
186246
fname = openFileDialog.GetPath()
187247
print("Selected file: ", fname)
188248
openFileDialog.Destroy()
@@ -192,8 +252,12 @@ def pick_file():
192252
def Mbox(title, text, style):
193253
return ctypes.windll.user32.MessageBoxW(0, text, title, style)
194254

195-
196-
run()
255+
if __name__ == '__main__':
256+
params = {}
257+
run(params)
197258
# image_location = params['inputImagePath']
198259
# result_location = params['resultPath']
199260
# imsave(result_location, output_data)
261+
262+
# Changelog:
263+
# v1.10: - Bug fixed with wxPython app not being run in v1.00

0 commit comments

Comments
 (0)