diff --git a/.gitignore b/.gitignore index 0272e3f..6479810 100644 --- a/.gitignore +++ b/.gitignore @@ -1,84 +1,30 @@ -# Django stuff: +# Generated data files +*.npy +*.pkl *.log -local_settings.py -# Flask stuff: -instance/ -.webassets-cache - -# vscode -.vscode/ - -# Created by https://www.gitignore.io/api/venv,linux,macos,python,windows,virtualenv,jupyternotebooks -# Edit at https://www.gitignore.io/?templates=venv,linux,macos,python,windows,virtualenv,jupyternotebooks - -### JupyterNotebooks ### -# gitignore template for Jupyter Notebooks -# website: http://jupyter.org/ - -.ipynb_checkpoints -*/.ipynb_checkpoints/* - -# IPython -profile_default/ -ipython_config.py - -# Remove previous ipynb_checkpoints -# git rm -r .ipynb_checkpoints/ - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon +# Environment files +.env -# Thumbnails -._* +# Model files +20170512-110547.zip +20170512-110547/ -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent +# Database directories +al_database/ +database/ +database_aligned/ -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk +# Temporary files +temp_embeddings.npy +temp_images/ +temp_images_aligned/ -### Python ### -# Byte-compiled / optimized / DLL files +# Python __pycache__/ *.py[cod] *$py.class - -# C extensions *.so - -# Distribution / packaging .Python build/ develop-eggs/ @@ -92,129 +38,17 @@ parts/ sdist/ var/ wheels/ -pip-wheel-metadata/ -share/python-wheels/ *.egg-info/ .installed.cfg *.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Scrapy stuff: -.scrapy -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -### venv ### -# Virtualenv -# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ -pyvenv.cfg -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ -pip-selfcheck.json - -### VirtualEnv ### -# Virtualenv -# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +# IDEs +.vscode/ +.idea/ +*.swp +*.swo +*~ -### Windows ### -# Windows thumbnail cache files +# OS +.DS_Store Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# End of https://www.gitignore.io/api/venv,linux,macos,python,windows,virtualenv,jupyternotebooks diff --git a/requirements.txt b/requirements.txt index c3d1ec1..1b8b1a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,11 +15,11 @@ scikit-image>=0.13.1 scikit-learn>=0.19.0 scipy>=1.0.0 setuptools>=38.6.0 -tensorflow<2.0.0 +tensorflow>=2.16.0 python-dotenv>=0.12.0 #pynder -git+git://github.com/cjekel/pynder +git+https://github.com/cjekel/pynder #tindetheus -e . diff --git a/setup.py b/setup.py index a9148a3..98f59dc 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "imageio >= 2.2.0", "scikit-learn >= 0.19.0", "scikit-image >= 0.13.1", - "tensorflow < 2.0.0", + "tensorflow >= 2.16.0", "pandas >= 0.21.0", "future >= 0.16.0", "joblib >= 0.13.0", diff --git a/tindetheus/export_embeddings.py b/tindetheus/export_embeddings.py index f59fc5a..b4d6e55 100644 --- a/tindetheus/export_embeddings.py +++ b/tindetheus/export_embeddings.py @@ -80,6 +80,8 @@ from skimage.transform import resize import time import tensorflow as tf +# Disable TensorFlow 2.x behavior for compatibility +tf.compat.v1.disable_eager_execution() import numpy as np # import sys import os @@ -108,15 +110,15 @@ def main(model_dir='20170512-110547', data_dir='database_aligned', os.path.isdir(os.path.join(path_exp, name))] with tf.Graph().as_default(): - with tf.Session() as sess: + with tf.compat.v1.Session() as sess: # Load the model facenet.load_model(model_dir) # Get input and output tensors - images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0") # noqa: E501 - embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0") # noqa: E501 - phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0") # noqa: E501 + images_placeholder = tf.compat.v1.get_default_graph().get_tensor_by_name("input:0") # noqa: E501 + embeddings = tf.compat.v1.get_default_graph().get_tensor_by_name("embeddings:0") # noqa: E501 + phase_train_placeholder = tf.compat.v1.get_default_graph().get_tensor_by_name("phase_train:0") # noqa: E501 # Run forward pass to calculate embeddings nrof_images = len(image_list) @@ -177,8 +179,8 @@ def load_and_align_data(image_paths, image_size, margin, gpu_memory_fraction): print('Creating networks and loading parameters') with tf.Graph().as_default(): - gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) # noqa: E501 - sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, + gpu_options = tf.compat.v1.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) # noqa: E501 + sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(gpu_options=gpu_options, log_device_placement=False)) with sess.as_default(): pnet, rnet, onet = detect_face.create_mtcnn(sess, None) diff --git a/tindetheus/facenet_clone/align/detect_face.py b/tindetheus/facenet_clone/align/detect_face.py index 8c0b61d..8c88626 100644 --- a/tindetheus/facenet_clone/align/detect_face.py +++ b/tindetheus/facenet_clone/align/detect_face.py @@ -30,6 +30,8 @@ import numpy as np import tensorflow as tf +# Disable TensorFlow 2.x behavior for compatibility +tf.compat.v1.disable_eager_execution() #from math import floor import cv2 import os @@ -85,10 +87,10 @@ def load(self, data_path, session, ignore_missing=False): data_dict = np.load(data_path, encoding='latin1', allow_pickle=True).item() #pylint: disable=no-member for op_name in data_dict: - with tf.variable_scope(op_name, reuse=True): + with tf.compat.v1.variable_scope(op_name, reuse=True): for param_name, data in iteritems(data_dict[op_name]): try: - var = tf.get_variable(param_name) + var = tf.compat.v1.get_variable(param_name) session.run(var.assign(data)) except ValueError: if not ignore_missing: @@ -122,7 +124,7 @@ def get_unique_name(self, prefix): def make_var(self, name, shape): """Creates a new TensorFlow variable.""" - return tf.get_variable(name, shape, trainable=self.trainable) + return tf.compat.v1.get_variable(name, shape, trainable=self.trainable) def validate_padding(self, padding): """Verifies that the padding is one of the supported ones.""" @@ -150,7 +152,7 @@ def conv(self, assert c_o % group == 0 # Convolution for a given input and kernel convolve = lambda i, k: tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding) - with tf.variable_scope(name) as scope: + with tf.compat.v1.variable_scope(name) as scope: kernel = self.make_var('weights', shape=[k_h, k_w, c_i // group, c_o]) # This is the common-case. Convolve the input without any further complications. output = convolve(inp, kernel) @@ -165,7 +167,7 @@ def conv(self, @layer def prelu(self, inp, name): - with tf.variable_scope(name): + with tf.compat.v1.variable_scope(name): i = int(inp.get_shape()[-1]) alpha = self.make_var('alpha', shape=(i,)) output = tf.nn.relu(inp) + tf.multiply(alpha, -tf.nn.relu(-inp)) @@ -182,7 +184,7 @@ def max_pool(self, inp, k_h, k_w, s_h, s_w, name, padding='SAME'): @layer def fc(self, inp, num_out, name, relu=True): - with tf.variable_scope(name): + with tf.compat.v1.variable_scope(name): input_shape = inp.get_shape() if input_shape.ndims == 4: # The input is spatial. Vectorize it first. @@ -191,11 +193,13 @@ def fc(self, inp, num_out, name, relu=True): dim *= int(d) feed_in = tf.reshape(inp, [-1, dim]) else: - feed_in, dim = (inp, input_shape[-1].value) + feed_in, dim = (inp, int(input_shape[-1])) weights = self.make_var('weights', shape=[dim, num_out]) biases = self.make_var('biases', [num_out]) - op = tf.nn.relu_layer if relu else tf.nn.xw_plus_b - fc = op(feed_in, weights, biases, name=name) + if relu: + fc = tf.nn.relu(tf.matmul(feed_in, weights) + biases, name=name) + else: + fc = tf.add(tf.matmul(feed_in, weights), biases, name=name) return fc @@ -210,7 +214,7 @@ def softmax(self, target, axis, name=None): max_axis = tf.reduce_max(target, axis, keepdims=True) target_exp = tf.exp(target-max_axis) normalize = tf.reduce_sum(target_exp, axis, keepdims=True) - softmax = tf.div(target_exp, normalize, name) + softmax = tf.divide(target_exp, normalize, name) return softmax class PNet(Network): @@ -277,16 +281,16 @@ def create_mtcnn(sess, model_path): if not model_path: model_path,_ = os.path.split(os.path.realpath(__file__)) - with tf.variable_scope('pnet'): - data = tf.placeholder(tf.float32, (None,None,None,3), 'input') + with tf.compat.v1.variable_scope('pnet'): + data = tf.compat.v1.placeholder(tf.float32, (None,None,None,3), 'input') pnet = PNet({'data':data}) pnet.load(os.path.join(model_path, 'det1.npy'), sess) - with tf.variable_scope('rnet'): - data = tf.placeholder(tf.float32, (None,24,24,3), 'input') + with tf.compat.v1.variable_scope('rnet'): + data = tf.compat.v1.placeholder(tf.float32, (None,24,24,3), 'input') rnet = RNet({'data':data}) rnet.load(os.path.join(model_path, 'det2.npy'), sess) - with tf.variable_scope('onet'): - data = tf.placeholder(tf.float32, (None,48,48,3), 'input') + with tf.compat.v1.variable_scope('onet'): + data = tf.compat.v1.placeholder(tf.float32, (None,48,48,3), 'input') onet = ONet({'data':data}) onet.load(os.path.join(model_path, 'det3.npy'), sess) diff --git a/tindetheus/facenet_clone/facenet.py b/tindetheus/facenet_clone/facenet.py index 76c1bb3..189ebee 100644 --- a/tindetheus/facenet_clone/facenet.py +++ b/tindetheus/facenet_clone/facenet.py @@ -378,8 +378,8 @@ def load_model(model, input_map=None): print('Metagraph file: %s' % meta_file) print('Checkpoint file: %s' % ckpt_file) - saver = tf.train.import_meta_graph(os.path.join(model_exp, meta_file), input_map=input_map) - saver.restore(tf.get_default_session(), os.path.join(model_exp, ckpt_file)) + saver = tf.compat.v1.train.import_meta_graph(os.path.join(model_exp, meta_file), input_map=input_map) + saver.restore(tf.compat.v1.get_default_session(), os.path.join(model_exp, ckpt_file)) def get_model_filenames(model_dir): files = os.listdir(model_dir) @@ -389,7 +389,7 @@ def get_model_filenames(model_dir): elif len(meta_files)>1: raise ValueError('There should not be more than one meta file in the model directory (%s)' % model_dir) meta_file = meta_files[0] - ckpt = tf.train.get_checkpoint_state(model_dir) + ckpt = tf.compat.v1.train.get_checkpoint_state(model_dir) if ckpt and ckpt.model_checkpoint_path: ckpt_file = os.path.basename(ckpt.model_checkpoint_path) return meta_file, ckpt_file @@ -535,6 +535,9 @@ def store_revision_info(src_path, output_dir, arg_string): git_diff = ' '.join(cmd) + ': ' + e.strerror # Store a text file in the log directory + # Ensure the directory exists + if not os.path.exists(output_dir): + os.makedirs(output_dir) rev_info_filename = os.path.join(output_dir, 'revision_info.txt') with open(rev_info_filename, "w") as text_file: text_file.write('arguments: %s\n--------------------\n' % arg_string) diff --git a/tindetheus/image_processing.py b/tindetheus/image_processing.py index 0d9c1a0..8b5c520 100644 --- a/tindetheus/image_processing.py +++ b/tindetheus/image_processing.py @@ -27,6 +27,7 @@ import os import shutil +import ssl import matplotlib.pyplot as plt import imageio @@ -40,7 +41,11 @@ FileNotFoundError = IOError try: - from urllib.request import urlretrieve + from urllib.request import urlretrieve, urlopen + import urllib.request + # Create SSL context that doesn't verify certificates + ssl_context = ssl._create_unverified_context() + urllib.request.install_opener(urllib.request.build_opener(urllib.request.HTTPSHandler(context=ssl_context))) except ImportError: from urllib import urlretrieve @@ -53,21 +58,35 @@ def clean_temp_images(): def clean_temp_images_aligned(): # delete the temp images aligned dir - shutil.rmtree('temp_images_aligned') + if os.path.exists('temp_images_aligned'): + shutil.rmtree('temp_images_aligned', ignore_errors=True) def download_url_photos(urls, userID, is_temp=False): # define a function which downloads the pictures of urls + import urllib.request count = 0 image_list = [] if is_temp is True: os.makedirs('temp_images/temp') + + # Create SSL context that doesn't verify certificates for macOS + ssl_context = ssl._create_unverified_context() + for url in urls: if is_temp is True: image_list.append('temp_images/temp/'+userID+'.'+str(count)+'.jpg') else: image_list.append('temp_images/'+userID+'.'+str(count)+'.jpg') - urlretrieve(url, image_list[-1]) + + # Download with SSL context + try: + with urllib.request.urlopen(url, context=ssl_context) as response: + with open(image_list[-1], 'wb') as out_file: + out_file.write(response.read()) + except Exception as e: + print(f"Warning: Could not download image {count} for user {userID}: {e}") + count += 1 return image_list @@ -139,10 +158,31 @@ def show_images(images, holdon=False, title=None, nmax=49): n_row = n // n_col else: n_row = n // 3 + 1 + + # Create a reasonable figure size (width, height in inches) + # Smaller size to leave room for terminal + figsize = (n_col * 3, n_row * 3) + if title is None: - plt.figure() + fig = plt.figure(figsize=figsize) else: - plt.figure(title) + fig = plt.figure(title, figsize=figsize) + + # Position window on left half of screen (macOS compatible) + try: + manager = plt.get_current_fig_manager() + # Use matplotlib's backend to position the window + # Position at (0, 0) which is top-left, and let the OS handle sizing + if hasattr(manager, 'window'): + # For TkAgg backend on macOS + try: + # Get the window and position it + manager.window.wm_geometry("+0+0") + except: + pass + except: + pass # Fallback if positioning fails + plt.tight_layout() for j, i in enumerate(images): if j == nmax: diff --git a/tindetheus/machine_learning.py b/tindetheus/machine_learning.py index ed79df2..15f5c84 100644 --- a/tindetheus/machine_learning.py +++ b/tindetheus/machine_learning.py @@ -136,14 +136,21 @@ def like_or_dislike(): # define a function to get like or dislike input likeOrDislike = '0' while likeOrDislike != 'j' and likeOrDislike != 'l' \ - and likeOrDislike != 'f' and likeOrDislike != 's': + and likeOrDislike != 'f' and likeOrDislike != 's' \ + and likeOrDislike != 'n' and likeOrDislike != 'q': + + try: + likeOrDislike = input() + except KeyboardInterrupt: + print('\n\nExiting gracefully...') + raise SystemExit(0) - likeOrDislike = input() if likeOrDislike == 'j' or likeOrDislike == 'f': return 'Dislike' elif likeOrDislike == 'l' or likeOrDislike == 's': return 'Like' + elif likeOrDislike == 'n' or likeOrDislike == 'q': + return 'Skip' else: - print('you must enter either l or s for like,' - ' or j or f for dislike') + print('you must enter either l or s for like, j or f for dislike, or n or q to skip/quit') likeOrDislike = input() diff --git a/tindetheus/tinder_client.py b/tindetheus/tinder_client.py index 52a58ee..dd5c75c 100644 --- a/tindetheus/tinder_client.py +++ b/tindetheus/tinder_client.py @@ -61,6 +61,7 @@ from builtins import input import os +import sys import time import pynder from pynder.errors import RecsTimeout @@ -70,6 +71,9 @@ import tensorflow as tf import joblib +# Suppress macOS IMKClient messages +os.environ['PYTHONUNBUFFERED'] = '1' + from tindetheus import tindetheus_align import tindetheus.facenet_clone.facenet as facenet from tindetheus.export_embeddings import load_and_align_data @@ -132,6 +136,7 @@ def look_at_users(self, users): # Browse user profiles one at a time. You will be presented with the # opportunity to like or dislike profiles. Your history will be # stored in a database that you can use for training. + for user in users: print('********************************************************') print(user.name, user.age, 'Distance in km: ', user.distance_km) @@ -140,7 +145,7 @@ def look_at_users(self, users): print(user.bio) print('--------------------------------------------------------') print('Do you like this user?') - print('type l or s for like, or j or f for dislike ') + print('type l or s for like, j or f for dislike, or n or q to skip/quit') urls = user.get_photos(width='640') image_list = imgproc.download_url_photos(urls, user.id) imgproc.show_images(image_list) @@ -148,18 +153,47 @@ def look_at_users(self, users): didILike = ml.like_or_dislike() plt.close('all') + # Handle skip + if didILike == 'Skip': + print('⊘ Skipped') + # Clean up images without saving + for img in image_list: + try: + os.remove(img) + except: + pass + continue + dbase_names = imgproc.move_images(image_list, user.id, didILike) + api_success = False if didILike == 'Like': - print(user.like()) - self.likes_left -= 1 + try: + result = user.like() + print(f'✓ Liked {user.name} (user_id: {user.id})') + if result: + print(f' → Match! {result}') + self.likes_left -= 1 + api_success = True + except Exception as e: + print(f'✗ Error liking {user.name}: {e}') + print(f' → User NOT saved to database due to API error') else: - print(user.dislike()) - userList = [user.id, user.name, user.age, user.bio, - user.distance_km, user.jobs, user.schools, - user.get_photos(width='640'), dbase_names, didILike] - self.database.append(userList) - np.save('database.npy', self.database) + try: + user.dislike() + print(f'✓ Passed {user.name} (user_id: {user.id})') + api_success = True + except Exception as e: + print(f'✗ Error passing {user.name}: {e}') + print(f' → User NOT saved to database due to API error') + + # Only save to database if API call succeeded + if api_success: + userList = [user.id, user.name, user.age, user.bio, + user.distance_km, user.jobs, user.schools, + user.get_photos(width='640'), dbase_names, didILike] + self.database.append(userList) + np.save('database.npy', np.array(self.database, dtype=object)) def like_or_dislike_users(self, users): # automatically like or dislike users based on your previously trained @@ -190,9 +224,9 @@ def like_or_dislike_users(self, users): image_list_temp, label_list = facenet.get_image_paths_and_labels(train_set) # noqa: E501 # Get input and output tensors - images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0") # noqa: E501 - embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0") # noqa: E501 - phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0") # noqa: E501 + images_placeholder = tf.compat.v1.get_default_graph().get_tensor_by_name("input:0") # noqa: E501 + embeddings = tf.compat.v1.get_default_graph().get_tensor_by_name("embeddings:0") # noqa: E501 + phase_train_placeholder = tf.compat.v1.get_default_graph().get_tensor_by_name("phase_train:0") # noqa: E501 # Run forward pass to calculate embeddings nrof_images = len(image_list_temp) @@ -265,17 +299,36 @@ def like_or_dislike_users(self, users): dbase_names = imgproc.move_images_temp(image_list, user.id) + api_success = False if didILike == 'Like': - print(user.like()) - self.likes_left -= 1 + try: + result = user.like() + print(f'✓ Liked {user.name} (user_id: {user.id})') + if result: + print(f' → Match! {result}') + self.likes_left -= 1 + api_success = True + except Exception as e: + print(f'✗ Error liking {user.name}: {e}') + print(f' → User NOT saved to database due to API error') else: - print(user.dislike()) - userList = [user.id, user.name, user.age, user.bio, - user.distance_km, user.jobs, user.schools, - user.get_photos(width='640'), dbase_names, - didILike] - self.al_database.append(userList) - np.save('al_database.npy', self.al_database) + try: + user.dislike() + print(f'✓ Passed {user.name} (user_id: {user.id})') + api_success = True + except Exception as e: + print(f'✗ Error passing {user.name}: {e}') + print(f' → User NOT saved to database due to API error') + + # Only save to database if API call succeeded + if api_success: + userList = [user.id, user.name, user.age, user.bio, + user.distance_km, user.jobs, user.schools, + user.get_photos(width='640'), dbase_names, + didILike] + self.al_database.append(userList) + np.save('al_database.npy', np.array(self.al_database, dtype=object)) + imgproc.clean_temp_images_aligned() def browse(self): diff --git a/tindetheus/tindetheus.py b/tindetheus/tindetheus.py index 0f85aba..0579649 100755 --- a/tindetheus/tindetheus.py +++ b/tindetheus/tindetheus.py @@ -32,6 +32,8 @@ import matplotlib.pyplot as plt import numpy as np import tensorflow as tf +# Disable TensorFlow 2.x behavior for compatibility +tf.compat.v1.disable_eager_execution() import joblib try: @@ -139,7 +141,7 @@ def main(args, facebook_token, x_auth_token=None, retries=20): print('... Loading the facenet model ...') print('... be patient this may take some time ...') with tf.Graph().as_default(): - with tf.Session() as sess: + with tf.compat.v1.Session() as sess: # pass the tf session into client object my_sess = client(facebook_token, args.distance, args.model_dir, likes_left=args.likes, diff --git a/tindetheus/tindetheus_align.py b/tindetheus/tindetheus_align.py index d47b4da..65003bd 100644 --- a/tindetheus/tindetheus_align.py +++ b/tindetheus/tindetheus_align.py @@ -61,6 +61,8 @@ import sys import os import tensorflow as tf +# Disable TensorFlow 2.x behavior for compatibility +tf.compat.v1.disable_eager_execution() import numpy as np import tindetheus.facenet_clone.facenet as facenet from tindetheus.facenet_clone.align import detect_face @@ -83,8 +85,8 @@ def main(input_dir='database', output_dir='database_aligned', image_size=182, print('Creating networks and loading parameters') with tf.Graph().as_default(): - gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) # noqa: E501 - sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, + gpu_options = tf.compat.v1.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) # noqa: E501 + sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(gpu_options=gpu_options, log_device_placement=False)) with sess.as_default(): pnet, rnet, onet = detect_face.create_mtcnn(sess, None)