diff --git a/Application/learn_static.py b/Application/learn_static.py index 6e25bc9eb6f1eb7f0f46a458374f91c2be418d62..dbadc254ce4d2864616dbb0f12963dece7e39e5e 100644 --- a/Application/learn_static.py +++ b/Application/learn_static.py @@ -4,9 +4,6 @@ #except: # pass -import matplotlib -matplotlib.use("Agg") - from keras.layers import Dense, Dropout, Activation, Cropping2D, Flatten, Convolution1D, Convolution2D, MaxPooling1D,MaxPooling2D from keras.models import Sequential import keras @@ -16,7 +13,6 @@ from keras.preprocessing.image import ImageDataGenerator from keras.utils import np_utils import TRex import utils -import matplotlib.pyplot as plt import shutil @@ -163,31 +159,6 @@ def reinitialize_network(): metrics=['accuracy']) model.summary(print_fn=TRex.log) - -def plot_medians(title, train_X, train_Y, classes): - lengths = {} - f, axes = utils.axes_for_array(len(classes)) - for ax, c in zip(axes, classes): - index = train_Y == c - ax.set_title(str(c)+": "+str(len(train_X[index]))) - lengths[c] = len(train_X[index]) - - subdata = np.copy(train_X[index]) - - if len(subdata) == 0: - #TRex.log("skipping class "+str(c)+" because its empty") - continue - - img = np.max(subdata.astype(float), axis=0)[:,:,0] - img = np.stack((img, )*3, axis=2).astype(np.uint8) - ax.imshow(img) - - del subdata - - TRex.log("#samples per class: "+str(lengths)) - #TRex.imshow(title, utils.figure_as_image()) - #utils.show_figure(title, output_path="") - class UserCancelException(Exception): """Raised when user clicks cancel""" pass @@ -249,105 +220,11 @@ class ValidationCallback(keras.callbacks.Callback): distance = np.abs(Y - zeros).sum(axis=1) - if do_plot: - f, [ax, bx] = plt.subplots(1, 2, figsize=(15, 5)) - ax.scatter(np.arange(len(distance)), distance, label="d", s = 1, c = np.ones(len(distance)), alpha = 0.5) - pts = np.argmax(Y, axis=1) - color = Y.sum(axis=1) - - for j in range(len(color)): - color[j] = color[j] * len(Y[j][Y[j] > 0.01])# / len(obj.classes) - - pts = np.concatenate((pts, [0, ]), axis=0) - color = np.concatenate((color, [10, ]), axis=0) - - im = bx.scatter(np.arange(len(pts)), pts, label="Y", s = 1, c = color, alpha = 0.5) - bx.set_yticks(np.arange(len(obj.classes_subset))) - bx.set_ylim(-1, len(obj.classes_subset)) - #TRex.log(color.max(), color.min()) - plt.colorbar(im) - plt.suptitle(c) - ax.legend() - bx.legend() - plt.show() - plt.close(f) - result[i, 0] = np.median(np.argmax(Y, axis=1)) result[i, 1] = distance.std() result[i, 2] = np.median(Y.sum(axis=1)) #distance.mean() result[i, 3] = (np.argmax(Y, axis=1) == i).sum() / len(Y) return result, predictions - - def plot_confusion_matrix(self, cm, classes, - normalize, - title, - cmap, ax = None): - """ - This function prints and plots the confusion matrix. - Normalization can be applied by setting `normalize=True`. - """ - do_show = False - - if normalize: - cm = cm.astype('float') / (1+cm.sum(axis=1)[:, np.newaxis]) - - if ax == None: - f, ax = plt.subplots(1,1) - do_show = True - - im = ax.imshow(cm, interpolation='nearest', cmap=cmap) - ax.set_title(title) - cbar = plt.colorbar(im, ax = ax) - cbar_ticks = np.linspace(0., 1., num=10, endpoint=True) - cbar.set_ticks(cbar_ticks) - - tick_marks = np.arange(len(classes)) - ax.set_xticks(tick_marks) - ax.set_xticklabels([str(c) for c in classes]) - ax.set_yticks(tick_marks) - ax.set_yticklabels([str(c) for c in classes]) - - fmt = '.2f' if normalize else 'd' - thresh = cm.max() / 2. - - ax.set_ylabel('True label') - ax.set_xlabel('Predicted label') - - #if do_show: - # utils.show_figure("confusion matrix", output_path="") - #plt.tight_layout() - - def plot_confusion(self, X_test, Y_test, predictions = None, title = "", ax = None, cmap = None): - classes = self.classes - #TRex.log("shapes:", X_test.shape, Y_test.shape) - - y = None - if type(predictions) == type(None): - y = self.model.predict(X_test) - else: - y = np.concatenate(predictions, axis=0) - assert len(y) == len(X_test) - - result = np.zeros_like(np.ndarray(shape=(len(classes),len(classes))), dtype=float) - - wrong = 0 - correct = 0 - - for i in range(len(X_test)): - a = np.argmax(y[i,0:len(classes)]) - b = np.argmax(Y_test[i,0:len(classes)]) - - if a == b: - correct = correct+1 - else: - wrong = wrong + 1 - - result[a, b] = result[a, b] + 1 - #result_x.append(a) - #result_y.append(b) - - title = title + " (accuracy "+str(1-wrong/float(correct+wrong))+")" - self.plot_confusion_matrix(result, [str(classes[i]) for i in classes], normalize=True, title = title, ax = ax, cmap=cmap) def update_status(self, print_out = False, logs = {}): description = "epoch "+str(min(self.epoch+1, self.epochs))+"/"+str(self.epochs) @@ -375,29 +252,11 @@ class ValidationCallback(keras.callbacks.Callback): update_work_percent(min(epoch + 1, self.epochs) / self.epochs) - #fig = plt.figure(figsize=(25,10)) - #gs = fig.add_gridspec(2,2, width_ratios=[1,3]) - #ax = fig.add_subplot(gs[0,0]) - #dx = fig.add_subplot(gs[0,1]) - #bx = fig.add_subplot(gs[1,:]) - self.epoch = min(epoch + 1, self.epochs) if np.shape(self.X_test)[-1] > 0: result, predictions = self.plot_comparison_raw(do_plot = False, length = -1) - #dx.plot(np.arange(len(result)), result[:, 3], label="% correct") - #dx.scatter(np.arange(len(result)), result[:, 3]) - #for i in np.arange(len(result)): - # dx.annotate(str(classes[i])+": "+str(int(result[:, 3][i]*100))+"%", (i + 0.01, result[:, 3][i] + 0.01)) - #dx.set_ylim(0, 1) - #dx.set_xticks(np.arange(len(result))) - #dx.set_xticklabels([str(classes[i]) for i in classes]) - #plt.title("epoch "+str(epoch)+" range "+str(np.array(self.settings["global_segment"]))) - #utils.show_figure("classes recognition") - - #self.plot_confusion(np.concatenate(self.X_test, axis=0), np.concatenate(self.Y_test, axis=0), predictions = predictions, ax = ax) - for i in range(0, len(result[:, 3])): if not i in self.per_class_accuracy: self.per_class_accuracy[i] = [] @@ -406,12 +265,6 @@ class ValidationCallback(keras.callbacks.Callback): self.worst_values.append(np.min(result[:, 3])) set_per_class_accuracy(result[:, 3].astype(np.float)) - - #bx.fill_between(np.arange(len(self.worst_values)), self.worst_values, self.mean_values, where=np.array(self.worst_values) <= np.array(self.mean_values), facecolor="red", interpolate = True, alpha= 0.25) - - #bx.plot(np.arange(len(self.worst_values)), self.worst_values, label="min", color="blue") - #bx.plot(np.arange(len(self.mean_values)), self.mean_values, label="mean") - worst_acc_per_class = np.min(result[:, 3]) else: result = None @@ -424,7 +277,6 @@ class ValidationCallback(keras.callbacks.Callback): self.uniquenesses.append(unique) set_uniqueness_history(self.uniquenesses) - #bx.plot(np.arange(len(self.uniquenesses)), self.uniquenesses, label="uniqueness", color="red") # check whether our worst value improved, but only use it if it wasnt the first epoch if unique > self.best_result["unique"] and (self.compare_acc <= 0 or unique >= self.compare_acc**2): @@ -540,36 +392,7 @@ class ValidationCallback(keras.callbacks.Callback): set_stop_reason("overfitting") TRex.log("[STOP]Â overfitting. stopping with loss diffs: "+str(change)) self.model.stop_training = True - - #if worst_acc_per_class >= min_acceptable_value and (worst_acc_per_class >= 0.99 or (len(self.worst_values) >= min_number_iterations and self.worst_values[-1] >= min_acceptable_value)): - # TRex.log("[STOP] stopping training with minimum validation accuracy of "+str(worst_acc_per_class)+" per class") - # self.model.stop_training = True -#else: -# TRex.log("\tcontinuing with worst accuracy of "+str(worst_value)) - - #if len(self.better_values) > 0: - # bx.scatter(np.array(self.better_values).T[0], np.array(self.better_values).T[1], label="improvements", color="red") - # for i,j in zip(np.array(self.better_values).T[0], np.array(self.better_values).T[1]): - # bx.annotate(str(int(j * 1000) / 10.0)+"%",xy=(i,j), xytext=(1,5), textcoords='offset points') - #if len(self.much_better_values) > 0: - # bx.scatter(np.array(self.much_better_values).T[0], np.array(self.much_better_values).T[1], label="eligble", color="green") - - #if self.compare_acc > 0: - # bx.axhline(y=self.compare_acc, label="previous best", color="gray", linestyle="--") - # bx.axhline(y=self.compare_acc**2, label="previous accept.", color="gray", linestyle="--") - #bx.set_ylim(-0.05, 1.05) - - #if len(self.uniquenesses) < 20: - # bx.set_xticks(np.arange(len(self.uniquenesses))) - #else: - # bx.set_xticks(np.arange(len(self.uniquenesses), 5)) - #bx.set_xlabel("epochs") - #bx.set_ylabel("accuracy") - #plt.legend() - #plt.close(plt.gcf()) - #im = utils.figure_as_image() - #TRex.imshow("training overview", im) - #utils.show_figure(self.filename + self.prefix + " " + str(epoch) + " training overview", output_path=self.settings["output_path"], im = im) + self.update_status(True, logs=logs) self.batches = 0 return unique @@ -675,7 +498,6 @@ def start_learning(): for i, c in zip(np.arange(len(classes)), classes): mi = max(mi, len(Y_train[np.argmax(Y_train, axis=1) == c])) - plot_medians(filename + output_prefix + " dataset", X_train, np.argmax(Y_train, axis=1), np.array(classes, dtype=int)) per_epoch = max(settings["min_iterations"], int(len(X_train) // batch_size ) * 0.5 ) #* 2.0) # i am using augmentation settings["per_epoch"] = per_epoch TRex.log(str(settings)) diff --git a/Application/src/tracker/CMakeLists.txt b/Application/src/tracker/CMakeLists.txt index 536c97c79f1369443f4430d3a351f90c8dcd7255..568f659d8f931da15b4f1e1f063642cf67bd9fd6 100644 --- a/Application/src/tracker/CMakeLists.txt +++ b/Application/src/tracker/CMakeLists.txt @@ -122,7 +122,6 @@ set(RESOURCE_COPY_FILES ) set(RESOURCE_COPY_SINGLE_FILES ${CMAKE_SOURCE_DIR}/default.settings - ${CMAKE_SOURCE_DIR}/utils.py ${CMAKE_SOURCE_DIR}/learn_static.py ) @@ -228,4 +227,4 @@ install(TARGETS ${targets} install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/fonts DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex) install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/html DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gfx DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex) -install(FILES ${CMAKE_SOURCE_DIR}/default.settings ${CMAKE_SOURCE_DIR}/utils.py ${CMAKE_SOURCE_DIR}/learn_static.py DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex) +install(FILES ${CMAKE_SOURCE_DIR}/default.settings ${CMAKE_SOURCE_DIR}/learn_static.py DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex) diff --git a/Application/src/tracker/python/GPURecognition.cpp b/Application/src/tracker/python/GPURecognition.cpp index 9042f2d4ea211076d532a92445e179c6b7bcfa34..db27da251f9a146cc8e9bc17d5fcdba61c4c3db1 100644 --- a/Application/src/tracker/python/GPURecognition.cpp +++ b/Application/src/tracker/python/GPURecognition.cpp @@ -239,7 +239,7 @@ PYBIND11_EMBEDDED_MODULE(TRex, m) { namespace track { namespace py = pybind11; std::shared_ptr<py::scoped_interpreter> guard = nullptr; - pybind11::module utils, numpy, TRex, plt, matplotlib, _main; + pybind11::module numpy, TRex, _main; pybind11::dict* _locals = nullptr; std::mutex module_mutex; @@ -424,24 +424,7 @@ namespace track { "\t\tfound = False\nprint('setting version',sys.version,found,physical)\n" \ "set_version(sys.version, found, physical)\n"); - matplotlib = py::module::import("matplotlib"); - - //#ifdef __linux__ - matplotlib.attr("use")("Agg"); - //#endif - - plt = py::module::import("matplotlib.pyplot"); - //main.attr("array") = std::vector<float>{1,2,3,4}; - //plt.attr("plot")(main.attr("array")); - //plt.attr("show")(); - numpy = _main.import("numpy"); - try { - track::utils = _main.import("utils"); - } catch(py::error_already_set &e) { - Debug("Python runtime error: '%s'", e.what()); - e.restore(); - } TRex = _main.import("TRex"); _locals = new py::dict("model"_a="None"); @@ -489,7 +472,7 @@ namespace track { } try { - track::utils = track::numpy = track::TRex = track::plt = track::matplotlib = _main = pybind11::module(); + track::numpy = track::TRex = _main = pybind11::module(); { std::lock_guard<std::mutex> guard(module_mutex); diff --git a/Application/src/tracker/python/check_python.cpp b/Application/src/tracker/python/check_python.cpp index 6b60406af55d7ba4248092ddad609e1d36a461ab..063562d7484db64f5d2cc3060bf99cf548531720 100644 --- a/Application/src/tracker/python/check_python.cpp +++ b/Application/src/tracker/python/check_python.cpp @@ -21,10 +21,6 @@ int main(int argc, char**argv) { printf("loading keras...\n"); #endif importlib.attr("find_loader")("keras").attr("name"); -#ifndef NDEBUG - printf("loading matplotlib...\n"); -#endif - importlib.attr("find_loader")("matplotlib").attr("name"); #ifndef NDEBUG printf("success.\n"); #endif diff --git a/Application/src/tracker/tracking/Accumulation.cpp b/Application/src/tracker/tracking/Accumulation.cpp index 95f444059eb64eeea10780d71d789b8f0a70d320..eafcde5eacd78f1184ff822bd98a15b21d4374fd 100644 --- a/Application/src/tracker/tracking/Accumulation.cpp +++ b/Application/src/tracker/tracking/Accumulation.cpp @@ -101,7 +101,7 @@ void Accumulation::setup() { try { Recognition::check_learning_module(); } catch(const std::future_error& error) { - SOFT_EXCEPTION("Checking the learning module failed ('%s'). Most likely one of the required libraries is missing from the current python environment (check for keras, tensorflow, matplotlib and pillow).", error.what()); + SOFT_EXCEPTION("Checking the learning module failed ('%s'). Most likely one of the required libraries is missing from the current python environment (check for keras and tensorflow).", error.what()); } } diff --git a/Application/utils.py b/Application/utils.py deleted file mode 100644 index f2cc3dd982a9e32e6f16c11c3f718e91221b1903..0000000000000000000000000000000000000000 --- a/Application/utils.py +++ /dev/null @@ -1,71 +0,0 @@ -def axes_for_array(length): - import numpy as np - import matplotlib.pyplot as plt - - rest = 0 - cols = min(16, length) - if length % cols > 0: - rest = 1 - - figsize = (cols * 5, 5 * (length // cols + rest)) - fig, axes = plt.subplots(length // cols + rest, cols, figsize=figsize) - print(figsize) - - axes = np.array(axes).flatten() - for ax in axes: - ax.axis('off') - axes = axes[:length] - - return fig, axes - -def figure_as_image(): - import io - from PIL import Image - import matplotlib.pyplot as plt - import numpy as np - import os - - plt.gcf().set_tight_layout(True) - #plt.gcf().patch.set_facecolor('black') - plt.gcf().patch.set_alpha(0.75) - buf = io.BytesIO() - plt.savefig(buf, format='png', transparent=True, facecolor=plt.gcf().get_facecolor(), edgecolor='none') - buf.seek(0) - im = Image.open(buf) - im = np.array(im).astype(np.uint8) - buf.close() - plt.close(plt.gcf()) - - return im - -def show_figure(title="plot", output_path="", im = None): - import TRex - from PIL import Image - import numpy as np - import os - - if type(im) == type(None): - im = Image.fromarray(figure_as_image()) - else: - im = Image.fromarray(im) - try: - path = "/var/www/example.com/html/"+title.replace(" ", "_").replace("/", "-")+".png" - im.save(path, "PNG") - TRex.log("saved as"+str(path)) - except Exception as e: - TRex.warn(str(e)) - - if len(output_path) > 0: - try: - if not output_path.endswith(os.sep): - output_path = output_path + os.sep - path = output_path+title.replace(" ", "_").replace("/", "-")+".png" - im.save(path, "PNG") - TRex.log("saved as"+str(path)) - except Exception as e: - TRex.warn(str(e)) - - im = np.array(im).astype(np.uint8) - - #TRex.imshow(title, im) - diff --git a/conda/meta.yaml b/conda/meta.yaml index f8e1a2ae63ff3e54f744d960ea353220e98ec0ef..1afefd101d12ce2668ed621f3670e016e59d2ca3 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -67,8 +67,6 @@ requirements: - tensorflow-gpu ==1.13.* [not osx] - tensorflow ==1.13.* [osx] - keras - - matplotlib - - pillow - ffmpeg [win] - python [win] - ffmpeg ==4.0 [not win]