diff --git a/Application/src/commons/common/gui/DrawBase.h b/Application/src/commons/common/gui/DrawBase.h
index 285c16c79cc2cfb07ea6f275c71509b660e08a63..ca52a1fddab92048d2b0db2d0b8b944e73420421 100644
--- a/Application/src/commons/common/gui/DrawBase.h
+++ b/Application/src/commons/common/gui/DrawBase.h
@@ -28,8 +28,6 @@ namespace gui {
         virtual ~Base();
         
         virtual LoopStatus update_loop() { return LoopStatus::IDLE; }
-        
-        virtual float dpi_scale() const { return 1; }
         virtual void set_background_color(const Color&) {}
         
         virtual void set_frame_recording(bool v) {
diff --git a/Application/src/commons/common/gui/FileChooser.cpp b/Application/src/commons/common/gui/FileChooser.cpp
index fe8a20d711200e3b739121acb04309481ee4cf26..99703eda6ad96c4fc81299ea85699687743e25a9 100644
--- a/Application/src/commons/common/gui/FileChooser.cpp
+++ b/Application/src/commons/common/gui/FileChooser.cpp
@@ -58,18 +58,17 @@ FileChooser::FileChooser(const file::Path& start, const std::string& extension,
             {
                 std::lock_guard guard(_graph->lock());
                 Size2 size(e.size.width, e.size.height);
-                size /= _base.dpi_scale();
                 
                 float min_height = 820;
-                auto scale = gui::interface_scale() / max(1, min_height / size.height) / _base.dpi_scale();
+                auto scale = gui::interface_scale() / max(1, min_height / size.height);
                 _graph->set_size(size);
                 _graph->set_scale(scale);
                 
                 update_size();
                 
-                //if(_base.window_dimensions().height * _base.dpi_scale() < min_height)
+                //if(_base.window_dimensions().height < min_height)
                 {
-                    _graph->set_scale(1 / (min_height / _base.dpi_scale() / e.size.height));
+                    _graph->set_scale(1 / (min_height / e.size.height));
                     update_size();
                 }
                 
@@ -457,7 +456,7 @@ void FileChooser::file_selected(size_t, file::Path p) {
 }
 
 void FileChooser::update_size() {
-    float s = _graph->scale().x / gui::interface_scale() / _base.dpi_scale();
+    float s = _graph->scale().x / gui::interface_scale();
     
     if(_selected_text && !_selected_file.empty()) {
         _selected_text->set_max_size(Size2(_graph->width() - 20));
diff --git a/Application/src/commons/common/gui/IMGUIBase.cpp b/Application/src/commons/common/gui/IMGUIBase.cpp
index 78b603ea43084bbcb56c6c073dd6f2da1f262040..073ae5fd864b763c3857a3020b715faad444be4d 100644
--- a/Application/src/commons/common/gui/IMGUIBase.cpp
+++ b/Application/src/commons/common/gui/IMGUIBase.cpp
@@ -360,7 +360,6 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
     
     int fw, fh;
     glfwGetFramebufferSize(window, &fw, &fh);
-    base->_last_framebuffer_size = Size2(fw, fh);
     
     GLFWmonitor* monitor = glfwGetWindowMonitor(window);
     if(!monitor) {
@@ -414,16 +413,20 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
     float dpi_scale = 1 / max(xscale, yscale);//max(float(fw) / float(width), float(fh) / float(height));
     im_font_scale = max(1, dpi_scale) * 0.75f;
     base->_dpi_scale = dpi_scale;
+    base->_graph->set_scale(1 / dpi_scale);
+    
+    base->_last_framebuffer_size = Size2(fw, fh).mul(base->_dpi_scale);
     
     //Debug("dpi_scale:%f gui::interface_scale:%f xscale:%f yscale:%f", dpi_scale, gui::interface_scale(), xscale, yscale);
     
     {
         Event e(EventType::WINDOW_RESIZED);
-        e.size.width = fw;
-        e.size.height = fh;
+        e.size.width = fw * dpi_scale;
+        e.size.height = fh * dpi_scale;
 
         base->event(e);
     }
+    
     base->_graph->set_dirty(NULL);
 }
 
@@ -513,7 +516,7 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
         
         int fw, fh;
         glfwGetFramebufferSize(_platform->window_handle(), &fw, &fh);
-        _last_framebuffer_size = Size2(fw, fh);
+        _last_framebuffer_size = Size2(fw, fh).mul(_dpi_scale);
         
         const float base_scale = 32;
         //float dpi_scale = max(float(fw) / float(width), float(fh) / float(height));
@@ -565,12 +568,13 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
             base->_graph->set_dirty(NULL);
         });
         glfwSetCursorPosCallback(_platform->window_handle(), [](GLFWwindow* window, double xpos, double ypos) {
+            auto base = base_pointers.at(window);
+            
             Event e(EventType::MMOVE);
             auto &io = ImGui::GetIO();
-            e.move.x = float(xpos * io.DisplayFramebufferScale.x);
-            e.move.y = float(ypos * io.DisplayFramebufferScale.y);
+            e.move.x = float(xpos * io.DisplayFramebufferScale.x) * base->_dpi_scale;
+            e.move.y = float(ypos * io.DisplayFramebufferScale.y) * base->_dpi_scale;
             
-            auto base = base_pointers.at(window);
             base->event(e);
             
             base->_graph->set_dirty(NULL);
@@ -585,12 +589,13 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
             
             double xpos, ypos;
             glfwGetCursorPos(window, &xpos, &ypos);
+            
+            auto base = base_pointers.at(window);
             auto &io = ImGui::GetIO();
-            e.mbutton.x = float(xpos * io.DisplayFramebufferScale.x);
-            e.mbutton.y = float(ypos * io.DisplayFramebufferScale.y);
+            e.mbutton.x = float(xpos * io.DisplayFramebufferScale.x) * base->_dpi_scale;
+            e.mbutton.y = float(ypos * io.DisplayFramebufferScale.y) * base->_dpi_scale;
             e.mbutton.button = GLFW_MOUSE_BUTTON_RIGHT == button ? 1 : 0;
             
-            auto base = base_pointers.at(window);
             base->event(e);
             base->_graph->set_dirty(NULL);
         });
@@ -642,10 +647,6 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
         base_pointers.erase(_platform->window_handle());
     }
 
-    float IMGUIBase::dpi_scale() const {
-        return _dpi_scale;
-    }
-
     void IMGUIBase::set_background_color(const Color& color) {
         if(_platform)
             _platform->set_clear_color(color);
@@ -704,6 +705,9 @@ void IMGUIBase::update_size_scale(GLFWwindow* window) {
         int fw, fh;
         auto window = _platform->window_handle();
         glfwGetFramebufferSize(window, &fw, &fh);
+        fw *= _dpi_scale;
+        fh *= _dpi_scale;
+        
         if(fw > 0 && fh > 0 && (fw != _last_framebuffer_size.width || fh != _last_framebuffer_size.height))
         {
 #ifndef NDEBUG
@@ -1155,7 +1159,7 @@ void IMGUIBase::draw_element(const DrawOrder& order) {
             
             auto font = _fonts.at(ptr->font().style);
             
-            list->AddText(font, ptr->global_text_scale().x * font->FontSize * (ptr->font().size / im_font_scale / io.DisplayFramebufferScale.x), bds.pos(), (ImColor)ptr->color(), ptr->txt().c_str());
+            list->AddText(font, ptr->global_text_scale().x * font->FontSize * (ptr->font().size / im_font_scale / _dpi_scale / io.DisplayFramebufferScale.x), bds.pos(), (ImColor)ptr->color(), ptr->txt().c_str());
             
             break;
         }
@@ -1305,7 +1309,7 @@ void IMGUIBase::draw_element(const DrawOrder& order) {
         o->set_visible(false);
         
         auto &io = ImGui::GetIO();
-        Vec2 scale = (_graph->scale() / gui::interface_scale()) .div(Vec2(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y));
+        Vec2 scale = (_graph->scale() / gui::interface_scale() / _dpi_scale) .div(Vec2(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y));
         Transform transform;
         transform.scale(scale);
         
@@ -1323,7 +1327,7 @@ void IMGUIBase::draw_element(const DrawOrder& order) {
         
         //bool skip = false;
         auto cache = o->cached(this);
-        auto dim = window_dimensions() / dpi_scale();
+        auto dim = window_dimensions() / _dpi_scale;
         
         if(!Bounds(0, 0, dim.width-0, dim.height-0).overlaps(bounds)) {
             ++_skipped;
diff --git a/Application/src/commons/common/gui/IMGUIBase.h b/Application/src/commons/common/gui/IMGUIBase.h
index 677f5a44f7a49c23d1a58a3ed3504655ef7c86ac..381e60fcc2cadbea3da104404ab40bae1e0f822a 100644
--- a/Application/src/commons/common/gui/IMGUIBase.h
+++ b/Application/src/commons/common/gui/IMGUIBase.h
@@ -133,7 +133,6 @@ namespace gui {
         Bounds text_bounds(const std::string& text, Drawable*, const Font& font) override;
         uint32_t line_spacing(const Font& font) override;
         Size2 window_dimensions() override;
-        float dpi_scale() const override;
         template<class F, class... Args>
         auto exec_main_queue(F&& f, Args&&... args) -> std::future<typename std::invoke_result_t<F, Args...>>
         {
diff --git a/Application/src/commons/common/gui/MetalImpl.mm b/Application/src/commons/common/gui/MetalImpl.mm
index 47535a50ebefbb53d3b30354a0ee4fcf4c9dfda8..1b0295c829d5ee1110e9b080d965cd4fe537f6b6 100644
--- a/Application/src/commons/common/gui/MetalImpl.mm
+++ b/Application/src/commons/common/gui/MetalImpl.mm
@@ -65,7 +65,14 @@ extern "C"{
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 250 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
             auto cstr = [string cStringUsingEncoding:NSASCIIStringEncoding];
             auto paths = cmn::Meta::fromStr<std::vector<file::Path>>(cstr);
-            if(gui::metal::current_instance) {
+            for(auto it = paths.begin(); it != paths.end(); ) {
+                if(!it->exists()) {
+                    it = paths.erase(it);
+                } else
+                    ++it;
+            }
+            
+            if(!paths.empty() && gui::metal::current_instance) {
                 if(!gui::metal::current_instance->open_files(paths)) {
                     gui::metal::current_instance->message("Cannot open "+std::string(cstr)+".");
                 }
diff --git a/Application/src/grabber/CropWindow.cpp b/Application/src/grabber/CropWindow.cpp
index 6350bcd271df27579ba52505b2635e1d42e476cf..f6db25297ed019b1e2abec5950a32f25f7e2cad7 100644
--- a/Application/src/grabber/CropWindow.cpp
+++ b/Application/src/grabber/CropWindow.cpp
@@ -56,7 +56,7 @@ namespace gui {
         [this, &grabber, &scale, &okay](SFLoop& loop){
             std::unique_lock<std::recursive_mutex> guard(_graph->lock());
             auto desktop = _base->window_dimensions();
-            auto size = _video_size; //* _base->dpi_scale();
+            auto size = _video_size;
             
             if (desktop.width >= desktop.height) {
                 if (size.width > desktop.width) {
diff --git a/Application/src/grabber/default_config.cpp b/Application/src/grabber/default_config.cpp
index f607758b30b881a0df20b8b5be779bc2666aa808..9761e0a55e7a34b1364d2f00dca1c715dcf2a3d5 100644
--- a/Application/src/grabber/default_config.cpp
+++ b/Application/src/grabber/default_config.cpp
@@ -134,15 +134,7 @@ namespace default_config {
         CONFIG("cam_undistort", false, "If set to true, the recorded video image will be undistorted using `cam_undistort_vector` (1x5) and `cam_matrix` (3x3).");
         CONFIG("image_invert", false, "Inverts the image greyscale values before thresholding.");
         
-        CONFIG("gui_interface_scale",
-#if defined(__linux__)
-              float(1.25)
-#elif defined(WIN32) || defined(__WIN32__)
-              float(1.25)
-#else
-              float(0.75)
-#endif
-               , "A lower number will make the texts and GUI elements bigger.");
+        CONFIG("gui_interface_scale", float(1.25), "A lower number will make the texts and GUI elements bigger.");
         
         CONFIG("meta_species", std::string(""), "Name of the species used.");
         CONFIG("meta_age_days", long_t(-1), "Age of the individuals used in days.");
diff --git a/Application/src/tracker/CMakeLists.txt b/Application/src/tracker/CMakeLists.txt
index 191c9b0509a30a1ae5fdc25360d961b80482479a..a9f0fd1a09e62dbfb405ac7212dc0bb6620e77c3 100644
--- a/Application/src/tracker/CMakeLists.txt
+++ b/Application/src/tracker/CMakeLists.txt
@@ -118,6 +118,7 @@ set(RESOURCE_COPY_FILES
 set(RESOURCE_COPY_SINGLE_FILES
 	${CMAKE_SOURCE_DIR}/default.settings
     ${CMAKE_SOURCE_DIR}/learn_static.py
+    ${CMAKE_CURRENT_SOURCE_DIR}/python/trex_init.py
 )
 
 IF("${CMAKE_SYSTEM}" MATCHES "Linux")
@@ -238,4 +239,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}/learn_static.py DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex)
+install(FILES ${CMAKE_SOURCE_DIR}/default.settings ${CMAKE_SOURCE_DIR}/learn_static.py ${CMAKE_CURRENT_SOURCE_DIR}/python/trex_init.py DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/share/trex)
diff --git a/Application/src/tracker/VideoOpener.cpp b/Application/src/tracker/VideoOpener.cpp
index bc21f0fc0814520b3dfa0ece28ec5e748fa78389..0f19f752905e455eedffc7f721e389a799fad6e7 100644
--- a/Application/src/tracker/VideoOpener.cpp
+++ b/Application/src/tracker/VideoOpener.cpp
@@ -403,7 +403,7 @@ VideoOpener::VideoOpener()
             if(image) {
                 _screenshot->set_source(std::move(image));
                 
-                auto max_scale = _file_chooser->graph()->scale().reciprocal() * _file_chooser->base().dpi_scale() * 0.3f;
+                auto max_scale = _file_chooser->graph()->scale().reciprocal() * 0.3f;
                 auto max_size = Size2(_file_chooser->graph()->width(), _file_chooser->graph()->height()).mul(max_scale);
                 auto scree_size = _screenshot->source()->bounds().size();
                 auto size = max_size;
diff --git a/Application/src/tracker/gui/HttpGui.cpp b/Application/src/tracker/gui/HttpGui.cpp
index 3caf6a7e8c61ba622ed1184f5e054ce63b356466..b16509d38d10a71bf6e3bd916e3112e4fbcc212d 100644
--- a/Application/src/tracker/gui/HttpGui.cpp
+++ b/Application/src/tracker/gui/HttpGui.cpp
@@ -86,7 +86,7 @@ Httpd::Response HttpGui::page(const std::string &url) {
         {
             std::lock_guard<std::recursive_mutex> lock(_gui.lock());
             if(GUI::instance() && GUI::instance()->base())
-                _base.set_window_size(GUI::instance()->base()->window_dimensions().mul(_gui.scale().reciprocal() * GUI_SETTINGS(gui_interface_scale)));
+                _base.set_window_size(GUI::instance()->base()->window_dimensions().mul(_gui.scale().reciprocal() * gui::interface_scale()));
             else
                 _base.set_window_size(Size2(_gui.width(), _gui.height()));
             if(GUI_SETTINGS(nowindow)) {
diff --git a/Application/src/tracker/gui/Label.cpp b/Application/src/tracker/gui/Label.cpp
index 1f84580945f9f8cc70389fb2133e41421a9127a3..91760a2a86caaa2be7c1c85ed2e8bea8f3f02a2b 100644
--- a/Application/src/tracker/gui/Label.cpp
+++ b/Application/src/tracker/gui/Label.cpp
@@ -34,7 +34,7 @@ void Label::update(DrawStructure& base, Section* s, float alpha, bool disabled)
         if(!base.scale().empty())
             scale = base.scale().reciprocal().mul(ptr->scale().reciprocal());
         
-        screen._size = GUI::instance() && GUI::instance()->base() ? GUI::instance()->base()->window_dimensions().mul(scale * GUI_SETTINGS(gui_interface_scale)) : Size2(Tracker::average().bounds().size());
+        screen._size = GUI::instance() && GUI::instance()->base() ? GUI::instance()->base()->window_dimensions().mul(scale * gui::interface_scale()) : Size2(Tracker::average().bounds().size());
         offset = -(_center - (screen.pos() + Size2(screen.width * 0.5, screen.height * 0.95))) / screen.width;
     }
 
diff --git a/Application/src/tracker/gui/RecognitionSummary.cpp b/Application/src/tracker/gui/RecognitionSummary.cpp
index f4f005f04119a84fc546f6a5aad0b3128c46ff93..46149e940020835208928310641b2729f4ed813c 100644
--- a/Application/src/tracker/gui/RecognitionSummary.cpp
+++ b/Application/src/tracker/gui/RecognitionSummary.cpp
@@ -9,7 +9,7 @@ namespace gui {
     void RecognitionSummary::update(gui::DrawStructure& base) {
         auto & cache = GUI::instance()->cache();
         
-        const float interface_scale = GUI_SETTINGS(gui_interface_scale);
+        const float interface_scale = gui::interface_scale();
         
         Font title_font(0.9f / interface_scale, Style::Bold, Align::Center);
         Font font(0.8f / interface_scale);
diff --git a/Application/src/tracker/gui/gui.cpp b/Application/src/tracker/gui/gui.cpp
index 0b27a59ba72173deb2272d754fa0ccafc284b254..85722340c8cc3cb2f3c099843dfe7622222ab632 100644
--- a/Application/src/tracker/gui/gui.cpp
+++ b/Application/src/tracker/gui/gui.cpp
@@ -840,7 +840,7 @@ void GUI::do_recording() {
 #if WITH_SFML
     
     
-    float interface_scale = 1 / GUI_SETTINGS(gui_interface_scale);
+    float interface_scale = 1 / gui::interface_scale();
     sf::Text text("Saving to "+_recording_path.str(), SFBase::font(), 18 / interface_scale);
     sf::Text subtext("frame "+Meta::toStr(_recording_frame)+" length:"+Meta::toStr(duration), SFBase::font(), 17 / interface_scale);
     
@@ -3871,7 +3871,7 @@ void GUI::local_event(const gui::Event &event) {
                 _gui.mouse_up(event.mbutton.button == 0);
         }
         else if(event.type == gui::WINDOW_RESIZED) {
-            const float interface_scale = GUI_SETTINGS(gui_interface_scale);
+            const float interface_scale = gui::interface_scale();
             Size2 size(event.size.width * interface_scale, event.size.height * interface_scale);
             
             float scale = min(size.width / float(_average_image.cols),
diff --git a/Application/src/tracker/misc/default_config.cpp b/Application/src/tracker/misc/default_config.cpp
index 38df1851cd744d0f9d2012791d284f5f796a70f1..69df442f0ab1e2f359720f4780ddb5e8f8626c67 100644
--- a/Application/src/tracker/misc/default_config.cpp
+++ b/Application/src/tracker/misc/default_config.cpp
@@ -307,7 +307,7 @@ file::Path conda_environment_path() {
         
         CONFIG("gui_transparent_background", false, "If enabled, fonts might look weird but you can record movies (and images) with transparent background (if gui_background_color.alpha is < 255).");
         
-        CONFIG("gui_interface_scale", float(1), "Scales the whole interface. A value greater than 1 will make it smaller.");
+        CONFIG("gui_interface_scale", float(1.25), "Scales the whole interface. A value greater than 1 will make it smaller.");
         CONFIG("gui_max_path_time", float(3), "Length (in time) of the trails shown in GUI.");
         
         CONFIG("gui_draw_only_filtered_out", false, "Only show filtered out blob texts.");
diff --git a/Application/src/tracker/python/CMakeLists.txt b/Application/src/tracker/python/CMakeLists.txt
index 0d155f3462a91cf5d5e8dea30fded3d80688f2b7..6f42e801a11b12bbfcb552a53dd6a763a62eca69 100644
--- a/Application/src/tracker/python/CMakeLists.txt
+++ b/Application/src/tracker/python/CMakeLists.txt
@@ -5,7 +5,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 # add actual library
 if(UNIX)
-    add_library(tracker_python STATIC ${SRCS} ${HDRS})
+    add_library(tracker_python STATIC ${SRCS} ${HDRS} ${CMAKE_CURRENT_SOURCE_DIR}/trex_init.py)
 elseif(WIN32)
     add_library(tracker_python SHARED ${SRCS} ${HDRS})
 endif()
diff --git a/Application/src/tracker/python/GPURecognition.cpp b/Application/src/tracker/python/GPURecognition.cpp
index 23efd4a843c987839a0cdd6512c2b298e6ca0971..e1b278097df8c4d20c28cf39c35f4f4b7f96daca 100644
--- a/Application/src/tracker/python/GPURecognition.cpp
+++ b/Application/src/tracker/python/GPURecognition.cpp
@@ -361,6 +361,7 @@ std::shared_future<bool> PythonIntegration::reinit() {
         try {
             _main = py::module::import("__main__");
             _main.def("set_version", [](std::string x, bool has_gpu, std::string physical_name) {
+                Debug("set_version called with '%S' and '%S'", &x, &physical_name);
                 auto array = utils::split(x, ' ');
                 if(array.size() > 0) {
                     array = utils::split(array.front(), '.');
@@ -372,56 +373,20 @@ std::shared_future<bool> PythonIntegration::reinit() {
                 
                 python_uses_gpu() = has_gpu;
                 python_gpu_name() = physical_name;
-                
-                Debug("retrieved version %S", &x);
             });
             
-            if(_settings->map().get<bool>("recognition_enable").value())
-                py::exec("import sys\n" \
-                         "found = True\n" \
-                         "physical = ''\n" \
-                         "if int(sys.version[0]) >= 3:\n"\
-                         "\timport importlib\n" \
-                         "\ttry:\n" \
-                             "\t\timportlib.import_module('tensorflow')\n" \
-                             "\t\timport tensorflow\n"
-#if defined(__APPLE__) && defined(__aarch64__)
-                             "\t\tfrom tensorflow.python.compiler.mlcompute import mlcompute\n"
-                             "\t\tif mlcompute.is_apple_mlc_enabled():\n"
-                                "\t\t\tfound = True\n"
-                                "\t\t\tphysical = 'MLC'\n"
-                             "\t\telse:\n"
-#else
-                             "\t\tif True:\n"
-#endif
-                             "\t\t\tfrom tensorflow.compat.v1 import ConfigProto, InteractiveSession\n"
-                             "\t\t\tconfig = ConfigProto()\n"
-                             "\t\t\tconfig.gpu_options.allow_growth=True\n"
-                             "\t\t\tsess = InteractiveSession(config=config)\n"
-                             "\t\t\tfrom tensorflow.python.client import device_lib\n" \
-                             "\t\t\tgpus = [x.physical_device_desc for x in device_lib.list_local_devices() if x.device_type == 'GPU']\n"
-                             "\t\t\tfound = len(gpus) > 0\n"
-                             "\t\t\tif found:\n" \
-                                "\t\t\t\tfor device in gpus:\n" \
-                                        "\t\t\t\t\tphysical = device.split(',')[1].split(': ')[1]\n" \
-                         "\texcept ImportError:\n"
-                         "\t\tfound = False\n" \
-                         "else:\n" \
-                         "\ttry:\n" \
-                         "\t\timp.find_module('tensorflow')\n" \
-                         "\t\tfrom tensorflow.python.client import device_lib\n" \
-                         "\t\tfound = len([x.physical_device_desc for x in device_lib.list_local_devices() if x.device_type == 'GPU']) > 0\n"
-                         "\texcept ImportError:\n" \
-                         "\t\tfound = False\nprint('setting version',sys.version,found,physical)\n" \
-                         "set_version(sys.version, found, physical)\n");
-            
-            numpy = _main.import("numpy");
             TRex = _main.import("TRex");
             
-            _locals = new py::dict("model"_a="None");
+            if(_settings->map().get<bool>("recognition_enable").value()) {
+                try {
+                    auto cmd = utils::read_file("trex_init.py");
+                    py::exec(cmd);
+                } catch(const UtilsException& ex) {
+                    Warning("Error while executing 'trex_init.py'. Content: %s", ex.what());
+                }
+            }
             
-            if(_settings->map().get<bool>("recognition_enable").value())
-                _main.import("tensorflow");
+            _locals = new py::dict("model"_a="None");
             
             python_initialized() = true;
             python_initializing() = false;
diff --git a/Application/src/tracker/python/trex_init.py b/Application/src/tracker/python/trex_init.py
new file mode 100644
index 0000000000000000000000000000000000000000..c04d5dc378a7a64bbbe931df98a872a97291922b
--- /dev/null
+++ b/Application/src/tracker/python/trex_init.py
@@ -0,0 +1,48 @@
+import sys
+import numpy as np
+
+if not hasattr(sys, "argv") or not sys.argv or len(sys.argv) == 0:
+    sys.argv = [""]
+    print("avoiding tensorflow bug")
+
+found = False
+physical = ''
+if int(sys.version[0]) >= 3:
+    import importlib
+    try:
+        importlib.import_module('tensorflow')
+        import tensorflow
+
+        import platform
+        if platform.system() == "Darwin":
+            from tensorflow.python.compiler.mlcompute import mlcompute
+            if mlcompute.is_apple_mlc_enabled():
+                found = True
+                physical = 'MLC'
+            else:
+                physical = ''
+
+        if not found:
+            from tensorflow.compat.v1 import ConfigProto, InteractiveSession
+            config = ConfigProto()
+            config.gpu_options.allow_growth=True
+            sess = InteractiveSession(config=config)
+            from tensorflow.python.client import device_lib
+            gpus = [x.physical_device_desc for x in device_lib.list_local_devices() if x.device_type == 'GPU']
+            found = len(gpus) > 0
+            if found:
+                for device in gpus:
+                    physical = device.split(',')[1].split(': ')[1]
+
+    except ImportError:
+        found = False
+else:
+    try:
+        imp.find_module('tensorflow')
+        from tensorflow.python.client import device_lib
+        found = len([x.physical_device_desc for x in device_lib.list_local_devices() if x.device_type == 'GPU']) > 0
+    except ImportError:
+        pass
+
+print('setting version',sys.version,found,physical)
+set_version(sys.version, found, physical)
\ No newline at end of file