Repository: davidsandberg/facenet
Branch: master
Commit: 096ed770f163
Files: 94
Total size: 669.0 KB
Directory structure:
gitextract_mncf1i0j/
├── .gitignore
├── .project
├── .pydevproject
├── .pylintrc
├── .travis.yml
├── LICENSE.md
├── README.md
├── __init__.py
├── contributed/
│ ├── __init__.py
│ ├── batch_represent.py
│ ├── cluster.py
│ ├── clustering.py
│ ├── export_embeddings.py
│ ├── face.py
│ ├── predict.py
│ └── real_time_face_recognition.py
├── data/
│ ├── learning_rate_retrain_tripletloss.txt
│ ├── learning_rate_schedule_classifier_casia.txt
│ ├── learning_rate_schedule_classifier_msceleb.txt
│ ├── learning_rate_schedule_classifier_vggface2.txt
│ └── pairs.txt
├── requirements.txt
├── src/
│ ├── __init__.py
│ ├── align/
│ │ ├── __init__.py
│ │ ├── align_dataset_mtcnn.py
│ │ ├── det1.npy
│ │ ├── det2.npy
│ │ ├── det3.npy
│ │ └── detect_face.py
│ ├── calculate_filtering_metrics.py
│ ├── classifier.py
│ ├── compare.py
│ ├── decode_msceleb_dataset.py
│ ├── download_and_extract.py
│ ├── facenet.py
│ ├── freeze_graph.py
│ ├── generative/
│ │ ├── __init__.py
│ │ ├── calculate_attribute_vectors.py
│ │ ├── models/
│ │ │ ├── __init__.py
│ │ │ ├── dfc_vae.py
│ │ │ ├── dfc_vae_large.py
│ │ │ ├── dfc_vae_resnet.py
│ │ │ └── vae_base.py
│ │ ├── modify_attribute.py
│ │ └── train_vae.py
│ ├── lfw.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── dummy.py
│ │ ├── inception_resnet_v1.py
│ │ ├── inception_resnet_v2.py
│ │ └── squeezenet.py
│ ├── train_softmax.py
│ ├── train_tripletloss.py
│ └── validate_on_lfw.py
├── test/
│ ├── batch_norm_test.py
│ ├── center_loss_test.py
│ ├── restore_test.py
│ ├── train_test.py
│ └── triplet_loss_test.py
├── tmp/
│ ├── __init__.py
│ ├── align_dataset.m
│ ├── align_dataset.py
│ ├── align_dlib.py
│ ├── cacd2000_split_identities.py
│ ├── dataset_read_speed.py
│ ├── deepdream.py
│ ├── detect_face_v1.m
│ ├── detect_face_v2.m
│ ├── download_vgg_face_dataset.py
│ ├── funnel_dataset.py
│ ├── invariance_test.txt
│ ├── mnist_center_loss.py
│ ├── mnist_noise_labels.py
│ ├── mtcnn.py
│ ├── mtcnn_test.py
│ ├── mtcnn_test_pnet_dbg.py
│ ├── network.py
│ ├── nn2.py
│ ├── nn3.py
│ ├── nn4.py
│ ├── nn4_small2_v1.py
│ ├── random_test.py
│ ├── rename_casia_directories.py
│ ├── seed_test.py
│ ├── select_triplets_test.py
│ ├── test1.py
│ ├── test_align.py
│ ├── test_invariance_on_lfw.py
│ ├── vggface16.py
│ ├── vggverydeep19.py
│ ├── visualize.py
│ ├── visualize_vgg_model.py
│ └── visualize_vggface.py
└── util/
└── plot_learning_curves.m
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
led / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# 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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
# PyCharm project setting
.idea
================================================
FILE: .project
================================================
facenet
org.python.pydev.PyDevBuilder
org.python.pydev.pythonNature
================================================
FILE: .pydevproject
================================================
/${PROJECT_DIR_NAME}
/${PROJECT_DIR_NAME}/src
python 2.7
Default
================================================
FILE: .pylintrc
================================================
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=1
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=cv2
# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
[ELIF]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=100
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )??$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of boolean expressions in a if statement
max-bool-expr=5
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
================================================
FILE: .travis.yml
================================================
language: python
sudo: required
python:
- "2.7"
- "3.5"
# command to install dependencies
install:
# numpy not using wheel to avoid problem described in
# https://github.com/tensorflow/tensorflow/issues/6968
- pip install --no-binary numpy --upgrade numpy
- pip install -r requirements.txt
# command to run tests
script:
- export PYTHONPATH=./src:./src/models:./src/align
- python -m unittest discover -s test --pattern=*.py 1>&2
dist: trusty
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2016 David Sandberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Face Recognition using Tensorflow [![Build Status][travis-image]][travis]
[travis-image]: http://travis-ci.org/davidsandberg/facenet.svg?branch=master
[travis]: http://travis-ci.org/davidsandberg/facenet
This is a TensorFlow implementation of the face recognizer described in the paper
["FaceNet: A Unified Embedding for Face Recognition and Clustering"](http://arxiv.org/abs/1503.03832). The project also uses ideas from the paper ["Deep Face Recognition"](http://www.robots.ox.ac.uk/~vgg/publications/2015/Parkhi15/parkhi15.pdf) from the [Visual Geometry Group](http://www.robots.ox.ac.uk/~vgg/) at Oxford.
## Compatibility
The code is tested using Tensorflow r1.7 under Ubuntu 14.04 with Python 2.7 and Python 3.5. The test cases can be found [here](https://github.com/davidsandberg/facenet/tree/master/test) and the results can be found [here](http://travis-ci.org/davidsandberg/facenet).
## News
| Date | Update |
|----------|--------|
| 2018-04-10 | Added new models trained on Casia-WebFace and VGGFace2 (see below). Note that the models uses fixed image standardization (see [wiki](https://github.com/davidsandberg/facenet/wiki/Training-using-the-VGGFace2-dataset)). |
| 2018-03-31 | Added a new, more flexible input pipeline as well as a bunch of minor updates. |
| 2017-05-13 | Removed a bunch of older non-slim models. Moved the last bottleneck layer into the respective models. Corrected normalization of Center Loss. |
| 2017-05-06 | Added code to [train a classifier on your own images](https://github.com/davidsandberg/facenet/wiki/Train-a-classifier-on-own-images). Renamed facenet_train.py to train_tripletloss.py and facenet_train_classifier.py to train_softmax.py. |
| 2017-03-02 | Added pretrained models that generate 128-dimensional embeddings.|
| 2017-02-22 | Updated to Tensorflow r1.0. Added Continuous Integration using Travis-CI.|
| 2017-02-03 | Added models where only trainable variables has been stored in the checkpoint. These are therefore significantly smaller. |
| 2017-01-27 | Added a model trained on a subset of the MS-Celeb-1M dataset. The LFW accuracy of this model is around 0.994. |
| 2017‑01‑02 | Updated to run with Tensorflow r0.12. Not sure if it runs with older versions of Tensorflow though. |
## Pre-trained models
| Model name | LFW accuracy | Training dataset | Architecture |
|-----------------|--------------|------------------|-------------|
| [20180408-102900](https://drive.google.com/open?id=1R77HmFADxe87GmoLwzfgMu_HY0IhcyBz) | 0.9905 | CASIA-WebFace | [Inception ResNet v1](https://github.com/davidsandberg/facenet/blob/master/src/models/inception_resnet_v1.py) |
| [20180402-114759](https://drive.google.com/open?id=1EXPBSXwTaqrSC0OhUdXNmKSh9qJUQ55-) | 0.9965 | VGGFace2 | [Inception ResNet v1](https://github.com/davidsandberg/facenet/blob/master/src/models/inception_resnet_v1.py) |
NOTE: If you use any of the models, please do not forget to give proper credit to those providing the training dataset as well.
## Inspiration
The code is heavily inspired by the [OpenFace](https://github.com/cmusatyalab/openface) implementation.
## Training data
The [CASIA-WebFace](http://www.cbsr.ia.ac.cn/english/CASIA-WebFace-Database.html) dataset has been used for training. This training set consists of total of 453 453 images over 10 575 identities after face detection. Some performance improvement has been seen if the dataset has been filtered before training. Some more information about how this was done will come later.
The best performing model has been trained on the [VGGFace2](https://www.robots.ox.ac.uk/~vgg/data/vgg_face2/) dataset consisting of ~3.3M faces and ~9000 classes.
## Pre-processing
### Face alignment using MTCNN
One problem with the above approach seems to be that the Dlib face detector misses some of the hard examples (partial occlusion, silhouettes, etc). This makes the training set too "easy" which causes the model to perform worse on other benchmarks.
To solve this, other face landmark detectors has been tested. One face landmark detector that has proven to work very well in this setting is the
[Multi-task CNN](https://kpzhang93.github.io/MTCNN_face_detection_alignment/index.html). A Matlab/Caffe implementation can be found [here](https://github.com/kpzhang93/MTCNN_face_detection_alignment) and this has been used for face alignment with very good results. A Python/Tensorflow implementation of MTCNN can be found [here](https://github.com/davidsandberg/facenet/tree/master/src/align). This implementation does not give identical results to the Matlab/Caffe implementation but the performance is very similar.
## Running training
Currently, the best results are achieved by training the model using softmax loss. Details on how to train a model using softmax loss on the CASIA-WebFace dataset can be found on the page [Classifier training of Inception-ResNet-v1](https://github.com/davidsandberg/facenet/wiki/Classifier-training-of-inception-resnet-v1) and .
## Pre-trained models
### Inception-ResNet-v1 model
A couple of pretrained models are provided. They are trained using softmax loss with the Inception-Resnet-v1 model. The datasets has been aligned using [MTCNN](https://github.com/davidsandberg/facenet/tree/master/src/align).
## Performance
The accuracy on LFW for the model [20180402-114759](https://drive.google.com/open?id=1EXPBSXwTaqrSC0OhUdXNmKSh9qJUQ55-) is 0.99650+-0.00252. A description of how to run the test can be found on the page [Validate on LFW](https://github.com/davidsandberg/facenet/wiki/Validate-on-lfw). Note that the input images to the model need to be standardized using fixed image standardization (use the option `--use_fixed_image_standardization` when running e.g. `validate_on_lfw.py`).
================================================
FILE: __init__.py
================================================
================================================
FILE: contributed/__init__.py
================================================
================================================
FILE: contributed/batch_represent.py
================================================
#!/usr/bin/env python
# coding=utf-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
"""
Allows you to generate embeddings from a directory of images in the format:
Instructions:
Image data directory should look like the following figure:
person-1
├── image-1.jpg
├── image-2.png
...
└── image-p.png
...
person-m
├── image-1.png
├── image-2.jpg
...
└── image-q.png
Trained Model:
- Both the trained model metagraph and the model parameters need to exist
in the same directory, and the metagraph should have the extension '.meta'.
####
USAGE:
$ python batch_represent.py -d -o --trained_model_dir
###
"""
"""
Attributions:
The code is heavily inspired by the code from by David Sandberg's ../src/validate_on_lfw.py
The concept is inspired by Brandon Amos' github.com/cmusatyalab/openface/blob/master/batch-represent/batch-represent.lua
"""
#----------------------------------------------------
# MIT License
#
# Copyright (c) 2017 Rakshak Talwar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#----------------------------------------------------
import os
import sys
import argparse
import importlib
import time
sys.path.insert(1, "../src")
import facenet
import numpy as np
from sklearn.datasets import load_files
import tensorflow as tf
from six.moves import xrange
def main(args):
with tf.Graph().as_default():
with tf.Session() as sess:
# create output directory if it doesn't exist
output_dir = os.path.expanduser(args.output_dir)
if not os.path.isdir(output_dir):
os.makedirs(output_dir)
# load the model
print("Loading trained model...\n")
meta_file, ckpt_file = facenet.get_model_filenames(os.path.expanduser(args.trained_model_dir))
facenet.load_model(args.trained_model_dir, meta_file, ckpt_file)
# grab all image paths and labels
print("Finding image paths and targets...\n")
data = load_files(args.data_dir, load_content=False, shuffle=False)
labels_array = data['target']
paths = data['filenames']
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
image_size = images_placeholder.get_shape()[1]
embedding_size = embeddings.get_shape()[1]
# Run forward pass to calculate embeddings
print('Generating embeddings from images...\n')
start_time = time.time()
batch_size = args.batch_size
nrof_images = len(paths)
nrof_batches = int(np.ceil(1.0*nrof_images / batch_size))
emb_array = np.zeros((nrof_images, embedding_size))
for i in xrange(nrof_batches):
start_index = i*batch_size
end_index = min((i+1)*batch_size, nrof_images)
paths_batch = paths[start_index:end_index]
images = facenet.load_data(paths_batch, do_random_crop=False, do_random_flip=False, image_size=image_size, do_prewhiten=True)
feed_dict = { images_placeholder:images, phase_train_placeholder:False}
emb_array[start_index:end_index,:] = sess.run(embeddings, feed_dict=feed_dict)
time_avg_forward_pass = (time.time() - start_time) / float(nrof_images)
print("Forward pass took avg of %.3f[seconds/image] for %d images\n" % (time_avg_forward_pass, nrof_images))
print("Finally saving embeddings and gallery to: %s" % (output_dir))
# save the gallery and embeddings (signatures) as numpy arrays to disk
np.save(os.path.join(output_dir, "gallery.npy"), labels_array)
np.save(os.path.join(output_dir, "signatures.npy"), emb_array)
def parse_arguments(argv):
parser = argparse.ArgumentParser(description="Batch-represent face embeddings from a given data directory")
parser.add_argument('-d', '--data_dir', type=str,
help='directory of images with structure as seen at the top of this file.')
parser.add_argument('-o', '--output_dir', type=str,
help='directory containing aligned face patches with file structure as seen at the top of this file.')
parser.add_argument('--trained_model_dir', type=str,
help='Load a trained model before training starts.')
parser.add_argument('--batch_size', type=int, help='Number of images to process in a batch.', default=50)
return parser.parse_args(argv)
if __name__ == "__main__":
main(parse_arguments(sys.argv[1:]))
================================================
FILE: contributed/cluster.py
================================================
# MIT License
#
# Copyright (c) 2017 PXL University College
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Clusters similar faces from input folder together in folders based on euclidean distance matrix
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import tensorflow as tf
import numpy as np
import os
import sys
import argparse
import facenet
import align.detect_face
from sklearn.cluster import DBSCAN
def main(args):
pnet, rnet, onet = create_network_face_detection(args.gpu_memory_fraction)
with tf.Graph().as_default():
with tf.Session() as sess:
facenet.load_model(args.model)
image_list = load_images_from_folder(args.data_dir)
images = align_data(image_list, args.image_size, args.margin, pnet, rnet, onet)
images_placeholder = sess.graph.get_tensor_by_name("input:0")
embeddings = sess.graph.get_tensor_by_name("embeddings:0")
phase_train_placeholder = sess.graph.get_tensor_by_name("phase_train:0")
feed_dict = {images_placeholder: images, phase_train_placeholder: False}
emb = sess.run(embeddings, feed_dict=feed_dict)
nrof_images = len(images)
matrix = np.zeros((nrof_images, nrof_images))
print('')
# Print distance matrix
print('Distance matrix')
print(' ', end='')
for i in range(nrof_images):
print(' %1d ' % i, end='')
print('')
for i in range(nrof_images):
print('%1d ' % i, end='')
for j in range(nrof_images):
dist = np.sqrt(np.sum(np.square(np.subtract(emb[i, :], emb[j, :]))))
matrix[i][j] = dist
print(' %1.4f ' % dist, end='')
print('')
print('')
# DBSCAN is the only algorithm that doesn't require the number of clusters to be defined.
db = DBSCAN(eps=args.cluster_threshold, min_samples=args.min_cluster_size, metric='precomputed')
db.fit(matrix)
labels = db.labels_
# get number of clusters
no_clusters = len(set(labels)) - (1 if -1 in labels else 0)
print('No of clusters:', no_clusters)
if no_clusters > 0:
if args.largest_cluster_only:
largest_cluster = 0
for i in range(no_clusters):
print('Cluster {}: {}'.format(i, np.nonzero(labels == i)[0]))
if len(np.nonzero(labels == i)[0]) > len(np.nonzero(labels == largest_cluster)[0]):
largest_cluster = i
print('Saving largest cluster (Cluster: {})'.format(largest_cluster))
cnt = 1
for i in np.nonzero(labels == largest_cluster)[0]:
misc.imsave(os.path.join(args.out_dir, str(cnt) + '.png'), images[i])
cnt += 1
else:
print('Saving all clusters')
for i in range(no_clusters):
cnt = 1
print('Cluster {}: {}'.format(i, np.nonzero(labels == i)[0]))
path = os.path.join(args.out_dir, str(i))
if not os.path.exists(path):
os.makedirs(path)
for j in np.nonzero(labels == i)[0]:
misc.imsave(os.path.join(path, str(cnt) + '.png'), images[j])
cnt += 1
else:
for j in np.nonzero(labels == i)[0]:
misc.imsave(os.path.join(path, str(cnt) + '.png'), images[j])
cnt += 1
def align_data(image_list, image_size, margin, pnet, rnet, onet):
minsize = 20 # minimum size of face
threshold = [0.6, 0.7, 0.7] # three steps's threshold
factor = 0.709 # scale factor
img_list = []
for x in xrange(len(image_list)):
img_size = np.asarray(image_list[x].shape)[0:2]
bounding_boxes, _ = align.detect_face.detect_face(image_list[x], minsize, pnet, rnet, onet, threshold, factor)
nrof_samples = len(bounding_boxes)
if nrof_samples > 0:
for i in xrange(nrof_samples):
if bounding_boxes[i][4] > 0.95:
det = np.squeeze(bounding_boxes[i, 0:4])
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0] - margin / 2, 0)
bb[1] = np.maximum(det[1] - margin / 2, 0)
bb[2] = np.minimum(det[2] + margin / 2, img_size[1])
bb[3] = np.minimum(det[3] + margin / 2, img_size[0])
cropped = image_list[x][bb[1]:bb[3], bb[0]:bb[2], :]
aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
prewhitened = facenet.prewhiten(aligned)
img_list.append(prewhitened)
if len(img_list) > 0:
images = np.stack(img_list)
return images
else:
return None
def create_network_face_detection(gpu_memory_fraction):
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
return pnet, rnet, onet
def load_images_from_folder(folder):
images = []
for filename in os.listdir(folder):
img = misc.imread(os.path.join(folder, filename))
if img is not None:
images.append(img)
return images
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('model', type=str,
help='Either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file')
parser.add_argument('data_dir', type=str,
help='The directory containing the images to cluster into folders.')
parser.add_argument('out_dir', type=str,
help='The output directory where the image clusters will be saved.')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--margin', type=int,
help='Margin for the crop around the bounding box (height, width) in pixels.', default=44)
parser.add_argument('--min_cluster_size', type=int,
help='The minimum amount of pictures required for a cluster.', default=1)
parser.add_argument('--cluster_threshold', type=float,
help='The minimum distance for faces to be in the same cluster', default=1.0)
parser.add_argument('--largest_cluster_only', action='store_true',
help='This argument will make that only the biggest cluster is saved.')
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: contributed/clustering.py
================================================
""" Face Cluster """
import tensorflow as tf
import numpy as np
import importlib
import argparse
import facenet
import os
import math
def face_distance(face_encodings, face_to_compare):
"""
Given a list of face encodings, compare them to a known face encoding and get a euclidean distance
for each comparison face. The distance tells you how similar the faces are.
:param faces: List of face encodings to compare
:param face_to_compare: A face encoding to compare against
:return: A numpy ndarray with the distance for each face in the same order as the 'faces' array
"""
import numpy as np
if len(face_encodings) == 0:
return np.empty((0))
#return 1/np.linalg.norm(face_encodings - face_to_compare, axis=1)
return np.sum(face_encodings*face_to_compare,axis=1)
def load_model(model_dir, meta_file, ckpt_file):
model_dir_exp = os.path.expanduser(model_dir)
saver = tf.train.import_meta_graph(os.path.join(model_dir_exp, meta_file))
saver.restore(tf.get_default_session(), os.path.join(model_dir_exp, ckpt_file))
def _chinese_whispers(encoding_list, threshold=0.55, iterations=20):
""" Chinese Whispers Algorithm
Modified from Alex Loveless' implementation,
http://alexloveless.co.uk/data/chinese-whispers-graph-clustering-in-python/
Inputs:
encoding_list: a list of facial encodings from face_recognition
threshold: facial match threshold,default 0.6
iterations: since chinese whispers is an iterative algorithm, number of times to iterate
Outputs:
sorted_clusters: a list of clusters, a cluster being a list of imagepaths,
sorted by largest cluster to smallest
"""
#from face_recognition.api import _face_distance
from random import shuffle
import networkx as nx
# Create graph
nodes = []
edges = []
image_paths, encodings = zip(*encoding_list)
if len(encodings) <= 1:
print ("No enough encodings to cluster!")
return []
for idx, face_encoding_to_check in enumerate(encodings):
# Adding node of facial encoding
node_id = idx+1
# Initialize 'cluster' to unique value (cluster of itself)
node = (node_id, {'cluster': image_paths[idx], 'path': image_paths[idx]})
nodes.append(node)
# Facial encodings to compare
if (idx+1) >= len(encodings):
# Node is last element, don't create edge
break
compare_encodings = encodings[idx+1:]
distances = face_distance(compare_encodings, face_encoding_to_check)
encoding_edges = []
for i, distance in enumerate(distances):
if distance > threshold:
# Add edge if facial match
edge_id = idx+i+2
encoding_edges.append((node_id, edge_id, {'weight': distance}))
edges = edges + encoding_edges
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
# Iterate
for _ in range(0, iterations):
cluster_nodes = G.nodes()
shuffle(cluster_nodes)
for node in cluster_nodes:
neighbors = G[node]
clusters = {}
for ne in neighbors:
if isinstance(ne, int):
if G.node[ne]['cluster'] in clusters:
clusters[G.node[ne]['cluster']] += G[node][ne]['weight']
else:
clusters[G.node[ne]['cluster']] = G[node][ne]['weight']
# find the class with the highest edge weight sum
edge_weight_sum = 0
max_cluster = 0
#use the max sum of neighbor weights class as current node's class
for cluster in clusters:
if clusters[cluster] > edge_weight_sum:
edge_weight_sum = clusters[cluster]
max_cluster = cluster
# set the class of target node to the winning local class
G.node[node]['cluster'] = max_cluster
clusters = {}
# Prepare cluster output
for (_, data) in G.node.items():
cluster = data['cluster']
path = data['path']
if cluster:
if cluster not in clusters:
clusters[cluster] = []
clusters[cluster].append(path)
# Sort cluster output
sorted_clusters = sorted(clusters.values(), key=len, reverse=True)
return sorted_clusters
def cluster_facial_encodings(facial_encodings):
""" Cluster facial encodings
Intended to be an optional switch for different clustering algorithms, as of right now
only chinese whispers is available.
Input:
facial_encodings: (image_path, facial_encoding) dictionary of facial encodings
Output:
sorted_clusters: a list of clusters, a cluster being a list of imagepaths,
sorted by largest cluster to smallest
"""
if len(facial_encodings) <= 1:
print ("Number of facial encodings must be greater than one, can't cluster")
return []
# Only use the chinese whispers algorithm for now
sorted_clusters = _chinese_whispers(facial_encodings.items())
return sorted_clusters
def compute_facial_encodings(sess,images_placeholder,embeddings,phase_train_placeholder,image_size,
embedding_size,nrof_images,nrof_batches,emb_array,batch_size,paths):
""" Compute Facial Encodings
Given a set of images, compute the facial encodings of each face detected in the images and
return them. If no faces, or more than one face found, return nothing for that image.
Inputs:
image_paths: a list of image paths
Outputs:
facial_encodings: (image_path, facial_encoding) dictionary of facial encodings
"""
for i in range(nrof_batches):
start_index = i*batch_size
end_index = min((i+1)*batch_size, nrof_images)
paths_batch = paths[start_index:end_index]
images = facenet.load_data(paths_batch, False, False, image_size)
feed_dict = { images_placeholder:images, phase_train_placeholder:False }
emb_array[start_index:end_index,:] = sess.run(embeddings, feed_dict=feed_dict)
facial_encodings = {}
for x in range(nrof_images):
facial_encodings[paths[x]] = emb_array[x,:]
return facial_encodings
def get_onedir(paths):
dataset = []
path_exp = os.path.expanduser(paths)
if os.path.isdir(path_exp):
images = os.listdir(path_exp)
image_paths = [os.path.join(path_exp,img) for img in images]
for x in image_paths:
if os.path.getsize(x)>0:
dataset.append(x)
return dataset
def main(args):
""" Main
Given a list of images, save out facial encoding data files and copy
images into folders of face clusters.
"""
from os.path import join, basename, exists
from os import makedirs
import numpy as np
import shutil
import sys
if not exists(args.output):
makedirs(args.output)
with tf.Graph().as_default():
with tf.Session() as sess:
image_paths = get_onedir(args.input)
#image_list, label_list = facenet.get_image_paths_and_labels(train_set)
meta_file, ckpt_file = facenet.get_model_filenames(os.path.expanduser(args.model_dir))
print('Metagraph file: %s' % meta_file)
print('Checkpoint file: %s' % ckpt_file)
load_model(args.model_dir, meta_file, ckpt_file)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
image_size = images_placeholder.get_shape()[1]
print("image_size:",image_size)
embedding_size = embeddings.get_shape()[1]
# Run forward pass to calculate embeddings
print('Runnning forward pass on images')
nrof_images = len(image_paths)
nrof_batches = int(math.ceil(1.0*nrof_images / args.batch_size))
emb_array = np.zeros((nrof_images, embedding_size))
facial_encodings = compute_facial_encodings(sess,images_placeholder,embeddings,phase_train_placeholder,image_size,
embedding_size,nrof_images,nrof_batches,emb_array,args.batch_size,image_paths)
sorted_clusters = cluster_facial_encodings(facial_encodings)
num_cluster = len(sorted_clusters)
# Copy image files to cluster folders
for idx, cluster in enumerate(sorted_clusters):
#save all the cluster
cluster_dir = join(args.output, str(idx))
if not exists(cluster_dir):
makedirs(cluster_dir)
for path in cluster:
shutil.copy(path, join(cluster_dir, basename(path)))
def parse_args():
"""Parse input arguments."""
import argparse
parser = argparse.ArgumentParser(description='Get a shape mesh (t-pose)')
parser.add_argument('--model_dir', type=str, help='model dir', required=True)
parser.add_argument('--batch_size', type=int, help='batch size', required=30)
parser.add_argument('--input', type=str, help='Input dir of images', required=True)
parser.add_argument('--output', type=str, help='Output dir of clusters', required=True)
args = parser.parse_args()
return args
if __name__ == '__main__':
""" Entry point """
main(parse_args())
================================================
FILE: contributed/export_embeddings.py
================================================
"""
Exports the embeddings and labels of a directory of images as numpy arrays.
Typicall usage expect the image directory to be of the openface/facenet form and
the images to be aligned. Simply point to your model and your image directory:
python facenet/contributed/export_embeddings.py ~/models/facenet/20170216-091149/ ~/datasets/lfw/mylfw
Output:
embeddings.npy -- Embeddings as np array, Use --embeddings_name to change name
labels.npy -- Integer labels as np array, Use --labels_name to change name
label_strings.npy -- Strings from folders names, --labels_strings_name to change name
Use --image_batch to dictacte how many images to load in memory at a time.
If your images aren't already pre-aligned, use --is_aligned False
I started with compare.py from David Sandberg, and modified it to export
the embeddings. The image loading is done use the facenet library if the image
is pre-aligned. If the image isn't pre-aligned, I use the compare.py function.
I've found working with the embeddings useful for classifications models.
Charles Jekel 2017
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
from scipy import misc
import tensorflow as tf
import numpy as np
import sys
import os
import argparse
import facenet
import align.detect_face
import glob
from six.moves import xrange
def main(args):
train_set = facenet.get_dataset(args.data_dir)
image_list, label_list = facenet.get_image_paths_and_labels(train_set)
# fetch the classes (labels as strings) exactly as it's done in get_dataset
path_exp = os.path.expanduser(args.data_dir)
classes = [path for path in os.listdir(path_exp) \
if os.path.isdir(os.path.join(path_exp, path))]
classes.sort()
# get the label strings
label_strings = [name for name in classes if \
os.path.isdir(os.path.join(path_exp, name))]
with tf.Graph().as_default():
with tf.Session() as sess:
# Load the model
facenet.load_model(args.model_dir)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
# Run forward pass to calculate embeddings
nrof_images = len(image_list)
print('Number of images: ', nrof_images)
batch_size = args.image_batch
if nrof_images % batch_size == 0:
nrof_batches = nrof_images // batch_size
else:
nrof_batches = (nrof_images // batch_size) + 1
print('Number of batches: ', nrof_batches)
embedding_size = embeddings.get_shape()[1]
emb_array = np.zeros((nrof_images, embedding_size))
start_time = time.time()
for i in range(nrof_batches):
if i == nrof_batches -1:
n = nrof_images
else:
n = i*batch_size + batch_size
# Get images for the batch
if args.is_aligned is True:
images = facenet.load_data(image_list[i*batch_size:n], False, False, args.image_size)
else:
images = load_and_align_data(image_list[i*batch_size:n], args.image_size, args.margin, args.gpu_memory_fraction)
feed_dict = { images_placeholder: images, phase_train_placeholder:False }
# Use the facenet model to calcualte embeddings
embed = sess.run(embeddings, feed_dict=feed_dict)
emb_array[i*batch_size:n, :] = embed
print('Completed batch', i+1, 'of', nrof_batches)
run_time = time.time() - start_time
print('Run time: ', run_time)
# export emedings and labels
label_list = np.array(label_list)
np.save(args.embeddings_name, emb_array)
np.save(args.labels_name, label_list)
label_strings = np.array(label_strings)
np.save(args.labels_strings_name, label_strings[label_list])
def load_and_align_data(image_paths, image_size, margin, gpu_memory_fraction):
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
print('Creating networks and loading parameters')
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
nrof_samples = len(image_paths)
img_list = [None] * nrof_samples
for i in xrange(nrof_samples):
print(image_paths[i])
img = misc.imread(os.path.expanduser(image_paths[i]))
img_size = np.asarray(img.shape)[0:2]
bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
det = np.squeeze(bounding_boxes[0,0:4])
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0]-margin/2, 0)
bb[1] = np.maximum(det[1]-margin/2, 0)
bb[2] = np.minimum(det[2]+margin/2, img_size[1])
bb[3] = np.minimum(det[3]+margin/2, img_size[0])
cropped = img[bb[1]:bb[3],bb[0]:bb[2],:]
aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
prewhitened = facenet.prewhiten(aligned)
img_list[i] = prewhitened
images = np.stack(img_list)
return images
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('model_dir', type=str,
help='Directory containing the meta_file and ckpt_file')
parser.add_argument('data_dir', type=str,
help='Directory containing images. If images are not already aligned and cropped include --is_aligned False.')
parser.add_argument('--is_aligned', type=str,
help='Is the data directory already aligned and cropped?', default=True)
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--margin', type=int,
help='Margin for the crop around the bounding box (height, width) in pixels.',
default=44)
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.',
default=1.0)
parser.add_argument('--image_batch', type=int,
help='Number of images stored in memory at a time. Default 500.',
default=500)
# numpy file Names
parser.add_argument('--embeddings_name', type=str,
help='Enter string of which the embeddings numpy array is saved as.',
default='embeddings.npy')
parser.add_argument('--labels_name', type=str,
help='Enter string of which the labels numpy array is saved as.',
default='labels.npy')
parser.add_argument('--labels_strings_name', type=str,
help='Enter string of which the labels as strings numpy array is saved as.',
default='label_strings.npy')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: contributed/face.py
================================================
# coding=utf-8
"""Face Detection and Recognition"""
# MIT License
#
# Copyright (c) 2017 François Gervais
#
# This is the work of David Sandberg and shanren7 remodelled into a
# high level container. It's an attempt to simplify the use of such
# technology and provide an easy to use facial recognition package.
#
# https://github.com/davidsandberg/facenet
# https://github.com/shanren7/real_time_face_recognition
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import pickle
import os
import cv2
import numpy as np
import tensorflow as tf
from scipy import misc
import align.detect_face
import facenet
gpu_memory_fraction = 0.3
facenet_model_checkpoint = os.path.dirname(__file__) + "/../model_checkpoints/20170512-110547"
classifier_model = os.path.dirname(__file__) + "/../model_checkpoints/my_classifier_1.pkl"
debug = False
class Face:
def __init__(self):
self.name = None
self.bounding_box = None
self.image = None
self.container_image = None
self.embedding = None
class Recognition:
def __init__(self):
self.detect = Detection()
self.encoder = Encoder()
self.identifier = Identifier()
def add_identity(self, image, person_name):
faces = self.detect.find_faces(image)
if len(faces) == 1:
face = faces[0]
face.name = person_name
face.embedding = self.encoder.generate_embedding(face)
return faces
def identify(self, image):
faces = self.detect.find_faces(image)
for i, face in enumerate(faces):
if debug:
cv2.imshow("Face: " + str(i), face.image)
face.embedding = self.encoder.generate_embedding(face)
face.name = self.identifier.identify(face)
return faces
class Identifier:
def __init__(self):
with open(classifier_model, 'rb') as infile:
self.model, self.class_names = pickle.load(infile)
def identify(self, face):
if face.embedding is not None:
predictions = self.model.predict_proba([face.embedding])
best_class_indices = np.argmax(predictions, axis=1)
return self.class_names[best_class_indices[0]]
class Encoder:
def __init__(self):
self.sess = tf.Session()
with self.sess.as_default():
facenet.load_model(facenet_model_checkpoint)
def generate_embedding(self, face):
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
prewhiten_face = facenet.prewhiten(face.image)
# Run forward pass to calculate embeddings
feed_dict = {images_placeholder: [prewhiten_face], phase_train_placeholder: False}
return self.sess.run(embeddings, feed_dict=feed_dict)[0]
class Detection:
# face detection parameters
minsize = 20 # minimum size of face
threshold = [0.6, 0.7, 0.7] # three steps's threshold
factor = 0.709 # scale factor
def __init__(self, face_crop_size=160, face_crop_margin=32):
self.pnet, self.rnet, self.onet = self._setup_mtcnn()
self.face_crop_size = face_crop_size
self.face_crop_margin = face_crop_margin
def _setup_mtcnn(self):
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
return align.detect_face.create_mtcnn(sess, None)
def find_faces(self, image):
faces = []
bounding_boxes, _ = align.detect_face.detect_face(image, self.minsize,
self.pnet, self.rnet, self.onet,
self.threshold, self.factor)
for bb in bounding_boxes:
face = Face()
face.container_image = image
face.bounding_box = np.zeros(4, dtype=np.int32)
img_size = np.asarray(image.shape)[0:2]
face.bounding_box[0] = np.maximum(bb[0] - self.face_crop_margin / 2, 0)
face.bounding_box[1] = np.maximum(bb[1] - self.face_crop_margin / 2, 0)
face.bounding_box[2] = np.minimum(bb[2] + self.face_crop_margin / 2, img_size[1])
face.bounding_box[3] = np.minimum(bb[3] + self.face_crop_margin / 2, img_size[0])
cropped = image[face.bounding_box[1]:face.bounding_box[3], face.bounding_box[0]:face.bounding_box[2], :]
face.image = misc.imresize(cropped, (self.face_crop_size, self.face_crop_size), interp='bilinear')
faces.append(face)
return faces
================================================
FILE: contributed/predict.py
================================================
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
#----------------------------------------------------
# MIT License
#
# Copyright (c) 2017 Rishi Rai
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#----------------------------------------------------
import tensorflow as tf
import numpy as np
import argparse
import facenet
import os
import sys
import math
import pickle
from sklearn.svm import SVC
from scipy import misc
import align.detect_face
from six.moves import xrange
def main(args):
images, cout_per_image, nrof_samples = load_and_align_data(args.image_files,args.image_size, args.margin, args.gpu_memory_fraction)
with tf.Graph().as_default():
with tf.Session() as sess:
# Load the model
facenet.load_model(args.model)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
# Run forward pass to calculate embeddings
feed_dict = { images_placeholder: images , phase_train_placeholder:False}
emb = sess.run(embeddings, feed_dict=feed_dict)
classifier_filename_exp = os.path.expanduser(args.classifier_filename)
with open(classifier_filename_exp, 'rb') as infile:
(model, class_names) = pickle.load(infile)
print('Loaded classifier model from file "%s"\n' % classifier_filename_exp)
predictions = model.predict_proba(emb)
best_class_indices = np.argmax(predictions, axis=1)
best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices]
k=0
#print predictions
for i in range(nrof_samples):
print("\npeople in image %s :" %(args.image_files[i]))
for j in range(cout_per_image[i]):
print('%s: %.3f' % (class_names[best_class_indices[k]], best_class_probabilities[k]))
k+=1
def load_and_align_data(image_paths, image_size, margin, gpu_memory_fraction):
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
print('Creating networks and loading parameters')
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
nrof_samples = len(image_paths)
img_list = []
count_per_image = []
for i in xrange(nrof_samples):
img = misc.imread(os.path.expanduser(image_paths[i]))
img_size = np.asarray(img.shape)[0:2]
bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
count_per_image.append(len(bounding_boxes))
for j in range(len(bounding_boxes)):
det = np.squeeze(bounding_boxes[j,0:4])
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0]-margin/2, 0)
bb[1] = np.maximum(det[1]-margin/2, 0)
bb[2] = np.minimum(det[2]+margin/2, img_size[1])
bb[3] = np.minimum(det[3]+margin/2, img_size[0])
cropped = img[bb[1]:bb[3],bb[0]:bb[2],:]
aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
prewhitened = facenet.prewhiten(aligned)
img_list.append(prewhitened)
images = np.stack(img_list)
return images, count_per_image, nrof_samples
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('image_files', type=str, nargs='+', help='Path(s) of the image(s)')
parser.add_argument('model', type=str,
help='Could be either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file')
parser.add_argument('classifier_filename',
help='Classifier model file name as a pickle (.pkl) file. ' +
'For training this is the output and for classification this is an input.')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
parser.add_argument('--margin', type=int,
help='Margin for the crop around the bounding box (height, width) in pixels.', default=44)
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: contributed/real_time_face_recognition.py
================================================
# coding=utf-8
"""Performs face detection in realtime.
Based on code from https://github.com/shanren7/real_time_face_recognition
"""
# MIT License
#
# Copyright (c) 2017 François Gervais
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import argparse
import sys
import time
import cv2
import face
def add_overlays(frame, faces, frame_rate):
if faces is not None:
for face in faces:
face_bb = face.bounding_box.astype(int)
cv2.rectangle(frame,
(face_bb[0], face_bb[1]), (face_bb[2], face_bb[3]),
(0, 255, 0), 2)
if face.name is not None:
cv2.putText(frame, face.name, (face_bb[0], face_bb[3]),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0),
thickness=2, lineType=2)
cv2.putText(frame, str(frame_rate) + " fps", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0),
thickness=2, lineType=2)
def main(args):
frame_interval = 3 # Number of frames after which to run face detection
fps_display_interval = 5 # seconds
frame_rate = 0
frame_count = 0
video_capture = cv2.VideoCapture(0)
face_recognition = face.Recognition()
start_time = time.time()
if args.debug:
print("Debug enabled")
face.debug = True
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
if (frame_count % frame_interval) == 0:
faces = face_recognition.identify(frame)
# Check our current fps
end_time = time.time()
if (end_time - start_time) > fps_display_interval:
frame_rate = int(frame_count / (end_time - start_time))
start_time = time.time()
frame_count = 0
add_overlays(frame, faces, frame_rate)
frame_count += 1
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--debug', action='store_true',
help='Enable some debug outputs.')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: data/learning_rate_retrain_tripletloss.txt
================================================
# Learning rate schedule
# Maps an epoch number to a learning rate
0: 0.1
300: 0.01
400: 0.001
1000: 0.0001
================================================
FILE: data/learning_rate_schedule_classifier_casia.txt
================================================
# Learning rate schedule
# Maps an epoch number to a learning rate
0: 0.05
60: 0.005
80: 0.0005
91: -1
================================================
FILE: data/learning_rate_schedule_classifier_msceleb.txt
================================================
# Learning rate schedule
# Maps an epoch number to a learning rate
0: 0.1
150: 0.01
180: 0.001
251: 0.0001
================================================
FILE: data/learning_rate_schedule_classifier_vggface2.txt
================================================
# Learning rate schedule
# Maps an epoch number to a learning rate
0: 0.05
100: 0.005
200: 0.0005
276: -1
================================================
FILE: data/pairs.txt
================================================
10 300
Abel_Pacheco 1 4
Akhmed_Zakayev 1 3
Akhmed_Zakayev 2 3
Amber_Tamblyn 1 2
Anders_Fogh_Rasmussen 1 3
Anders_Fogh_Rasmussen 1 4
Angela_Bassett 1 5
Angela_Bassett 2 5
Angela_Bassett 3 4
Ann_Veneman 3 5
Ann_Veneman 6 10
Ann_Veneman 10 11
Anthony_Fauci 1 2
Antony_Leung 1 2
Antony_Leung 2 3
Anwar_Ibrahim 1 2
Augusto_Pinochet 1 2
Barbara_Brezigar 1 2
Benjamin_Netanyahu 1 4
Benjamin_Netanyahu 4 5
Bernard_Law 2 3
Bernard_Law 3 4
Bertrand_Bonello 1 2
Bill_Frist 2 9
Bill_Frist 4 5
Bob_Graham 2 4
Bob_Graham 3 6
Bob_Graham 4 6
Bob_Graham 5 6
Boris_Becker 2 6
Brad_Johnson 1 3
Brad_Johnson 2 3
Brad_Johnson 2 4
Brian_Griese 1 2
Candice_Bergen 1 2
Candice_Bergen 2 3
Carla_Myers 1 2
Cathy_Freeman 1 2
Chang_Dae-whan 1 2
Charles_Grassley 1 2
Clare_Short 1 3
Clare_Short 1 4
Corinne_Coman 1 2
Dai_Bachtiar 1 2
Dale_Earnhardt_Jr 1 3
David_Caruso 1 2
Demi_Moore 1 3
Dick_Vermeil 1 2
Doris_Roberts 1 2
Doris_Roberts 1 3
Drew_Barrymore 1 2
Edmund_Stoiber 4 7
Edmund_Stoiber 5 7
Edmund_Stoiber 7 12
Edmund_Stoiber 9 11
Elinor_Caplan 1 2
Emmanuelle_Beart 1 2
Emmanuelle_Beart 1 3
Federico_Trillo 1 2
Federico_Trillo 1 3
Federico_Trillo 2 3
Francis_Ford_Coppola 1 2
Fred_Thompson 1 2
Fred_Thompson 1 3
Fred_Thompson 2 3
Garry_Trudeau 1 2
Gary_Williams 1 2
Gene_Robinson 1 2
Gene_Robinson 1 3
Gene_Robinson 2 3
George_Galloway 1 3
George_Galloway 2 3
George_Galloway 2 4
Geraldine_Chaplin 1 2
Geraldine_Chaplin 1 4
Geraldine_Chaplin 3 4
Gerardo_Gambala 1 2
Gian_Marco 1 2
Gian_Marco 2 3
Gillian_Anderson 1 2
Gordon_Brown 6 9
Gordon_Brown 10 13
Grant_Hackett 1 2
Grant_Hackett 1 3
Grant_Hackett 1 5
Gray_Davis 7 22
Gray_Davis 21 26
Gregg_Popovich 1 5
Gregg_Popovich 3 4
Guy_Ritchie 1 2
Hamzah_Haz 1 2
Harbhajan_Singh 1 2
Hootie_Johnson 1 2
Hugo_Chavez 2 27
Hugo_Chavez 27 53
Hugo_Chavez 36 51
Hugo_Chavez 41 50
Hugo_Chavez 45 56
Isaiah_Washington 1 2
Jack_Grubman 1 2
Jacques_Rogge 1 9
Jacques_Rogge 3 7
Jacques_Rogge 3 10
Jacques_Rogge 4 6
Jacques_Rogge 4 9
Jacques_Rogge 5 8
Jacques_Rogge 6 8
James_Caan 1 2
James_Caan 1 3
James_Caan 2 3
James_Jones 1 2
Jamling_Norgay 1 2
Janica_Kostelic 1 2
Jeanne_Moreau 1 2
Jeffrey_Archer 1 2
Jennifer_Garner 1 3
Jennifer_Garner 4 9
Jennifer_Garner 5 6
Jennifer_Garner 5 9
Jennifer_Garner 7 12
Jennifer_Garner 8 11
Jeremy_Greenstock 2 24
Jeremy_Greenstock 3 22
Jeremy_Greenstock 5 11
Jeremy_Greenstock 10 14
Jeremy_Greenstock 17 21
Jessica_Lange 1 2
Jimmy_Carter 1 7
Jimmy_Carter 4 6
Jimmy_Carter 5 8
Jimmy_Carter 6 7
Jodie_Foster 1 2
John_Manley 1 6
John_Manley 2 5
John_McCain 2 3
John_McCain 3 7
John_McCain 6 7
John_Snow 3 15
John_Snow 4 16
John_Snow 9 11
Johnson_Panjaitan 1 2
Jorge_Castaneda 1 2
Jose_Serra 1 9
Jose_Serra 2 8
Jose_Serra 3 5
Jose_Serra 3 7
Jose_Serra 6 9
Jose_Theodore 1 2
Joseph_Blatter 1 2
Joseph_Ralston 1 2
Juan_Pablo_Montoya 1 8
Juan_Pablo_Montoya 2 4
Juan_Pablo_Montoya 4 5
Julianna_Margulies 1 2
Justin_Guarini 1 2
Justin_Guarini 2 3
Justine_Henin 2 3
Kate_Winslet 1 2
Kate_Winslet 1 4
Kate_Winslet 2 3
Kate_Winslet 2 4
Kathy_Winters 1 2
Kelvin_Sampson 1 2
Kevin_Stallings 1 2
Kim_Jong-Il 2 3
Kristin_Davis 1 2
Kristin_Davis 2 3
Lance_Armstrong 1 17
Lance_Armstrong 5 10
Lance_Armstrong 7 11
Lance_Armstrong 10 18
Lance_Armstrong 14 17
Laurent_Jalabert 1 2
Lindsey_Graham 1 2
Lisa_Gottsegen 1 2
Lleyton_Hewitt 1 13
Lleyton_Hewitt 16 27
Lleyton_Hewitt 18 37
Lleyton_Hewitt 24 36
Luis_Ernesto_Derbez_Bautista 3 6
Mario_Dumont 1 2
Mark_Wahlberg 1 3
Mark_Wahlberg 2 3
Mark_Wahlberg 2 4
Marlene_Weingartner 1 2
Martha_Bowen 1 2
Martin_Cauchon 1 2
Martin_Hoellwarth 1 2
Martin_Sheen 1 2
Matthew_Broderick 1 4
Matthew_Broderick 2 3
Mike_Krzyzewski 1 6
Mikhail_Gorbachev 1 2
Monica_Bellucci 1 4
Monica_Bellucci 2 4
Naomi_Campbell 1 2
Nestor_Kirchner 3 30
Nestor_Kirchner 12 21
Nestor_Kirchner 17 25
Nicolas_Lapentti 1 2
Noah_Wyle 2 3
Nora_Bendijo 1 2
Nursultan_Nazarbayev 1 2
Pamela_Anderson 1 2
Pamela_Anderson 1 5
Patricia_Heaton 1 2
Patty_Schnyder 1 2
Patty_Schnyder 2 3
Patty_Schnyder 2 4
Patty_Schnyder 3 4
Paul_Bremer 6 17
Paul_Bremer 7 10
Paul_Bremer 9 15
Paul_Bremer 14 16
Paul_Sarbanes 1 3
Paul_Sarbanes 2 3
Paul_William_Hurley 1 2
Pervez_Musharraf 1 6
Pervez_Musharraf 2 16
Pervez_Musharraf 3 10
Pervez_Musharraf 4 14
Pervez_Musharraf 5 7
Pervez_Musharraf 5 15
Phil_Gramm 1 2
Prince_Edward 1 2
Ricardo_Lagos 3 12
Ricardo_Lagos 23 27
Ricardo_Monasterio 1 2
Rich_Gannon 1 2
Rick_Perry 1 4
Rick_Perry 1 5
Rick_Perry 2 4
Rick_Perry 3 4
Robert_Bonner 2 3
Robert_Evans 2 3
Robert_Fico 1 2
Romano_Prodi 3 5
Roy_Moore 2 5
Roy_Moore 3 6
Sachiko_Yamada 1 2
Sachiko_Yamada 1 4
Sachiko_Yamada 2 3
Sachiko_Yamada 2 4
Saeb_Erekat 1 2
Sam_Bith 1 2
Sam_Bith 1 3
Sam_Bith 2 3
Sean_Hayes 1 2
Sergio_Garcia 1 2
Silvia_Farina_Elia 1 2
Steve_Ballmer 1 2
Steve_Ballmer 1 3
Stockard_Channing 1 3
Stockard_Channing 2 3
Terry_McAuliffe 1 2
Terry_McAuliffe 1 3
Thomas_Rupprath 1 3
Thomas_Rupprath 2 3
Tom_Ridge 6 16
Tom_Ridge 8 25
Tom_Ridge 9 26
Tom_Ridge 18 22
Tommy_Haas 4 5
Tommy_Thompson 1 2
Tommy_Thompson 1 7
Tommy_Thompson 2 8
Tommy_Thompson 4 8
Tommy_Thompson 6 9
Tomoko_Hagiwara 1 2
Trent_Lott 1 2
Trent_Lott 2 3
Trent_Lott 2 8
Trent_Lott 6 11
Trent_Lott 7 10
Trent_Lott 8 16
Tsutomu_Takebe 1 2
Tyler_Hamilton 1 2
Tyra_Banks 1 2
Vaclav_Havel 2 4
Vaclav_Havel 2 5
Vaclav_Havel 2 6
Vaclav_Havel 4 9
Vaclav_Havel 5 7
Valerie_Harper 1 2
Vince_Carter 3 4
Vincent_Brooks 2 3
Vincent_Brooks 2 7
Vincent_Brooks 4 5
Vincent_Brooks 4 7
Vincent_Gallo 1 2
Vitali_Klitschko 1 2
Vitali_Klitschko 3 4
William_Macy 1 4
William_Macy 2 4
William_Macy 3 4
Woody_Allen 2 4
Woody_Allen 3 5
Yukiko_Okudo 1 2
Zico 1 2
Zico 2 3
Abdel_Madi_Shabneh 1 Dean_Barker 1
Abdel_Madi_Shabneh 1 Giancarlo_Fisichella 1
Abdel_Madi_Shabneh 1 Mikhail_Gorbachev 1
Abdul_Rahman 1 Portia_de_Rossi 1
Abel_Pacheco 1 Jong_Thae_Hwa 2
Abel_Pacheco 2 Jean-Francois_Lemounier 1
Afton_Smith 1 Dwayne_Wade 1
Ahmad_Jbarah 1 James_Comey 1
Akhmed_Zakayev 2 Donna_Morrissey 1
Alan_Dershowitz 1 Bertrand_Bonello 1
Alanis_Morissette 1 Martin_Cauchon 1
Alexander_Lukashenko 1 Heather_Chinnock 1
Alfonso_Cuaron 1 Jason_Priestley 1
Alfonso_Cuaron 1 Patty_Schnyder 2
Alfonso_Soriano 1 Bill_Nelson 2
Alfonso_Soriano 1 Julio_De_Brun 1
Alfonso_Soriano 1 Patty_Schnyder 3
Alonzo_Mourning 1 Cecilia_Cheung 1
Amber_Tamblyn 2 Benjamin_Netanyahu 1
Amporn_Falise 1 Joe_Pantoliano 1
Anders_Fogh_Rasmussen 2 Johnson_Panjaitan 2
Andre_Bucher 1 Joseph_Ralston 1
Andre_Bucher 1 Maria_Garcia 1
Andrew_Gilligan 1 Henry_Castellanos 1
Andrew_Shutley 1 Edmund_Stoiber 5
Andrew_Shutley 1 Mitchell_Swartz 1
Andrew_Shutley 1 Saeb_Erekat 2
Andy_Dick 1 Simon_Yam 1
Andy_Griffith 1 Osrat_Iosef 1
Andy_Wisecarver 1 Dimitar_Berbatov 1
Angela_Lansbury 1 Steven_Van_Zandt 1
Angela_Lansbury 2 John_Coomber 1
Ann_Veneman 6 Sergio_Garcia 2
Ann_Veneman 8 Ted_Williams 1
Annie-Jeanne_Reynaud 1 SJ_Twu 1
Anthony_Carter 1 Eliza_Dushku 1
Antonio_Cassano 1 Paul_Celluci 1
Anwar_Ibrahim 1 David_Alpay 1
Armand_Sargen 1 Daryl_Sabara 1
Armand_Sargen 1 Kelvin_Sampson 3
Armand_Sargen 1 Lisa_Gottsegen 2
Atom_Egoyan 1 Bill_Stapleton 1
Atom_Egoyan 1 Janis_Ruth_Coulter 1
Barbara_Brezigar 2 Doris_Roberts 2
Barbara_Felt-Miller 1 Leticia_Dolera 1
Bart_Freundlich 1 Ernie_Grunfeld 1
Bart_Freundlich 1 Kirsten_Gilham 1
Benjamin_Martinez 1 Garry_McCoy 1
Benjamin_Netanyahu 1 Maria_Callas 1
Benjamin_Netanyahu 5 Frank_Beamer 1
Bernard_Law 1 Liu_Xiaoqing 1
Bernard_Law 3 Valerie_Harper 2
Bertrand_Bonello 1 Jong_Thae_Hwa 2
Bill_Bradley 1 Chen_Tsai-chin 1
Bill_Bradley 1 Helen_Alvare 1
Bill_Elliott 1 Mary_Anne_Souza 1
Bill_Frist 5 Jimmy_Kimmel 2
Bill_Maher 1 Brad_Russ 1
Bill_Maher 1 Juliette_Binoche 1
Bill_Nelson 1 Kim_Jong-Il 3
Bill_Nelson 2 Gillian_Anderson 1
Bill_Stapleton 1 Sedigh_Barmak 1
Bill_Stapleton 1 Valerie_Harper 1
Billy_Bob_Thornton 1 Herb_Dhaliwal 1
Billy_Bob_Thornton 1 Nong_Duc_Manh 1
Bob_Alper 1 Kevin_Millwood 1
Bob_Graham 2 Dwayne_Wade 1
Bob_Petrino 1 Geraldine_Chaplin 4
Bob_Petrino 1 Jorge_Castaneda 1
Boris_Becker 4 Julianna_Margulies 2
Brad_Russ 1 Hana_Urushima 1
Brad_Russ 1 Romeo_Gigli 1
Brawley_King 1 Tom_Glavine 2
Brian_Griese 2 Jeffrey_Archer 2
Brian_Griese 2 Laura_Elena_Harring 1
Brian_Griese 2 Nicolas_Lapentti 2
Bryan_Adams 1 Michael_Kors 1
Bryan_Adams 1 Mohamed_Seineldin 1
Calbert_Cheaney 1 Ian_Smith 1
Calbert_Cheaney 1 Robert_Downey_Jr 1
Carl_Reiner 1 Hamid_Efendi 1
Carl_Reiner 2 John_Engler 1
Carl_Reiner 2 Prince_Rainier_III 1
Carl_Reiner 2 Tom_Glavine 2
Carlo_Azeglio_Ciampi 1 Francis_Ford_Coppola 1
Carlos_Arroyo 1 Shane_Phillips 1
Carlos_Paternina 1 Emily_Stevens 1
Carlos_Paternina 1 Paul_Sarbanes 1
Casey_Mears 1 Mike_Davis 1
Casey_Mears 1 Yukiko_Okudo 1
Cathy_Freeman 2 William_Martin 2
Cecilia_Cheung 1 Daryl_Parks 1
Cecilia_Cheung 1 Pascal_Affi_Nguessan 1
Chen_Tsai-chin 1 Dereck_Whittenburg 1
Chen_Tsai-chin 1 Mamdouh_Habib 1
Cho_Myung-kyun 1 David_Bell 1
Cho_Myung-kyun 1 Fernando_Sanz 1
Cho_Myung-kyun 1 Georgia_Giddings 1
Cho_Myung-kyun 1 Richard_Fine 1
Choi_Yun-yong 1 Chuck_Eidson 1
Chris_Dodd 1 Taylor_Twellman 1
Chris_Swecker 1 Tom_Vilsack 1
Christian_Lacroix 1 Laura_Elena_Harring 1
Christian_Lacroix 1 Ornella_Muti 1
Chuck_Eidson 1 Sigourney_Weaver 1
Clare_Short 4 Don_Carcieri 1
Coco_dEste 1 Darvis_Patton 1
Coco_dEste 1 Melina_Kanakaredes 1
Coco_dEste 1 Tom_Rouen 1
Coleen_Rowley 1 Nong_Duc_Manh 1
Corinne_Coman 2 Frank_Beamer 1
Dale_Earnhardt_Jr 1 Nick_Reilly 1
Dario_Franchitti 1 Henry_Castellanos 1
Darren_Campel 1 Hilary_McKay 1
Darvis_Patton 1 Gerard_Tronche 1
Darvis_Patton 1 William_Macy 4
Daryl_Parks 1 Guus_Hiddink 1
Daryl_Sabara 1 Nick_Reilly 1
Daryl_Sabara 1 Valentina_Tereshkova 1
Dave_Johnson 1 Howard_Stern 1
Dave_Tucker 1 Gary_Gitnick 1
David_Collenette 1 Salman_Khan 1
David_Westerfield 1 Stan_Kroenke 1
Dean_Jacek 1 Larry_Wilmore 1
Demi_Moore 2 Fred_Thompson 1
Demi_Moore 2 Linus_Roache 1
Dereck_Whittenburg 1 Lindsey_Graham 2
Dianne_Reeves 1 Larry_Wilmore 1
Dianne_Reeves 1 Romeo_Gigli 1
Don_Carcieri 1 Janica_Kostelic 1
Dora_Bakoyianni 1 Richard_Sambrook 2
Dora_Bakoyianni 1 Saeb_Erekat 2
Doris_Roberts 1 Nong_Duc_Manh 1
Doug_Wilson 1 Szu_Yu_Chen 1
Douglas_Gansler 1 Martin_Brooke 1
Douglas_Gansler 1 Ronald_Kadish 1
Dwayne_Wade 1 Mike_Farrar 1
Edward_Arsenault 1 Jim_Hardin 1
Einars_Repse 1 Minnie_Mendoza 1
Einars_Repse 1 Tim_Blake_Nelson 1
Elinor_Caplan 1 Hilary_McKay 1
Eliza_Dushku 1 George_Lucas 1
Eliza_Dushku 1 Itzhak_Perlman 1
Emily_Stevens 1 Janez_Drnovsek 1
Emmanuelle_Beart 2 Phil_Jackson 1
Eric_Daze 1 Sterling_Hitchcock 1
Erika_Christensen 2 Michael_Dell 1
Erika_Christensen 2 Woody_Allen 2
Eriko_Tamura 1 Georgia_Giddings 1
Ernie_Grunfeld 1 Frank_Coraci 1
Eugene_Melnyk 1 Mahima_Chaudhari 1
Fatma_Kusibeh 1 Lee_Baca 1
Federico_Trillo 1 Jonathan_Woodgate 1
Fernando_Alonso 1 Sam_Brownback 1
Fernando_Sanz 1 Miranda_Otto 1
Fernando_Sanz 1 Roy_Moore 1
Flor_Montulo 2 Juan_Pablo_Montoya 1
Francisco_Garcia 1 Marsha_Sharp 1
Francois_Ozon 1 Makiya_Ali_Hassan 1
Frank_Coraci 1 Tomoko_Hagiwara 2
Frank_Van_Ecke 1 Tsutomu_Takebe 1
Fred_Thompson 2 Helen_Alvare 1
Fred_Thompson 2 Sterling_Hitchcock 1
Fred_Thompson 3 Magda_Kertasz 1
Garry_Trudeau 1 Pat_Riley 1
Garry_Witherall 1 Howard_Stern 1
Garry_Witherall 1 Ingrid_Betancourt 1
Garry_Witherall 1 Martin_Keown 1
Gary_Gero 1 Kim_Hong-gul 1
Gary_Gero 1 Phil_Gramm 1
Gavin_Degraw 1 Jeffrey_Archer 1
Gene_Robinson 3 Martha_Bowen 2
Georgia_Giddings 1 Mahima_Chaudhari 1
Geovani_Lapentti 1 Rodney_Rempt 1
Geovani_Lapentti 1 Sam_Brownback 1
Gerard_de_Cortanze 1 Mark_Wahlberg 1
Gian_Marco 2 Kevin_Stallings 2
Giancarlo_Fisichella 1 Maria_Callas 1
Gideon_Yago 1 Natalie_Williams 1
Gideon_Yago 1 Paul_William_Hurley 1
Glenn_Plummer 1 Maria_Garcia 1
Grant_Hackett 1 Todd_Robbins 1
Grant_Hackett 3 Milo_Djukanovic 3
Gray_Davis 26 Karen_Lynn_Gorney 1
Gregg_Popovich 3 Vernon_Forrest 1
Gregor_Gysi 1 Tomoko_Hagiwara 1
Guy_Ritchie 2 Herb_Dhaliwal 1
Guy_Ritchie 2 William_Macy 1
Hamid_Efendi 1 Jimmy_Carter 8
Hamzah_Haz 2 Hilary_McKay 1
Harald_Ringstorff 1 Pat_Riley 1
Harald_Ringstorff 1 Romano_Prodi 6
Heather_Chinnock 1 Jean-Francois_Lemounier 1
Helen_Alvare 1 Milo_Djukanovic 1
Henry_Castellanos 1 Pamela_Anderson 4
Henry_Castellanos 1 Tommy_Shane_Steiner 1
Herb_Dhaliwal 1 Hung_Wan-ting 1
Hilary_McKay 1 Kevin_Millwood 1
Howard_Stern 1 Maria_Callas 1
Hugo_Chavez 33 Karen_Lynn_Gorney 1
Hugo_Chavez 60 Steve_Shiver 1
Imam_Samudra 1 Ivana_Trump 1
Imelda_Marcos 1 Patty_Schnyder 4
Jack_Smith 1 Mary_Jo_Myers 1
James_Caan 2 Paul_Sarbanes 2
James_Comey 1 Juan_Carlos_Morales 1
James_Comey 1 Paul_William_Hurley 1
Jamling_Norgay 1 Zico 2
Jan_Pronk 1 Kim_Dong-hwa 1
Janez_Drnovsek 1 Sterling_Hitchcock 1
Janica_Kostelic 2 Yasushi_Akashi 1
Janice_Abreu 1 Kevin_Sorbo 1
Jeffrey_Ashby 1 Michael_Dell 1
Jennifer_Garner 6 Mike_Duke 1
Jennifer_Renee_Short 1 Taylor_Twellman 1
Jerry_Seinfeld 1 Tim_Blake_Nelson 1
Jerry_Tarkanian 1 Thomas_Rupprath 1
Jessica_Lange 2 Sedigh_Barmak 1
Jim_Freudenberg 1 Nigel_Redden 1
Jim_Freudenberg 1 Tina_Pisnik 1
Jim_Haslett 1 Tsutomu_Takebe 1
Jim_Otto 1 Rafiq_Hariri 1
Jimmy_Gurule 1 Terry_McAuliffe 1
Jodie_Foster 3 Joe_Pantoliano 1
John_Herrington 1 Luis_Ernesto_Derbez_Bautista 2
John_Richardson 1 Yasushi_Akashi 1
John_Snow 17 Se_Hyuk_Joo 1
Jonathan_Arden 1 Joseph_Ralston 1
Jorge_Castaneda 1 Robert_Fico 1
Jose_Rosado 1 Micky_Arison 1
Joseph_Blatter 1 Ronald_Kadish 1
Joseph_Ralston 2 Juan_Pablo_Montoya 5
Joseph_Ralston 2 Yoshiyuki_Kamei 1
Juliette_Binoche 1 Matthew_Broderick 3
Julio_De_Brun 1 Patty_Schnyder 1
Julio_De_Brun 1 Vernon_Forrest 1
Justin_Guarini 2 Prince_Edward 1
Kate_Winslet 2 Mike_Duke 1
Katie_Wagner 1 Stan_Kroenke 1
Keith_Lowen 1 Robert_Evans 2
Keith_Lowen 1 Silvia_Farina_Elia 2
Ken_Loach 1 Taku_Yamasaki 1
Kevin_Crane 1 Mike_Krzyzewski 2
Kevin_Millwood 1 Mitchell_Crooks 1
Kim_Clijsters 4 Martin_Short 1
Kim_Hong-gul 1 Milo_Djukanovic 3
Kim_Jong-Il 3 Rick_Reed 1
Lance_Armstrong 9 Maria_Garcia 1
Laurent_Jalabert 2 Vincent_Gallo 1
Leon_LaPorte 1 Ted_Williams 1
Leon_LaPorte 1 Tommy_Thompson 5
Leonardo_Fernandez 1 Romano_Prodi 7
Leticia_Dolera 1 Tom_Glavine 1
Lorraine_Bracco 1 Momcilo_Perisic 1
Luis_Ernesto_Derbez_Bautista 1 Tyra_Banks 1
Maria_Burks 1 Todd_Parrott 1
Mario_Lemieux 1 Stan_Kroenke 1
Mark_Everson 1 Martin_Sheen 2
Marquier_Montano_Contreras 1 SJ_Twu 1
Marsha_Sharp 1 Steve_Shiver 1
Martin_Cauchon 2 Vitali_Klitschko 3
Martin_Hoellwarth 2 Mary_Katherine_Smart 1
Martina_Hingis 1 Terry_McAuliffe 2
Melina_Kanakaredes 1 Ornella_Muti 1
Michael_Dell 1 Mike_Duke 1
Michael_Dell 1 Nigel_Redden 1
Michael_Richards 1 Silvia_Farina_Elia 3
Milan_Kucan 1 Salman_Khan 1
Nancy_Kerrigan 1 Sam_Brownback 1
Naomi_Campbell 1 Tom_Ridge 16
Nina_Jacobson 1 Portia_de_Rossi 1
Noah_Wyle 3 Robbie_Coltrane 1
Nora_Bendijo 1 William_Martin 2
Nursultan_Nazarbayev 1 Robert_Bonner 1
Pascal_Affi_Nguessan 1 Tom_Moss 1
Pat_Summitt 1 Paul_Celluci 1
Patty_Schnyder 3 Pernilla_Bjorn 1
Patty_Schnyder 3 Prince_Philippe 1
Patty_Schnyder 4 Ricardo_Lagos 25
Pervez_Musharraf 3 Richard_Rodriguez 1
Phil_Gramm 2 Stefan_Tafrov 1
Rachel_Kempson 1 Zorica_Radovic 1
Rachel_Roy 1 Steve_Shiver 1
Richard_Fine 1 Richard_Rodriguez 1
Rick_Reed 1 Ruth_Bader_Ginsburg 1
Robbie_Naish 1 Zhong_Nanshan 1
Robert_Bonner 2 Vincent_Brooks 2
Robert_Downey_Jr 1 Tommy_Shane_Steiner 1
Robert_Evans 1 Todd_Robbins 1
Romeo_Gigli 1 Tom_Harkin 4
Saeb_Erekat 1 Tom_Coverdale 2
Se_Hyuk_Joo 1 Tom_Rouen 1
Sergio_Garcia 2 Thomas_Watjen 1
Simon_Yam 1 Terry_McAuliffe 3
Simon_Yam 1 Tommy_Haas 5
Stan_Kroenke 1 William_Hyde 1
Steve_Ballmer 1 Tina_Pisnik 1
Steve_Ballmer 2 Vincent_Gallo 3
Steve_Shiver 1 Thomas_Rupprath 3
Tina_Fey 1 Todd_Parrott 1
Abdullah_Gul 1 6
Abdullah_Gul 1 8
Abdullah_Gul 7 14
Abdullah_Gul 9 12
Abdullah_Gul 9 15
Adolfo_Rodriguez_Saa 1 2
Adrien_Brody 2 3
Adrien_Brody 2 12
Adrien_Brody 5 10
Adrien_Brody 7 8
Al_Sharpton 1 4
Al_Sharpton 2 4
Al_Sharpton 2 7
Al_Sharpton 3 4
Alexandra_Stevenson 1 2
Alexandra_Stevenson 1 3
Alexandra_Vodjanikova 1 2
Alicia_Silverstone 1 2
Ana_Palacio 3 7
Ana_Palacio 6 8
Andre_Agassi 1 5
Andre_Agassi 2 16
Andre_Agassi 4 33
Andre_Agassi 9 25
Andre_Agassi 17 25
Anna_Kournikova 2 3
Anna_Kournikova 2 12
Anna_Kournikova 3 8
Anna_Kournikova 7 8
Anna_Kournikova 7 11
Annette_Lu 1 2
Arnold_Palmer 1 3
Arnold_Palmer 2 3
Aron_Ralston 1 2
Arturo_Gatti 2 3
Bashar_Assad 1 3
Bashar_Assad 2 4
Bernardo_Segura 1 2
Bill_Gates 3 16
Bill_Gates 7 15
Bill_Gates 11 13
Bill_Gates 13 17
Bo_Pelini 1 2
Bob_Stoops 2 4
Bob_Stoops 2 5
Bobby_Robson 1 2
Bode_Miller 1 2
Caroline_Kennedy 1 3
Caroline_Kennedy 2 3
Catherine_Zeta-Jones 1 11
Catherine_Zeta-Jones 4 9
Celso_Amorim 1 2
Chan_Gailey 1 2
Chanda_Rubin 2 5
Chanda_Rubin 4 5
Charles_Bronson 1 2
Charles_Kartman 1 2
Charles_Schumer 1 2
Chris_Rock 1 2
Christine_Baumgartner 1 2
Christine_Baumgartner 2 4
Colin_Farrell 1 7
Colin_Farrell 2 7
Colin_Farrell 3 6
Colin_Farrell 4 8
Dalai_Lama 1 2
Daniel_Radcliffe 1 4
Daryl_Hannah 1 2
David_Anderson 1 2
David_Anderson 1 3
David_Beckham 1 15
David_Beckham 9 16
David_Beckham 11 29
David_Beckham 13 29
David_Beckham 15 24
David_Beckham 20 27
David_Beckham 27 31
Denzel_Washington 2 4
Denzel_Washington 3 5
Dianne_Feinstein 1 2
Dianne_Feinstein 1 3
Dianne_Feinstein 2 3
Dick_Clark 1 2
Dick_Clark 1 3
Donald_Fehr 1 3
Donald_Fehr 1 4
Donald_Fehr 2 3
Donald_Fehr 3 4
Dwayne_Johnson 1 2
Ed_Rosenthal 1 2
Erik_Morales 1 2
Erik_Morales 2 3
Evan_Rachel_Wood 2 3
Evander_Holyfield 1 2
Eve_Pelletier 1 2
Farouk_al-Sharaa 1 2
Farouk_al-Sharaa 1 3
Farouk_al-Sharaa 2 3
Frank_Cassell 1 2
Frank_Cassell 1 3
Fujio_Cho 1 4
Fujio_Cho 2 5
Fujio_Cho 3 5
Fujio_Cho 4 6
Fujio_Cho 5 6
Gao_Qiang 1 2
Geoff_Hoon 1 2
Geoff_Hoon 3 4
Geoff_Hoon 4 5
George_Brumley 1 2
George_Papandreou 1 2
George_Papandreou 1 3
George_Papandreou 1 4
George_Papandreou 3 4
Gloria_Allred 1 2
Greg_Ostertag 1 2
Greg_Owen 1 2
Hanan_Ashrawi 1 2
Harry_Kalas 1 2
Hayley_Tullett 1 2
Howard_Dean 1 3
Howard_Dean 1 7
Howard_Dean 2 8
Howard_Dean 4 5
Howard_Dean 5 12
Hu_Jintao 4 14
Hu_Jintao 5 12
Hu_Jintao 5 15
Hu_Jintao 11 13
Ian_McKellen 1 3
Ibrahim_Jaafari 1 2
Isabella_Rossellini 1 3
Ishaq_Shahryar 1 2
Ismail_Merchant 1 2
Jacques_Chirac 2 43
Jacques_Chirac 19 28
James_Cameron 1 3
James_McGreevey 1 3
James_McGreevey 1 4
Jason_Alexander 1 2
Jason_Kidd 2 8
Jason_Kidd 3 8
Jason_Kidd 6 8
Jelena_Dokic 1 2
Jelena_Dokic 2 4
Jelena_Dokic 2 8
Jelena_Dokic 3 4
Jelena_Dokic 4 5
Jelena_Dokic 4 7
Jelena_Dokic 4 8
Jelena_Dokic 5 6
Jelena_Dokic 7 8
Jennifer_Connelly 1 3
Jennifer_Connelly 1 4
Jennifer_Connelly 2 4
Jennifer_Connelly 3 4
Jennifer_Keller 1 4
Jennifer_Keller 3 4
Jennifer_Reilly 1 2
Jennifer_Thompson 1 2
Jim_Hahn 1 3
Jim_Hahn 1 4
Jim_Hahn 3 4
Johnny_Carson 1 2
Jorge_Batlle 1 2
Jorge_Batlle 1 3
Jorge_Rodolfo_Canicoba_Corral 1 2
Juan_Ignacio_Chela 1 2
Juan_Ignacio_Chela 1 3
Juan_Ignacio_Chela 2 3
Justin_Gatlin 1 2
Karen_Mok 1 2
Katie_Harman 1 2
Katie_Harman 1 3
Katie_Harman 2 3
Kenneth_Branagh 1 2
Kevin_Costner 1 3
Kevin_Costner 2 6
Kevin_Costner 2 8
Kevin_Costner 6 8
Larry_Lindsey 1 2
Leonardo_DiCaprio 3 7
Leonardo_DiCaprio 5 6
Leonardo_DiCaprio 6 8
Lindsay_Davenport 2 10
Lindsay_Davenport 5 9
Lisa_Ling 1 2
Lucy_Liu 2 4
Lucy_Liu 2 5
Lucy_Liu 3 5
Manfred_Stolpe 1 2
Maria_Luisa_Mendonca 1 2
Mario_Kreutzberger 1 2
Melissa_Etheridge 1 2
Michael_Jordan 1 2
Michael_Jordan 1 3
Michael_Jordan 2 4
Mikhail_Youzhny 1 2
Mitchell_Daniels 1 2
Mitchell_Daniels 1 4
Mitchell_Daniels 3 4
Mohammad_Khatami 1 5
Mohammad_Khatami 3 9
Mohammad_Khatami 8 10
Monique_Garbrecht-Enfeldt 1 3
Natalie_Maines 2 5
Natalie_Maines 4 5
Nelson_Mandela 1 3
Norodom_Sihanouk 1 3
Norodom_Sihanouk 2 3
Osama_bin_Laden 2 4
Osama_bin_Laden 3 4
Oxana_Fedorova 1 2
Peter_Bacanovic 1 2
Philippe_Noiret 1 2
Placido_Domingo 1 2
Placido_Domingo 2 3
Prince_William 1 2
Princess_Aiko 1 2
Priscilla_Presley 1 2
Richard_Haass 1 2
Richard_Shelby 1 2
Rick_Barnes 1 2
Rick_Barnes 1 3
Rick_Dinse 1 3
Rick_Dinse 2 3
Rio_Ferdinand 1 2
Rita_Grande 1 2
Rita_Grande 2 3
Robin_McLaurin_Williams 1 2
Saddam_Hussein 2 4
Saddam_Hussein 2 10
Saddam_Hussein 3 11
Saddam_Hussein 6 9
Sally_Field 1 2
Salma_Hayek 1 10
Salma_Hayek 1 11
Sandra_Bullock 1 3
Sandra_Bullock 1 4
Sandra_Bullock 2 4
Sandra_Bullock 3 4
Sarah_Hughes 1 6
Sarah_Hughes 2 5
Sarah_Hughes 3 5
Sarah_Hughes 4 6
Sharon_Frey 1 2
Silvio_Berlusconi 6 30
Silvio_Berlusconi 8 23
Silvio_Berlusconi 13 21
Silvio_Berlusconi 17 29
Silvio_Berlusconi 18 25
Silvio_Berlusconi 23 28
Silvio_Berlusconi 24 30
Silvio_Berlusconi 26 32
Spencer_Abraham 3 17
Steffi_Graf 2 5
Steffi_Graf 3 4
Steven_Spielberg 1 5
Steven_Spielberg 1 6
Steven_Spielberg 3 6
Steven_Spielberg 4 6
Steven_Spielberg 4 7
Steven_Spielberg 6 7
Theresa_May 1 2
Theresa_May 2 3
Tippi_Hedren 1 2
Todd_Haynes 1 2
Todd_Haynes 1 3
Todd_Haynes 1 4
Todd_Haynes 2 4
Tony_Blair 18 86
Tony_Blair 32 48
Tony_Blair 32 110
Tony_Blair 53 102
Tony_Blair 91 134
Tony_Blair 92 133
Tony_Blair 105 121
Vicente_Fox 4 30
Vicente_Fox 9 16
Vicente_Fox 11 17
Vicente_Fox 15 30
Vojislav_Kostunica 1 3
Vojislav_Kostunica 2 4
Vojislav_Kostunica 4 7
Vojislav_Kostunica 5 7
Walter_Mondale 1 6
Walter_Mondale 1 7
Walter_Mondale 5 7
Walter_Mondale 6 8
Walter_Mondale 7 9
Wang_Yingfan 2 3
William_Bratton 1 3
William_Donaldson 1 5
William_Donaldson 3 5
William_Donaldson 4 6
Xavier_Malisse 1 3
Xavier_Malisse 3 4
Xavier_Malisse 3 5
Yevgeny_Kafelnikov 1 4
Zarai_Toledo 1 2
Adolfo_Rodriguez_Saa 1 Dave_Odom 1
Adolfo_Rodriguez_Saa 1 Nancy_Powell 1
Adrien_Brody 3 Damon_Dash 1
Ahmed_Ahmed 1 Mike_Smith 1
Al_Sharpton 5 Cole_Chapman 1
Alberto_Sordi 1 James_Cameron 2
Alejandro_Lerner 1 Jesper_Parnevik 1
Alejandro_Lerner 1 TA_McLendon 1
Alex_Penelas 1 Robin_Johansen 1
Alex_Penelas 2 Gretchen_Mol 1
Alexandra_Stevenson 3 Ronde_Barber 1
Ali_Adbul_Karim_Madani 1 Carey_Lowell 1
Ali_Mohammed_Maher 1 Isabela_Moraes 1
Ali_Mohammed_Maher 1 Isidro_Pastor 1
Alicia_Silverstone 2 Jennifer_Thompson 1
Alicia_Silverstone 2 Jonathan_Tiomkin 1
Alicia_Silverstone 2 Serge_Tchuruk 1
Andre_Agassi 31 Boris_Jordan 1
Andre_Techine 1 Lloyd_Richards 1
Andy_Benes 1 Doug_Moe 1
Andy_Benes 1 Mitar_Rasevic 1
Andy_Bryant 1 Mike_Slive 1
Anna_Kournikova 8 Colin_Farrell 1
Anne_ONeil 1 Sophie 1
Anthony_Lee_Johnson 1 Dave_Williams 1
Arnold_Palmer 1 Stephanie_Zimbalist 1
Arnold_Palmer 3 Charles_Kartman 1
Aron_Ralston 1 Bill_Fennelly 1
Bart_Hendricks 1 Philippe_Noiret 1
Ben_Kingsley 1 Daryl_Hannah 1
Ben_Kingsley 1 Jean_Nagel 1
Ben_Kingsley 1 Perry_Farrell 1
Benjamin_Neulander 1 Robin_Tunney 1
Bernardo_Segura 1 Debra_Shank 1
Bernardo_Segura 2 Douglas_Paal 1
Bernardo_Segura 2 Jeanette_Stauffer 1
Bill_Pryor 1 Ronde_Barber 1
Bob_Melvin 1 Richard_Hamilton 1
Bob_Stoops 3 Wayne_Allard 1
Bobby_Jackson 1 Bruce_Gebhardt 1
Bobby_Jackson 1 JP_Suarez 1
Bobby_Jackson 1 Madge_Overhouse 1
Bobby_Jackson 1 Nicola_Wells 1
Bobby_Robson 1 Rollie_Massimino 1
Bode_Miller 1 David_Howard 1
Bode_Miller 1 Steffi_Graf 1
Boris_Jordan 1 Kim_Weeks 1
Boris_Jordan 1 Vincent_Sombrotto 1
Brad_Alexander_Smith 1 Jason_Alexander 2
Brad_Alexander_Smith 1 Kate_Lee 1
Brad_Alexander_Smith 1 Tatiana_Gratcheva 1
Brandon_Webb 1 Helmut_Panke 1
Brandon_Webb 1 Larry_Hahn 1
Brandon_Webb 1 Ryan_Leaf 1
Brennon_Leighton 1 Laurel_Clark 1
Brett_Hawke 1 Teri_Files 1
Bruce_Gebhardt 1 Jean-Luc_Bideau 1
Bruce_Gebhardt 1 Masao_Azuma 1
Bryan_Cooley 1 Katie_Harman 3
Bryan_Murray 1 Eric_Schacht 1
Bryan_Murray 1 Mikhail_Youzhny 1
Bryan_Murray 1 Mitchell_Daniels 2
Camille_Colvin 1 Irina_Yatchenko 1
Carey_Lowell 1 Charlie_Coles 1
Carl_Pope 1 Larry_Hahn 1
Carolina_Barco 1 Daryl_Hannah 1
Carolina_Barco 1 Lindsay_Davenport 22
Carolina_Barco 1 Norodom_Sihanouk 1
Caroline_Kennedy 3 Henry_Suazo 1
Catherine_Bell 1 Guillaume_Cannet 1
Catherine_Zeta-Jones 10 Pier_Ferdinando_Casini 1
Catherine_Zeta-Jones 11 Hayley_Tullett 2
Celso_Amorim 2 Juljia_Vysotskij 1
Celso_Amorim 2 Kevin_Costner 1
Celso_Amorim 2 Thomas_Stewart 1
Chanda_Rubin 3 Richard_Tubb 1
Chante_Jawan_Mallard 1 Stephen_Glassroth 1
Chante_Jawan_Mallard 1 Vicente_Fox 23
Charles_Bronson 2 Hu_Jintao 4
Charles_Kartman 1 Debra_Shank 1
Charles_Schumer 2 James_Watt 1
Charles_Schumer 2 Justin_Gatlin 2
Charles_Schumer 2 Lionel_Chalmers 1
Chris_Rock 2 Dalai_Lama 1
Christine_Baumgartner 2 Vincent_Sombrotto 1
Christine_Baumgartner 3 Lars_Burgsmuller 1
Chyung_Dai-chul 1 Dan_Reeves 1
Cindy_Moll 1 Daniel_Radcliffe 3
Cindy_Moll 1 James_McPherson 1
Cindy_Moll 1 Robin_Johansen 1
Claire_De_Gryse 1 Deb_Santos 1
Claire_Tomalin 1 Steve_Case 1
Clay_Campbell 1 Leonardo_DiCaprio 2
Cole_Chapman 1 Marisol_Martinez_Sambran 1
Colin_Phillips 1 Ian_McKellen 3
Colin_Phillips 1 Lloyd_Richards 1
Colin_Prescot 1 Laurie_Hobbs 1
Connie_Freydell 1 Tommy_Maddox 1
Craig_OClair 1 Steve_Avery 1
Damarius_Bilbo 1 Juljia_Vysotskij 1
Damon_Dash 1 Henry_Suazo 1
Daniel_Comisso_Urdaneta 1 Larry_Ralston 1
Daniel_Radcliffe 3 Diane_Green 2
Daniel_Radcliffe 3 Rick_Barnes 2
Daniel_Radcliffe 3 Vicente_Fox 32
Dany_Heatley 1 Richard_Parsons 1
Dany_Heatley 1 Terry_Hoeppner 1
Dave_Odom 1 Maritza_Macias_Furano 1
David_Beckham 22 Laura_Morante 1
David_Duval 1 Philippe_Noiret 2
David_Ho 1 Doug_Moe 1
David_Ho 1 Erskine_Bowles 1
David_Ho 1 Evander_Holyfield 1
David_Howard 1 Hugo_Conte 1
Denzel_Washington 4 Henry_Suazo 1
Des_Brown 1 Eliott_Spitzer 1
Des_Brown 1 Svetislav_Pesic 1
Diana_Ross 1 Rick_Rickert 1
Dianne_Feinstein 3 Dwayne_Johnson 2
Dick_Clark 3 Manfred_Stolpe 1
Dino_Risi 1 Gabriel_Farhi 1
Doc_Rivers 1 Melissa_Joan_Hart 1
Dominick_Dunne 1 Nicoletta_Braschi 1
Don_Flanagan 1 Ed_Sullivan 1
Don_Flanagan 1 Ratna_Sari_Dewi_Sukarno 1
Donald_Keyser 1 Salma_Hayek 2
Douglas_Paal 1 Ed_Sullivan 1
Douglas_Paal 1 Richard_Hamilton 1
Dusty_Baker 1 Saddam_Hussein 2
Ed_Rendell 1 Jamie_Dimon 1
Ed_Rendell 1 Richard_Cohen 1
Eddie_Murray 1 Kevin_Costner 7
Elaine_Stritch 1 Richard_Parsons 1
Elena_Tihomirova 1 Mike_Slive 1
Elena_Tihomirova 1 Mohammed_Abu_Sharia 1
Eric_Schacht 1 Jennifer_Keller 2
Erik_Morales 3 Werner_Schlager 1
Erin_Brockovich 1 Henry_Suazo 1
Erin_Brockovich 1 Mike_Carona 1
Evan_Rachel_Wood 1 Sharon_Frey 1
Evander_Holyfield 1 Julio_Rossi 1
Evander_Holyfield 1 Michael_Jordan 3
Evander_Holyfield 1 Mike_Carona 1
Fatmir_Limaj 1 Todd_Haynes 4
Felicity_Huffman 1 Nelson_Acosta 1
Felipe_De_Borbon 1 Jose_Bove 1
Frank_Cassell 2 Jesper_Parnevik 1
Frank_Cassell 3 Ronde_Barber 1
Fred_Durst 1 Marisol_Martinez_Sambran 1
Fred_Durst 1 Shavon_Earp 1
Fujio_Cho 1 Javier_Vargas 1
Fujio_Cho 2 Tatsuya_Fuji 1
Fujio_Cho 3 Michael_Brandon 1
Fujio_Cho 6 Olene_Walker 1
Gabriel_Farhi 1 Lars_Burgsmuller 1
Gao_Qiang 2 Kenneth_Brill 1
Gary_Stevens 1 Wanda_Ilene_Barzee 1
Geoff_Hoon 1 Osama_bin_Laden 3
Geoff_Hoon 3 Richard_Tubb 1
Geoff_Hoon 5 Thomas_Stewart 1
George_Brumley 1 Manfred_Stolpe 1
George_Brumley 1 Ryan_Leaf 1
George_Brumley 2 Sergei_Yushenkov 1
George_Papandreou 2 Tatiana_Panova 1
George_Papandreou 4 Larry_Lindsey 2
George_Papandreou 4 Paul_LeClerc 1
Ghassan_Elashi 1 Rick_Rickert 1
Gloria_Allred 2 Roman_Tam 1
Greg_Kinsey 1 Priscilla_Presley 1
Greg_Ostertag 2 Kevin_Costner 6
Greg_Owen 1 Mark_Sisk 1
Greg_Owen 2 Mike_Smith 1
Gretchen_Mol 1 Isabella_Rossellini 2
Gunilla_Backman 1 Kathleen_Abernathy 1
Hanan_Ashrawi 1 Mario_Kreutzberger 2
Hans_Leistritz 1 Saddam_Hussein 18
Hans_Leistritz 1 Sue_Grafton 1
Hans_Peter_Briegel 1 Theresa_May 2
Harriet_Lessy 1 Mike_Carona 1
Harry_Kalas 2 Joe_Strummer 1
Harry_Kalas 2 Lewis_Booth 1
Hayley_Tullett 1 Ian_McKellen 1
Henry_Suazo 1 Ratna_Sari_Dewi_Sukarno 1
Hernan_Crespo 1 Ronde_Barber 1
Hiroyuki_Yoshino 1 Rollie_Massimino 1
Hu_Jintao 6 Jerome_Jenkins 1
Hugh_Jessiman 1 Solomon_Passy 1
Hugh_Jessiman 1 TA_McLendon 1
Hugo_Conte 1 Laurent_Woulzy 1
Irina_Yatchenko 1 Katie_Harman 2
Isidro_Pastor 1 Mark_Butcher 1
Ismail_Merchant 1 Mack_Brown 2
Ismail_Merchant 2 Kathleen_Abernathy 1
Ivan_Helguera 1 William_Donaldson 4
Iveta_Benesova 1 Jacques_Chirac 50
Jacques_Chirac 20 Tzipora_Obziler 1
Jacques_Chirac 35 Richard_Shelby 2
James_Cameron 1 Richard_Shelby 2
James_McGreevey 1 Katie_Harman 2
James_McGreevey 1 Tzipora_Obziler 1
James_Sensenbrenner 1 Jimmy_Smits 1
James_Sensenbrenner 1 Maria_Shkolnikova 1
James_Watt 1 Priscilla_Presley 2
Jamie_Dimon 1 Robert_Korzeniowski 1
Jason_Alexander 1 Mike_Maroth 1
Jason_Alexander 1 Wayne_Allard 1
Jason_Kidd 7 Louisa_Baileche 1
Javier_Vargas 1 Jesse_Helms 1
Jeanette_Gray 1 Keith_Fotta 1
Jeanette_Stauffer 1 Marie-Josee_Croze 1
Jeffrey_Donaldson 1 Leonardo_DiCaprio 8
Jeffrey_Donaldson 1 Peter_Bacanovic 1
Jennifer_Connelly 4 Martin_Bandier 1
Jesper_Parnevik 1 Justin_Gatlin 2
Jimmy_Smits 1 Robin_Johansen 1
Jimmy_Smits 1 Shane_Hmiel 1
Joe_Crede 1 Tom_DeLay 1
John_Burkett 1 Leonardo_DiCaprio 2
John_McKay 1 Mary_Sue_Coleman 1
Johnny_Hallyday 1 Olene_Walker 1
Jonathan_Tiomkin 1 Rita_Grande 2
Jorge_Rodolfo_Canicoba_Corral 1 Wayne_Allard 1
Jose_Bove 1 Juergen_Trittin 1
Juljia_Vysotskij 1 Patrick_Coleman 1
Kate_Lee 1 Toshimitsu_Motegi 1
Kathie_Louise_Saunders 1 Roberto_Lavagna 1
Kathie_Louise_Saunders 1 Rosalyn_Carter 1
Kenneth_Branagh 1 Pinar_del_Rio 1
Kevin_Costner 5 Stephen_Glassroth 1
Khader_Rashid_Rahim 1 Richard_Cohen 1
Khalid_Khannouchi 1 Werner_Schlager 1
Kim_Su_Nam 1 Todd_Haynes 4
Kim_Weeks 1 Marie-Josee_Croze 1
Kimora_Lee 1 Robin_Johansen 1
Kurt_Suzuki 1 Scott_Hoch 1
Larry_Lindsey 1 Wanda_Ilene_Barzee 1
Larry_Ralston 1 Richard_Carl 1
Larry_Ralston 1 William_Donaldson 6
Larry_Ralston 1 Willie_Wilson 1
Laurel_Clark 1 Laurent_Woulzy 1
Laurel_Clark 1 Priscilla_Presley 1
Leandrinho_Barbosa 1 Melissa_Joan_Hart 1
Leandrinho_Barbosa 1 Olene_Walker 1
Leon_Barmore 1 Sachin_Tendulkar 1
Leon_Barmore 1 Yusaku_Miyazato 1
Leonard_Schrank 1 Marie_Haghal 1
Leonard_Schrank 1 Rick_Rickert 1
Linda_Franklin 1 Melissa_Joan_Hart 1
Lindsay_Davenport 1 Martin_Burnham 1
Lindsay_Davenport 17 Oxana_Fedorova 3
Lionel_Chalmers 1 Mohammad_Fares 1
Lisa_Ling 2 Mike_Maroth 1
Lucy_Liu 3 Prince_William 1
Maria_Luisa_Mendonca 2 Stephane_Delajoux 1
Maria_Luisa_Mendonca 2 Terunobu_Maeda 1
Maria_Shkolnikova 1 Martin_Rodriguez 1
Mariana_Ohata 1 Xavier_Malisse 3
Mario_Kreutzberger 1 Shavon_Earp 1
Mario_Kreutzberger 2 Raul_Cubas 1
Maritza_Macias_Furano 1 Qusai_Hussein 1
Mark_Butcher 1 Scott_Hoch 1
Mark_Sisk 1 Mehdi_Baala 1
Mark_Sisk 1 Stephen_Swindal 1
Masao_Azuma 1 Mikhail_Kalashnikov 1
McGuire_Gibson 1 Richard_Haass 1
Mehdi_Baala 1 Steve_Avery 1
Melissa_Joan_Hart 1 Mikhail_Kalashnikov 1
Melissa_Joan_Hart 1 Sue_Grafton 1
Michael_Brandon 1 Toshimitsu_Motegi 1
Michael_Shelby 1 Olene_Walker 1
Michel_Kratochvil 1 Sheldon_Silver 1
Mike_Eskew 1 Zarai_Toledo 1
Mike_OConnell 1 Roberto_Lavagna 1
Mike_Sherman 1 Natalie_Maines 3
Mike_Sherman 1 Paige_Fitzgerald 1
Milt_Heflin 1 Pier_Ferdinando_Casini 1
Nicholoas_DiMarzio 1 Richard_Parsons 1
Nikki_McKibbin 1 Stephen_Swindal 1
Nikki_McKibbin 1 Steven_Tyler 1
Osama_Al_Baz 1 Patricia_Wartusch 1
Osama_Al_Baz 1 Sandra_Day_OConner 1
Patricia_Phillips 1 Thierry_Falise 2
Paula_Locke 1 Teri_Files 1
Peter_Bacanovic 2 Robert_Korzeniowski 1
Pier_Ferdinando_Casini 1 Ratna_Sari_Dewi_Sukarno 1
Priscilla_Presley 2 Raul_Rivero 1
Raaf_Schefter 1 Rick_Dinse 2
Richard_Sterner 1 Steven_Spielberg 2
Rick_Dinse 2 Shavon_Earp 1
Roberto_Lavagna 1 Sandra_Bullock 4
Rod_Stewart 1 Steffi_Graf 2
Rodolfo_Abalos 1 Thierry_Falise 3
Roman_Tam 1 Zalmay_Khalilzad 1
Scott_Hoch 1 Thomas_Stewart 1
Seymour_Cassell 1 Todd_Haynes 4
Shaun_Rusling 1 Vincent_Sombrotto 1
Sheldon_Silver 1 Xavier_Malisse 3
Stephane_Delajoux 1 Tristan_Gretzky 1
Takahiro_Mori 1 Tony_Blair 64
Thierry_Falise 2 Werner_Schlager 1
Aaron_Sorkin 1 2
Abdullah 1 3
Abdullah 2 3
Abdullah 2 4
Abdullah 3 4
Abid_Hamid_Mahmud_Al-Tikriti 1 2
Abid_Hamid_Mahmud_Al-Tikriti 1 3
Alan_Ball 1 2
Albert_Costa 3 5
Albert_Costa 5 6
Ali_Khamenei 1 2
Ali_Khamenei 1 3
Amelia_Vega 1 7
Amelia_Vega 2 7
Amelia_Vega 3 5
Antonio_Banderas 1 5
Antonio_Banderas 2 5
Antonio_Banderas 3 5
Arye_Mekel 1 2
Azra_Akin 1 3
Azra_Akin 1 4
Bernard_Landry 2 3
Bernard_Landry 2 4
Bernard_Landry 3 4
Biljana_Plavsic 1 2
Biljana_Plavsic 1 3
Biljana_Plavsic 2 3
Bob_Hope 1 5
Bob_Hope 3 6
Bob_Hope 4 5
Bob_Hope 4 7
Bridget_Fonda 1 3
Bridget_Fonda 2 3
Carlos_Ruiz 1 3
Carlos_Ruiz 2 3
Carly_Fiorina 1 2
Carly_Fiorina 1 3
Cherie_Blair 1 3
Cherie_Blair 1 4
Cherie_Blair 2 4
Cherie_Blair 3 4
Chuck_Yeager 1 2
Chung_Mong-joon 1 2
Claire_Hentzen 1 2
Claire_Leger 1 2
Darren_Clarke 1 2
David_Caraway 1 2
David_Leahy 1 2
Dick_Cheney 2 14
Dick_Cheney 3 11
Dick_Cheney 3 12
Dick_Cheney 8 10
Dino_de_Laurentis 1 2
Don_Nickles 1 2
Doris_Schroeder 1 3
Doris_Schroeder 2 4
Eduardo_Duhalde 2 3
Eduardo_Duhalde 2 12
Eduardo_Duhalde 3 4
Eduardo_Duhalde 6 13
Eduardo_Duhalde 7 10
Eduardo_Duhalde 10 12
Edwin_Edwards 1 3
Eric_Rosser 1 2
Ernie_Eves 1 2
Ernie_Fletcher 1 2
Eva_Dimas 1 2
Fernando_Vargas 1 2
Fernando_Vargas 1 3
Fernando_Vargas 1 4
Fernando_Vargas 2 3
Fernando_Vargas 3 4
Frank_Lautenberg 1 2
George_HW_Bush 1 3
George_HW_Bush 2 13
George_HW_Bush 4 6
George_HW_Bush 5 8
George_HW_Bush 9 10
Gisele_Bundchen 1 2
Glafcos_Clerides 1 2
Glafcos_Clerides 1 3
Glafcos_Clerides 2 3
Glafcos_Clerides 2 4
Greg_Gilbert 1 2
Hashim_Thaci 1 2
Hassan_Wirajuda 1 2
Hector_Babenco 1 3
Hector_Babenco 2 3
Hideki_Matsui 1 2
Hillary_Clinton 1 10
Hillary_Clinton 1 14
Hillary_Clinton 4 5
Hillary_Clinton 7 10
Hillary_Clinton 11 13
Hisao_Oguchi 1 2
Hitomi_Soga 1 4
Hitomi_Soga 1 5
Hitomi_Soga 2 3
Hitomi_Soga 3 4
JJ_Redick 1 2
Jean_Brumley 1 2
Jean_Carnahan 1 2
Jeremy_Shockey 1 2
Jerry_Regier 1 3
Jerry_Regier 2 3
Jerry_Springer 1 2
Jerry_Springer 1 4
Jessica_Lynch 1 2
Jiang_Zemin 1 17
Jiang_Zemin 2 3
Jiang_Zemin 4 10
Jiang_Zemin 7 9
Jiang_Zemin 15 18
Jim_Harrick 1 2
Jiri_Novak 3 4
Jiri_Novak 3 8
Jiri_Novak 3 9
Jiri_Novak 5 6
Jiri_Novak 5 10
Jiri_Novak 5 11
Jiri_Novak 7 10
Joe_Torre 1 3
Joe_Torre 2 4
John_Wolf 1 2
Jonathan_Edwards 1 6
Jonathan_Edwards 2 7
Jonathan_Edwards 3 6
Jonathan_Edwards 5 6
Jonathan_Edwards 5 7
Jonathan_Edwards 6 8
Jose_Manuel_Durao_Barroso 1 2
Jose_Manuel_Durao_Barroso 1 6
Jose_Manuel_Durao_Barroso 2 5
Jose_Manuel_Durao_Barroso 3 5
Jose_Manuel_Durao_Barroso 4 5
Joseph_Biden 1 4
Joseph_Biden 2 3
Joseph_Biden 3 4
Judi_Dench 1 2
Judy_Genshaft 1 2
Keanu_Reeves 1 9
Keanu_Reeves 4 7
Keanu_Reeves 6 9
Keanu_Reeves 6 10
Keanu_Reeves 7 12
Keira_Knightley 1 2
Ken_Watanabe 1 2
Kieran_Prendergast 1 2
King_Abdullah_II 1 3
King_Abdullah_II 1 4
King_Abdullah_II 2 5
King_Abdullah_II 3 4
Kirk_Ferentz 1 2
Kurt_Busch 1 2
Larry_Bowa 1 2
Larry_Thompson 1 3
Larry_Thompson 1 4
Larry_Thompson 2 4
Laura_Bush 1 11
Laura_Bush 21 24
Laura_Bush 21 39
Laura_Bush 26 29
Lauren_Hutton 1 2
Leslie_Ann_Woodward 1 2
Leslie_Moonves 1 2
Lyle_Vanclief 1 2
Magui_Serna 1 2
Makhdoom_Amin_Fahim 1 3
Makhdoom_Amin_Fahim 2 3
Marc-Andre_Fleury 1 2
Marco_Antonio_Barrera 1 5
Marco_Antonio_Barrera 5 6
Marie-Reine_Le_Gougne 1 2
Marieta_Chrousala 1 2
Marieta_Chrousala 1 3
Marieta_Chrousala 2 3
Marina_Anissina 1 2
Mark_Hamister 1 2
Martha_Stewart 1 3
Martha_Stewart 1 5
Martha_Stewart 2 3
Martha_Stewart 2 5
Martha_Stewart 3 4
Martin_Brodeur 1 2
Martin_McCauley 1 2
Martin_Verkerk 1 2
Martin_Verkerk 1 3
Martin_Verkerk 2 3
Martina_McBride 1 3
Martina_McBride 2 4
Matt_Doherty 1 2
Matt_Doherty 1 3
Matt_Doherty 2 3
Matthew_Perry 1 6
Matthew_Perry 2 7
Matthew_Perry 3 4
Megawati_Sukarnoputri 6 23
Megawati_Sukarnoputri 7 22
Megawati_Sukarnoputri 10 15
Megawati_Sukarnoputri 11 24
Megawati_Sukarnoputri 20 24
Megawati_Sukarnoputri 20 30
Meghann_Shaughnessy 1 2
Michael_Capellas 1 2
Michael_Sullivan 1 2
Mike_Brey 1 2
Naji_Sabri 1 6
Naji_Sabri 2 4
Naji_Sabri 2 7
Naji_Sabri 3 8
Naji_Sabri 6 7
Nanni_Moretti 1 2
Nastassia_Kinski 1 2
Natalie_Coughlin 2 3
Natalie_Coughlin 4 6
Natalie_Coughlin 5 6
Norah_Jones 3 15
Norah_Jones 4 12
Norah_Jones 7 15
Norah_Jones 9 15
Norah_Jones 11 12
Norm_Coleman 5 7
Oscar_De_La_Hoya 1 3
Oscar_De_La_Hoya 2 6
Oscar_De_La_Hoya 2 7
Pascal_Lamy 1 2
Pat_Burns 1 2
Paul_McCartney 3 4
Paul_McCartney 3 5
Paul_Wellstone 1 2
Paul_Wellstone 1 3
Paul_Wellstone 2 3
Penelope_Cruz 1 2
Penelope_Cruz 1 3
Pete_Rose 1 2
Prince_Harry 1 2
Prince_Harry 2 3
Princess_Caroline 1 2
Princess_Caroline 2 5
Raquel_Welch 1 2
Reggie_Miller 1 2
Renee_Zellweger 2 13
Renee_Zellweger 2 16
Renee_Zellweger 3 16
Ricardo_Sanchez 1 6
Ricardo_Sanchez 2 4
Richard_Butler 1 2
Rubens_Barrichello 2 3
Rubens_Barrichello 4 5
Rubens_Barrichello 4 8
Rubens_Barrichello 6 11
Rubens_Barrichello 9 12
Samira_Makhmalbaf 1 2
Samuel_Waksal 1 2
Samuel_Waksal 1 3
Samuel_Waksal 1 4
Samuel_Waksal 2 4
Scott_McClellan 1 3
Scott_McClellan 2 4
Scott_McClellan 2 5
Scott_Rudin 1 2
Shane_Warne 1 2
Sheila_Wellstone 1 2
Sheryl_Crow 1 3
Silvan_Shalom 2 3
Silvan_Shalom 2 4
Silvan_Shalom 2 6
Silvan_Shalom 3 4
Silvan_Shalom 3 6
Steve_Mariucci 1 3
Steve_Mariucci 2 3
Steven_Seagal 1 2
Taha_Yassin_Ramadan 3 12
Taha_Yassin_Ramadan 7 13
Tammy_Lynn_Michaels 1 2
Theodore_Tweed_Roosevelt 1 2
Theodore_Tweed_Roosevelt 1 3
Theodore_Tweed_Roosevelt 2 3
Tom_Crean 1 2
Tom_Crean 3 5
Tom_Crean 4 5
Tony_Bennett 1 3
Torri_Edwards 1 2
Tung_Chee-hwa 1 2
Tung_Chee-hwa 1 8
Tung_Chee-hwa 2 8
Vidar_Helgesen 1 2
Warren_Buffett 1 2
Warren_Buffett 1 3
Wen_Jiabao 1 12
Wen_Jiabao 2 11
Wen_Jiabao 4 7
Wen_Jiabao 5 6
Wen_Jiabao 7 9
Wen_Jiabao 7 12
Wen_Jiabao 8 12
Wen_Jiabao 10 11
Wen_Jiabao 11 12
Wesley_Clark 1 2
Yuri_Malenchenko 1 2
Abbas_Kiarostami 1 Fujio_Mitarai 1
Abdullah 1 Teresa_Heinz_Kerry 1
Abdullah 3 Samuel_Waksal 1
Abdullah 4 Julio_Cesar_Franco 1
Abid_Hamid_Mahmud_Al-Tikriti 1 Anjum_Hussain 1
Abid_Hamid_Mahmud_Al-Tikriti 2 Doris_Schroeder 1
Adam_Freier 1 Hillary_Clinton 3
Adam_Freier 1 Princess_Caroline 1
Adam_Freier 1 Regina_Ip 1
Alan_Ball 1 Kristin_Scott_Thomas 1
Alan_Ball 2 Yuri_Malenchenko 1
Albert_Costa 6 Gary_Barnett 1
Albert_Costa 6 John_Marburger 1
Albert_Costa 6 Wen_Jiabao 7
Alberta_Lee 1 Babe_Ruth 1
Alex_Popov 1 Kent_Rominger 2
Alex_Popov 1 Matthew_During 1
Ali_Khamenei 2 Roberto_Canessa 1
Amelia_Vega 1 Gina_Lollobrigida 1
Amelia_Vega 5 Jim_Harrick 1
Amy_Pascal 1 Eduardo_Duhalde 7
Amy_Pascal 1 Hank_Azaria 1
Amy_Pascal 1 John_Marburger 1
Amy_Redford 1 Roman_Coppola 1
Amy_Redford 1 Victor_Kraatz 1
Anderson_Varejao 1 Dennis_Oswald 1
Anderson_Varejao 1 Garth_Drabinsky 1
Andrei_Nikolishin 1 Angelica_Romero 1
Andrew_Bernard 1 Don_Nickles 2
Andrew_Bernard 1 Hassan_Wirajuda 1
Andrew_Bernard 1 Mark_Broxmeyer 1
Andrew_Fastow 1 Luca_Cordero_di_Montezemolo 1
Andrew_Fastow 1 Meghann_Shaughnessy 1
Andrew_Fastow 1 Tomas_Malik 1
Andrew_Luster 1 Eric_Rosser 1
Andrew_Luster 1 Jose_Manuel_Durao_Barroso 6
Andrew_Luster 1 Lisa_Murkowski 1
Anita_DeFrantz 1 Carla_Gay_Balingit 1
Anita_DeFrantz 1 Penny_Lancaster 1
Anjum_Hussain 1 David_Caraway 2
Anne_Cavers 1 James_Barksdale 1
Anne_Cavers 1 Stephen_Oake 1
Anthony_Hazen 1 Debra_Yang 1
Antonio_Catania 1 Barry_Bonds 1
Antonio_Catania 1 Taylyn_Solomon 1
Aretha_Franklin 1 Jean_Brumley 1
Aretha_Franklin 1 Teruaki_Masumoto 1
Art_Lopez 1 Diane_Lane 1
Arthur_Johnson 1 Selma_Phoenix 1
Arye_Mekel 2 Chung_Mong-joon 1
Arye_Mekel 2 Georgina_Papin 1
Babe_Ruth 1 Jim_Harrick 1
Babe_Ruth 1 Pete_Aldridge 1
Barry_Bonds 1 James_Barksdale 1
Barry_Bonds 1 Mickey_Sherman 1
Barry_Switzer 1 Jiang_Zemin 11
Barry_Switzer 1 Kirk_Ferentz 2
Bernard_Giraudeau 1 Keira_Knightley 1
Bernard_Landry 3 Stacey_Jones 1
Bernard_Landry 4 Sylvia_Plachy 1
Biljana_Plavsic 1 Kieran_Prendergast 2
Bill_Cartwright 1 Claude_Jorda 1
Bill_Lerach 1 Martin_Verkerk 2
Bob_Hope 1 Stanley_Ho 1
Bob_Hope 5 Micah_Knorr 1
Bob_Hope 5 Mitchell_Potter 1
Bob_Menendez 1 David_Caraway 2
Bob_Menendez 1 Lauren_Hutton 1
Bob_Riley 1 Danny_Ainge 1
Bob_Riley 1 Nastassia_Kinski 2
Bob_Riley 1 Sheila_Wellstone 2
Brad_Wilk 1 Phil_Cline 1
Brad_Wilk 1 Scott_Dalton 1
Brian_Grazier 1 Tomas_Malik 1
Brian_StPierre 1 Steve_Mariucci 2
Cari_Davis 1 Don_Henley 1
Cari_Davis 1 Mark_Broxmeyer 1
Carin_Koch 1 John_Banko 2
Carla_Gay_Balingit 1 Frank_Lautenberg 2
Carla_Gay_Balingit 1 Paula_Dobriansky 1
Carlos_Ruiz 1 Peter_Schultz 1
Carlos_Ruiz 3 Jennifer_Tilly 1
Carly_Fiorina 2 Peter_Ueberroth 1
Catherine_Woodard 1 Mike_Sweeney 1
Chan_Ho_Park 1 Xiang_Xu 1
Chance_Mock 1 Herb_Ritts 1
Chance_Mock 1 Shafal_Mosed 1
Chance_Mock 1 Simona_Hradil 1
Chance_Mock 1 Troy_Jenkins 1
Charles_Taylor 7 Tom_Curley 1
Chea_Sophara 1 John_Wolf 1
Chris_Cirino 1 Jen_Bice 1
Chris_Cirino 1 Mary_Lou_Markakis 1
Chris_Cirino 1 Peri_Gilpin 1
Christina_Sawaya 1 Greg_Gilbert 1
Chung_Mong-joon 1 David_Modell 1
Chung_Mong-joon 1 Luca_Cordero_di_Montezemolo 1
Chung_Mong-joon 1 Nick_Markakis 1
Chung_Mong-joon 2 John_Rusnak 1
Claire_Leger 1 David_Caraway 2
Claire_Leger 1 Jerry_Sexton 1
Claire_Leger 1 Nobuyuki_Idei 1
Clark_Randt 1 Katie_Boone 1
Clark_Randt 1 Marc-Andre_Fleury 1
Clemente_de_la_Vega 1 Ron_Gonzales 1
Colin_Campbell 1 Frank_Keating 1
Colin_Campbell 1 Jean_Carnahan 2
Colin_Campbell 1 Mitchell_Potter 1
Colleen_Atwood 1 Penelope_Cruz 2
Craig_Morgan 1 Matthew_McConaughey 1
Dan_Duquette 1 Paddy_Torsney 1
Daniel_Ortega 1 Norah_Jones 6
Daniel_Patrick_Moynihan 1 Eglis_Yaima_Cruz 1
Daniel_Patrick_Moynihan 1 Newton_Carlton_Slawson 1
Daniel_Rouse 1 Doris_Schroeder 1
Daniel_Rouse 1 Mike_Johanns 1
Daniell_Sunjata 1 Marc-Andre_Fleury 2
Danny_Ainge 1 Lee_Ann_Terlaji 1
David_Leahy 1 Jerry_Sexton 1
David_Scott_Morris 1 Valerie_Thwaites 1
David_Zeplowitz 1 Jerry_Springer 1
Dawn_Staley 1 Hasan_Wirayuda 1
Debra_Rose 1 Jonathan_Edwards 2
Debra_Yang 1 Hashim_Thaci 2
Debra_Yang 1 Yekaterina_Guseva 1
Denis_Fassou-Nguesso 1 William_Overlin 1
Derrick_Taylor 1 Giuseppe_Morchio 1
Derrick_Taylor 1 William_Overlin 1
Dick_Cheney 5 James_Murdoch 1
Dick_Cheney 8 Nobuyuki_Idei 1
Dick_Smothers 1 Yoon_Won-Sik 1
Dita_Von_Tesse 1 Mohammed_Al-Douri 12
Don_Henley 1 Ernie_Eves 1
Don_Henley 1 Gil_Cates 1
Don_Henley 1 Stephen_Frears 1
Don_Henley 1 Ziwang_Xu 1
Donald_Regan 1 John_Gruden 1
Doris_Schroeder 2 Joe_Mantegna 1
Eduardo_Duhalde 1 Paula_Dobriansky 1
Eduardo_Duhalde 2 Tab_Turner 1
Eduardo_Duhalde 13 James_Murdoch 1
Edward_Egan 1 Ernie_Fletcher 2
Edward_Johnson 1 Jessica_Capshaw 1
El_Hadji_Diouf 1 Hitomi_Soga 2
Emilio_Botin 1 Luca_Cordero_di_Montezemolo 1
Emilio_Botin 1 Robert_Hyatt 1
Enrique_Iglesias 1 Gisele_Bundchen 2
Eric_Bana 1 Mike_Sweeney 1
Eric_Bana 1 Tab_Turner 1
Eric_Benet 1 Mohammad_Mustapha_Miro 1
Eric_Rosser 1 Marc-Andre_Fleury 2
Eric_Rosser 1 Peter_Chan 1
Ernie_Eves 2 Hana_Makhmalbaf 1
Fernando_Vargas 1 Julio_Cesar_Franco 1
Fernando_Vargas 3 Martin_Verkerk 3
Flavia_Pennetta 1 Larry_Flynt 1
Flavia_Pennetta 1 Micah_Knorr 1
Flavia_Pennetta 1 Paul_Wellstone 1
Frank_Keating 1 Paul_McCartney 7
Frank_Lautenberg 2 Michael_Capellas 1
Frank_Lautenberg 2 Steve_Allee 1
Fujio_Mitarai 1 Harvey_Weinstein 1
Gabriella_Bo 1 Jeremy_Shockey 2
Gavyn_Arthur 1 Kevin_Hearn 1
Gavyn_Arthur 1 Lynne_Slepian 1
Gavyn_Arthur 1 Zahir_Shah 1
George_HW_Bush 7 George_Maxwell_Richards 1
George_HW_Bush 13 Penny_Lancaster 1
George_Maxwell_Richards 1 Reggie_Miller 1
Georgina_Papin 1 Mary_Lou_Retton 1
Georgina_Papin 1 Svend_Robinson 1
Gerry_Kelly 1 Keira_Knightley 1
Giannina_Facio 1 Peri_Gilpin 1
Gideon_Black 1 Kevin_Hearn 1
Gideon_Black 1 Shafal_Mosed 1
Gisele_Bundchen 2 Penny_Lancaster 1
Giuseppe_Morchio 1 Penny_Lancaster 1
Greg_Frers 1 Mohammed_Al-Douri 4
Greg_Gilbert 1 Mehmet_Ali_Sahin 1
Gregorio_Honasan 1 Jim_Schwarz 1
Gregorio_Honasan 1 Jonathan_Fine 1
Gregorio_Honasan 1 Matt_Doherty 1
Hama_Arba_Diallo 1 Zhang_Yimou 1
Hana_Makhmalbaf 1 Raquel_Welch 1
Hassan_Wirajuda 1 Scott_Dalton 1
Hector_Babenco 2 Talisa_Bratt 1
Herb_Ritts 1 Mark_Broxmeyer 1
Hugh_Campbell 1 Ken_Watanabe 1
Hugh_Campbell 1 Masamori_Tokuyama 1
Hugh_Campbell 1 Tom_Foy 1
Imran_Khan 1 Matt_Morris 1
Imran_Khan 1 Nancy_Humbert 1
Ivan_Lee 1 Jennifer_Furminger 1
James_Hallock 1 Robert_Beck 1
James_Murdoch 1 Martina_McBride 3
Jamie_Kellner 1 Tomas_Malik 1
Jamie_King 1 Lauren_Hutton 2
Jane_Fonda 2 Martha_Stewart 4
Janet_Leigh 1 Marianne_Stanley 1
Jaromir_Jagr 1 Troy_Jenkins 1
Jean_Brumley 2 Jim_Harrick 1
Jen_Bice 1 Judi_Dench 2
Jennifer_Furminger 1 Matthew_During 1
Jennifer_Tilly 1 Serge_Klarsfeld 1
Jennifer_Tilly 1 Stella_Tennant 1
Jeremy_Shockey 2 Robert_Beck 1
Jerry_Regier 2 Paulina_Rodriguez_Davila 1
Jerry_Regier 3 Lee_Hyung-taik 1
Jerry_Regier 3 Pete_Rose 2
Jessica_Capshaw 1 Penelope_Cruz 2
Jiang_Zemin 4 Michelangelo_Antonioni 1
Jiang_Zemin 13 Roman_Coppola 1
Jim_Sterk 1 Jonathan_Edwards 3
Jim_Sterk 1 Ken_Watanabe 2
Joey_Harrington 1 Nick_Price 1
John_Lynch 1 Michael_Sullivan 1
John_Robbins 1 Tom_Foy 1
John_Thune 1 Milan_Milutinovic 1
John_Velazquez 1 Marco_Antonio_Barrera 3
John_Velazquez 1 Tammy_Lynn_Michaels 1
John_Wolf 2 Prince_Harry 1
Jonathan_Byrd 1 Mike_Matheny 1
Jonathan_Byrd 1 Sheikh_Ahmed_Yassin 1
Jonathan_Horton 1 Lee_Ann_Terlaji 1
Jorge_Alberto_Galindo 1 Roger_King 1
Joseph_Biden 5 Mahdi_Al_Bassam 1
Joseph_Biden 5 Tung_Chee-hwa 4
Judy_Genshaft 1 Shane_Warne 1
Jules_Asner 1 Robert_Beck 1
Julien_Varlet 1 Scott_Dalton 1
Kate_Burton 1 Martha_Stewart 2
Kate_Richardson 1 Roman_Coppola 1
Katie_Boone 1 Uthai_Pimchaichon 1
Katie_Smith 1 Leland_Chapman 1
Katrin_Susi 1 Luca_Cordero_di_Montezemolo 1
Kay_Bailey_Hutchison 1 Theodore_Tweed_Roosevelt 3
Kieran_Prendergast 1 Lachlan_Murdoch 1
King_Abdullah_II 4 Robert_Hyatt 1
Kirk_Ferentz 2 Milan_Milutinovic 1
Lachlan_Murdoch 1 Mickey_Sherman 1
Larry_Flynt 1 Phil_Cline 1
Larry_Greene 1 Mike_Brey 2
Laurence_Tribe 1 Uthai_Pimchaichon 1
Lee_Ann_Terlaji 1 Roman_Coppola 1
Lee_Yuan-tseh 1 Shafal_Mosed 1
Lee_Yuan-tseh 1 Yuri_Malenchenko 2
Leland_Chapman 1 Theodore_Tweed_Roosevelt 1
Leslie_Moonves 2 Robert_Hyatt 1
Lisa_Murkowski 1 Serge_Klarsfeld 1
Magui_Serna 1 Maura_Tierney 1
Mahdi_Al_Bassam 1 Marc-Andre_Fleury 2
Mahdi_Al_Bassam 1 Mother_Teresa 1
Malak_Habbak 1 Prince_Harry 3
Manuel_Pellegrini 1 Rolf_Eckrodt 1
Manuela_Montebrun 1 Martina_McBride 2
Manuela_Montebrun 1 Steven_Seagal 2
Marion_Fahnestock 1 Wen_Jiabao 3
Mark_Hamister 1 Xiang_Xu 1
Martha_Martinez_Flores 1 Mike_Brey 2
Martha_Stewart 5 Victor_Kraatz 1
Martin_Lawrence 1 Mickey_Sherman 1
Martin_Lawrence 1 Penny_Lancaster 1
Martin_McCauley 2 Steven_Seagal 1
Martin_Verkerk 1 Steven_Seagal 1
Martina_McBride 3 Peter_Schultz 1
Masamori_Tokuyama 1 Regina_Ip 1
Masamori_Tokuyama 1 Serge_Melac 1
Matt_Doherty 2 Saoud_Al_Faisal 1
Meghann_Shaughnessy 1 William_Perry 1
Mehmet_Ali_Sahin 1 Peri_Gilpin 1
Mehmet_Ali_Sahin 1 Raquel_Welch 2
Michael_Capellas 1 Victor_Garber 1
Mickey_Sherman 1 Roman_Coppola 1
Mike_Brey 2 Nick_Markakis 1
Mike_Johanns 1 Pascal_Lamy 1
Mike_Matheny 1 Norm_Coleman 5
Mohammad_Mustapha_Miro 1 Steve_Mariucci 2
Mother_Teresa 1 Yekaterina_Guseva 1
Nancy_Humbert 1 Park_Na-kyong 1
Nanni_Moretti 1 Shigeru_Ishiba 1
Natalia_Dmitrieva 1 Willie_Nelson 1
Natalie_Juniardi 1 Uthai_Pimchaichon 1
Nick_Price 1 Tab_Turner 1
Norm_Coleman 4 Peri_Gilpin 1
Norm_Coleman 7 Scott_McClellan 5
Paddy_Torsney 1 Tung_Chee-hwa 9
Park_Na-kyong 1 Vecdi_Gonul 1
Patrick_Rafter 1 Peter_Care 1
Pierre_Van_Hooijdonk 1 Scott_McClellan 1
Regina_Ip 1 Rohman_al-Ghozi 1
Renee_Zellweger 9 Yuri_Malenchenko 2
Rolf_Eckrodt 2 Teresa_Heinz_Kerry 1
Rubens_Barrichello 10 Stella_Tennant 1
Saoud_Al_Faisal 1 Vecdi_Gonul 1
Scott_Dalton 1 Zach_Safrin 1
Scott_McClellan 2 Tom_Schnackenberg 1
Todd_MacCulloch 1 Willie_Nelson 1
Tom_Curley 1 Wanda_de_la_Jesus 1
Troy_Jenkins 1 Walid_Al-Awadi 1
William_Overlin 1 Yekaterina_Guseva 1
Abdoulaye_Wade 1 2
Abdoulaye_Wade 1 3
Abdoulaye_Wade 2 3
Adam_Sandler 1 2
Adam_Sandler 1 4
Adam_Sandler 2 3
Aicha_El_Ouafi 1 3
Aicha_El_Ouafi 2 3
Akbar_Hashemi_Rafsanjani 1 3
Akbar_Hashemi_Rafsanjani 2 3
Al_Pacino 1 2
Al_Pacino 1 3
Alex_Barros 1 2
Allyson_Felix 1 3
Allyson_Felix 1 4
Allyson_Felix 1 5
Allyson_Felix 4 5
Anastasia_Myskina 1 2
Andy_Roddick 8 12
Andy_Roddick 10 15
Andy_Roddick 13 15
Anna_Nicole_Smith 1 2
Antonio_Palocci 1 8
Antonio_Palocci 3 6
Antonio_Palocci 4 5
Antonio_Palocci 5 7
Antonio_Palocci 6 8
Arnoldo_Aleman 1 3
Arnoldo_Aleman 3 5
Ashton_Kutcher 1 3
Ashton_Kutcher 2 3
Augusto_Roa_Bastos 1 2
Aung_San_Suu_Kyi 1 2
Barry_Zito 1 2
Bill_Graham 1 9
Bill_Graham 3 4
Bill_Graham 4 6
Bill_Graham 5 6
Bob_Dole 1 3
Bruce_Weber 1 2
Carlos_Mesa 1 2
Carolyn_Dawn_Johnson 1 2
Carolyn_Dawn_Johnson 2 3
Celine_Dion 3 8
Chakib_Khelil 1 2
Chen_Shui-bian 2 4
Chen_Shui-bian 3 5
Christopher_Walken 1 3
Christopher_Walken 1 4
Claudia_Pechstein 1 2
Claudia_Pechstein 1 4
Claudia_Pechstein 3 4
Claudia_Pechstein 3 5
Claudia_Pechstein 4 5
Clay_Aiken 2 4
Clay_Aiken 3 4
Clay_Aiken 3 5
Colin_Powell 40 71
Colin_Powell 49 234
Colin_Powell 133 170
Colin_Powell 182 198
Cristina_Fernandez 1 2
Daisy_Fuentes 2 3
Damon_van_Dam 1 2
Dan_Wheldon 1 2
David_Coulthard 1 2
David_Kelley 1 2
Debra_Brown 1 2
Dennis_Erickson 1 2
Derek_Lowe 1 2
Eddie_Sutton 1 2
Edie_Falco 1 2
Elijah_Wood 2 3
Elizabeth_Hurley 1 4
Elizabeth_Hurley 2 5
Emily_Robison 1 2
Ethan_Hawke 1 4
Eunice_Barber 1 2
Felix_Mantilla 1 2
Fidel_Castro 1 18
Fidel_Castro 3 7
Fidel_Castro 5 8
Fidel_Castro 8 12
Fidel_Castro 11 13
Francisco_Flores 1 2
Francisco_Flores 1 3
Frank_Dunham_Jr 1 2
Franko_Simatovic 1 2
Fred_Eckhard 1 2
Fred_Eckhard 1 3
Fred_Eckhard 2 3
GL_Peiris 1 2
GL_Peiris 1 3
GL_Peiris 2 3
GL_Peiris 2 4
Garry_Kasparov 1 2
Hassan_Nasrallah 1 2
Heidi_Klum 1 3
Heidi_Klum 1 4
Heidi_Klum 2 4
Heidi_Klum 3 4
Heinz_Feldmann 1 2
Heinz_Feldmann 2 3
Iban_Mayo 1 2
Imad_Moustapha 1 2
Inam-ul-Haq 1 2
James_Gandolfini 1 3
James_Gandolfini 2 3
Janet_Thorpe 1 2
Jean-Pierre_Raffarin 1 2
Jean-Pierre_Raffarin 1 6
Jean-Pierre_Raffarin 3 4
Jean-Pierre_Raffarin 3 5
Jean-Pierre_Raffarin 4 7
Jean-Pierre_Raffarin 5 7
Jean-Pierre_Raffarin 6 7
Jeffrey_Scott_Postell 1 2
Jennifer_Capriati 2 14
Jennifer_Capriati 7 32
Jennifer_Capriati 33 42
Job_Cohen 1 2
John_McCormack 1 2
John_Paul_II 1 4
John_Paul_II 2 5
John_Paul_II 2 8
John_Paul_II 4 9
John_Paul_II 10 11
John_Ruiz 1 2
John_Stallworth 1 2
John_Stockton 2 4
John_Travolta 2 6
John_Travolta 3 5
John_Travolta 5 7
Jonathan_Mostow 1 2
Jorge_Arce 1 2
Joschka_Fischer 1 10
Joschka_Fischer 6 11
Joschka_Fischer 7 11
Joschka_Fischer 11 17
Joschka_Fischer 15 16
Jose_Canseco 1 3
Juan_Manuel_Marquez 1 2
Juan_Manuel_Marquez 1 3
Juan_Manuel_Marquez 2 3
Juan_Valencia_Osorio 1 2
Julie_Gerberding 9 13
Julie_Gerberding 12 15
Kate_Hudson 1 4
Kate_Hudson 1 8
Kate_Hudson 2 3
Kate_Hudson 4 9
Kate_Hudson 6 7
Kemal_Dervis 1 3
Kemal_Dervis 2 3
Kenneth_Evans 1 2
Kifah_Ajouri 1 2
Larry_Lucchino 1 2
Latrell_Sprewell 1 2
Lech_Walesa 1 2
Lee_Tae-sik 1 2
Lisa_Marie_Presley 1 3
Liza_Minnelli 2 3
Liza_Minnelli 3 4
Liza_Minnelli 3 6
Liza_Minnelli 4 5
Liza_Minnelli 5 6
Liza_Minnelli 6 7
Madonna 1 4
Madonna 2 3
Madonna 4 5
Mariah_Carey 3 6
Mary_Tyler_Moore 1 2
Mathias_Reichhold 1 2
Matt_Damon 1 2
Matt_Damon 1 3
Matt_Damon 2 4
Matt_Damon 3 4
Maureen_Fanning 1 2
Melanie_Griffith 1 2
Melanie_Griffith 1 3
Melanie_Griffith 2 3
Michael_Ballack 1 2
Michael_Winterbottom 1 3
Michael_Winterbottom 2 3
Michelle_Collins 1 2
Milo_Maestrecampo 1 2
Mohamed_Benaissa 1 2
Mohamed_ElBaradei 2 4
Mohamed_ElBaradei 3 8
Morgan_Freeman 1 2
Muhammad_Ali 1 3
Muhammad_Ali 1 7
Muhammad_Ali 2 5
Muhammad_Ali 6 10
Muhammad_Ali 7 9
Mukesh_Ambani 1 2
Mukesh_Ambani 1 3
Paris_Hilton 1 2
Pat_Cox 1 2
Paul_Burrell 3 7
Paul_Burrell 5 11
Paul_Burrell 8 10
Paul_Wolfowitz 8 10
Paula_Radcliffe 1 2
Paula_Radcliffe 1 3
Paula_Radcliffe 2 3
Paula_Radcliffe 2 4
Paula_Radcliffe 3 4
Paula_Radcliffe 3 5
Paula_Radcliffe 4 5
Paulo_Cesar_Pinheiro 1 2
Pedro_Solbes 1 3
Pedro_Solbes 1 4
Pedro_Solbes 2 3
Pedro_Solbes 3 4
Pete_Carroll 1 2
Pete_Carroll 1 3
Pete_Carroll 2 3
Pete_Sampras 2 12
Pete_Sampras 2 13
Pete_Sampras 3 15
Pete_Sampras 4 20
Pete_Sampras 6 7
Pete_Sampras 6 8
Pete_Sampras 10 13
Pete_Sampras 12 15
Peter_Struck 1 5
Peter_Struck 2 5
Phil_Vassar 1 2
Pierre_Boulanger 1 2
Prince_Willem-Alexander 1 2
Prince_Willem-Alexander 1 3
Prince_Willem-Alexander 2 3
Queen_Elizabeth_II 3 7
Queen_Elizabeth_II 9 12
Queen_Elizabeth_II 10 11
Queen_Elizabeth_II 10 12
Ray_Nagin 1 2
Ricardo_Maduro 1 2
Richard_Branson 1 2
Richard_Virenque 1 4
Richard_Virenque 1 6
Richard_Virenque 1 7
Richard_Virenque 2 7
Richard_Virenque 2 8
Rick_Carlisle 2 4
Rick_Wagoner 1 2
Robbie_Williams 1 2
Robbie_Williams 1 3
Roberto_Carlos 2 3
Roberto_Carlos 2 4
Roseanne_Barr 1 2
Roseanne_Barr 2 3
Ruben_Studdard 1 2
Sammy_Sosa 1 2
Sarah_Jessica_Parker 1 3
Sarah_Jessica_Parker 2 4
Sarah_Jessica_Parker 3 4
Sharon_Davis 1 2
Shaul_Mofaz 1 2
Shaul_Mofaz 2 3
Stan_Heath 1 2
Svetlana_Koroleva 1 2
Terrell_Suggs 1 2
Tim_Henman 2 12
Tim_Henman 8 19
Tom_Daschle 7 8
Tom_Daschle 15 21
Tom_Daschle 15 22
Tony_Curtis 1 2
Valentino_Rossi 1 2
Valentino_Rossi 2 4
Valentino_Rossi 3 6
Valentino_Rossi 4 5
Valentino_Rossi 5 6
Vanessa_Redgrave 1 3
Vanessa_Redgrave 1 4
Vanessa_Redgrave 2 5
Vanessa_Redgrave 3 4
Victoria_Clarke 1 5
Vladimiro_Montesinos 1 2
Vladimiro_Montesinos 1 3
Vladimiro_Montesinos 2 3
Wayne_Ferreira 1 2
Wayne_Ferreira 1 3
Wayne_Ferreira 1 5
Wayne_Ferreira 2 5
Wayne_Ferreira 3 4
Will_Smith 1 2
Yasser_Arafat 1 6
Yasser_Arafat 1 8
Yasser_Arafat 2 3
Yasser_Arafat 2 5
Yasser_Arafat 3 4
Yasser_Arafat 3 8
Yasser_Arafat 4 5
Yasser_Arafat 5 8
Yuri_Fedotov 1 2
Zoran_Djindjic 1 3
Zoran_Djindjic 1 4
Aaron_Patterson 1 Frank_Bell 1
Abdoulaye_Wade 4 Bruce_Weber 2
Abner_Martinez 1 Carlos_Alberto 1
Adam_Sandler 2 Matthew_Ouimet 1
Adam_Sandler 3 Saeed_Anwar 1
Adolfo_Aguilar_Zinser 3 Jaime_Pressly 1
Agnelo_Queiroz 1 Aung_San_Suu_Kyi 2
Agnelo_Queiroz 1 Dave_Barr 1
Aicha_El_Ouafi 3 Michael_Lechner 1
Akbar_Hashemi_Rafsanjani 1 Larry_Harris 1
Al_Pacino 2 Charles_Cope 1
Alex_Barros 1 Brandon_Jones 1
Alex_Barros 2 Will_Smith 2
Alex_Ferguson 1 Rainer_Gut 1
Alex_Wallau 1 Shireen_Amir_Begum 1
Alexandra_Jackson 1 Larry_Harris 1
Alfonso_Portillo 1 Benito_Santiago 1
Alfonso_Portillo 1 Faye_Alibocus 1
Alfonso_Portillo 1 Fidel_Castro 17
Ali_Abdullah_Saleh 1 Khalid_Qazi 1
Allan_Houston 1 Andy_Garcia 1
Allan_Houston 1 Heidi_Klum 1
Allan_Houston 1 Thomas_Mesereau_Jr 1
Ally_Sheedy 1 Hugh_Carey 1
Ally_Sheedy 1 Myung_Yang 1
Amanda_Marsh 1 Tony_Curtis 2
Anastasia_Myskina 1 Raul_Gonzalez 1
Anastasia_Myskina 3 Len_Jenoff 2
Andrzej_Tyszkiewicz 1 Wes_Craven 1
Andy_Griggs 1 Lech_Walesa 2
Andy_Rooney 1 Jessica_Simpson 1
Anna_Nicole_Smith 2 Marcus_Garrettson 1
Antonio_Palocci 3 Liza_Minnelli 1
Antonio_Palocci 5 JC_Chasez 1
Antonio_Palocci 5 Jose_Woldenberg 1
Antonio_Palocci 6 John_Geoghan 1
Antonio_Palocci 8 Hans_Corell 1
Arif_Mardin 1 Eduardo_Fischer 1
Arnaud_Lagardere 1 Melanie_Griffith 3
Ashton_Kutcher 2 Daniel_Barenboim 1
Asif_Hanif 1 Robbie_Williams 1
Asmaa_Assad 1 Barry_Hinson 1
Aung_San_Suu_Kyi 1 Charla_Moye 1
Azmi_Bishara 1 Sammy_Sosa 2
Barry_Hinson 1 Nino_DAngelo 1
Barry_Zito 2 Chris_Gratton 1
Bill_Graham 8 Michelle_Hofland 1
Bill_Graham 9 Jacqueline_Marris 1
Bill_Readdy 1 Brendan_Gaughan 1
Bill_Readdy 1 Jaymon_Crabb 1
Bill_Readdy 1 Yasser_Arafat 3
Billy_Rork 1 Eva_Mendes 1
Billy_Rork 1 German_Khan 1
Billy_Rork 1 Peter_Struck 2
Bison_Dele 1 Brian_McIntyre 1
Bob_Dole 2 Dai_Chul_Chyung 1
Bob_Dole 2 John_Henry 1
Bob_Dole 3 Chris_Gratton 1
Bob_Dole 3 Hugh_Carey 1
Bob_Geldof 1 Zoran_Djindjic 2
Bob_Geldof 2 Ed_Wade 1
Bob_Holden 1 Fernando_Leon_de_Aranoa 1
Bob_Iger 1 Edie_Falco 1
Bob_Iger 1 Jean-Claude_Van_Damme 1
Brian_Clemens 1 Brian_Meadors 1
Brian_Clemens 1 Melanie_Griffith 2
Brian_Heidik 2 Djabir_Said-Guerni 1
Brian_McIntyre 1 Hans_Corell 1
Brian_McIntyre 1 Mohammed_Abulhasan 1
Brian_Pavlich 1 Ruben_Wolkowyski 1
Brook_Robinson 1 Tom_McClintock 1
Brooke_Adams 1 Paula_Prentiss 1
Brooke_Gordon 1 Joschka_Fischer 12
Bruce_Weber 1 Hal_Sellers 1
Bryan_Thomas 1 Joey_Mantia 1
Bustam_A_Zedan_Aljanabi 1 Kajsa_Bergqvist 1
Calvin_Joseph_Coleman 1 Hassan_Nasrallah 1
Carla_Sullivan 1 Edie_Falco 1
Carlos_Barragan 1 Chen_Shui-bian 3
Carlos_Salinas 1 Norman_Mailer 1
Carlos_Salinas 1 Sonya_Walger 1
Carolyn_Dawn_Johnson 3 Lydia_Shum 1
Carolyn_Kuhl 1 Pierre_Boulanger 1
Celine_Dion 2 John_Stallworth 2
Celine_Dion 5 Linda_Baboolal 1
Celine_Dion 5 Tom_Poston 1
Chakib_Khelil 2 Chuck_Woolery 1
Charla_Moye 1 Patti_Balgojevich 1
Charles_Cope 1 Garry_Alejano 1
Charles_Holzner 1 Eurico_Guterres 1
Charles_Holzner 1 Greg_Kinnear 1
Chen_Shui-bian 3 Gaston_Gaudio 1
Chris_Gratton 1 Mario_Vasquez_Rana 1
Chris_Kolanas 1 Joshua_Gracin 1
Claudia_Pechstein 2 Mireille_Jospin-Dandieu 1
Clay_Aiken 1 Svetlana_Koroleva 1
Colin_Powell 95 Frank_Hsieh 1
Craig_David 1 Tom_McClintock 1
Craig_Wilson 1 Kajsa_Bergqvist 1
Cristina_Fernandez 2 Stephen_Cooper 1
Curtis_Joseph 1 Terrell_Suggs 2
Cynthia_Rowley 1 Michael_Friedman 1
Damon_van_Dam 2 Jason_Sorens 1
Daniel_Barenboim 1 Tyler_Grillo 1
Daniel_Bruehl 1 Gus_Frerotte 1
Daniel_Bruehl 1 Max_Mosley 1
Daniel_Bruehl 1 Ramon_Cardenas 1
Daniele_Bergamin 1 Kenneth_Evans 1
Danielle_Spencer 1 Rachel_Wheatley 1
Darcy_Regier 1 William_Hurt 1
Dave_Matthews 1 Linda_Dano 1
Dave_Matthews 1 Paul_Burrell 7
Dave_McNealey 1 Gerald_Riley 1
David_Bisbal 1 Terri_Clark 1
David_Chase 1 Ekaterina_Dmitriev 1
David_McCullough 1 Evo_Morales 1
David_McKiernan 1 Fernando_Leon_de_Aranoa 1
David_McKiernan 1 Jane_Leeves 1
Dennis_Erickson 2 Hisham_Halawi 1
Dennis_Erickson 2 Noer_Muis 1
Derek_Lowe 2 Hisham_Halawi 1
Derek_Lowe 2 Madonna 1
Derek_Lowe 2 Mohamed_Benaissa 1
Diego_Colorado 1 Jason_Sorens 1
Diego_Colorado 1 John_Gordnick 1
Diego_Diego_Lerman 1 Francisco_Flores 2
Diego_Diego_Lerman 1 Lesley_Coppin 1
Djabir_Said-Guerni 1 Paul_Tracy 1
Djabir_Said-Guerni 1 Pedro_Solbes 3
Dominik_Hrbaty 1 Toshi_Izawa 1
Donald_Keck 1 Kyoko_Nakayama 1
Donald_Keck 1 Tom_Poston 1
Donna_Walker 1 Jacqueline_Marris 1
Dragan_Covic 1 Todd_Reid 1
Dudley_Rogers 1 Syed_Ibrahim 1
Dunn_Lampton 1 Jessica_Simpson 1
Dustin_Hoffman 1 Nicole_Parker 1
Ed_Wade 1 Roger_Staubach 1
Ed_Wade 1 Terri_Clark 1
Eddie_Lucio 1 Patti_Balgojevich 1
Eddie_Sutton 1 James_Wattana 1
Eddie_Sutton 1 Jeanne_Anne_Schroeder 1
Eddie_Sutton 2 Ronald_Ito 1
Eduardo_Fischer 1 Kimberly_Bruckner 1
Edward_Lohn 1 Lily_Safra 1
Edward_Lohn 1 Nino_DAngelo 1
Ekaterina_Dmitriev 1 Mitch_Kupchak 1
Eladio_Larez 1 Frank_Pallone 1
Eli_Broad 1 Ravan_AG_Farhadi 1
Elijah_Wood 2 Stefano_Gabbana 1
Elijah_Wood 3 Marcus_Garrettson 1
Elijan_Ingram 1 Michelle_Hofland 1
Elijan_Ingram 1 Nastia_Liukin 1
Elvis_Costello 1 Jaime_Pressly 1
Emelie_Loit 1 Thomas_Mesereau_Jr 1
Eric_Staal 1 Jerry_Lewis 1
Erin_Hershey_Presley 1 Frank_Dunham_Jr 1
Erin_Hershey_Presley 1 Yukio_Hatoyama 1
Eva_Mendes 1 Larry_Harris 1
Faye_Alibocus 1 Frank_Bell 1
Faye_Alibocus 1 Tommy_Tubberville 1
Felix_Mantilla 1 Jerry_Lewis 1
Fernando_Leon_de_Aranoa 1 John_Scarlett 1
Fernando_Leon_de_Aranoa 1 Mike_Leach 1
Fidel_Castro 7 Hu_Maoyuan 1
Francisco_Flores 4 Hisham_Halawi 1
Frank_Bell 1 Khatol_Mohammad_Zai 1
Frank_Dunham_Jr 1 Tom_McClintock 1
Frank_Hsieh 1 Paula_Prentiss 1
Frank_Pallone 1 Jim_Wall 1
Frank_Pallone 1 Mary_Tyler_Moore 2
Frank_Schmoekel 1 Ronald_Ito 1
Franko_Simatovic 2 Tyler_Grillo 1
Franz_Gsell 1 John_Scarlett 1
Franz_Gsell 1 Sarah_Jessica_Parker 2
Fred_Eckhard 1 Rachel_Wheatley 1
Garry_Alejano 1 Iban_Mayo 1
Garry_Alejano 1 Michael_Olowokandi 1
Garry_Alejano 1 Morgan_Freeman 2
Garry_Alejano 1 Peter_Struck 5
Gary_Marshall 1 Rashid_Qureshi 1
Gerald_Fitch 1 Robin_Williams 1
Gerald_Riley 1 Michael_Hagee 1
German_Khan 1 Morgan_Freeman 2
Grady_Little 1 Robert_Morvillo 1
Hal_Sellers 1 Janet_Thorpe 1
Hans_Corell 1 John_Gordnick 1
Heidi_Klum 2 Paul_Reiser 1
Heidi_Klum 3 Pedro_Solbes 1
Hermando_Harton 1 Paris_Hilton 2
Holly_Robinson_Peete 1 Michael_Hagee 1
Howard_Ross 1 Kajsa_Bergqvist 1
Howard_Ross 1 Patsy_Hardy 1
Hugh_Carey 1 Lawrence_Roberts 1
Hugh_Carey 1 Tracee_Treadwell 1
Iban_Mayo 2 Juan_Valencia_Osorio 1
Iban_Mayo 2 Rosalie_Perkov 1
Ibrahim_Al-Marashi 1 John_Travolta 3
Ibrahim_Al-Marashi 1 Joshua_Gracin 1
Imad_Moustapha 2 Kyoko_Nakayama 1
Ira_Einhorn 1 John_Ruiz 2
Jacqueline_Marris 1 Matthew_Ouimet 1
Jaime_Pressly 1 Tiago_Splitter 1
James_Brown 1 Mary_Blige 1
James_Brown 1 Paul_Reiser 1
James_Mathis 1 Yuri_Fedotov 1
James_Wattana 1 Paul_Reiser 1
James_Wattana 1 Ron_Kirk 1
James_Young 1 Jeffrey_Scott_Postell 2
James_Young 1 Ronald_Harwood 1
Jane_Leeves 1 Tom_McClintock 1
Janet_Crawford 1 Thomas_Scavone 1
Jason_Sorens 1 Lidija_Djukanovic 1
Jason_Vale 1 Marcus_Garrettson 1
Jason_Vale 1 Zoran_Djindjic 3
Jaymon_Crabb 1 Ted_Christopher 1
Jeff_Weaver 1 Kyoko_Nakayama 1
Jeff_Weaver 1 Rosalie_Perkov 1
Jeffrey_Scott_Postell 1 Tara_Dawn_Christensen 1
Jeffrey_Scott_Postell 2 Lesley_Coppin 1
Jennifer_Capriati 26 Ruben_Wolkowyski 1
Jim_Bunning 1 Terence_Newman 1
Jim_Jeffords 1 Peter_Rasch 1
Jim_Jeffords 1 Tom_Sizemore 1
Job_Cohen 1 John_Stockton 2
John_Franco 1 Paul_Wolfowitz 4
John_Gordnick 1 Linda_Dano 1
John_Gordnick 1 Paul_Vathis 1
John_Gordnick 1 Yasser_Arafat 3
John_Stockton 4 Patsy_Hardy 1
John_Travolta 2 Lech_Walesa 1
Juan_Valencia_Osorio 1 Tom_Daschle 6
Juergen_Schrempp 1 Mitt_Romney 1
Julien_Boutter 1 Saeed_Anwar 1
Kaisser_Bazan 1 Lawrence_Vito 1
Kaisser_Bazan 1 Pierre_Lacroix 1
Kajsa_Bergqvist 1 Tayshaun_Prince 1
Keith_Snyder 1 Terri_Clark 1
Kemal_Dervis 3 Roger_Staubach 1
Kifah_Ajouri 1 Laurie_Pirtle 1
Kifah_Ajouri 1 Raul_Gonzalez 1
Kimberly_Bruckner 1 Pete_Carroll 1
Kirk_Douglas 1 Nida_Blanca 1
Larry_Harris 1 Michael_Lechner 1
Larry_Lucchino 1 Rudy_Tomjanovich 1
Latrell_Sprewell 1 Rosalie_Perkov 1
Laura_Schlessinger 1 Tony_Curtis 1
Laurie_Pirtle 1 Roberta_Combs 1
Lawrence_Roberts 1 Lynne_Thigpen 1
Lawrence_Roberts 1 Nick_Cassavetes 1
Lech_Walesa 2 Rick_Wagoner 2
Len_Jenoff 2 Tom_Daschle 7
Lew_Rywin 1 Terri_Clark 1
Linda_Dano 1 Terence_Newman 1
Lydia_Shum 1 Mario_Vasquez_Rana 1
Lynne_Thigpen 1 Mary_Blige 1
Malcolm_Glazer 1 Noer_Muis 1
Malcolm_Glazer 1 Tabare_Vazquez 1
Marc_Bulger 1 Paul_Wolfowitz 7
Marcus_Garrettson 1 Pham_Sy_Chien 1
Marcus_Garrettson 1 Roberto_Carlos 3
Maribel_Dominguez 1 Michael_Winterbottom 3
Marion_Barry 1 Steve_Peace 1
Mark_Hogan 1 Queen_Elizabeth_II 11
Mark_Hogan 1 Roger_Toussaint 1
Mary_Blige 1 Raul_Gonzalez 1
Massoud_Barzani 1 Pierre_Lacroix 1
Max_Mosley 1 Raul_Gonzalez 1
Melvin_Talbert 1 Rudy_Tomjanovich 1
Michael_Hagee 1 Sonya_Walger 1
Michael_Killeen 1 Sammy_Sosa 2
Michael_Olowokandi 1 Pete_Carroll 2
Michael_Winterbottom 1 Pierre_Boulanger 1
Mike_Price 2 Tom_Miller 1
Milo_Maestrecampo 1 Yuri_Fedotov 1
Milo_Maestrecampo 2 Steve_Peace 1
Milo_Maestrecampo 3 Stacey_Dales-Schuman 1
Mitt_Romney 1 Nida_Blanca 1
Mohamed_ElBaradei 8 Rachel_Wheatley 1
Mohammad_Aktar 1 Rafeeuddin_Ahmed 1
Mohammad_Aktar 1 Tom_McClintock 1
Mohammed_Abulhasan 1 Stephane_Rousseau 1
Mohammed_Abulhasan 1 Vladimiro_Montesinos 1
Nastia_Liukin 1 Nicole_Parker 1
Nastia_Liukin 1 Sharon_Davis 2
Nicolas_Latorre 1 Paula_Prentiss 1
Nicolas_Latorre 1 Vassilis_Xiros 1
Nicolas_Latorre 1 William_Delahunt 1
Pete_Sampras 10 Stan_Heath 1
Phil_Vassar 2 Tabare_Vazquez 1
Philip_Zalewski 1 Stefan_Holm 1
Roberto_Carlos 1 Yasser_Arafat 5
Roger_Cook 1 Wilbert_Foy 1
Roger_Staubach 1 Severino_Antinori 1
Ron_Kirk 1 Troy_Hudson 1
Sammy_Sosa 2 Stan_Heath 2
Sandra_Ceccarelli 1 Stephen_Cooper 1
Sandra_Ceccarelli 1 Tom_Coughlin 1
Shireen_Amir_Begum 1 Sushma_Swaraj 1
Sinead_OConnor 1 Stephane_Rochon 1
Aitor_Gonzalez 1 2
Alec_Baldwin 2 4
Allison_Janney 1 2
Alvaro_Noboa 1 3
Alvaro_Noboa 2 3
Amanda_Coetzer 1 2
Amer_al-Saadi 1 3
Amer_al-Saadi 1 4
Amer_al-Saadi 2 4
Ana_Guevara 2 7
Ana_Guevara 3 7
Anneli_Jaatteenmaki 1 2
Ari_Fleischer 6 9
Ari_Fleischer 7 12
Arianna_Huffington 1 2
Arianna_Huffington 1 4
Arianna_Huffington 2 3
Arianna_Huffington 2 4
Arnaud_Clement 1 2
Arsinee_Khanjian 1 2
Art_Howe 1 2
Art_Howe 1 3
Art_Howe 1 4
Art_Howe 2 3
Art_Howe 3 4
Ben_Affleck 2 3
Ben_Affleck 2 4
Ben_Affleck 2 7
Ben_Affleck 3 6
Ben_Affleck 5 6
Betsy_Smith 1 2
Bill_Callahan 1 3
Blythe_Hartley 1 2
Bob_Huggins 1 3
Bob_Huggins 3 4
Bobby_Goldwater 1 2
Bono 1 2
Bono 1 3
Bono 2 3
Brad_Garrett 1 3
Brad_Garrett 2 3
Brad_Garrett 2 4
Brian_Mulroney 1 2
Bud_Selig 1 2
Bud_Selig 2 3
Bud_Selig 2 4
Carla_Del_Ponte 1 2
Carla_Del_Ponte 2 4
Carla_Del_Ponte 2 5
Carla_Del_Ponte 3 5
Carlos_Ghosn 1 2
Carlos_Manuel_Pruneda 1 2
Carlos_Manuel_Pruneda 1 3
Carlos_Menem 2 21
Carlos_Menem 5 18
Carlos_Menem 8 15
Carlos_Menem 11 12
Carlos_Menem 14 21
Carlos_Menem 16 18
Carmen_Electra 3 4
Carmen_Electra 4 6
Charlotte_Rampling 1 2
Chick_Hearn 1 2
Christine_Todd_Whitman 2 3
Christine_Todd_Whitman 5 6
Christopher_Reeve 1 3
Chuck_Amato 1 2
Cindy_Crawford 2 3
Cindy_Margolis 1 2
Claire_Danes 1 3
Claire_Danes 2 3
Conan_OBrien 1 2
Conan_OBrien 2 3
Conan_OBrien 2 4
Conchita_Martinez 1 2
Conchita_Martinez 1 3
Dan_Morales 1 2
Dan_Morales 1 3
David_Hyde_Pierce 1 2
David_Hyde_Pierce 1 3
David_Hyde_Pierce 2 3
David_Hyde_Pierce 2 4
David_Myers 1 2
David_Nalbandian 1 3
David_Nalbandian 2 9
David_Nalbandian 3 4
David_Nalbandian 4 13
David_Nalbandian 11 12
David_Stern 1 2
David_Stern 2 3
Derek_Jeter 2 3
Derek_Jeter 2 4
Donatella_Versace 1 3
Donatella_Versace 2 3
Donna_Shalala 1 2
Edmund_Hillary 1 2
Edmund_Hillary 1 3
Edmund_Hillary 2 3
Elisabeth_Schumacher 1 2
Elizabeth_Smart 3 5
Erin_Runnion 1 3
Erin_Runnion 2 3
Erin_Runnion 2 4
Erin_Runnion 3 4
Fernando_Henrique_Cardoso 1 2
Fernando_Henrique_Cardoso 1 3
Fernando_Henrique_Cardoso 1 4
Fernando_Henrique_Cardoso 2 7
Fernando_Henrique_Cardoso 5 7
Fernando_Henrique_Cardoso 6 7
Francis_Mer 1 2
Franz_Fischler 1 2
Gary_Locke 1 2
Gerry_Adams 1 3
Gerry_Adams 1 7
Gerry_Adams 2 6
Gerry_Adams 3 5
Gerry_Adams 4 6
Gerry_Adams 5 6
Gianna_Angelopoulos-Daskalaki 1 2
Gil_de_Ferran 1 5
Gil_de_Ferran 2 4
Gil_de_Ferran 3 5
Goh_Kun 1 2
Grady_Irvin_Jr 1 2
Gunter_Pleuger 3 5
Gunter_Pleuger 3 6
Harry_Belafonte 1 2
Harry_Schmidt 1 3
Harry_Schmidt 1 4
Harry_Schmidt 2 3
Harry_Schmidt 3 4
Helen_Clark 2 4
Hermann_Maier 1 2
Ian_Thorpe 1 7
Ian_Thorpe 1 10
Ian_Thorpe 3 9
Ian_Thorpe 5 7
Ian_Thorpe 6 10
Isabelle_Huppert 1 2
James_Butts 1 2
Jan-Michael_Gambill 1 2
Jan-Michael_Gambill 2 3
Jean-Francois_Pontal 1 3
Jean-Marc_de_La_Sabliere 1 2
Jean-Sebastien_Giguere 1 2
Jeb_Bush 1 6
Jeb_Bush 2 6
Jeb_Bush 5 7
Jeffrey_Jones 1 2
Jim_OBrien 1 2
Jim_OBrien 1 3
Joe_Gatti 1 2
John_Cusack 1 2
John_Edwards 1 3
John_Edwards 1 7
John_Edwards 2 5
John_Edwards 3 7
John_Edwards 4 6
John_Edwards 4 8
John_Edwards 6 7
John_Spencer 1 2
John_Taylor 1 2
John_Walsh 1 2
Jolanta_Kwasniewski 1 2
Jose_Mourinho 1 2
Juergen_Peters 1 2
Kalpana_Chawla 1 4
Kalpana_Chawla 2 3
Kalpana_Chawla 2 5
Kalpana_Chawla 3 4
Kelli_White 1 2
Kim_Jin-sun 1 2
Lana_Clarkson 1 2
Laura_Hernandez 1 2
Laura_Linney 1 2
Laura_Linney 1 3
Laura_Linney 2 4
Laura_Linney 3 4
Lenny_Wilkens 1 2
Lenny_Wilkens 1 3
Lenny_Wilkens 2 3
Lloyd_Ward 1 2
Mahathir_Mohamad 1 7
Mahathir_Mohamad 1 12
Mahathir_Mohamad 6 10
Mark_Cuban 1 2
Mark_Heller 1 2
Mark_Schweiker 1 2
Marty_Mornhinweg 1 2
Marty_Mornhinweg 1 3
Marty_Mornhinweg 2 3
Michael_Phelps 1 2
Michael_Phelps 2 4
Mick_Jagger 2 4
Miguel_Estrada 1 2
Mike_Myers 1 6
Mike_Myers 2 3
Mike_Myers 2 4
Mike_Myers 2 5
Nadine_Vinzens 1 2
Nathan_Lane 1 2
Nicolas_Cage 1 2
Nicolas_Cage 2 4
Nicolas_Cage 3 4
Nicole_Kidman 3 11
Nicole_Kidman 8 17
Nicole_Kidman 11 13
Nicole_Kidman 13 14
Nicole_Kidman 15 19
Omar_Sharif 1 2
Omar_Sharif 1 3
Omar_Sharif 1 4
Omar_Sharif 2 3
Parris_Glendening 1 2
Patrick_Leahy 1 2
Patrick_McEnroe 1 2
Patrick_Stewart 1 2
Paul_Gascoigne 1 3
Peter_Hillary 1 2
Phan_Van_Khai 1 2
Phan_Van_Khai 1 3
Phan_Van_Khai 2 3
Prince_Claus 1 4
Prince_Claus 2 3
Prince_Claus 2 4
Raghad_Saddam_Hussein 1 2
Ray_Allen 1 2
Ray_Allen 2 3
Richard_Crenna 1 2
Richard_Gere 1 10
Richard_Gere 6 9
Richard_Myers 1 2
Richard_Myers 1 4
Richard_Myers 4 8
Richard_Myers 15 16
Rick_Romley 1 3
Rob_Lowe 1 3
Rob_Lowe 1 4
Rob_Lowe 2 3
Rob_Lowe 3 4
Robby_Ginepri 1 2
Robert_Witt 1 2
Rod_Blagojevich 1 2
Rolandas_Paksas 1 2
Russell_Coutts 1 2
Ruth_Dreifuss 1 2
Sally_Kirkland 1 4
Sean_Patrick_OMalley 1 3
Sebastian_Saja 1 2
Sebastian_Saja 1 3
Sila_Calderon 1 2
Sila_Calderon 1 3
Sila_Calderon 1 4
Sila_Calderon 2 3
Stanley_Tong 1 2
Steve_Park 1 2
Susie_Castillo 1 2
Sylvester_Stallone 1 5
Sylvester_Stallone 2 4
Sylvester_Stallone 3 8
Sylvester_Stallone 4 5
Takashi_Sorimachi 1 2
Tang_Jiaxuan 2 6
Tang_Jiaxuan 2 11
Tang_Jiaxuan 4 9
Tang_Jiaxuan 5 9
Tang_Jiaxuan 7 10
Terje_Roed-Larsen 1 2
Thomas_Birmingham 1 2
Tiger_Woods 2 6
Tiger_Woods 3 21
Tiger_Woods 5 11
Tiger_Woods 5 12
Tiger_Woods 6 18
Tiger_Woods 6 21
Tiger_Woods 9 12
Tiger_Woods 9 23
Tiger_Woods 16 18
Tim_Curry 1 2
Tom_Brady 1 2
Toshihiko_Fukui 1 2
Toshihiko_Fukui 1 3
Uma_Thurman 1 3
Uma_Thurman 2 3
Vaclav_Klaus 1 2
Vanessa_Incontrada 1 2
Vanessa_Incontrada 1 3
Vanessa_Incontrada 1 4
Vanessa_Incontrada 2 3
Vanessa_Incontrada 2 4
Vanessa_Incontrada 3 4
Vin_Diesel 1 2
Vladimir_Spidla 1 2
Vladimir_Spidla 1 3
Vladimir_Spidla 2 3
Win_Aung 1 3
Win_Aung 1 4
Zhang_Ziyi 1 3
Zhang_Ziyi 2 3
Adrian_Annus 1 Jorge_Marquez-Ruarte 1
Adrian_Annus 1 Patrick_Bourrat 1
Adrian_Murrell 1 Jose_Cevallos 1
Adrian_Murrell 1 Paul_Brandt 1
Ahmed_Ibrahim_Bilal 1 Beatrice_Dalle 1
Ahmed_Ibrahim_Bilal 1 Lee_Chang-dong 1
Aileen_Riggin_Soule 1 Norio_Ohga 1
Aitor_Gonzalez 2 Horace_Donovan_Reid 1
Ajit_Agarkar 1 Jesse_James 1
Akbar_Al_Baker 1 Andrei_Konchalovsky 1
Akbar_Al_Baker 1 Bobby_Goldwater 1
Alain_Cervantes 1 Bob_Huggins 3
Alain_Cervantes 1 Pierre_Png 1
Alanna_Ubach 1 Paul_Gascoigne 1
Alec_Baldwin 4 Goh_Kun 2
Alex_Holmes 1 Beatrice_Dalle 1
Alfred_Sant 1 Randall_Tobias 1
Alfredo_Moreno 1 Dyab_Abou_Jahjah 1
Alfredo_Moreno 1 Suzanne_Torrance 1
Alfredo_Pena 1 Emmanuel_Milingo 1
Alvaro_Noboa 1 Phan_Van_Khai 1
Alvaro_Noboa 2 Timothy_Rigas 1
Amanda_Coetzer 1 Bridgette_Wilson-Sampras 2
Amanda_Coetzer 1 Eddie_Jordan 1
Amer_al-Saadi 4 Miguel_Cotto 1
Amy_Brenneman 1 Russell_Coutts 2
Amy_Brenneman 1 Terje_Roed-Larsen 1
Andrew_Firestone 1 Harry_Schmidt 4
Andrew_Firestone 1 Ian_Campbell 1
Andrew_Firestone 1 Jose_Acasuso 1
Andrew_Firestone 1 Omar_Sharif 4
Andy_Graves 1 Gil_de_Ferran 1
Angela_Alvarado_Rosa 1 Gerald_Calabrese 1
Angela_Alvarado_Rosa 1 Jeffrey_Jones 1
Anneli_Jaatteenmaki 2 Eric_Robert_Rudolph 2
Anneli_Jaatteenmaki 2 Gerry_Adams 6
Anneli_Jaatteenmaki 2 Jorge_Marquez-Ruarte 1
Anthony_Corso 1 Johnny_Benson 1
Anthony_Corso 1 Ray_Allen 3
Anthony_Pico 1 Stephanie_Cohen_Aloro 1
Ari_Fleischer 1 Razali_Ismail 1
Ari_Fleischer 9 Jean-Marc_de_La_Sabliere 2
Arianna_Huffington 4 Philippe_Gagnon 1
Arnaud_Clement 1 Jeffrey_Jones 2
Arnaud_Clement 1 King_Gyanendra 1
Arnaud_Clement 2 Grady_Irvin_Jr 2
Arnold_Scott 1 Randy_Dryer 1
Art_Howe 2 Luciano_Bovicelli 1
Art_Howe 3 Teresa_Worbis 1
Artieas_Shanks 1 Derek_King 1
Astrid_Betancourt 1 Frederick_Madden 1
Barbara_De_Brun 1 Cosmo_Iacavazzi 1
Barry_Collier 1 Narendra_Modi 1
Ben_Affleck 3 Patricia_Hearst 1
Ben_Affleck 4 Daniel_Scioli 1
Ben_Affleck 7 Marcio_de_Souza 1
Ben_Broussard 1 Rudi_Voeller 1
Betsy_Smith 2 Steven_Kinlock 1
Betty_Williams 1 Mary_Catherine_Correll 1
Bianca_Jagger 1 Dario_Camuffo 1
Bianca_Jagger 1 Fabricio_Oberto 1
Bill_Callahan 1 Gina_Gershon 1
Bill_Kollar 1 Gina_Gershon 1
Bill_Kollar 1 Jose_Miguel_Aleman 1
Bill_Kollar 1 Mae_Jemison 1
Bill_Kollar 1 Mohammed_Ashraf_Hafiz 1
Bill_Kollar 1 Patty_Sheehan 1
Bill_Parsons 1 Donna_Barrera 1
Bill_Stein 1 Vanessa_Incontrada 4
Blythe_Hartley 1 Jackie_Dennis 1
Blythe_Hartley 2 Gil_de_Ferran 2
Bob_Curtis 1 Helen_Clark 1
Bob_Huggins 3 Sylvester_Stallone 2
Bobby_Goldwater 1 John_Moxley 1
Bobby_Goldwater 1 Ulrich_Kueperkoch 1
Bono 3 Ian_Huntley 1
Brad_Garrett 1 Hoda_Asfor 1
Brad_Garrett 4 Wang_Nan 1
Brandon_Hammond 1 Thomas_Kelly 1
Brandon_Robinson 1 Giovanny_Cordoba 1
Brandon_Robinson 1 Michael_Linscott 1
Brandon_Robinson 1 Shi_Guangsheng 1
Brendan_Stai 1 Dan_Guerrero 1
Brett_Boone 1 Jean-Marc_de_La_Sabliere 1
Brett_Boone 1 Teresa_Worbis 1
Brian_Billick 1 Ian_Huntley 1
Brian_Billick 1 John_Wayne 1
Brian_Billick 1 Stephanie_Moore 1
Brian_Olson 1 Roberto_Tovar 1
Bud_Selig 1 Franz_Fischler 1
Bud_Selig 3 John_Duprey 1
Carla_Moreno 1 Suzanne_Torrance 1
Carla_Moreno 1 Tang_Jiaxuan 3
Carlos_Beltran 1 Ulrich_Kueperkoch 1
Carlos_Ghosn 1 Jim_Paxson 1
Carlos_Ghosn 2 Ray_Allen 3
Carlton_Dotson 1 Jim_Paxson 1
Carlton_Dotson 1 Patrick_Bourrat 1
Carlton_Dotson 1 Porter_Goss 1
Carlton_Dotson 1 Vyacheslav_Fetisov 1
Cass_Ballenger 1 Norio_Ohga 1
Cecile_de_France 1 Dyab_Abou_Jahjah 1
Cecile_de_France 1 Terrence_Kiel 1
Charles_Bell 1 Tatjana_Gsell 1
Charlotte_Rampling 1 Lana_Clarkson 2
Chick_Hearn 1 Mohammed_Salmane 1
Christopher_Reeve 4 Pauline_Landers 1
Christopher_Reeve 4 Scott_OGrady 1
Cindy_Margolis 1 Mark_Cuban 2
Claire_Danes 2 Nadine_Vinzens 1
Claudio_Lopez 1 Gabrielle_Rose 1
Collis_Temple_III 1 Eva_Amurri 1
Collis_Temple_III 1 Rob_Niedermayer 1
Collis_Temple_III 1 Santiago_Botero 1
Collis_Temple_III 1 Simon_Chalk 1
Conan_OBrien 1 Liliana_Cavani 1
Corinna_Harfouch 1 Ivo_Dubs 1
Corinna_Harfouch 1 Tim_Curry 1
Cristina_Kirchner 1 Stefanie_De_Roux 1
Dan_Boyle 1 Paul_Clark 1
Dan_Boyle 1 Thabo_Mbeki 3
Daniel_Chin 1 Ian_Huntley 1
Daniel_Chin 1 Jim_Letten 1
Daniel_Chin 1 Julia_Glass 1
Daniel_Scioli 1 Lena_Katina 1
Daniel_Scioli 1 Lindsay_Lohan 1
Dario_Camuffo 1 Eli_Stutsman 1
David_Brinkley 1 Jeff_Bridges 1
David_Brinkley 1 Stephen_Arigbabu 1
David_Montoya 1 Mary_Elizabeth_Mastrantonio 1
David_Siegel 1 Francis_Mer 1
Dennis_Johnson 1 Satnarine_Sharma 1
Denys_Arcand 1 Nadine_Vinzens 2
Derek_Jeter 1 Tian_Zhuang_Zhuang 1
Derek_Jeter 3 Jolanta_Kwasniewski 2
Derek_King 1 Yasein_Taher 1
Derrick_Battie 1 Ian_Huntley 1
Diego_Armando_Maradona 1 Robert_Gordon_Card 1
Don_King 1 Thomas_Kelly 1
Don_King 1 Zurab_Tsereteli 1
Donna_Barrera 1 Francis_Mer 2
Donna_Shalala 2 Sereyvuth_Kem 1
Duncan_Fletcher 1 John_Cusack 2
Duncan_Fletcher 1 Mike_Alden 1
Dustin_Brown 1 Jose_Cevallos 1
Dyab_Abou_Jahjah 1 John_Cornyn 1
Ed_Mekertichian 1 Paul_Clark 1
Edmund_Hillary 2 Miguel_Cotto 1
Elena_Likhovtseva 1 Marty_Mornhinweg 2
Eli_Stutsman 1 Kalpana_Chawla 4
Eli_Stutsman 1 Marcio_de_Souza 1
Eli_Stutsman 1 Michael_Phelps 1
Elizabeth_Regan 1 Eugene_Teslovic 1
Emmanuel_Milingo 1 Enrica_Fico 1
Enola_Rice 1 Lana_Clarkson 2
Erin_Runnion 3 Rob_Lowe 2
Eugene_Teslovic 1 Goh_Kun 1
Eugene_Teslovic 1 Jean-Marc_de_La_Sabliere 2
Eva_Amurri 1 Tanya_Holyk 1
Fabricio_Oberto 1 Rudi_Voeller 1
Felix_Sanchez 1 Ian_Moran 1
Fernando_Henrique_Cardoso 1 Michael_Phelps 1
Fernando_Henrique_Cardoso 8 Sherry_Fisher 1
Francis_Mer 2 Patrick_Bourrat 1
Franz_Fischler 2 Robert_Lange 1
Frederick_Madden 1 Gary_Condit 1
Gary_Bauer 1 Greg_Hodge 1
Gary_Condit 1 Nathan_Lane 2
Gary_Locke 1 Marcio_de_Souza 1
Gen_Meredith 1 Matthew_Vaughan 1
Gerry_Adams 8 Jamir_Miller 1
Gilles_Panizzi 1 Jim_Piper 1
Gina_Gershon 1 Patricia_Garone 1
Gina_Gershon 1 Zhang_Ziyi 2
Giovanny_Cordoba 1 Jackie_Sherrill 1
Giovanny_Cordoba 1 Keith_Olbermann 1
Grady_Irvin_Jr 2 Oracene_Williams 1
Graeme_Smith 1 John_Salazar 1
Graham_Bentley 1 Jason_Clermont 1
Guillaume_Depardieu 1 Manuel_Llorente 1
Gunter_Pleuger 1 Nicole_Kidman 2
Gunter_Pleuger 2 Robby_Ginepri 1
Gunter_Pleuger 3 Vaclav_Klaus 1
Hanns_Schumacher 1 Martin_Gecht 1
Henri_Proglio 1 Ibrahim_Haddad 1
Henri_Proglio 1 Jeffery_Hendren 1
Hermann_Maier 1 Phan_Van_Khai 1
Hermann_Maier 2 Stephen_Arigbabu 1
Hideki_Sato 1 Peter_Mugyeni 1
Hideki_Sato 1 Troy_Aikman 1
Hoda_Asfor 1 Juergen_Peters 1
Hoda_Asfor 1 Lindsay_Lohan 1
Horace_Donovan_Reid 1 Rob_Lowe 1
Hunter_Kemper 1 Marsha_Thomason 1
Ian_Campbell 1 Mike_Alden 1
Ian_Huntley 1 Jalen_Rose 1
Ian_Huntley 1 Sebastian_Saja 2
Ian_Moran 1 Stephanie_Cohen_Aloro 1
Ian_Thorpe 5 Mickey_Gilley 1
Ignacio_Antonio_Velasco 1 Rich_Brooks 1
Iran_Brown 1 Margaret_Caruso 1
Isabelle_Huppert 1 Marcio_de_Souza 1
Isabelle_Huppert 2 Phan_Van_Khai 3
Ivan_Shvedoff 1 Josh_Childress 1
Ivan_Shvedoff 1 Miguel_Estrada 2
Ivan_Shvedoff 1 Vojislav_Seselj 1
Izzat_Ibrahim 1 Jerry_Rice 1
Jacques_Villeneuve 1 Wim_Duisenberg 1
Jalen_Rose 1 Suzanne_Torrance 1
James_Butts 1 Nicole_Kidman 2
James_Butts 2 Jerry_Colangelo 1
James_Butts 2 Sherry_Fisher 1
James_May 1 Trevor_McDonald 1
James_May 1 Vaclav_Klaus 2
Jamie_Cooke 1 Kalpana_Chawla 5
Jamie_Cooke 1 Mickey_Rooney 1
Jamir_Miller 1 Laura_Hernandez 1
Jana_Pittman 1 Liv_Tyler 1
Jason_Clermont 1 Jose_Carlo_Fernandez 1
Jason_Clermont 1 Patty_Duke 1
Jeff_Bridges 1 Landon_Donovan 1
Jeff_Bridges 1 Patty_Duke 1
Jeffery_Hendren 1 Jeremy_Wotherspoon 1
Jennifer_McCoy 1 Manuel_Llorente 1
Jennifer_McCoy 1 William_Cocksedge 1
Jerry_Colangelo 1 Vin_Diesel 2
Jerry_Rice 1 Joe_Gatti 2
Jessica_Brungo 1 Landon_Donovan 1
Jim_OBrien 1 Nadine_Vinzens 1
Jim_Paxson 1 Robert_Gordon_Card 1
Joe_Gatti 2 Mike_Samp 1
Joel_Todd 1 John_Fox 1
Joel_Todd 1 Momir_Nikolic 1
John_Cornyn 1 Jose_Mourinho 2
John_Cornyn 1 Robert_Weitzel 1
John_Cornyn 1 Toshihiko_Fukui 2
John_Dallager 1 Jose_Canseco_Sr 1
John_Spencer 2 Stephanie_Moore 1
John_Walsh 1 Kalpana_Chawla 1
John_Wright 1 Sandra_Milo 1
John_Wright 1 Trevor_McDonald 1
Johnny_Benson 1 Lana_Clarkson 2
Johnny_Benson 1 Teresa_Worbis 1
Jolanta_Kwasniewski 2 Martin_Howard 1
Jose_Canseco_Sr 1 Julia_Glass 1
Jose_Mourinho 1 Joseph_LePore 1
Jose_Mourinho 2 LeRoy_Millette_Jr 1
Jose_Vicente_Rangel 1 Leuris_Pupo 1
Jose_Vicente_Rangel 1 Scott_OGrady 1
Joy_Lee_Sadler 1 Laurie_Chan 1
Joy_Lee_Sadler 1 Norio_Ohga 1
Joy_Lee_Sadler 1 Stephanie_Moore 1
Karen_Pereiras 1 Michael_Phelps 2
Keith_Brown 1 Nicole_Kidman 17
Keith_Brown 1 William_Harrison 1
Keith_Van_Horn 1 Sherry_Fisher 1
Kelli_White 1 Rudi_Voeller 1
King_Gyanendra 1 Otto_Reich 1
Lana_Clarkson 1 Mike_Samp 1
Landon_Donovan 1 Robby_Ginepri 1
Larry_Tanenbaum 1 Mike_Samp 1
Laura_Ziskin 1 Reyyan_Uzuner 1
Laura_Ziskin 1 Robert_Gordon_Card 1
LeRoy_Millette_Jr 1 Leuris_Pupo 1
Lee_Chang-dong 1 Phil_Bredesen 1
Liliana_Cavani 1 Richard_Pennington 1
Lindsay_Lohan 1 Mireya_Elisa_Moscoso_Rodriguez 1
Lloyd_Ward 2 Tina_Andrews 1
Mark_Heller 1 Nicolas_Kiefer 1
Mark_Heller 1 Parris_Glendening 1
Mark_Heller 1 Peter_Hillary 2
Martin_Gecht 1 Peter_Hillary 1
Mary_Elizabeth_Mastrantonio 1 Vaclav_Klaus 1
Michael_Arif 1 Sean_Patrick_OMalley 3
Michael_Linscott 1 Tom_Brady 2
Mick_Jagger 3 Oracene_Williams 1
Mo_Elleithee 1 Tanya_Holyk 1
Mohammed_Ashraf_Hafiz 1 Rod_Bryden 1
Mukhtar_Alytnbayev 1 Oracene_Williams 1
Patricia_Garone 1 Sean_Patrick_OMalley 2
Patricia_Hearst 1 Scott_Dickson 1
Patty_Duke 1 Simon_Chalk 1
Paul_Bettany 1 Ulrich_Kueperkoch 1
Paul_Gascoigne 3 Tian_Liang 1
Paul_Greengrass 1 Tim_Pawlenty 1
Perry_Compton 1 William_Shatner 1
Peter_Camejo 1 Ruth_Christofferson 1
Porter_Goss 1 Tara_Kirk 1
Rand_Miller 1 Robert_Nillson 1
Rich_Brooks 1 Sharess_Harrell 1
Richard_Pennington 1 Robby_Ginepri 2
Robert_Gordon_Card 1 William_Shatner 1
Robert_Kipkoech_Cheruiyot 1 Sally_Kirkland 3
Robert_Kipkoech_Cheruiyot 1 Steve_Park 1
Russell_Coutts 1 Tian_Liang 1
Sandra_Milo 1 Satnarine_Sharma 1
Steve_Nesbitt 1 Win_Aung 4
Sylvester_Stallone 7 TJ_Ford 1
Sylvie_Guillem 1 Vadim_Devyatovskiy 1
Tara_Kirk 1 Win_Aung 1
Aaron_Peirsol 1 4
Aaron_Peirsol 3 4
Adrian_Nastase 1 2
Ahmed_Chalabi 1 3
Ahmed_Chalabi 1 5
Albrecht_Mentz 1 2
Alejandro_Toledo 20 36
Alejandro_Toledo 21 24
Alejandro_Toledo 21 30
Alejandro_Toledo 23 27
Alejandro_Toledo 26 29
Alexander_Losyukov 1 3
Alexander_Losyukov 2 3
Alexander_Losyukov 2 4
Alimzhan_Tokhtakhounov 1 2
Amelie_Mauresmo 7 14
Amelie_Mauresmo 11 17
Amelie_Mauresmo 14 17
Angelo_Reyes 1 2
Angelo_Reyes 1 3
Begum_Khaleda_Zia 1 2
Ben_Curtis 1 2
Bijan_Namdar_Zangeneh 1 2
Bill_Paxton 1 2
Bill_Paxton 1 3
Bill_Paxton 2 4
Bill_Paxton 3 4
Billy_Crystal 1 2
Billy_Crystal 1 3
Billy_Crystal 1 5
Billy_Crystal 3 5
Billy_Graham 1 2
Bob_Colvin 1 2
Brian_Cowen 1 2
Butch_Davis 1 2
Byron_Scott 1 2
Carol_Burnett 1 2
Charles_Mathews 1 2
Christine_Ebersole 1 2
Claudia_Schiffer 1 2
Condoleezza_Rice 1 4
Condoleezza_Rice 2 10
Condoleezza_Rice 4 5
Condoleezza_Rice 8 9
Condoleezza_Rice 9 10
Costas_Simitis 1 4
Costas_Simitis 1 5
Costas_Simitis 3 5
Costas_Simitis 4 6
Cristina_Saralegui 1 2
Cruz_Bustamante 1 4
Cruz_Bustamante 3 5
David_Heymann 3 5
Diana_Krall 1 6
Diana_Krall 3 4
Diana_Munz 1 3
Diana_Munz 2 3
Dominique_de_Villepin 2 13
Dominique_de_Villepin 3 8
Dominique_de_Villepin 3 10
Dominique_de_Villepin 7 11
Dominique_de_Villepin 10 14
Dominique_de_Villepin 11 12
Don_Siegelman 1 3
Don_Siegelman 2 4
Donald_Pettit 1 2
Donald_Pettit 1 3
Donald_Pettit 2 3
Doug_Collins 1 2
Edward_James_Olmos 1 2
Elin_Nordegren 1 2
Elizabeth_Taylor 1 2
Ellen_DeGeneres 1 2
Elton_John 1 4
Elton_John 2 3
Elton_John 3 6
Elton_John 5 6
Elton_John 5 7
Emma_Watson 2 3
Emma_Watson 3 4
Emma_Watson 3 5
Fabrice_Santoro 1 3
Fabrice_Santoro 2 3
Flavia_Delaroli 1 2
George_Lopez 1 4
George_Lopez 2 4
George_Lopez 2 5
George_Lopez 4 5
Gerard_Depardieu 1 2
Gerhard_Schroeder 5 43
Gerhard_Schroeder 17 25
Gerhard_Schroeder 27 32
Gerhard_Schroeder 45 67
Gerhard_Schroeder 66 100
Gilberto_Rodriguez_Orejuela 1 3
Gilberto_Rodriguez_Orejuela 2 3
Gilberto_Rodriguez_Orejuela 3 4
Giuseppe_Gibilisco 1 3
Giuseppe_Gibilisco 1 4
Giuseppe_Gibilisco 3 4
Guillermo_Canas 1 2
Guillermo_Canas 1 3
Guillermo_Canas 2 4
Guillermo_Canas 3 4
Hans_Blix 7 8
Hans_Blix 7 18
Hans_Blix 7 38
Hans_Blix 8 24
Hans_Blix 9 12
Hans_Blix 26 36
Hans_Blix 27 37
Hans_Blix 31 37
Heath_Ledger 1 2
Heath_Ledger 1 4
Heath_Ledger 2 3
Heath_Ledger 2 4
Herta_Daeubler-Gmelin 1 2
Hilary_Duff 1 3
Hilary_Duff 2 3
Hosni_Mubarak 6 7
Hun_Sen 1 4
Hun_Sen 2 4
Iain_Duncan_Smith 1 3
Iain_Duncan_Smith 2 3
Iain_Duncan_Smith 2 4
Iain_Duncan_Smith 3 4
Inocencio_Arias 1 2
JK_Rowling 1 2
JK_Rowling 2 3
JK_Rowling 2 4
JK_Rowling 3 5
Jackie_Chan 1 3
Jackie_Chan 5 8
Jane_Kaczmarek 1 2
Janet_Napolitano 1 2
Janet_Napolitano 1 4
Jay_Leno 1 3
Jay_Leno 2 3
Jean-David_Levitte 1 2
Jean-David_Levitte 1 4
Jean-David_Levitte 2 5
Jean-David_Levitte 3 4
Jean-David_Levitte 4 9
Jeff_Van_Gundy 1 2
Jeff_Van_Gundy 1 3
Jeff_Van_Gundy 2 3
Jim_Furyk 1 6
Jim_Furyk 3 6
John_Garamendi 1 2
John_Rigas 1 2
John_Warner 1 2
John_Warner 1 3
John_Warner 2 4
John_Warner 3 4
Julia_Tymoshenko 1 2
Julia_Tymoshenko 1 3
Julia_Tymoshenko 2 3
Keith_Bogans 1 3
Keith_Bogans 2 3
Ken_Macha 1 3
Ken_Macha 2 3
Kenneth_Bowersox 1 2
Kenneth_Bowersox 1 3
Kenneth_Bowersox 2 3
Kristanna_Loken 1 2
Kristanna_Loken 3 4
Kristanna_Loken 4 5
LK_Advani 1 2
LK_Advani 1 3
Lauren_Killian 1 2
Lennox_Lewis 1 2
Lennox_Lewis 1 3
Lili_Taylor 1 2
Lily_Tomlin 1 2
Lon_Kruger 1 2
Lynn_Abraham 1 2
Mahmoud_Abbas 7 11
Mahmoud_Abbas 15 20
Mahmoud_Abbas 22 27
Mark_Richt 1 2
Mark_Richt 1 3
Mary-Kate_Olsen 1 2
Mary-Kate_Olsen 2 3
Matt_Dillon 1 2
Max_Mayfield 1 2
Megan_Mullally 1 2
Megan_Mullally 1 3
Michael_Caine 1 2
Michael_Caine 1 3
Michael_Caine 3 4
Michael_J_Sheehan 1 2
Michael_Keaton 1 2
Michael_Powell 1 2
Michael_Powell 1 3
Michael_Powell 1 5
Michael_Powell 2 3
Michael_Powell 2 4
Michael_Powell 2 5
Michael_Powell 4 5
Miguel_Contreras 1 2
Mike_Weir 1 6
Mike_Weir 3 11
Mikhail_Kasyanov 1 2
Mikhail_Kasyanov 1 3
Mikhail_Kasyanov 3 4
Mohammed_Baqir_al-Hakim 1 3
Monica_Lewinsky 1 2
Monica_Lewinsky 1 3
Monica_Lewinsky 2 3
Nan_Wang 1 3
Nan_Wang 2 3
Nan_Wang 3 4
Nancy_Demme 1 2
Nancy_Reagan 1 2
Naoto_Kan 1 3
Naoto_Kan 2 3
Natasha_McElhone 1 2
Natasha_McElhone 1 3
Neri_Marcore 1 2
Nicholas_Tse 1 2
Nicolas_Escude 1 2
Noelle_Bush 1 3
Noelle_Bush 1 4
Noelle_Bush 2 4
Orrin_Hatch 1 2
Padraig_Harrington 1 3
Padraig_Harrington 1 4
Padraig_Harrington 2 4
Pedro_Almodovar 1 2
Pedro_Almodovar 3 5
Pedro_Almodovar 5 6
Penelope_Ann_Miller 1 2
Peter_Arnett 1 3
Peter_Arnett 2 3
Petria_Thomas 1 2
Petro_Symonenko 1 2
Prince_Charles 1 2
Prince_Charles 3 4
Prince_Charles 3 5
Raoul_Ruiz 1 2
Raoul_Ruiz 2 3
Raoul_Ruiz 2 4
Raoul_Ruiz 3 4
Ricky_Ponting 1 2
Robert_Stack 1 2
Robin_Cook 1 2
Roger_Federer 4 5
Roger_Federer 4 7
Roger_Federer 6 7
Ronaldo_Luis_Nazario_de_Lima 1 4
Ronaldo_Luis_Nazario_de_Lima 2 3
Ronaldo_Luis_Nazario_de_Lima 2 4
Ronaldo_Luis_Nazario_de_Lima 3 4
Roy_Williams 1 3
Roy_Williams 2 4
Sally_Ride 1 2
Scott_McNealy 1 2
Scott_Peterson 1 2
Scott_Peterson 1 5
Scott_Peterson 2 5
Scott_Peterson 3 4
Scott_Ritter 1 2
Sean_OKeefe 3 4
Sean_Penn 1 2
Sean_Penn 2 3
Sebastien_Grosjean 1 2
Sebastien_Grosjean 1 4
Sharon_Stone 1 2
Sharon_Stone 1 3
Sharon_Stone 1 4
Sharon_Stone 1 5
Sharon_Stone 2 4
Sonia_Gandhi 1 3
Sonia_Gandhi 1 4
Steve_Backley 1 2
Steven_Hatfill 1 2
Tassos_Papadopoulos 1 3
Taufik_Hidayat 1 2
Taufik_Hidayat 1 3
Taufik_Hidayat 2 3
Thomas_Malchow 1 2
Tom_Cruise 3 5
Tom_Cruise 4 10
Tom_Cruise 6 10
Toni_Braxton 1 3
Wayne_Gretzky 1 2
Wayne_Gretzky 1 4
William_Bulger 1 3
William_Bulger 2 4
Winona_Ryder 12 13
Winona_Ryder 12 18
Winona_Ryder 12 19
Xanana_Gusmao 1 4
Xanana_Gusmao 2 3
Xanana_Gusmao 3 5
Xanana_Gusmao 4 5
Yann_Martel 1 2
Yashwant_Sinha 1 3
Yashwant_Sinha 1 5
Yashwant_Sinha 5 7
Aaron_Guiel 1 Pascal_Rheaume 1
Aaron_Guiel 1 Steve_Zahn 1
Adrian_Nastase 2 Princess_Victoria 1
Ahmed_Chalabi 1 Rosario_Dawson 1
Ahmed_Ghazi 1 Julia_Tymoshenko 3
Ahmet_Demir 1 Wally_Szczerbiak 1
Ain_Seppik 1 Gerhard_Schroeder 55
Ain_Seppik 1 Misty_Dawn_Clymer 1
Ain_Seppik 1 Raoul_Ruiz 1
Ain_Seppik 1 Susan_Whelan 1
Aishwarya_Rai 1 Chloe_Sevigny 1
Aishwarya_Rai 1 Dinah_Turner 1
Aishwarya_Rai 1 Rosario_Dawson 1
Alan_Zemaitis 1 Lauren_Killian 1
Alex_Cejka 1 Taufik_Hidayat 2
Alexandre_Daigle 1 Brent_Coles 1
Ali_Bin_Hussein 1 Ben_Cahoon 1
Ali_Bin_Hussein 1 Oswald_Gruebel 1
Ali_Bin_Hussein 1 Raf_Vallone 1
Alimzhan_Tokhtakhounov 1 Jeane_Kirkpatrick 1
Alimzhan_Tokhtakhounov 2 Butch_Davis 1
Alisha_Richman 1 Camille_Lewis 1
Alisha_Richman 1 Katerina_Smrzova 1
Alisha_Richman 1 Miguel_Rosseto 1
Amelie_Mauresmo 3 Laura_Flessel 1
Amelie_Mauresmo 18 Bob_Colvin 1
Ana_Claudia_Talancon 1 Piers_Sellers 1
Andrea_Kiser 1 Ellen_Barkin 1
Andrea_Kiser 1 Imre_Kertasz 1
Andrea_Kiser 1 Matt_Dillon 1
Andrea_Kiser 1 Yann_Martel 2
Andres_DAlessandro 1 Leticia_Van_de_Putte 1
Andres_DAlessandro 1 Ronaldo_Luis_Nazario_de_Lima 1
Anette_Hosoi 1 Rolf_Zimmermann 1
Anette_Hosoi 1 Sheila_Taormina 1
Anette_Hosoi 1 Tora_Takagi 1
Angelo_Reyes 1 Chip_Knight 1
Angelo_Reyes 1 Oliver_Neuville 1
Anne_Heche 1 Sasha_Alexander 1
Anne_Heche 1 Tanya_Lindenmuth 1
Antje_Buschschulte 1 Jerry_Angelo 1
Anton_Balasingham 1 Matt_Siebrandt 1
Anton_Balasingham 1 Will_Ferrell 1
Armando_Avila_Panchame 1 Monica_Gabrielle 1
Armando_Avila_Panchame 1 Retief_Goosen 1
BJ_Habibie 1 Craig_MacTavish 1
Baz_Luhrmann 1 Danny_Avalon 1
Begum_Khaleda_Zia 1 Eric_Idle 1
Begum_Khaleda_Zia 1 Michael_Andretti 1
Begum_Khaleda_Zia 1 Picabo_Street 1
Ben_Cahoon 1 Nate_Blackwell 1
Ben_Cahoon 1 Roy_Williams 3
Ben_Curtis 3 Jim_Calhoun 1
Benicio_Del_Toro 1 Elizabeth_Taylor 1
Benicio_Del_Toro 1 Ismail_Khan 1
Benicio_Del_Toro 1 Tonya_Payne 1
Bijan_Namdar_Zangeneh 1 Petro_Symonenko 1
Billy_Graham 1 Karin_Pilsaeter 1
Billy_Graham 1 Piers_Sellers 1
Billy_Graham 2 Howard_Wilkinson 1
Bob_Colvin 2 Janet_Napolitano 1
Boris_Henry 1 John_Reid 2
Brandon_Boyd 1 James_Brosnahan 1
Brandon_Boyd 1 Neil_Moritz 1
Brent_Coles 1 Zoe_Ball 1
Brett_Hull 1 Gregorio_Rosal 1
Brett_Hull 1 Kirsten_Clark 1
Brett_Hull 1 Ralph_Nader 1
Brett_Perry 1 Neri_Marcore 1
Bruce_Willis 1 Carlos_Juarez 1
Bruce_Willis 1 Jim_Carrey 1
Bruce_Willis 1 Petria_Thomas 2
Bryant_Young 1 Jim_Bollman 1
Bryant_Young 1 Maurice_Cheeks 1
Buddy_Ryan 1 James_Brosnahan 1
Buddy_Ryan 1 Nancy_Reagan 2
Butch_Davis 2 Herta_Daeubler-Gmelin 2
Byron_Scott 1 Jane_Clayson 1
Camille_Lewis 1 Lincoln_Chafee 1
Camille_Lewis 1 Nathirah_Hussein 1
Carol_Burnett 1 Raf_Vallone 1
Carol_Niedermayer 1 Kristin_Scott 1
Catherine_Ndereba 1 Janet_Napolitano 4
Chandrika_Kumaratunga 1 Kevin_Satterfield 1
Charles_Mathews 1 Will_Ferrell 1
Charles_Mathews 2 Kristin_Scott 1
Charlie_Garner 1 Luo_Linquan 1
Charlie_Williams 1 Julia_Tymoshenko 1
Cheryl_Ford 1 Chris_Cookson 1
Chip_Knight 1 Ronald_Post 1
Chloe_Sevigny 1 Emyr_Jones_Parry 1
Chloe_Sevigny 1 Petria_Thomas 3
Chris_Cornell 1 Desmon_Farmer 1
Christine_Ebersole 2 Paul_Walker 1
Christoph_Daum 1 Scott_Hubbard 1
Christopher_Conyers 1 Michael_Milton 1
Christopher_Conyers 1 Raoul_Ruiz 1
Chuck_Bednarik 1 Mario_Jardel 1
Cindy_Zagorski 1 Rosie_Perez 1
Claudia_Schiffer 1 Lynn_Abraham 2
Claudia_Schiffer 3 Lin_Yung_Hsi 1
Colin_Cowie 1 Mstislav_Rostropovich 1
Condoleezza_Rice 2 Mehmet_Okur 1
Condoleezza_Rice 7 Ryan_Nyquist 1
Costas_Simitis 2 Lorraine_Fenton 1
Craig_MacTavish 1 Vince_Dooley 1
Cristina_Saralegui 1 Dave_Robertson 1
Cruz_Bustamante 2 Dean_Barkley 3
Cyndi_Thompson 1 Nicolas_Escude 2
Cyndi_Thompson 2 Owen_Nolan 1
Dalia_Rabin-Pelosoff 1 Sean_Combs 1
Daniel_Darnell 1 Malcolm_Jamal_Warner 1
Danny_Avalon 1 Sean_Penn 2
David_Blaine 1 Nicholas_Tse 2
David_Blaine 1 Ramon_Delgado 1
David_Heymann 3 Norm_Macdonald 1
David_Surrett 1 Michael_Taylor 1
David_Tornberg 1 Ricky_Ponting 1
Deece_Eckstein 1 Diana_Munz 1
Deece_Eckstein 1 Tommy_Lewis 1
Denis_Coderre 1 Don_Siegelman 1
Denis_Coderre 1 John_Eder 1
Desmon_Farmer 1 Lin_Yung_Hsi 1
Diana_Krall 4 Ramon_Delgado 1
Dick_Armey 1 Mehmet_Okur 1
Dinah_Turner 1 Mekhi_Phifer 1
Dinah_Turner 1 Tammy_Helm 1
Don_Boudria 1 Roy_Chaderton 1
Don_Boudria 1 Sananda_Maitreya 1
Don_Matthews 1 Kirsten_Clark 1
Don_Matthews 1 Pa_Kou_Hang 1
Don_Matthews 1 Peter_Arnett 2
Don_Siegelman 2 Elizabeth_Taylor 2
Donald_Pettit 1 Edward_James_Olmos 2
Doug_Collins 1 Kristanna_Loken 5
Dyana_Calub 1 Ronald_Post 1
Earl_Counter 1 Joe_Friedberg 1
Edward_Albee 1 Nicola_Bono 1
Edward_Belvin 1 Jacqueline_Gold 1
Edward_James_Olmos 2 Mariano_Zabaleta 1
Elin_Nordegren 1 George_Brumley_III 1
Elin_Nordegren 1 Samantha_Daniels 1
Elin_Nordegren 2 Leszek_Miller 3
Elisabeth_Welch 1 Piers_Sellers 1
Elizabeth_Taylor 1 Olympia_Dukakis 1
Ellen_DeGeneres 2 Lorraine_Fenton 1
Elva_Hsiao 1 Samantha_Daniels 1
Emma_Watson 2 Henry_Hyde 1
Emyr_Jones_Parry 1 Sally_Clark 1
Eric_Ryan_Donnelly 1 Iain_Duncan_Smith 1
Ernesto_Zedillo 1 Lenny_Kravitz 1
Ernesto_Zedillo 1 Megan_Mullally 2
Erwin_Mapasseng 1 Hilary_Duff 3
Evelyn_Lauder 1 Nathan_Powell 1
Fernando_Hierro 1 Prince_Charles 2
Flavia_Delaroli 2 John_Warner 4
Flavia_Delaroli 2 Vanessa_Laine 1
Fran_Drescher 1 Warren_Truss 1
Fran_Drescher 2 Jay_Leno 3
Frank_Murkowski 1 James_Brosnahan 1
Frank_Stallone 1 Tommy_Lewis 1
Frank_Stallone 2 Toni_Braxton 2
Gary_Coleman 1 Koichi_Tanaka 1
Gary_Coleman 1 Uri_Lopolianski 1
Gary_Sayler 1 Ralph_Sampson 1
George_Brumley_III 1 Will_Ferrell 1
George_Lopez 5 Iain_Duncan_Smith 1
Georgina_Bardach 1 Henry_Hilow 1
Gilberto_Rodriguez_Orejuela 3 Lennox_Lewis 1
Gilberto_Rodriguez_Orejuela 3 Nancy_Demme 1
Gordon_Lightfoot 1 Lima_Azimi 1
Gordon_Lightfoot 1 Robert_Nardelli 1
Gracia_Burnham 1 Jim_Calhoun 1
Gregorio_Rosal 1 Richard_Greenberg 1
Guenter_Verheugen 1 Kaspar_Villiger 1
Guillermo_Canas 1 Tim_Duncan 2
Guillermo_Canas 2 Michalis_Chrisohoides 1
Hal_McCoy 1 Rudolph_Holton 1
Hank_Aaron 1 Steve_Valentine 1
Hans_Eichel 1 Jimmy_Iovine 1
Hashan_Tillakaratne 1 John_Warner 3
Heath_Ledger 2 Melissa_Stark 1
Henry_Hilow 1 Monica_Gabrielle 1
Herta_Daeubler-Gmelin 2 Koichi_Tanaka 1
Hilary_Duff 1 Luther_Htu 1
Hun_Sen 2 John_Rigas 2
Idi_Amin 1 Stephen_Silas 1
Isabel_Orellana 1 Spike_Helmick 1
Ismael_Miranda 1 Janela_Jara 1
Ismael_Miranda 1 Peter_Greenspun 1
Ismail_Khan 1 Malcolm_Jamal_Warner 1
JK_Rowling 5 Sasha_Alexander 1
Jackie_Chan 3 Jennifer_Gratz 1
Jacqueline_Edwards 1 Meg_Wakeman 1
Jacqueline_Edwards 1 Noor_Mohammed 1
James_Baker 1 Mike_Tice 1
James_Harris 1 Keith_Bogans 2
James_Layug 1 Ralph_Sampson 1
Jane_Clayson 1 Rene_Antonio_Leon_Rodriguez 1
Jane_Kaczmarek 2 Morris_Watts 1
Jane_Russell 1 Martin_ONeill 1
Janela_Jara 1 Kirsten_Clark 1
Janela_Jara 1 Pa_Kou_Hang 1
Janela_Jara 1 Ricky_Cottrill 1
Janet_Napolitano 2 Laurie_Laychak 1
Javier_Camara 1 Nate_Blackwell 1
Jeane_Kirkpatrick 1 Jeff_Van_Gundy 3
Jeane_Kirkpatrick 1 Richard_Greenberg 1
Jeff_Van_Gundy 1 Richard_Naughton 1
Jeffrey_Katzenberg 1 Susan_Whelan 1
Jennette_Bradley 1 Tammy_Helm 1
Jim_Furyk 6 Linn_Thornton 1
John_Eastman 1 Ricky_Ponting 1
John_F_Kennedy_Jr 2 Nathan_Powell 1
John_Garamendi 1 Petro_Symonenko 2
John_Madden 1 Sara_Silverman 1
Jose_Luis_Rodriguez_Zapatero 1 Rene_Antonio_Leon_Rodriguez 1
Jose_Luis_Rodriguez_Zapatero 1 Steve_Lenard 1
Jose_Santos 1 Michael_Boyce 1
Joseph_Kabila 1 Rose_Linkins 1
Juan_Francisco_Palencia 1 Kristanna_Loken 2
Juan_Francisco_Palencia 1 Warren_Truss 1
Juan_Roman_Riquelme 1 Ralph_Sampson 1
Julia_Tymoshenko 2 Luis_Sanchez 1
Karin_Pilsaeter 1 Mike_Flanagan 1
Karin_Pilsaeter 1 Petria_Thomas 3
Keith_Bogans 2 Martin_ONeill 1
Kelly_Leigh 1 Spike_Helmick 1
Ken_Macha 3 Tommy_Lewis 1
Kenneth_Carlsen 1 Robin_Cook 1
Kevin_Borseth 1 Michael_Caine 4
Koichi_Tanaka 1 Ricardo_Lopez_Murphy 1
Kristin_Scott 1 Max_Mayfield 2
Laura_Flessel 1 Owen_Nolan 1
Lauren_Killian 2 Tommy_Lewis 1
Laurie_Laychak 1 Pa_Kou_Hang 1
Lawrence_Di_Rita 1 Mekhi_Phifer 1
Lennox_Lewis 3 Monte_Kiffin 1
Leon_Lai 1 Monica_Lewinsky 1
Leon_Lai 1 Sun_Myung_Moon 1
Lily_Tomlin 1 Marcos_Daniel_Jimenez 1
Lily_Tomlin 2 Sim_Yong 1
Linn_Thornton 1 Sherri_Coale 1
Linn_Thornton 1 Tom_Cruise 2
Lloyd_Mudiwa 1 Sebastien_Grosjean 1
Lois_Smart 1 Tavis_Smiley 1
Luis_Sanchez 1 Petro_Symonenko 1
Luo_Linquan 1 Martin_ONeill 1
Luther_Htu 1 Steve_Karsay 1
Lynn_Abraham 1 Michael_Keaton 2
Lynn_Abraham 2 Mariano_Zabaleta 1
Mark_Richt 3 Wilton_Gregory 1
Martha_Smith 1 Ray_Sherman 1
Martin_ONeill 1 Mike_Weir 11
Mary-Kate_Olsen 1 Sim_Yong 1
Matt_Siebrandt 1 Rodney_Dangerfield 1
Maurice_Cheeks 1 Steve_Austin 1
Mehmet_Okur 1 Randy_Travis 1
Michael_McNeely 1 Sean_Combs 1
Michael_Milton 1 Wilfredo_Moreno 1
Michael_Powell 1 Scott_Weiland 1
Miguel_Rosseto 1 Pascal_Rheaume 1
Miguel_Rosseto 1 Ricky_Ponting 2
Mike_Flanagan 1 Mohammed_Baqir_al-Hakim 2
Mike_Tice 1 Patti_Smith 1
Mohammed_Baqir_al-Hakim 2 Tatyana_Tomashova 1
Mufti_Mohammad_Syed 1 Raoul_Ruiz 4
Nancy_Demme 1 Roger_Mahony 1
Nancy_Reagan 1 Rafael_Bielsa 1
Natasha_McElhone 2 Robert_Nardelli 1
Nathirah_Hussein 1 Susan_Whelan 1
Neil_Moritz 1 Roy_Williams 2
Neil_Moritz 1 Xanana_Gusmao 5
Nelson_Shanks 1 Pedro_Martinez 1
Nelson_Shanks 1 Ren_Qingjin 1
Noor_Mohammed 1 Scott_Weiland 1
Oswald_Gruebel 1 Richard_Penniman 1
Parthiv_Patel 1 Tonya_Payne 1
Pauley_Perrette 1 Roy_Williams 4
Peter_Arnett 2 Rodney_Dangerfield 1
Peter_Greenspun 1 Rod_Thorn 1
Peter_Harvey 1 Warren_Truss 1
Raja_Ramani 1 Richard_Greenberg 1
Raja_Ramani 1 Will_Young 1
Ralph_Sampson 1 Samantha_Daniels 1
Raoul_Ruiz 3 Tirunesh_Dibaba 1
Ren_Qingjin 1 Wilton_Gregory 1
Ricardo_Lopez_Murphy 2 Roberto_Robaina 1
Ricky_Ponting 1 Ronaldo_Luis_Nazario_de_Lima 4
Robin_Cook 1 Wilton_Gregory 1
Roger_Federer 4 Steve_Backley 2
Ronald_Post 1 Steve_Karsay 1
Ryan_Nyquist 1 Winona_Ryder 22
Sally_Clark 1 Scott_Ritter 2
Samantha_Daniels 1 Taufik_Hidayat 3
Sherri_Coale 1 Troy_Garity 1
Steve_Valentine 1 Toni_Braxton 2
Tammy_Helm 1 Tom_Smothers 1
Tanya_Lindenmuth 1 Tora_Takagi 1
Toni_Braxton 3 Yann_Martel 2
Adam_Scott 1 2
Ahmad_Masood 1 2
Alan_Mulally 1 2
Alexander_Rumyantsev 1 2
Ali_Abbas 1 2
Amanda_Bynes 1 2
Amanda_Bynes 1 3
Amanda_Bynes 1 4
Amanda_Bynes 2 3
Andrei_Mikhnevich 1 2
Angela_Merkel 1 2
Angela_Merkel 4 5
Angelina_Jolie 1 15
Angelina_Jolie 2 11
Angelina_Jolie 8 15
Angelina_Jolie 9 15
Angelina_Jolie 11 20
Anthony_LaPaglia 1 2
Arlen_Specter 1 2
Atal_Bihari_Vajpayee 4 6
Barry_Alvarez 1 2
Bill_Belichick 1 2
Bill_Sizemore 1 2
Boris_Yeltsin 1 2
Britney_Spears 4 11
Bruce_Van_De_Velde 1 2
Camilla_Parker_Bowles 1 2
Carolina_Kluft 1 2
Carson_Palmer 1 3
Carson_Palmer 2 3
Catherine_Deneuve 1 4
Catherine_Deneuve 2 5
Catherine_Deneuve 3 5
Cesar_Maia 1 2
Charles_Moose 10 12
Chen_Liang_Yu 1 2
Choi_Sung-hong 1 5
Choi_Sung-hong 2 4
Choi_Sung-hong 3 4
Christina_Aguilera 1 2
Christina_Aguilera 1 4
Christina_Aguilera 2 4
Clara_Harris 1 5
Clara_Harris 2 4
Coretta_Scott_King 1 2
Coretta_Scott_King 1 3
Coretta_Scott_King 2 3
Courtney_Love 1 2
Daniel_Day-Lewis 1 3
Daniel_Day-Lewis 2 3
Daniela_Hantuchova 1 2
Debra_Messing 1 2
Dennis_Kucinich 2 7
Dick_Latessa 1 2
Donald_Rumsfeld 39 110
Donald_Rumsfeld 51 83
Donald_Rumsfeld 60 67
Eduard_Shevardnadze 1 5
Edward_Lu 4 6
Edwina_Currie 1 2
Edwina_Currie 2 4
Elizabeth_Shue 1 2
Ellen_Engleman 1 2
Emma_Thompson 1 2
Emma_Thompson 1 3
Emma_Thompson 2 3
Emmit_Smith 1 2
Fayssal_Mekdad 1 3
Fayssal_Mekdad 1 4
Frances_Fisher 1 2
Frank_Griswold 1 2
Gary_Forsee 1 2
Gloria_Macapagal_Arroyo 3 12
Gloria_Macapagal_Arroyo 3 25
Gloria_Macapagal_Arroyo 8 23
Gregory_Hines 1 2
Gus_Van_Sant 1 2
Gus_Van_Sant 1 3
Gwendal_Peizerat 1 2
Gwendal_Peizerat 1 3
Hal_Gehman 2 4
Hannah_Stockbauer 1 2
Harrison_Ford 1 12
Heizo_Takenaka 1 7
Heizo_Takenaka 3 8
Heizo_Takenaka 3 9
Hichiro_Naemura 1 2
Hipolito_Mejia 1 3
Hipolito_Mejia 1 4
Holly_Hunter 2 6
Holly_Hunter 3 7
Igor_Ivanov 5 16
Intisar_Ajouri 2 3
Jack_Nicholson 1 3
James_Blake 1 10
James_Blake 4 6
James_Blake 5 9
James_Kelly 4 5
James_Kopp 2 4
James_Smith 1 2
Jean_Chretien 2 39
Jean_Chretien 6 40
Jean_Chretien 8 35
Jean_Chretien 19 28
Jean_Chretien 28 52
Jean_Chretien 29 37
Jean_Chretien 34 36
Jeffrey_Immelt 1 2
Jennifer_Aniston 1 7
Jennifer_Aniston 1 16
Jennifer_Aniston 6 21
Jerry_Falwell 1 2
Jesse_Harris 1 3
Jesse_Harris 2 3
Joan_Claybrook 1 2
Joe_Calzaghe 1 2
Joe_Nichols 1 3
Joe_Nichols 2 4
Joe_Nichols 3 4
Joerg_Haider 1 2
John_Abizaid 1 2
John_Abizaid 1 7
John_Abizaid 2 3
John_Abizaid 4 7
John_Abizaid 4 8
John_Abizaid 5 6
John_Jumper 1 2
John_Mayer 1 2
John_Mayer 1 3
John_Negroponte 5 26
John_Negroponte 8 17
John_Negroponte 28 30
John_Reilly 1 2
John_Rowland 1 2
Johnny_Depp 1 2
Jon_Corzine 1 2
Jose_Dirceu 1 2
Jose_Sarney 1 3
Joseph_Estrada 1 3
Joseph_Estrada 2 3
Juan_Carlos_Ferrero 9 17
Jude_Law 1 2
Katherine_Harris 1 2
Katherine_Harris 1 4
Katherine_Harris 3 4
Kelly_Clarkson 1 2
Kiki_Vandeweghe 1 2
Kofi_Annan 8 14
Kofi_Annan 8 32
Kofi_Annan 13 25
Lance_Bass 1 4
Lance_Bass 2 4
Lance_Bass 2 5
Lance_Bass 4 5
Laurent_Gbagbo 1 2
Lee_Soo-hyuck 1 2
Leslie_Caldwell 2 3
Li_Zhaoxing 2 7
Liu_Mingkang 1 2
Luciano_Pavarotti 1 2
Luis_Gonzalez_Macchi 1 2
Luis_Gonzalez_Macchi 2 4
Luis_Gonzalez_Macchi 3 4
Luis_Gonzalez_Macchi 3 5
Luis_Horna 1 4
Luis_Horna 2 4
Luiz_Inacio_Lula_da_Silva 2 9
Luiz_Inacio_Lula_da_Silva 2 39
Luiz_Inacio_Lula_da_Silva 4 8
Luiz_Inacio_Lula_da_Silva 7 36
Luiz_Inacio_Lula_da_Silva 10 19
Luiz_Inacio_Lula_da_Silva 11 44
Luiz_Inacio_Lula_da_Silva 28 44
Madeleine_Albright 1 2
Madeleine_Albright 2 3
Marcus_Gronholm 1 2
Marissa_Jaret_Winokur 1 2
Mark_Geragos 1 2
Mark_Philippoussis 2 7
Mark_Philippoussis 3 11
Mark_Philippoussis 4 6
Mark_Philippoussis 4 9
Mark_Philippoussis 6 7
Mark_Philippoussis 6 9
Mark_Philippoussis 7 9
Markus_Naslund 1 2
Martha_Lucia_Ramirez 2 4
Martha_Lucia_Ramirez 3 4
Meryl_Streep 14 15
Mesut_Yilmaz 1 2
Michael_Schumacher 2 13
Michael_Schumacher 2 17
Michael_Schumacher 10 11
Michael_Schumacher 13 18
Michel_Temer 1 2
Michelle_Yeoh 1 2
Michelle_Yeoh 2 5
Monica_Seles 1 3
Monica_Seles 2 6
Monica_Seles 4 5
Moshe_Katsav 1 2
Moshe_Katsav 2 3
Muhammad_Saeed_al-Sahhaf 2 5
Muhammad_Saeed_al-Sahhaf 3 4
Muhammad_Saeed_al-Sahhaf 3 5
Nancy_Sinatra 1 2
Nicanor_Duarte_Frutos 3 6
Nicanor_Duarte_Frutos 3 7
Nicanor_Duarte_Frutos 3 11
Patti_Labelle 2 3
Paul_Pierce 1 2
Paul_Shanley 2 3
Phil_Mickelson 1 2
Princess_Anne 1 2
Princess_Elisabeth 1 2
Priscilla_Owen 1 2
Queen_Rania 2 3
Rachel_Hunter 1 4
Rachel_Hunter 2 3
Rachel_Hunter 3 4
Rafael_Ramirez 1 2
Rafael_Ramirez 2 3
Rafael_Ramirez 2 4
Ralph_Lauren 1 2
Recep_Tayyip_Erdogan 2 16
Recep_Tayyip_Erdogan 17 19
Reese_Witherspoon 3 4
Richard_Armitage 2 5
Richard_Armitage 6 7
Richard_Armitage 6 9
Richard_Armitage 8 9
Richard_Gephardt 2 10
Richard_Gephardt 3 11
Richard_Gephardt 5 9
Richard_Gephardt 10 11
Richard_Norton-Taylor 1 2
Richie_Adubato 1 2
Robert_Bullock 1 2
Robert_Mueller 4 5
Robert_Mugabe 1 2
Robert_Zoellick 2 3
Robert_Zoellick 3 7
Roberto_Benigni 1 2
Roh_Moo-hyun 28 32
Roman_Polanski 2 3
Roman_Polanski 4 6
Ron_Howard 1 2
Ronald_Reagan 1 3
Ronald_Reagan 2 3
Rosemarie_Stack 1 2
Roy_Jones_Jr 1 2
Rupert_Murdoch 1 2
Saburo_Kawabuchi 1 2
Sam_Mendes 1 2
Sam_Torrance 1 2
Sam_Torrance 1 3
Sam_Torrance 2 3
Sergei_Ivanov 1 3
Sergio_Vieira_De_Mello 1 2
Sergio_Vieira_De_Mello 4 9
Sergio_Vieira_De_Mello 7 8
Sergio_Vieira_De_Mello 8 11
Shannon_OBrien 1 2
Sheila_Fraser 1 2
Shimon_Peres 1 3
Shimon_Peres 3 4
Shimon_Peres 4 7
Sourav_Ganguly 1 3
Stanley_McChrystal 1 3
Stanley_McChrystal 2 3
Steve_Lavin 1 4
Strom_Thurmond 1 3
Surakait_Sathirathai 1 2
Susan_Collins 1 2
Tariq_Aziz 3 5
Terry_Stotts 1 2
Thaksin_Shinawatra 5 6
Thomas_OBrien 3 9
Tim_Chapman 1 2
Tom_Hanks 1 7
Tom_Hanks 4 6
Tom_Hanks 4 9
Tom_Hanks 5 6
Tom_Reilly 1 2
Tom_Reilly 2 3
Tommy_Franks 2 4
Tommy_Franks 4 8
Valery_Giscard_dEstaing 1 2
Valery_Giscard_dEstaing 1 6
Vanessa_Williams 1 2
Vanessa_Williams 2 3
Victoria_Beckham 1 2
Victoria_Beckham 1 3
Victoria_Beckham 2 3
Vladimir_Putin 16 21
Vladimir_Putin 22 31
Warren_Beatty 1 2
Yasar_Yakis 1 4
Yoko_Ono 1 4
Yoko_Ono 2 4
AJ_Lamas 1 Chris_Penn 1
Ahmed_Qureia 1 Stanley_McChrystal 3
Ahmet_Necdet_Sezer 1 John_Rowe 1
Alan_Dreher 1 Emily_Mason 1
Alan_Dreher 1 Francisco_Santos 1
Alan_Dreher 1 Robert_Bullock 2
Alan_Mulally 2 Tomomi_Morita 1
Alan_Stonecipher 1 Luis_Gonzalez 1
Alberto_Ruiz_Gallardon 1 James_Smith 2
Alessandra_Cerna 1 John_Darby 1
Alessandra_Cerna 1 John_Rowland 2
Alessandra_Cerna 1 Marina_Canetti 1
Alessandra_Cerna 1 Randy_Jackson 1
Alessandra_Cerna 1 Richard_Jewell 1
Alex_Cabrera 1 Fred_Huff 1
Alex_Cabrera 1 Tommy_Franks 9
Alex_Corretja 1 Jacky_Cheung 1
Alexandra_Spann 1 Beth_Blough 1
Ali_Hammoud 1 Randy_Jackson 1
Almeida_Baptista 1 Jan_Peter_Balkenende 1
Almeida_Baptista 1 Jason_Mewes 1
Almeida_Baptista 1 Taoufik_Mathlouthi 1
Amanda_Bynes 2 Grant_Rossenmeyer 1
Amy_Cotton 1 Matt_Walters 1
Amy_Cotton 1 Roberto_Guaterroma 1
Andrew_Jarecki 1 Barbara_Boxer 1
Andrew_Jarecki 1 Tessa_Jowell 1
Andy_North 1 Eric_Hinske 1
Andy_North 1 Marina_Kuptsova 1
Andy_North 1 Phil_Bennett 1
Angela_Merkel 2 Hal_Gehman 1
Angela_Merkel 3 Anna_Jones 1
Angela_Merkel 3 Frank_Griswold 1
Anna_Jones 1 Ray_Romano 8
Anthony_LaPaglia 1 Roberto_Guaterroma 1
Arlen_Specter 1 Bill_Butler 1
Arlen_Specter 2 Barbara_Boxer 1
Atal_Bihari_Vajpayee 3 Ruben_Sierra 1
Atsushi_Sato 1 Monica_Serra 1
Baburam_Bhattari 1 Muhammad_Saeed_al-Sahhaf 4
Barry_Alvarez 1 John_Jones 1
Bill_Belichick 1 John_Petty 1
Bill_Belichick 1 Phillipe_Comtois 1
Bill_Belichick 2 Roger_Machado 1
Bill_Byrne 1 Bill_Sizemore 1
Bill_Curry 1 Ellen_Martin 1
Bill_Curry 1 Richard_Langille 1
Bill_Curry 1 Roberto_Guaterroma 1
Billy_Beane 1 Tom_Welch 1
Boris_Trajkovski 1 Laurent_Gbagbo 2
Brad_Brownell 1 Hussam_Mohammed_Amin 1
Brandon_Fails 1 Christian_Lirette 1
Brandon_Fails 1 Ellen_Engleman 2
Brandon_Inge 1 Eric_Lloyd 1
Brenda_Magana 1 Nikolay_Davydenko 1
Brian_Jordan 1 Joe_Cravens 1
Brian_Lara 1 John_Darby 1
Brian_Lara 1 Stanley_Nelson 1
Calvin_Harrison 1 Luis_Gonzalez_Macchi 3
Calvin_Harrison 1 Richard_Gephardt 9
Calvin_Harrison 1 Suzanne_Fox 1
Camilla_Parker_Bowles 2 Gustavo_Franco 1
Carina_Lau_Ka-ling 1 Lin_Yi-fu 1
Carlos_Ortega 3 Lionel_Hampton 1
Carolina_Kluft 3 Gwen_Stefani 1
Carson_Palmer 3 Richard_Jewell 1
Catherine_Deneuve 4 Jade_Jagger 1
Catriona_Le_May_Doan 1 Craig_Burley 1
Catriona_Le_May_Doan 1 Phil_Mickelson 1
Charlie_Deane 1 Queen_Silvia 1
Charlotte_Church 1 Kaoru_Hasuike 1
Charlotte_Church 1 Sourav_Ganguly 1
Cheryl_Hines 1 Du_Qinglin 1
Cheryl_Hines 1 Lane_Odom 1
Chin-Hui_Tsao 1 Rosemarie_Stack 1
Choi_Sung-hong 4 Debra_Messing 1
Choi_Sung-hong 4 Frederique_van_der_Wal 1
Chris_Penn 1 Phil_Bennett 1
Chris_Penn 1 Taoufik_Mathlouthi 1
Christian_Lirette 1 Sargis_Sargsian 1
Christina_Aguilera 2 Joshua_Harapko 1
Christina_Aguilera 4 Jerry_Falwell 2
Christopher_Amolsch 1 Steve_Pagliuca 1
Christopher_Matero 1 Valery_Giscard_dEstaing 1
Claudine_Farrell 1 Mike_Miller 2
Clive_Woodward 1 Douglas_Faneuil 1
Clive_Woodward 1 Jose_Sarney 2
Coretta_Scott_King 1 Robert_Torricelli 1
Cori_Enghusen 1 Ernie_Stewart 1
Courtney_Love 1 Jennifer_Aniston 3
Courtney_Love 1 Ruben_Sierra 1
Craig_Burley 1 Stanley_McChrystal 3
Daniel_Coats 1 Kathryn_Grayson 1
Daniel_Day-Lewis 3 Scott_Yates 1
Daniela_Hantuchova 1 Jan_Peter_Balkenende 1
Danny_Green 1 Rodrigo_Rato 1
Darin_Erstad 1 Steve_Fehr 1
Daryl_Smith 1 Reese_Witherspoon 4
David_Hanson 1 Richard_Norton-Taylor 1
David_Hilt 1 Hipolito_Mejia 3
Dennis_Franchione 1 Hugh_Miller 1
Dennis_Kucinich 3 Sam_Torrance 2
Dennis_Kucinich 4 Radovan_Karadzic 1
Dennis_Kucinich 6 Iain_Anderson 1
Derek_Bond 1 John_Jumper 1
Diane_Ladd 1 Trevor_Watson 1
Dick_Latessa 1 John_Burnett 1
Dick_Latessa 2 Martha_Beatriz_Roque 1
Didier_Defago 1 Jerry_Falwell 2
Don_Hewitt 1 Guennadi_Chipouline 1
Donald_Carty 1 Ernie_Stewart 1
Donald_Carty 1 Jeffrey_Immelt 2
Donald_Carty 1 Vladimir_Putin 34
Du_Qinglin 1 Meryl_Streep 7
Dustan_Mohr 1 Edward_Flynn 1
Dustan_Mohr 1 Enrik_Vendt 1
Dustan_Mohr 1 Nikolay_Davydenko 1
Dustan_Mohr 1 Sourav_Ganguly 5
Dustan_Mohr 1 Theo_Angelopoulos 1
E_Clay_Shaw 1 Jerry_Jones 1
Eduard_Shevardnadze 3 Martha_Lucia_Ramirez 1
Edward_Flynn 1 Madeleine_Albright 2
Edward_Lu 1 Robert_Zoellick 7
Edwina_Currie 4 Eric_Hinske 2
Elena_de_Chavez 1 Jack_Goodman 1
Elizabeth_Shue 1 Odai_Hussein 1
Elizabeth_Shue 2 Princess_Hisako 1
Elizabeth_Shue 2 Terry_Stotts 1
Ellen_Engleman 1 Guennadi_Chipouline 1
Ellen_Saracini 1 Ray_Romano 6
Elsa_Zylberstein 2 Matt_Braker 1
Elvis_Stojko 1 Jerry_Falwell 1
Elvis_Stojko 1 Robert_Mueller 5
Emma_Thompson 3 Nathan_Doudney 1
Emmit_Smith 2 Rafael_Ramirez 4
Enrik_Vendt 1 Lane_Odom 1
Enrique_Oliu 1 Markus_Naslund 1
Enrique_Oliu 1 William_McDonough 1
Eric_Hinske 1 Juan_Antonio_Samaranch 1
Eric_Lloyd 1 Jessica_Alba 2
Eric_Lloyd 1 Valery_Giscard_dEstaing 1
Ernie_Harwell 1 Queen_Beatrix 3
Felipe_Perez_Roque 2 MC_Hammer 1
Frank_Griswold 1 Yana_Klochkova 1
Frank_Zappa 1 Markus_Naslund 1
Frederique_van_der_Wal 1 Pedro_Mahecha 1
Frederique_van_der_Wal 1 Raja_Zafar-ul-Haq 1
Gary_Leon_Ridgway 1 Robert_Wagner 1
Gary_Leon_Ridgway 1 Scott_Yates 1
Gary_Leon_Ridgway 1 Yana_Klochkova 1
Gene_Keady 1 Mark_Sacco 1
George_Gregan 1 John_Negroponte 27
Glen_DaSilva 1 Rachel_Hunter 4
Glen_DaSilva 1 Robert_Mugabe 2
Glen_Sather 1 Leslie_Caldwell 3
Glen_Sather 1 Trevor_Watson 1
Goran_Zivkovic 1 Lee_Soo-hyuck 2
Goran_Zivkovic 1 Martha_Sahagun_de_Fox 1
Goran_Zivkovic 1 Shane_Reynolds 1
Grant_Rossenmeyer 1 Trevor_Watson 1
Gregory_Hines 1 Marcus_Gronholm 2
Guennadi_Chipouline 1 Tom_Lantos 1
Guillermo_Ortiz 1 Nestor_Santillan 1
Guillermo_Ortiz 2 Strom_Thurmond 2
Gus_Van_Sant 3 Natalie_Stewart 1
Gwen_Stefani 1 Hugh_Miller 1
Gwendal_Peizerat 3 Turner_Stevenson 1
Hal_Gehman 1 Scott_Yates 1
Hamad_Bin_Isa_al-Khalifa 1 Marta_Dominguz 1
Harrison_Ford 2 Marcus_Gronholm 1
Harvey_Wachsman 1 Narayan_Singh_Pun 1
Heather_Locklear 1 John_Mayer 3
Heather_Locklear 1 Pablo_Khulental 1
Hichiro_Naemura 2 Richard_Jewell 1
Hipolito_Mejia 3 Jim_Ahern 1
Holly_Hunter 3 Joshua_Perper 1
Hugh_Hefner 1 Sam_Mendes 1
Iain_Anderson 1 James_Kopp 2
Iain_Anderson 1 Recep_Tayyip_Erdogan 12
Ilan_Goldfajn 1 Jennifer_Aniston 17
Ilie_Nastase 1 Michael_Lopez-Alegria 1
Intisar_Ajouri 3 Lin_Yi-fu 1
Itamar_Franco 1 Jessica_Alba 1
Jack_Goodman 1 Kirsten_Dunst 1
Jack_Goodman 1 Saburo_Kawabuchi 2
Jack_Nicholson 1 Pat_Wharton 1
Jack_Valenti 1 Shinzo_Abe 1
Jake_Plummer 1 Jose_Dirceu 2
Jakob_Kellenberger 1 Lara_Logan 1
Jakob_Kellenberger 1 Pedro_Mahecha 1
James_Maguire 1 Ronald_Reagan 1
James_Smith 2 Kyra_Sedgwick 1
Jason_Statham 1 Kwame_Kilpatrick 1
Jawad_Boulus 1 Narayan_Singh_Pun 1
Jean-Rene_Fourtou 1 Roh_Moo-hyun 28
Jeannette_Biedermann 1 Kenny_Brack 1
Jennifer_Granholm 1 Trudi_Lacey 1
Jerelle_Kraus 1 Warren_Beatty 1
Jesus_Cardenal 1 Pablo_Khulental 1
Jim_Hendry 1 Larry_Beinfest 1
Joan_Claybrook 2 Pablo_Latras 1
Joaquin_Sanchez 1 Richard_Armitage 1
Joe_Cocker 1 Martha_Beatriz_Roque 1
Joe_Cocker 1 Randy_Jackson 1
Joe_Cravens 1 Sam_Mendes 1
John_Barnett 1 Kathryn_Grayson 1
John_Darby 1 Masum_Turker 3
John_Ferguson 1 Paul_Schrader 1
John_Paul_DeJoria 1 Paul_Pierce 1
John_Reilly 2 Princess_Hisako 1
John_Rowland 2 Steve_Kerr 1
Johnny_Depp 1 Leo_Mullin 1
Johnny_Depp 1 Trudi_Lacey 1
Johnny_Htu 1 Roger_Machado 1
Jose_Dirceu 1 Robert_Torricelli 3
Juan_Antonio_Samaranch 1 Stefan_Koubek 1
Juergen_Braehmer 1 Shawn_Bradley 1
Juergen_Braehmer 1 Travis_Rudolph 1
Kathryn_Grayson 1 Queen_Beatrix 4
Kathryn_Grayson 1 Ruben_Sierra 1
Kathryn_Grayson 1 Shannon_OBrien 2
Katie_Holmes 1 Park_Jung_Sung 1
Kenny_Brack 1 Lin_Yi-fu 1
Kwame_Kilpatrick 1 Shannon_OBrien 2
Kyra_Sedgwick 1 Reese_Witherspoon 3
Kyra_Sedgwick 1 Richard_Hellfant 1
Kyra_Sedgwick 1 Wilbert_Elki_Meza_Majino 1
Lance_Bass 3 Queen_Rania 5
Lara_Logan 1 Turner_Stevenson 1
Laszlo_Kovacs 1 Luke_Ridnour 1
Laszlo_Kovacs 1 Olesya_Bonabarenko 2
Lee_Byung-woong 1 William_Hochul 2
Lee_Soo-hyuck 1 Robert_Bullock 1
Leslie_Caldwell 1 Shane_Reynolds 1
Leslie_Caldwell 2 Turner_Stevenson 1
Li_Zhaoxing 4 Susan_Sarandon 4
Linda_Mason 1 Rupert_Murdoch 2
Liu_Mingkang 2 Pedro_Pauleta 1
Liu_Ye 1 Ruben_Sierra 1
Liu_Ye 1 Steve_Alford 1
Loretta_Lynn_Harper 1 Michel_Temer 2
Luis_Gonzalez 1 Warren_Beatty 1
Madeleine_Albright 2 Martha_Lucia_Ramirez 2
Maha_Habib 1 Princess_Elisabeth 1
Marc_Anthony 1 Michael_Pfleger 1
Marcus_Gronholm 1 Teresa_Graves 1
Marcus_Gronholm 1 Tommy_Franks 8
Marina_Canetti 1 Saied_Hadi_al_Mudarissi 1
Mario_Alfaro-Lopez 1 Richard_Armitage 6
Mario_Alfaro-Lopez 1 Tom_Lantos 1
Mark_Dacey 1 Turner_Stevenson 1
Mark_Dacey 2 Steve_Cox 1
Mark_Kelly 1 Mark_Lazarus 1
Mark_Lazarus 1 Ronnie_Jagday 1
Mark_Sacco 1 Tono_Suratman 1
Markus_Naslund 1 Robert_Wagner 1
Martin_Kristof 1 Taia_Balk 1
Matt_Anderson 1 Seth_Gorney 1
Matt_Braker 1 Surakait_Sathirathai 1
Matt_Roney 1 Wilbert_Elki_Meza_Majino 1
Michael_Bolton 1 Robert_Bullock 2
Michael_Pfleger 1 Robert_Ehrlich 2
Michael_Schumacher 17 Natalie_Imbruglia 1
Michael_Shane_Jolly 1 Trudi_Lacey 1
Michel_Temer 1 Paul_Shanley 1
Michelle_Yeoh 5 Saburo_Kawabuchi 1
Mike_Helton 1 Octavio_Lara 1
Mike_Miller 2 Toby_Keith 1
Monica_Seles 2 Queen_Beatrix 4
Nancy_Sinatra 1 Sargis_Sargsian 1
Pablo_Khulental 1 Rosemarie_Stack 2
Park_Jung_Sung 1 Robert_Bullock 2
Paul_Pierce 2 Robert_Bullock 2
Pedro_Pauleta 1 Robert_Tyrrell 1
Pedro_Pauleta 1 Tommy_Franks 14
Phil_Morris 1 Priscilla_Owen 2
Phil_Morris 1 Roberto_Guaterroma 1
Phil_Morris 1 Yuri_Luzhkov 1
Queen_Rania 3 Ronnie_Jagday 1
Radovan_Karadzic 1 Richard_Langille 1
Randy_Jackson 1 Steve_Alford 1
Reese_Witherspoon 1 Sam_Torrance 1
Reese_Witherspoon 2 Toni_Jennings 1
Rina_Lazo 1 Ronald_Reagan 1
Robert_Ehrlich 2 Ron_Lantz 1
Robert_Mugabe 1 Tessa_Jowell 1
Robert_Torricelli 3 Taoufik_Mathlouthi 1
Robert_Tyrrell 1 Yuri_Luzhkov 1
Robert_Wagner 1 Tommy_Franks 11
Robin_Wright_Penn 1 Sam_Torrance 3
Robin_Wright_Penn 1 Yoko_Ono 6
Rogelio_Ramos 1 Ryan_Newman 1
Roman_Polanski 4 Toby_Keith 1
Ronnie_Jagday 1 Sidney_Kimmel 1
Scott_Yates 1 Steve_Cox 1
Sean_Patrick_Thomas 1 William_Hochul 1
Sharon_Osbourne 2 Shimon_Peres 6
Stefan_Koubek 1 Steve_Alford 1
Teri_Garr 1 Yana_Klochkova 1
Warren_Beatty 2 William_McDonough 1
Aleksander_Kwasniewski 1 2
Aleksander_Kwasniewski 2 4
Aleksander_Kwasniewski 3 4
Ali_Naimi 1 2
Ali_Naimi 1 5
Ali_Naimi 2 8
Amanda_Beard 1 2
Andrew_Cuomo 1 2
Arnold_Schwarzenegger 8 31
Arnold_Schwarzenegger 9 39
Arnold_Schwarzenegger 11 41
Arnold_Schwarzenegger 12 37
Arnold_Schwarzenegger 13 39
Arnold_Schwarzenegger 22 33
Arnold_Schwarzenegger 28 41
Bernard_Lord 1 2
Beth_Jones 1 2
Branko_Crvenkovski 2 3
Brigitte_Boisselier 1 2
Bruce_Springsteen 1 2
Bruce_Springsteen 1 3
Bruce_Springsteen 2 3
Bruce_Springsteen 2 4
Calista_Flockhart 1 5
Calista_Flockhart 4 6
Cameron_Diaz 1 3
Cameron_Diaz 3 6
Carol_Moseley_Braun 1 2
Carrie-Anne_Moss 1 3
Carrie-Anne_Moss 1 5
Carrie-Anne_Moss 2 5
Carrie-Anne_Moss 3 5
Carrie-Anne_Moss 4 5
Charlton_Heston 1 5
Charlton_Heston 2 5
Charlton_Heston 4 6
Chris_Bell 1 2
Chung_Mong-hun 1 2
Ciro_Gomes 1 2
Ciro_Gomes 2 5
Ciro_Gomes 3 5
Colin_Montgomerie 1 4
Colin_Montgomerie 2 3
Colin_Montgomerie 2 5
Colin_Montgomerie 4 5
David_Trimble 1 4
David_Trimble 1 5
David_Trimble 3 4
David_Wolf 1 2
Demetrius_Ferraciu 1 2
Dennis_Powell 1 2
Desiree_Lemosi 1 2
Dolma_Tsering 1 2
Doug_Melvin 1 2
Edward_Norton 1 2
Emanuel_Ginobili 2 3
Eric_Clapton 1 2
Fabiola_Zuluaga 1 2
Faye_Dunaway 1 2
Ferenc_Madl 1 2
Fernando_Gonzalez 1 5
Fernando_Gonzalez 1 8
Fernando_Gonzalez 2 6
Filippo_Inzaghi 1 2
Filippo_Inzaghi 1 3
Filippo_Inzaghi 2 3
Francis_George 1 2
Franz_Beckenbauer 1 2
Franz_Muentefering 1 2
Franz_Muentefering 3 4
Gary_Bergeron 1 2
George_Foreman 1 2
George_Pataki 1 3
George_Pataki 3 4
George_Pataki 3 5
George_Roy_Hill 1 2
Gonzalo_Sanchez_de_Lozada 7 8
Gonzalo_Sanchez_de_Lozada 7 10
Gonzalo_Sanchez_de_Lozada 8 11
Gonzalo_Sanchez_de_Lozada 8 12
Gregory_Geoffroy 1 2
Guillermo_Coria 7 13
Guillermo_Coria 19 22
Habib_Rizieq 1 3
Habib_Rizieq 2 3
Hamid_Karzai 1 3
Hamid_Karzai 4 13
Hamid_Karzai 19 22
Hilmi_Ozkok 1 2
Horst_Koehler 1 2
Horst_Koehler 1 3
Horst_Koehler 2 3
Howard_Schultz 1 2
Ilan_Ramon 1 2
Javier_Solana 4 8
Javier_Solana 6 9
Javier_Solana 6 10
Jay_Garner 1 3
Jean-Claude_Braquet 1 2
Jean-Claude_Trichet 1 2
Jean_Charest 1 10
Jean_Charest 2 11
Jean_Charest 7 10
Jean_Charest 8 13
Jean_Charest 8 17
Jefferson_Perez 1 2
Jim_Edmonds 1 2
John_Kerry 1 5
John_Kerry 3 4
John_Kerry 4 12
John_Kerry 9 13
John_Malkovich 1 2
John_Malkovich 1 3
John_McCallum 1 2
John_McEnroe 1 2
John_Rosa 1 3
Johnny_Unitas 1 2
Jong_Wook_Lee 3 4
Jose_Maria_Aznar 1 13
Jose_Maria_Aznar 6 13
Jose_Maria_Aznar 6 20
Jose_Maria_Aznar 15 23
Jose_Maria_Aznar 17 22
Julianne_Moore 4 9
Julianne_Moore 6 16
Julianne_Moore 6 19
Julianne_Moore 7 18
Julianne_Moore 12 15
Julio_Iglesias_Jr 1 2
Justin_Timberlake 1 2
Justin_Timberlake 1 3
Justin_Timberlake 5 6
Justin_Timberlake 6 8
Justine_Pasek 2 5
Justine_Pasek 2 6
Justine_Pasek 6 7
Kathleen_Glynn 1 2
Kim_Dae-jung 1 3
Kim_Dae-jung 1 5
Kim_Dae-jung 2 3
Kim_Dae-jung 4 6
Kirk_Johnson 1 2
Kirk_Johnson 1 3
Kirk_Johnson 2 3
Kosuke_Kitajima 1 2
Kurt_Russell 1 2
Larry_Coker 1 4
Larry_Coker 2 4
Larry_Ellison 1 2
Larry_Ellison 1 3
Lawrence_MacAulay 1 2
LeBron_James 1 4
LeBron_James 1 5
LeBron_James 3 4
LeBron_James 4 5
Lea_Fastow 1 2
Lee_Hoi-chang 1 2
Lee_Hoi-chang 2 4
Li_Peng 2 6
Li_Peng 4 7
Li_Peng 4 8
Li_Peng 4 9
Lim_Dong-won 1 2
Lindsay_Benko 1 2
Lou_Piniella 1 3
Lou_Piniella 2 3
Lucio_Gutierrez 1 2
Lucio_Gutierrez 3 10
Lucio_Gutierrez 6 7
Lucio_Gutierrez 6 8
Lucio_Gutierrez 8 13
Luis_Figo 2 3
Luis_Figo 2 4
Luke_Walton 1 2
Marat_Safin 1 2
Marat_Safin 1 3
Marat_Safin 2 3
Mariana_Pollack 1 3
Mariana_Pollack 2 3
Martin_McGuinness 3 4
Masahiko_Nagasawa 1 2
Michael_Chiklis 1 4
Michael_Chiklis 1 5
Michael_Chiklis 2 3
Michael_Chiklis 2 4
Michael_Chiklis 3 5
Michael_Chiklis 4 5
Michael_Douglas 1 2
Michael_Douglas 1 3
Michael_Douglas 2 4
Michael_Douglas 3 6
Michael_Douglas 4 5
Michael_Kostelnik 1 2
Michael_Leavitt 1 2
Michelle_Branch 1 2
Michelle_Kwan 1 4
Michelle_Kwan 4 5
Michelle_Kwan 6 8
Mike_Montgomery 1 2
Mike_Tyson 1 3
Mikhail_Wehbe 1 3
Minnie_Driver 1 2
Miyako_Miyazaki 1 2
Muammar_Gaddafi 1 2
Munir_Akram 1 2
Nadia_Petrova 1 2
Nadia_Petrova 1 3
Nadia_Petrova 1 4
Nadia_Petrova 2 3
Nadia_Petrova 3 4
Nadia_Petrova 4 5
Nancy_Pelosi 1 7
Nancy_Pelosi 2 9
Nancy_Pelosi 4 15
Nancy_Pelosi 12 14
Nia_Vardalos 1 3
Nia_Vardalos 3 4
Nia_Vardalos 3 5
Nicholas_Byron 1 2
Nikki_Reed 1 2
Olivia_Newton-John 1 2
Paradorn_Srichaphan 2 4
Paradorn_Srichaphan 4 5
Pascal_Quignard 1 3
Pascal_Quignard 2 3
Patrice_Chereau 1 2
Pedro_Malan 1 5
Pedro_Malan 3 5
Peter_Harrison 1 2
Rainer_Schuettler 1 4
Rainer_Schuettler 2 3
Rainer_Schuettler 2 4
Raymond_Odierno 1 2
Rebecca_Romijn-Stamos 1 2
Rebecca_Romijn-Stamos 1 3
Rebecca_Romijn-Stamos 1 4
Rebecca_Romijn-Stamos 3 4
Richard_Krajicek 1 3
Richard_Krajicek 2 3
Rick_Santorum 1 2
Rick_Santorum 1 3
Rick_Santorum 2 3
Rick_Stansbury 2 3
Rob_Marshall 1 3
Rob_Marshall 1 6
Rob_Marshall 2 4
Robert_Blackwill 1 2
Robert_Duvall 2 8
Robert_Horan 1 2
Robert_Redford 3 4
Robert_Redford 7 8
Robinson_Stevenin 1 2
Roger_Clemens 1 2
Sadie_Frost 1 2
Saparmurat_Niyazov 1 2
Sarah_Michelle_Gellar 1 2
Sarah_Michelle_Gellar 1 3
Sarah_Michelle_Gellar 2 3
Serena_Williams 1 41
Serena_Williams 3 32
Serena_Williams 14 40
Serena_Williams 41 47
Sergey_Lavrov 1 3
Sergey_Lavrov 1 6
Sergey_Lavrov 2 4
Sergey_Lavrov 3 5
Sergey_Lavrov 3 7
Sergey_Lavrov 4 8
Shane_Mosley 1 2
Sheila_Copps 2 3
Sheila_Copps 3 4
Shia_LaBeouf 1 2
Steve_Nash 1 3
Steve_Nash 1 4
Steve_Nash 2 4
Steve_Nash 2 5
Steve_Spurrier 1 2
Steve_Waugh 1 2
Susilo_Bambang_Yudhoyono 1 2
Susilo_Bambang_Yudhoyono 1 3
Susilo_Bambang_Yudhoyono 1 4
Susilo_Bambang_Yudhoyono 3 4
Suzanne_Gaudet 1 2
Thomas_Bjorn 1 2
Tim_Conway 1 2
Tim_Conway 1 3
Tim_Robbins 1 5
Tim_Robbins 2 4
Tim_Robbins 3 5
Tom_Craddick 1 3
Tom_Craddick 2 4
Tom_Craddick 3 4
Tracee_Ellis_Ross 1 2
Venus_Williams 2 9
Vivica_Fox 1 2
William_Ford_Jr 1 2
William_Ford_Jr 2 6
William_Ford_Jr 5 6
William_Rehnquist 1 2
Yossi_Beilin 1 2
Aaron_Eckhart 1 Akiko_Morigami 1
Aaron_Eckhart 1 AnFernce_Negron 1
Aaron_Eckhart 1 Sadie_Frost 1
Abdel_Aziz_Al-Hakim 1 Joe_Darrell 1
Abdullah_al-Attiyah 1 Rachel_Wadsworth 1
Abdullah_al-Attiyah 2 John_Lisowski 1
Abraham_Foxman 1 Doug_Melvin 2
Abraham_Foxman 1 Nikki_Reed 1
Adam_Rich 1 Jean-Claude_Trichet 1
Adam_Rich 1 John_Goold 1
Adam_Rich 1 Lisa_Girman 1
Adam_Rich 1 Roger_Clemens 1
Adam_Rich 1 Suzanne_Somers 1
Adrian_Fernandez 1 Nicolas_Massu 1
Aiysha_Smith 1 Yossi_Beilin 1
Akiko_Morigami 1 Shane_Mosley 1
Alastair_Johnston 1 Aleksander_Kwasniewski 4
Alastair_Johnston 1 Bill_Duffey 1
Albert_Brooks 1 Robinson_Stevenin 1
Albert_Brooks 1 Sheila_Copps 3
Aleksander_Kwasniewski 1 Guangdong_Ou_Guangyuan 1
Aleksander_Kwasniewski 2 George_Plimpton 1
Aleksander_Kwasniewski 2 Juan_Jose_Lucas 1
Aleksander_Kwasniewski 3 Billy_Crawford 1
Aleksander_Voloshin 1 Kristen_Rivera 1
Alessandro_Nesta 1 Paul_Kelleher 1
Alfredo_di_Stefano 1 Chris_Moore 1
Alfredo_di_Stefano 1 Maryn_McKenna 1
Alfredo_di_Stefano 1 Shamai_Leibowitz 1
Ali_Naimi 5 Morris_Dees 1
Aline_Chretien 1 Guillermo_Coria 17
Amy_Yasbeck 1 Chawki_Armali 1
AnFernce_Negron 1 Kristen_Rivera 1
Andrew_Cuomo 2 Todd_Petit 1
Anil_Ramsook 1 Takeo_Hiranuma 1
Annie_Chaplin 1 Charles_Tannok 1
Antanas_Valionis 1 William_Rehnquist 1
Avril_Lavigne 1 Shia_LaBeouf 2
Barbara_Becker 1 Chris_Noth 1
Barbara_Becker 1 Franz_Beckenbauer 2
Barbora_Strycova 1 Christiane_Wulff 1
Barry_Diller 1 Meles_Zenawi 1
Bartosz_Kizierowski 1 Faye_Wong 1
Ben_Wallace 1 Nia_Vardalos 5
Bernard_Lord 1 Joxel_Garcia 1
Bernard_Lord 2 Bing_Crosby 1
Beyonce_Knowles 1 Maurice_Papon 1
Bill_Duffey 1 Jong_Wook_Lee 1
Bill_Guerin 1 Julie_Goodenough 1
Bill_Herrion 1 Fernando_Valenzuela 1
Bill_Herrion 1 Johnny_Unitas 2
Bill_Richardson 1 George_McCloud 1
Billy_Andrade 1 Kellie_Coffey 1
Billy_Crawford 1 Jim_Edmonds 2
Billy_Edelin 1 Himmler_Rebu 1
Bing_Crosby 1 Stephen_Webster 1
Bixente_LIzarazu 1 Chris_Bell 2
Bixente_LIzarazu 1 Todd_Wike 1
Blythe_Danner 2 Hank_McKinnell 1
Bob_Eskridge 1 Marco_Pantani 1
Bob_Hartley 1 Lou_Piniella 3
Bob_Krueger 1 Gordana_Grubin 1
Bob_Krueger 1 Mariana_Pollack 1
Bob_Sulkin 1 Branko_Crvenkovski 3
Bobby_Kielty 1 Robert_Horan 2
Brajesh_Mishra 1 Mark_Podlesny 1
Brandon_Knight 1 Claudia_Cardinale 1
Brandon_Knight 1 Phil_Donahue 1
Brandon_Lloyd 1 Cha_Yung-gu 1
Brandon_Lloyd 1 James_Coburn 1
Brian_Schneider 1 Michael_Rolinee 1
Bruce_Springsteen 4 Ion_Tiriac 1
Cameron_Diaz 2 Shia_LaBeouf 1
Cameron_Diaz 5 Nadia_Petrova 2
Carla_Gugino 1 Kelly_Osbourne 1
Carla_Gugino 1 Kenny_Chesney 1
Carla_Gugino 1 Michael_Douglas 3
Carla_Gugino 1 Miguel_Aldana_Ibarra 1
Carlos_Fasciolo 1 Debbie_Allen 1
Carol_Williams 1 Gorden_Tallis 1
Carrie-Anne_Moss 2 Horacio_Julio_Pina 1
Carrie-Anne_Moss 4 Michael_Goldrich 1
Casey_Crowder 1 Keiko_Sofia_Fujimori 1
Casey_Crowder 1 Phoenix_Chang 1
Cha_Yung-gu 1 Takeo_Hiranuma 1
Charlene_Barshefsky 1 James_Coburn 1
Charles_Tannok 1 Larry_Coker 4
Charlie_Hunnam 1 Hestrie_Cloette 1
Charlie_Hunnam 1 Veronica_Lake 1
Charlton_Heston 4 Desiree_Lemosi 1
Chawki_Armali 1 Shoshannah_Stern 1
Chris_Bell 2 Pharrell_Williams 1
Chris_Forsyth 1 Nikki_Reed 2
Chris_Neil 1 John_Kerry 14
Chris_Noth 1 Takeshi_Kitano 1
Christine_Arron 1 Robert_Duvall 5
Christine_Arron 1 Steve_McManaman 1
Chuck_Hagel 1 Jeff_Roehm 1
Chuck_Hagel 1 Margaret_Hasley 1
Chuck_Hagel 1 Sebastian_Porto 1
Cliff_Ellis 1 John_Lisowski 1
Clifford_Etienne 1 Pharrell_Williams 1
Clifford_Etienne 1 Ray_Lewis 1
Clive_Lloyd 1 Harland_Braun 1
Colin_Montgomerie 1 Horacio_Julio_Pina 1
Daniel_Montenegro 1 Gustavo_Cisneros 1
Daniel_Montenegro 1 Nadia_Petrova 4
Daniel_Montenegro 1 Omar_Khan_Sharif 1
Daniel_Montenegro 1 Rick_Santorum 1
Danny_Glover 1 Morris_Dees 1
Danny_Glover 1 Patrice_Chereau 2
David_Trimble 4 John_Elway 1
David_Wolf 2 Emanuel_Ginobili 4
David_Wolf 2 Kathleen_Glynn 2
David_Wolf 2 Venus_Williams 6
Debbie_Allen 1 Sebastian_Cuattrin 1
Demetrius_Ferraciu 2 Edward_Seaga 1
Denise_Johnson 1 Nikki_Cascone 1
Denise_Johnson 2 Emanuel_Ginobili 3
Denise_Johnson 2 Filippo_Inzaghi 2
Dennis_Powell 1 Horst_Koehler 3
Dennis_Powell 1 Michael_Chiklis 2
Desiree_Lemosi 2 Dion_Glover 1
Dion_Glover 1 Michael_Weiss 1
Doug_Melvin 1 Gustavo_Cisneros 1
Doug_Melvin 3 Emma_Nicholson 1
Doug_Racine 1 Marisol_Breton 1
Ed_Book 1 Nur_Jaafar 1
Ed_Case 1 Sadam_Hassan 1
Edward_Seaga 1 George_Roy_Hill 1
Edward_Seaga 1 Sarah_Price 1
Eileen_Spina 1 Jeff_Bzdelik 1
Ekke_Hard_Forberg 1 Nikki_Reed 1
Elena_Bereznaya 1 Lene_Espersen 1
Elena_Bereznaya 1 Mario_Lobo_Zagallo 1
Elena_Bereznaya 1 Rick_Stansbury 2
Elisha_Cuthbert 1 Mariana_Pollack 2
Eliza_Manningham-Buller 1 Lawrence_MacAulay 2
Eric_Clapton 2 Niall_Connolly 1
Eric_Taino 1 Michael_Goldrich 1
Farida_Ragoonanan 1 Jorge_Enrique_Jimenez 1
Felix_Trinidad 1 Joe_Darrell 1
Felix_Trinidad 1 Justine_Pasek 4
Fernando_Valenzuela 1 Luis_Figo 3
Fernando_Valenzuela 1 Nicolas_Macrozonaris 1
Filippo_Inzaghi 1 Mohammed_Al_Hindi 1
Filippo_Inzaghi 1 Shanna_Zolman 1
Francis_Ricciardone 1 Sven_Goran_Eriksson 1
Franz_Beckenbauer 1 Gerald_Ford 1
Franz_Beckenbauer 2 Rick_Bragg 1
George_Foreman 2 Ralph_Goodale 1
George_Pataki 1 James_Dingemans 1
George_Pataki 2 Masahiko_Nagasawa 2
George_Plimpton 1 Ximena_Bohorquez 1
Gerald_Ford 1 Kurt_Budke 1
Gerald_Ford 1 Li_Peng 1
Giselle_Estefania_Tavarelli 1 John_Sununu 1
Giulio_Andreotti 1 Kurt_Russell 2
Giulio_Andreotti 1 Michael_Denzel 1
Gonzalo_Sanchez_de_Lozada 3 Shannyn_Sossamon 1
Graciano_Rocchigiani 1 Juan_Jose_Lucas 1
Gregory_Geoffroy 1 Sybille_Schmid 1
Gregory_Geoffroy 2 Kosuke_Kitajima 1
Gregory_Geoffroy 2 Wycliffe_Grousbeck 1
Guangdong_Ou_Guangyuan 1 Li_Ruihuan 1
Guangdong_Ou_Guangyuan 1 Nicole 1
Gustavo_Cisneros 1 Steve_Blake 1
Gustavo_Noboa 1 Lea_Fastow 2
Habib_Hisham 1 Pat_Rochester 1
Habib_Hisham 1 Paul_Wilson 1
Habib_Rizieq 1 Olivia_Newton-John 2
Habib_Rizieq 3 Kenny_Chesney 1
Hal_Sutton 2 Kellie_Coffey 1
Harland_Braun 1 Kathryn_Tucker 1
Hassanal_Bolkiah 1 Michael_Leavitt 1
Hestrie_Cloette 1 Nicholas_Byron 2
Hitoshi_Tanaka 1 Ramon_Ponce_de_Leon 1
Horacio_Julio_Pina 1 Zaini_Abdullah 1
Huang_Suey-Sheng 1 Lucrecia_Orozco 1
Huang_Suey-Sheng 1 Paul_Cerjan 1
Huang_Suey-Sheng 1 Robinson_Stevenin 1
Ian_Knop 1 Michel_Minard 1
Ilan_Ramon 3 Tatiana_Kennedy_Schlossberg 1
Ion_Tiriac 1 Lawrence_MacAulay 1
Ismail_Abu_Shanab 1 Michael_Denzel 1
Ismail_Abu_Shanab 1 Rebecca_Romijn-Stamos 1
Jack_Welch 1 Keizo_Yamada 1
James_Dingemans 1 Robert_Duvall 5
James_Dingemans 1 William_Morrow 1
Jamie_Lee_Curtis 1 William_Joppy 1
Jamie_Martin 1 Patrick_Ewing 1
Jan_Bjoerklund 1 Li_Ruihuan 1
Jan_Paul_Miller 1 Paradorn_Srichaphan 8
Jay_Garner 3 Reggie_Sanders 1
Jeff_Bzdelik 1 Zach_Parise 1
Jerry_Oliver 1 Rudolf_Schuster 1
Jerry_Oliver 1 Stefaan_Declerk 1
Jerry_Sloan 1 Julianne_Moore 9
Jerry_Sloan 1 Keiko_Sofia_Fujimori 1
Jerry_Sloan 1 Nikki_Cascone 1
Jim_Anderson 1 Jose_Luis_Santiago_Vasconcelos 1
Jim_Anderson 1 Mikhail_Wehbe 1
Joaquim_Levy 1 Judy_Vassar 1
Joe_Leonard 1 Kristen_Rivera 1
John_Baldacci 1 Nona_Gaye 1
John_Baldacci 1 Shia_LaBeouf 1
John_Elway 1 Mahmoud_Diyab_al-Ahmed 1
John_Kerry 9 Raja_Ibrahim 1
John_Kerry 14 Pat_Rochester 1
John_Lisowski 1 Michelle_Kwan 1
John_Malkovich 2 Paradorn_Srichaphan 7
John_Malkovich 3 Mona_Locke 1
John_Malkovich 3 Richard_Palmer 1
John_McCallum 1 Oliver_Phelps 1
John_McCallum 2 Rick_Bragg 1
John_McEnroe 2 Shane_Mosley 1
John_Prescott 1 Will_Ofenheusle 1
Johnnie_Lynn 1 Larry_Coker 4
Johnnie_Lynn 1 Richard_Palmer 1
Johnny_Unitas 1 Mark_Foley 1
Jonathan_Karsh 1 Samantha_Ledster 1
Joxel_Garcia 1 Lena_Olin 1
Joy_Bryant 1 Richard_Chamberlain 1
Julianne_Moore 4 Shia_LaBeouf 1
Julio_Iglesias_Jr 1 Ramon_Ponce_de_Leon 1
Justin_Timberlake 1 Suzanne_Somers 1
Kathleen_Glynn 2 Susilo_Bambang_Yudhoyono 1
Kathryn_Morris 1 Minnie_Driver 2
Kathryn_Tucker 1 Stella_McCartney 1
Katie_Couric 1 Sanjay_Gupta 1
Keiko_Sofia_Fujimori 1 Sureyya_Ayhan 1
Kellie_Coffey 1 Todd_Petit 1
Kenny_Chesney 1 Steve_Coogan 1
Kevin_Tarrant 1 Marisol_Breton 1
Kristen_Rivera 1 Valdas_Adamkus 2
Kurt_Russell 2 Mahmoud_Diyab_al-Ahmed 1
Kurt_Tanabe 1 William_Jackson 1
Kyle_McLaren 1 Sofia_Milos 1
Kyle_McLaren 1 Will_Ofenheusle 1
Kyle_Shewfelt 1 Larry_Coker 2
Lawrence_Foley 1 Rachel_Wadsworth 1
Lea_Fastow 1 Uday_Hussein 1
Lesia_Burlak 1 Nur_Jaafar 1
Lori_Berenson 1 Rudolf_Schuster 1
Lucio_Angulo 1 Sarah_Price 1
Lucio_Gutierrez 10 Pedro_Malan 5
Margaret_Hasley 1 Michael_Denzel 1
Mark_Redman 1 Stephen_Funk 1
Mark_Salter 1 Shanna_Zolman 1
Martin_Luther_King_III 1 Maryn_McKenna 1
Mary_Bono 1 Todd_Wike 1
Matt_LeBlanc 1 Robert_Redford 2
Mauro_Viza 1 William_Jackson 1
Max_Baucus 1 Paradorn_Srichaphan 5
Max_Baucus 1 Yossi_Beilin 2
Meles_Zenawi 1 Nawabzada_Nasrullah_Khan 1
Melissa_Mulloy 1 Paula_Abdul 1
Melissa_Mulloy 1 Roger_Lyons 1
Michael_Chiklis 1 Mohammed_Al_Hindi 1
Michael_Chiklis 1 Steve_Rush 1
Michael_Doleac 1 Nur_Jaafar 1
Michael_Goldrich 1 Suzanne_Somers 1
Michael_Kahn 1 Rick_Caruso 1
Michel_Minard 1 Suzanne_Gaudet 1
Michelle_Bachelet 1 Sami_Al-Arian 1
Miguel_Angel_Rodriguez 1 Sasha_Cohen 1
Mike_Bryan 1 Shanna_Zolman 1
Mike_Montgomery 1 Ray_Lewis 1
Milton_Wynants 1 Stuart_Townsend 1
Miyako_Miyazaki 2 Munir_Akram 2
Morris_Dees 1 Shamai_Leibowitz 1
Morris_Dees 1 Suzie_McConnell_Serio 1
Nathalie_Gagnon 1 Richard_Reid 1
Nicklas_Lidstrom 1 Norman_Jewison 1
Nicklas_Lidstrom 1 Sadie_Frost 3
Nicole_Hiltz 1 Zaini_Abdullah 1
Nona_Gaye 1 Paul_Cerjan 1
Oscar_Bolanos 1 Phil_Donahue 1
Oscar_Bolanos 1 Tatiana_Kennedy_Schlossberg 1
Pascal_Quignard 3 Patrick_Ewing 2
Pat_Rochester 1 Phoenix_Chang 1
Pat_Rochester 1 Will_Ofenheusle 1
Paul_Farley 1 Platon_Lebedev 1
Paula_Abdul 1 Robert_Vowler 1
Pharrell_Williams 1 Tyrone_Medley 1
Phoenix_Chang 1 Platon_Lebedev 1
Rachel_Wadsworth 1 Richard_Palmer 1
Raymond_Odierno 1 Richard_Reid 1
Reggie_Sanders 1 Rick_Santorum 2
Richard_Chamberlain 1 Steve_Patterson 1
Richard_Ward 1 Steve_Redgrave 1
Robert_Vowler 1 Tab_Baldwin 1
Roy_Rogers 1 Steven_Feldman 1
Scott_Rolen 1 William_Murabito 1
Sofia_Milos 1 Steve_Nash 3
Sofia_Milos 1 Will_Ofenheusle 1
Sonja_Kesselschlager 1 Tim_Robbins 3
Takeo_Hiranuma 1 Ty_Votaw 1
Ted_Washington 1 Ximena_Bohorquez 1
Ty_Votaw 1 William_Webster 1
Adrian_McPherson 1 2
Al_Davis 1 2
Al_Gore 2 6
Al_Gore 4 6
Alan_Greenspan 1 2
Alan_Greenspan 1 5
Alan_Greenspan 3 4
Alastair_Campbell 1 5
Alastair_Campbell 2 4
Alexander_Downer 1 2
Alexander_Downer 1 3
Alexander_Downer 1 4
Alexander_Downer 3 4
Alice_Fisher 1 2
Alison_Lohman 1 2
Alvaro_Silva_Calderon 1 2
Alvaro_Silva_Calderon 1 3
Alvaro_Uribe 7 20
Alvaro_Uribe 8 25
Alvaro_Uribe 12 13
Alvaro_Uribe 20 28
Anders_Ebbeson 2 3
Andrew_Bunner 1 2
Anibal_Ibarra 1 3
Antonio_Trillanes 1 3
Antonio_Trillanes 2 3
Asa_Hutchinson 1 2
Barbara_Walters 1 3
Barbara_Walters 1 4
Barbara_Walters 3 4
Ben_Howland 1 2
Ben_Howland 1 3
Ben_Howland 3 4
Benazir_Bhutto 1 4
Benazir_Bhutto 2 3
Benazir_Bhutto 2 4
Bill_Simon 5 9
Bill_Simon 11 15
Billy_Sollie 1 2
Boris_Berezovsky 1 2
Brooke_Shields 1 2
Bulent_Ecevit 1 4
Bulent_Ecevit 1 5
Bulent_Ecevit 2 6
Bulent_Ecevit 4 6
Candie_Kung 1 2
Candie_Kung 1 4
Carlo_Ancelotti 1 2
Carlo_Ancelotti 2 3
Carlos_Moya 8 17
Carlos_Moya 10 18
Carlos_Vives 1 4
Carlos_Vives 2 4
Carson_Daly 1 2
Cate_Blanchett 1 2
Cate_Blanchett 1 3
Cate_Blanchett 1 4
Cate_Blanchett 2 3
Cate_Blanchett 2 4
Chok_Tong_Goh 1 2
Chris_Byrd 1 2
Chris_Cooper 1 2
Chris_Tucker 1 2
Christine_Gregoire 1 4
Christine_Gregoire 2 3
Christine_Gregoire 2 4
Christopher_Patten 1 2
Clint_Eastwood 1 4
Clint_Eastwood 1 6
Constance_Marie 1 2
Constance_Marie 1 3
Dennis_Hastert 2 3
Dennis_Hastert 3 6
Dennis_Hastert 4 6
Dennis_Hastert 5 6
Dolly_Parton 1 2
Doug_Duncan 1 2
Edward_Kennedy 1 2
Edward_Kennedy 2 3
Edward_Said 1 2
Elena_Bovina 1 2
Elena_Bovina 1 3
Elena_Bovina 2 3
Eliane_Karp 1 3
Eliane_Karp 2 3
Eliane_Karp 2 4
Eliane_Karp 3 4
Elvis_Presley 1 2
Erika_Harold 1 3
Erika_Harold 2 3
Erika_Harold 3 4
Erika_Harold 4 5
Ernie_Els 1 3
Ernie_Els 1 4
Ernie_Els 2 3
Franco_Dragone 1 2
Frank_Solich 1 4
Frank_Solich 2 5
Frank_Solich 3 4
Gabriel_Batistuta 1 2
Gary_Carter 1 2
Gary_Carter 1 3
Gary_Doer 1 2
Gary_Doer 2 3
George_Tenet 1 2
George_Voinovich 1 3
George_Voinovich 2 3
Georgi_Parvanov 1 2
Goldie_Hawn 1 7
Goldie_Hawn 2 3
Goldie_Hawn 3 7
Goldie_Hawn 6 7
Goran_Persson 1 2
Gro_Harlem_Brundtland 1 2
Guillaume_Soro 1 2
Gwyneth_Paltrow 1 5
Gwyneth_Paltrow 1 6
Gwyneth_Paltrow 2 6
Gwyneth_Paltrow 3 6
Hee-Won_Han 1 2
Herb_Sendek 1 3
Herb_Sendek 3 4
Howard_Smith 1 2
Hugh_Grant 5 8
Hugh_Grant 6 9
Jack_Straw 25 28
James_Franco 1 2
James_Ivory 1 2
James_Schultz 1 2
James_Traficant 1 2
James_Traficant 2 3
Jan_Ullrich 1 4
Jan_Ullrich 2 6
Jan_Ullrich 3 6
Jane_Pauley 1 2
Jason_Jennings 1 2
Javier_Weber 1 2
Jennifer_Rodriguez 1 2
Jeong_Se-hyun 2 6
Jeong_Se-hyun 3 7
Jeong_Se-hyun 6 8
Jeong_Se-hyun 7 9
Jeong_Se-hyun 8 9
Jo_Dee_Messina 1 2
Joe_Lieberman 8 11
Joe_Lieberman 9 10
Joe_Mantello 1 2
John_Allen_Muhammad 2 9
John_Allen_Muhammad 5 7
John_Allen_Muhammad 6 10
John_Blaney 1 2
John_Brady 1 2
John_Howard 5 15
John_Howard 12 17
Johnny_Tapia 1 2
Johnny_Tapia 2 3
Jorge_Valdano 1 2
Joseph_Deiss 1 3
Junichiro_Koizumi 1 53
Junichiro_Koizumi 26 55
Junichiro_Koizumi 29 45
Kate_Capshaw 1 2
Kathryn_Bigelow 1 2
Kevin_Spacey 1 2
Kevin_Spacey 1 3
Kim_Ryong-sung 6 8
Kim_Ryong-sung 8 11
Klaus_Zwickel 1 2
Kristen_Breitweiser 2 3
Laila_Ali 2 3
Larry_Brown 1 3
Larry_Brown 2 4
Larry_Brown 2 7
Larry_Brown 4 7
Larry_Brown 6 7
Larry_Johnson 1 2
Lars_Von_Trier 1 2
Lars_Von_Trier 2 3
Leander_Paes 1 2
Liam_Neeson 1 3
Liam_Neeson 2 3
Lino_Oviedo 1 3
Lino_Oviedo 2 3
Ludivine_Sagnier 1 3
Ludivine_Sagnier 3 4
Lynne_Cheney 1 2
Lynne_Cheney 2 3
Maggie_Smith 1 2
Marcelo_Salas 1 2
Mariangel_Ruiz_Torrealba 1 2
Marisa_Tomei 1 2
Mary_Steenburgen 1 2
Mel_Brooks 1 2
Mel_Gibson 1 2
Mian_Khursheed_Mehmood_Kasuri 2 3
Mian_Khursheed_Mehmood_Kasuri 3 4
Michael_Moore 1 2
Michael_Moore 2 3
Michel_Duclos 1 2
Michelle_Pfeiffer 1 2
Mireya_Moscoso 2 3
Mireya_Moscoso 2 5
Mireya_Moscoso 4 5
Nabil_Shaath 1 3
Nabil_Shaath 2 3
Naomi_Watts 1 18
Naomi_Watts 6 9
Naomi_Watts 13 18
Natalie_Cole 1 3
Natalie_Cole 2 3
Nathalie_Baye 1 2
Nathalie_Baye 1 4
Nathalie_Baye 2 4
Nathalie_Baye 3 4
Oleksandr_Moroz 1 2
Oscar_Elias_Biscet 1 2
Oswaldo_Paya 1 3
Oswaldo_Paya 3 4
Patricia_Clarkson 1 2
Patricia_Clarkson 1 3
Patricia_Clarkson 2 3
Patricia_Clarkson 2 4
Patrick_Roy 1 2
Paul-Henri_Mathieu 1 2
Paul-Henri_Mathieu 1 3
Paul_Byrd 1 2
Paul_Kagame 1 2
Peter_Costello 1 2
Peter_Greenaway 1 2
Prince_Naruhito 1 2
Prince_Naruhito 1 3
Prince_Naruhito 2 3
Princess_Masako 1 2
Pupi_Avati 2 3
Queen_Latifah 1 3
Queen_Latifah 2 4
Queen_Latifah 3 4
Rachel_Griffiths 2 3
Ralph_Firman 1 2
Ralph_Klein 1 2
Ranil_Wickremasinghe 2 3
Rick_Pitino 1 3
Rick_Pitino 2 4
Rick_Pitino 3 4
Ricky_Martin 1 2
Rita_Moreno 1 2
Robert_De_Niro 1 4
Robert_De_Niro 3 6
Robert_Kocharian 4 5
Roberto_Marinho 2 3
Roger_Moore 3 5
Ron_Dittemore 1 2
Ron_Dittemore 1 3
Ron_Dittemore 4 6
Rudolph_Giuliani 1 20
Rudolph_Giuliani 2 5
Rudolph_Giuliani 3 20
Rudolph_Giuliani 4 17
Rudolph_Giuliani 15 20
Russell_Simmons 1 2
Russell_Simmons 1 4
Russell_Simmons 2 4
Sean_Astin 1 3
Sean_Astin 2 3
Shaukat_Aziz 1 2
Silvio_Fernandez 1 2
Sophia_Loren 1 2
Sophia_Loren 1 3
Sophia_Loren 1 7
Sophia_Loren 6 7
Stellan_Skarsgard 1 2
Tamara_Brooks 1 2
Thomas_Fargo 1 2
Thomas_Fargo 1 3
Thomas_Fargo 2 3
Thomas_Fargo 2 4
Thomas_Fargo 3 4
Tim_Allen 2 3
Tim_Allen 3 4
Tony_Shalhoub 1 2
Tony_Shalhoub 1 3
Tracy_McGrady 1 2
Vicente_Fernandez 2 3
Vicente_Fernandez 4 5
Vince_Gill 1 2
Wolfgang_Schuessel 1 4
Wolfgang_Schuessel 3 4
Wu_Yi 1 2
Wu_Yi 1 3
Wu_Yi 2 3
Yao_Ming 2 4
Yao_Ming 5 6
Yao_Ming 5 8
Yao_Ming 6 7
Yoriko_Kawaguchi 3 5
Yu_Shyi-kun 1 3
Yu_Shyi-kun 1 4
Yu_Shyi-kun 2 3
Zhang_Wenkang 1 2
Zinedine_Zidane 4 6
Abdullah_Nasseef 1 Bruce_Paltrow 1
Abdullah_Nasseef 1 Howard_Smith 2
Abdullah_Nasseef 1 Jan_De_Bont 1
Abdullah_Nasseef 1 Jim_Nochols 1
Abdullah_Nasseef 1 Oleg_Romantsev 1
Adam_Kennedy 1 Charlie_Sheen 1
Adrian_McPherson 2 Eduardo_Chillida 1
Al_Davis 1 Julian_Fantino 1
Alan_Greenspan 4 Kent_McCord 1
Alastair_Campbell 4 Li_Ka-shing 1
Alexa_Vega 1 Tony_Shalhoub 1
Alexander_Downer 2 Zeljko_Rebraca 1
Alexander_Downer 3 Luis_Berrondo 1
Alexandra_Pelosi 1 Ken_Kutaragi 1
Alexandre_Herchcovitch 1 Karen_Clarkson 1
Alice_Fisher 1 Gene_Sauers 1
Alicia_Witt 1 Jorge_Moreno 1
Alicia_Witt 1 Lino_Oviedo 1
Allan_Wagner 1 Larry_Campbell 1
Allan_Wagner 1 Rita_Moreno 1
Alvaro_Silva_Calderon 2 Stepan_Demirchian 1
Alvaro_Uribe 14 Patricia_Clarkson 1
Ana_Sebastiao 1 Marcos_Cafu 1
Ana_Sebastiao 1 Raza_Rabbani 1
Andrea_De_Cruz 1 Dionne_Warwick 1
Andrea_De_Cruz 1 Ismail_Cem 1
Andrea_De_Cruz 1 Natalya_Sazanovich 1
Andrea_De_Cruz 1 Yoon_Young-kwan 1
Andres_Manuel_Lopez_Obrador 1 Jim_Parque 1
Andres_Manuel_Lopez_Obrador 1 Norman_Mineta 1
Andrew_Bunner 2 Oscar_Elias_Biscet 2
Andrew_Weissmann 1 Ernie_Els 2
Andy_Warhol 1 Edith_Masai 1
Andy_Warhol 1 Paul-Henri_Mathieu 2
Anibal_Ibarra 2 David_Przybyszewski 1
Anthony_Ervin 1 Juan_Roman_Carrasco 1
Antonio_Elias_Saca 1 Peter_Holmberg 1
Antonio_Elias_Saca 1 Thomas_Fargo 4
Antonio_Trillanes 1 Katrin_Cartlidge 1
Antonio_Trillanes 3 Terry_Gilliam 1
Asa_Hutchinson 2 Gary_Sinise 1
Ascencion_Barajas 1 Chris_Hernandez 1
Ashley_Judd 1 Joan_Jett 1
Ashley_Postell 1 Cassandra_Heise 1
Ashley_Postell 1 Tony_Clement 1
Ashraf_Ghani 1 Boris_Berezovsky 1
Ashraf_Ghani 1 Qian_Qichen 1
Asif_Ali_Zardari 1 Steny_Hoyer 1
Assad_Ahmadi 1 Percy_Gibson 1
Barbara_Walters 1 Jewel_Howard-Taylor 1
Barbara_Walters 1 Peter_Greenaway 1
Barry_Williams 1 Wang_Fei 1
Benazir_Bhutto 4 Jane_Pauley 2
Benazir_Bhutto 5 Karen_Clarkson 1
Bijan_Darvish 1 Franco_Dragone 1
Bijan_Darvish 2 Frank_Taylor 1
Bilal_Erdogan 1 Lubomir_Zaoralek 1
Bill_Self 1 Yang_Jianli 1
Bill_Simon 1 Edward_Said 2
Billy_Gilman 1 Howard_Smith 2
Billy_Sollie 1 Mark_Swartz 1
Billy_Sollie 2 Hussein_Malik 1
Blas_Ople 1 Evan_Marriott 1
Blas_Ople 1 Felipe_Fernandez 1
Blas_Ople 1 Peter_Costello 1
Bob_Cantrell 1 Gerard_Kleisterlee 1
Bob_Cantrell 1 Mary_Landrieu 3
Bob_Goldman 1 Leigh_Winchell 1
Bob_Goldman 1 Maggie_Smith 1
Boris_Berezovsky 2 Leander_Paes 1
Brad_Gushue 1 Johannes_Rau 1
Brad_Miller 1 Irina_Lobacheva 1
Brad_Miller 1 Percy_Gibson 1
Brenda_van_Dam 1 Norbert_van_Heyst 1
Brian_Cashman 1 Delphine_Chuillot 1
Brian_Cashman 1 Russell_Simmons 3
Brian_Cook 1 Matt_Welsh 1
Bruno_Junquiera 1 Oscar_DLeon 1
Bulent_Ecevit 6 Eduardo_Romero 1
Bulent_Ecevit 6 Gilberto_Simoni 1
Candie_Kung 1 Steve_Allan 1
Carlo_Ancelotti 1 John_Tyson 1
Carlos_Vives 2 Randy_Johnson 1
Caroline_Dhavernas 1 Evgeni_Plushenko 1
Caroline_Dhavernas 1 Jeremy_Fogel 1
Carson_Daly 1 John_Moe 1
Carson_Daly 1 Tracy_Wyle 1
Cassandra_Heise 1 Shaukat_Aziz 2
Cate_Blanchett 3 Gina_Centrello 1
Cate_Blanchett 3 Ryan_Goodman 1
Catherine_Donkers 1 Eminem 1
Cedric_Benson 1 Marcus_Allen 1
Cedric_Benson 1 Robert_Lee_Yates_Jr 1
Cedric_Benson 1 Stacy_Nelson 1
Chistian_Stahl 1 Eliane_Karp 1
Chris_Cooper 2 Irfan_Ahmed 1
Chris_Cooper 2 Rick_Bland 1
Chris_Hernandez 1 Mauricio_Pochetino 1
Chris_Hernandez 1 Tonga 1
Chris_Hernandez 1 Wolfgang_Schuessel 1
Chris_Tucker 2 Jennifer_Pena 1
Chris_Tucker 2 Takuma_Sato 1
Chris_Whitney 1 Tom_Scully 1
Christine_Gregoire 4 Robert_Lee_Yates_Jr 1
Christine_Gregoire 4 Wang_Hailan 1
Christine_Rau 1 Jerry_Hall 1
Christine_Rau 1 Mel_Brooks 1
Christopher_Russell 1 Colleen_OClair 1
Christopher_Whittle 1 Felipe_Fernandez 1
Colleen_OClair 1 Tom_Hanusik 1
Curtis_Rodriguez 1 John_Blaney 2
Curtis_Rodriguez 1 Kathleen_Kennedy_Townsend 3
Dale_Bosworth 1 Frank_Taylor 1
Dale_Bosworth 1 Vladimir_Golovlyov 1
Dan_Quayle 1 Jim_Ryan 1
Dan_Quayle 1 Nick_Turner 1
Dan_Quayle 1 William_Umbach 1
Danny_Morgan 1 Jeff_George 1
Danny_Morgan 1 John_Allen_Muhammad 10
Darla_Moore 1 Paul_Johnson 1
Darrell_Royal 1 Louis_Van_Gaal 1
Dave_McGinnis 1 Michel_Therrien 1
David_Przybyszewski 1 Elena_Bovina 2
Delphine_Chuillot 1 Jim_Parque 1
Demetrin_Veal 1 Robert_Hanssen 1
Dennis_Hastert 5 Lubomir_Zaoralek 1
Dewayne_White 1 Joe_DeLamielleure 1
Dick_Posthumus 1 Jeff_George 1
Dick_Posthumus 1 Jim_Wong 1
Din_Samsudin 1 Pupi_Avati 2
Dionne_Warwick 1 Janine_Pietsch 1
Dominique_Perben 1 Osmond_Smith 1
Doug_Duncan 1 Kevin_Spacey 2
Doug_Duncan 2 John_Allen_Muhammad 2
Eddy_Hartenstein 1 Lyudmila_Putin 1
Eddy_Hartenstein 1 Matthias_Sammer 1
Eddy_Hartenstein 1 Sabah_Al-Ahmad_Al-Jaber_Al-Sabah 1
Eduardo_Chillida 1 Stephen_Crampton 1
Eduardo_Romero 1 Robert_Kocharian 5
Edward_Greenspan 1 Roy_Halladay 1
Edward_Greenspan 1 Sidney_Poitier 1
Edward_Kennedy 1 Mathilda_Karel_Spak 1
Edward_Kennedy 2 Jennifer_Pena 1
Edward_Said 1 Frank_Abagnale_Jr 1
Eminem 1 Wolfgang_Clement 1
Enrique_Bolanos 4 Janine_Pietsch 1
Enrique_Bolanos 4 Liam_Neeson 2
Ernie_Els 2 Marcus_Allen 1
Evgeni_Plushenko 1 Queen_Sofia 1
Evgeni_Plushenko 1 Riek_Blanjaar 1
Franco_Dragone 2 Louis_Van_Gaal 1
Franco_Frattini 1 Irina_Lobacheva 1
Frank_Abagnale_Jr 1 Nate_Hybl 1
Frank_Shea 1 Rob_Moore 1
Frank_Taylor 1 Jason_Jennings 1
Gabriel_Batistuta 1 Peter_Costello 1
Gabriel_Jorge_Ferreia 1 Zulfiqar_Ahmed 1
Gary_Doer 3 Wang_Hailan 1
Gary_Sinise 1 Roy_Halladay 1
Gene_Hackman 1 Queen_Noor 1
Gene_Sauers 1 Gina_Centrello 1
Geoff_Dixon 1 Jean_Todt 1
George_Allen 1 Roy_Halladay 1
George_Allen 1 Wan_Yanhai 1
George_Harrison 1 Robert_Lee_Yates_Jr 1
Georgi_Parvanov 1 Luis_Fonsi 1
Gianni_Agnelli 1 Marco_Irizarry 1
Gilberto_Simoni 1 Julio_Cesar_Chavez 1
Gong_Ruina 1 Hong_Myung 1
Gong_Ruina 1 Qian_Qichen 1
Gro_Harlem_Brundtland 2 Turner_Gill 1
Hector_Grullon 1 Jeong_Se-hyun 9
Henk_Bekedam 1 Koichi_Haraguchi 1
Henk_Bekedam 1 Manuel_Gehring 1
Henk_Bekedam 1 Michael_Kirby 1
Hiroki_Gomi 1 Kenneth_Cooper 1
Hiroki_Gomi 1 Sophia_Loren 2
Irina_Lobacheva 1 Steve_Allan 1
Ismail_Cem 1 Linda_Amicangioli 1
Jack_Osbourne 1 Kent_McCord 1
Jack_Straw 1 Manuel_Gehring 1
Jack_Straw 3 Norman_Mineta 1
James_Ballenger 1 Raza_Rabbani 1
James_Coviello 1 Judith_Nathan 1
James_Coviello 1 Robert_F_Kennedy_Jr 1
James_Morris 2 Silvio_Fernandez 2
James_Schultz 1 Tim_Curley 1
James_W_Kennedy 1 John_Connolly 1
James_W_Kennedy 1 Toutai_Kefu 1
James_Williams 1 Phillip_Seymor_Hoffmann 1
James_Williams 1 Shaun_Pollock 1
Jan_Ullrich 3 Javier_Weber 1
Jane_Menelaus 1 Junichiro_Koizumi 42
Jane_Menelaus 1 Sophia_Loren 1
Jason_Petty 1 Mayumi_Moriyama 1
Jean_Todt 1 Roger_Etchegaray 1
Jennifer_Pena 1 Sonia_Lopez 1
Jennifer_Pena 1 Tony_LaRussa 1
Jennifer_Rodriguez 1 Terry_Gilliam 1
Jennifer_Rodriguez 2 Joanna_Poitier 1
Jennifer_Rodriguez 2 Tony_Fernandes 1
Jerome_Golmard 1 Kristin_Chenoweth 1
Jewel_Howard-Taylor 1 Ken_Kutaragi 1
Jim_Parque 1 Michael_Adams 1
Jim_Parque 1 Rachel_Leigh_Cook 1
Jim_Ryan 1 Luis_Berrondo 1
Jimmy_Gobble 1 Robert_De_Niro 5
Joan_Collins 1 Zydrunas_Ilgauskas 1
Joan_Jett 1 Kevin_James 1
Joanna_Poitier 1 Michael_Moore 1
Joe_Lieberman 10 Joe_Mantello 1
Johannes_Rau 1 Oleksandr_Moroz 1
John_Connolly 1 Mel_Gibson 1
John_Connolly 1 Michael_Moore 3
John_Connolly 1 Norman_Mineta 1
John_Connolly 1 Uzi_Even 1
John_Cruz 1 Sean_Astin 3
John_Cruz 1 Steven_Briggs 1
John_Hartson 1 Oscar_Elias_Biscet 2
Joseph_Deiss 1 Tony_Fernandes 1
Joseph_Lopez 1 Rick_Pitino 1
Julian_Fantino 1 Quin_Snyder 1
Julio_Cesar_Chavez 1 Tom_Brennan 1
Junichi_Inamoto 1 Oleg_Romantsev 1
Junichiro_Koizumi 20 Tony_Fernandes 1
Karen_Clarkson 1 Kristen_Breitweiser 3
Karol_Kucera 1 Qian_Qichen 1
Karol_Kucera 1 Turner_Gill 1
Katrin_Cartlidge 1 Tony_LaRussa 1
Keith_Osik 1 Pupi_Avati 1
Kenneth_Cooper 1 Norman_Mineta 1
Kent_McCord 1 Natasha_Henstridge 1
Kevin_James 1 Roy_Halladay 1
Kevin_James 1 Suzanne_Haik_Terrell 1
Kevin_James 1 Yang_Jianli 1
Kevin_Spacey 2 Ray_Evernham 1
Koji_Uehara 1 Rob_Moore 1
Krishna_Bhadur_Mahara 1 Peter_Holmberg 1
Krishna_Bhadur_Mahara 1 Silvio_Fernandez 2
Kristen_Breitweiser 1 Tatiana_Shchegoleva 1
Laila_Ali 3 Tony_Fernandes 1
Larry_Johnson 1 Terry_Gilliam 1
Larry_Johnson 2 Marc_Racicot 1
Larry_Johnson 2 Tom_Hanusik 1
Lars_Von_Trier 1 Zhang_Wenkang 2
Leander_Paes 1 Ralph_Firman 1
Leo_Ramirez 1 Sabah_Al-Ahmad_Al-Jaber_Al-Sabah 1
Leonardo_Del_Vecchio 1 Maggie_Smith 1
Leonardo_Del_Vecchio 1 Tatiana_Shchegoleva 1
Liam_Neeson 1 Paul_Kagame 2
Lokendra_Bahadur_Chand 1 Steffeny_Holtz 1
Louis_Van_Gaal 1 Natasha_Henstridge 1
Lubomir_Zaoralek 1 Luis_Berrondo 1
Lubomir_Zaoralek 1 William_Umbach 1
Luis_Berrondo 1 Rita_Moreno 2
Luis_Fonsi 1 Oscar_DLeon 1
Luis_Fonsi 1 Steven_Briggs 1
Luis_Rosario_Huertas 1 Mary_Steenburgen 2
Makiko_Tanaka 1 Peter_Greenaway 1
Manijeh_Hekmat 1 Roger_Winter 1
Manijeh_Hekmat 1 T_Boone_Pickens 1
Marcelo_Salas 2 Tara_VanDerveer 1
Marco_Irizarry 1 Yang_Jianli 1
Mariangel_Ruiz_Torrealba 3 Pupi_Avati 1
Marisa_Tomei 2 Peter_Costello 2
Mark_Polansky 1 Miranda_Gaddis 1
Mary_Landrieu 3 Percy_Gibson 1
Mathilda_Karel_Spak 1 Mauricio_Macri 1
Mathilda_Karel_Spak 1 Tamara_Brooks 2
Matt_Welsh 1 Randy_Johnson 1
Mel_Brooks 2 Shoshana_Johnson 1
Michael_Kirby 1 Ranil_Wickremasinghe 2
Michael_Sheehan 1 Robert_Hanssen 1
Michel_Duclos 1 Quin_Snyder 1
Michel_Duclos 1 Suh_Young-hoon 1
Mike_Gable 1 Mohamed_Hammam 1
Mikhail_Khodorkovsky 1 Rita_Moreno 2
Mireya_Moscoso 4 San_Lan 1
Mohamed_Hammam 1 Roger_Moore 4
Nabil_Shaath 3 Silvie_Cabero 1
Naomi_Hayashi 1 Prakash_Hinduja 1
Natalya_Sazanovich 1 Pupi_Avati 4
Nikki_Teasley 1 Ryan_Goodman 1
Oleksandr_Moroz 1 Robert_De_Niro 1
Oscar_DLeon 1 Steven_Curtis_Chapman 1
Paul_Byrd 1 Wolfgang_Schwarz 1
Paul_Wollnough 1 Philip_Cummings 1
Paul_Wollnough 1 Yuvraj_Singh 1
Penelope_Taylor 1 Wang_Fei 1
Peter_Caruana 1 Philip_Cummings 1
Phillip_Seymor_Hoffmann 1 Silvio_Fernandez 1
Phillips_Idowu 1 Prince_Naruhito 2
Princess_Masako 2 Thomas_Wilkens 1
Quin_Snyder 1 Vagit_Alekperov 1
Ranil_Wickremasinghe 3 Stacy_Nelson 1
Reina_Hayes 1 Steffeny_Holtz 1
Rick_Pitino 3 Tony_Clement 1
Ricky_Martin 2 Roger_Etchegaray 1
Robert_F_Kennedy_Jr 1 Ron_Dittemore 1
Sidney_Poitier 1 Svend_Aage_Jensby 1
Abdel_Nasser_Assidi 1 2
Ai_Sugiyama 1 2
Ai_Sugiyama 1 4
Ai_Sugiyama 4 5
Aldo_Paredes 1 2
Alejandro_Avila 1 2
Alejandro_Avila 1 3
Alex_Sink 2 3
Allen_Iverson 1 2
Amram_Mitzna 1 2
Andrew_Niccol 1 2
Andy_Hebb 1 2
Anne_Krueger 1 2
Anne_McLellan 1 3
Anne_McLellan 2 3
Annette_Bening 1 2
Anthony_Hopkins 1 2
Ariel_Sharon 16 45
Arminio_Fraga 1 6
Arminio_Fraga 2 4
Arminio_Fraga 3 6
Arminio_Fraga 4 6
Art_Hoffmann 1 2
Ashanti 1 3
Ashanti 1 4
Ashanti 2 5
Ashanti 3 5
Ashanti 4 5
Augustin_Calleri 1 2
Augustin_Calleri 2 4
Augustin_Calleri 3 4
Bertie_Ahern 1 2
Bertie_Ahern 1 4
Bertie_Ahern 1 5
Bertie_Ahern 2 3
Bertie_Ahern 3 5
Bill_Clinton 2 4
Bill_Clinton 6 8
Bill_Clinton 6 10
Bill_Clinton 8 10
Bill_Clinton 9 12
Bill_Clinton 10 29
Bill_Clinton 18 28
Bill_McBride 4 7
Bill_McBride 4 10
Bill_Parcells 1 2
Binyamin_Ben-Eliezer 3 5
Binyamin_Ben-Eliezer 5 6
Binyamin_Ben-Eliezer 6 7
Brendan_Hansen 1 2
Brian_Wells 1 2
Carlos_Quintanilla_Schmidt 1 2
Carolina_Moraes 1 2
Cecilia_Bolocco 1 2
Cecilia_Bolocco 1 3
Cecilia_Bolocco 2 3
Cesar_Gaviria 2 4
Cesar_Gaviria 2 5
Cesar_Gaviria 3 6
Cesar_Gaviria 3 7
Cesar_Gaviria 4 6
Charlie_Zaa 1 2
Chita_Rivera 1 2
Christian_Longo 1 2
Christian_Longo 1 3
Christian_Wulff 1 2
Colin_Jackson 1 2
Darrell_Issa 1 2
Darrell_Porter 1 2
Dave_Campo 1 3
David_Dodge 1 2
David_Heyman 1 2
David_Spade 1 2
David_Wells 1 5
David_Wells 1 6
David_Wells 1 7
David_Wells 2 6
David_Wells 5 6
Debbie_Reynolds 1 3
Debbie_Reynolds 2 4
Dexter_Jackson 1 2
Diana_Taurasi 1 2
Donald_Evans 1 2
Duane_Lee_Chapman 1 2
Ed_Smart 1 3
Eileen_Coparropa 1 2
Eileen_Coparropa 1 3
Eileen_Coparropa 2 3
Elizabeth_Dole 1 3
Elizabeth_Dole 2 4
Fred_Funk 1 2
Gabriel_Valdes 1 2
Gary_Winnick 1 2
Geno_Auriemma 1 2
George_Karl 1 2
George_Robertson 2 3
George_Robertson 3 19
George_Robertson 7 19
George_Robertson 11 12
George_Ryan 1 4
George_Ryan 2 3
George_W_Bush 7 65
George_W_Bush 16 482
George_W_Bush 145 150
George_W_Bush 145 238
George_W_Bush 203 247
Gloria_Trevi 1 2
Gloria_Trevi 2 3
Gloria_Trevi 2 4
Gordon_Campbell 1 2
Greg_Rusedski 1 2
Greg_Rusedski 2 3
Greg_Rusedski 2 4
Greg_Rusedski 3 4
Gustavo_Kuerten 1 2
Gustavo_Kuerten 2 3
Guy_Hemmings 1 2
Halle_Berry 6 7
Halle_Berry 6 9
Halle_Berry 7 9
Heather_Mills 2 3
Heather_Mills 2 4
Heidi_Fleiss 1 2
Heidi_Fleiss 1 3
Henrique_Meirelles 1 2
Iva_Majoli 1 2
Jake_Gyllenhaal 3 5
Jake_Gyllenhaal 4 5
James_Cunningham 1 2
James_Cunningham 1 3
James_Cunningham 2 3
James_Parker 1 2
James_Wolfensohn 2 5
Jason_Lezak 1 2
Jay_Rasulo 1 2
Jean-Claude_Juncker 1 2
Jennifer_Lopez 1 3
Jennifer_Lopez 2 16
Jennifer_Lopez 3 10
Jennifer_Lopez 3 14
Jesse_Jackson 1 3
Jesse_Jackson 5 8
Jesse_Jackson 7 8
Jesse_James_Leija 1 2
Jesse_Ventura 2 3
Jia_Qinglin 1 2
Jim_Tressel 1 2
Jim_Tressel 1 4
Jim_Tressel 2 4
Joan_Laporta 1 6
Joan_Laporta 6 7
Joan_Laporta 6 8
Joe_Dumars 1 2
John_Ashcroft 3 5
John_Ashcroft 13 34
John_Ashcroft 42 43
John_Bolton 6 7
John_Bolton 11 16
John_Swofford 1 2
John_Swofford 1 3
John_Timoney 1 2
Jon_Gruden 1 2
Jon_Gruden 2 5
Jon_Gruden 3 6
Jon_Gruden 3 7
Julie_Taymor 1 2
Kamal_Kharrazi 1 5
Kamal_Kharrazi 2 3
Kamal_Kharrazi 2 6
Karin_Stoiber 1 2
Kim_Yong-il 1 2
Kim_Yong-il 1 3
Kimi_Raikkonen 1 3
Kimi_Raikkonen 2 3
Kjell_Magne_Bondevik 1 3
Kobe_Bryant 1 2
Kurt_Warner 1 2
Kurt_Warner 1 4
Kurt_Warner 2 4
Kurt_Warner 3 5
Kwon_Yang-sook 1 3
Kwon_Yang-sook 2 3
Lee_Jun 1 2
Leonid_Kuchma 1 2
Leonid_Kuchma 1 3
Leonid_Kuchma 2 3
Leonid_Kuchma 2 5
Leonid_Kuchma 4 5
Lina_Krasnoroutskaya 1 2
Lisa_Raymond 1 2
Lord_Hutton 1 2
Luiz_Felipe_Scolari 1 2
Lynn_Redgrave 2 3
Magdalena_Maleeva 1 2
Magdalena_Maleeva 1 3
Magdalena_Maleeva 2 3
Marcelo_Ebrard 1 2
Marcelo_Ebrard 1 3
Marcelo_Rios 1 3
Marcelo_Rios 1 4
Marcelo_Rios 2 3
Marcelo_Rios 3 4
Marcelo_Rios 3 5
Maria_Shriver 1 7
Maria_Shriver 1 8
Maria_Shriver 2 6
Maria_Shriver 2 8
Maria_Shriver 3 8
Marilyn_Monroe 1 2
Mario_Cipollini 1 2
Mark_Hurlbert 1 5
Mark_Hurlbert 2 3
Mark_Hurlbert 2 4
Martin_Scorsese 2 5
Martin_Scorsese 3 4
Marwan_Barghouthi 1 2
Michael_Bloomberg 1 12
Michael_Bloomberg 3 5
Michael_Bloomberg 7 11
Michael_Bloomberg 11 13
Michael_Chang 1 3
Michael_Chang 5 6
Michael_Jackson 1 6
Michael_Jackson 2 3
Michael_Jackson 2 11
Michael_Jackson 2 12
Michael_Jackson 11 12
Michael_Patrick_King 1 2
Michelle_Rodriguez 1 2
Mike_Babcock 1 2
Mike_Martz 1 3
Mike_Scioscia 1 2
Mikulas_Dzurinda 1 2
Miroljub 1 2
Nasser_al-Kidwa 1 2
Nick_Nolte 1 2
Nick_Nolte 1 3
Nick_Nolte 1 5
Nick_Nolte 2 4
Nick_Nolte 3 4
OJ_Simpson 1 2
Oprah_Winfrey 1 2
Oprah_Winfrey 2 3
Orlando_Bloom 2 3
Ozzy_Osbourne 1 3
Paul_Coppin 1 2
Paul_Martin 1 6
Paul_Martin 1 7
Paul_McNulty 1 2
Paul_ONeill 1 3
Paul_ONeill 5 7
Paul_Patton 1 2
Paula_Zahn 1 2
Pierce_Brosnan 1 5
Pierce_Brosnan 3 7
Pierce_Brosnan 6 9
Pierce_Brosnan 9 14
Pierre_Pettigrew 1 3
Ralf_Schumacher 5 8
Ricky_Barnes 1 2
Rita_Wilson 1 4
Rob_Schneider 1 2
Robbie_Fowler 1 2
Robert_Blake 1 3
Robert_Blake 1 4
Robert_Blake 5 6
Rogerio_Romero 1 2
Rupert_Grint 1 3
Salman_Rushdie 1 3
Salman_Rushdie 2 3
Scott_Sullivan 1 2
Scott_Wolf 1 2
Sepp_Blatter 1 2
Sepp_Blatter 1 3
Sepp_Blatter 2 3
Simon_Cowell 1 2
Slobodan_Milosevic 1 3
Slobodan_Milosevic 2 3
Slobodan_Milosevic 3 4
Stacy_Dragila 1 2
Stephen_Ambrose 1 2
Stephen_Daldry 1 2
Stephen_Friedman 1 2
Theo_Epstein 1 2
Thomas_Wyman 1 2
Tim_Floyd 1 2
Tom_Watson 1 3
Tom_Watson 2 3
Tommy_Robredo 1 3
Tommy_Robredo 2 3
Tony_Parker 1 2
Tony_Stewart 1 6
Tony_Stewart 2 3
Tony_Stewart 4 5
Tony_Stewart 4 6
Vladimir_Voltchkov 1 2
Wang_Yi 1 2
Zafarullah_Khan_Jamali 1 2
Zhu_Rongji 1 3
Zhu_Rongji 2 8
Aaron_Tippin 1 Enos_Slaughter 1
Aaron_Tippin 1 Juan_Carlos_Ortega 1
Aaron_Tippin 1 Marlon_Devonish 1
Adam_Ant 1 John_Perrota 1
Adam_Ant 1 Noel_Forgeard 1
Adam_Ant 1 Richard_Regenhard 1
Adam_Mair 1 Daniel_Osorno 1
Adoor_Gopalakarishnan 1 Nathalia_Gillot 1
Alain_Ducasse 1 Paul_ONeill 2
Alan_Greer 1 Alan_Trammell 1
Alan_Greer 1 Bob_Hayes 1
Alan_Trammell 1 Heidi_Fleiss 2
Alan_Trammell 1 Julie_Taymor 2
Aldo_Paredes 1 Suzanne_Mubarak 1
Aldo_Paredes 2 Zafarullah_Khan_Jamali 1
Alecos_Markides 1 Darryl_Stingley 1
Alecos_Markides 1 Wolfgang_Schneiderhan 1
Alejandro_Avila 3 Benjamin_Franklin 1
Alejandro_Avila 3 Darrell_Porter 1
Alek_Wek 1 Barbara_Bodine 1
Alek_Wek 1 Nasser_al-Kidwa 1
Alek_Wek 1 Ray_Bradbury 1
Alina_Kabaeva 1 Donald_Trump 1
Alina_Kabaeva 1 Jayson_Williams 2
Alyse_Beaupre 1 Elmar_Brok 1
Alyse_Beaupre 1 Helo_Pinheiro 1
Alyse_Beaupre 1 Hunter_Bates 1
Ambrose_Lee 1 Ben_Chandler 1
Amy_Gale 1 Herman_Edwards 1
Anastasia_Kelesidou 1 Brendan_Hansen 2
Anastasia_Kelesidou 1 Thomas_Wyman 2
Andrew_Niccol 1 Prince_Felipe 1
Andrew_Sabey 1 Federico_Castelan_Sayre 1
Andrew_Sabey 1 Greg_Rusedski 1
Andy_Madikians 1 Jon_Gruden 1
Andy_Madikians 1 Pedro_Alvarez 1
Andy_Madikians 1 Pierce_Brosnan 1
Andy_Perez 1 Elena_Dementieva 1
Andy_Perez 1 Stephen_Joseph 1
Angie_Martinez 1 Ruth_Pearce 1
Ann_Godbehere 1 Tom_Watson 1
Anne_McLellan 1 Tim_Howard 1
Annette_Bening 1 Ross_Verba 1
Anthony_Hopkins 2 Orlando_Bloom 1
Antonio_Bernardo 1 Billy_Donovan 1
Antonio_Bernardo 1 Dwain_Kyles 1
Antonio_Bernardo 1 Elizabeth_Hill 1
Antonio_Bernardo 1 Guy_Hemmings 1
Antonio_Bernardo 1 Kareena_Kapoor 1
Anzori_Kikalishvili 1 Carlos_Quintanilla_Schmidt 2
Anzori_Kikalishvili 1 Earl_Fritts 1
Anzori_Kikalishvili 1 Salman_Rushdie 1
Aram_Adler 1 Cesar_Gaviria 3
Aram_Adler 1 Deepa_Mehta 1
Arie_Haan 1 Tony_Parker 2
Ariel_Sharon 30 David_Ballantyne 1
Art_Hoffmann 2 Juan_Carlos_Ortega 1
Atiabet_Ijan_Amabel 1 John_Perrota 1
Augustin_Calleri 3 Lee_Jun 2
Barry_Nakell 1 Maria_Simon 1
Basdeo_Panday 1 Filippo_Volandri 1
Ben_Betts 1 Kimi_Raikkonen 3
Ben_Braun 1 Cecilia_Chang 1
Ben_Braun 1 Horace_Newcomb 1
Ben_Chandler 1 Larry_Hagman 1
Ben_Lee 1 Horace_Newcomb 1
Ben_Stein 1 David_Canary 1
Ben_Stein 1 Lionel_Richie 2
Bernadette_Peters 1 Ed_Smart 1
Bertie_Ahern 4 Jim_Leach 1
Bill_OReilly 1 Jim_Wessling 1
Billy_Boyd 1 Sid_Caesar 1
Billy_Donovan 1 Brandon_Spann 1
Billy_Donovan 1 Cabas 1
Billy_Donovan 1 William_Nessen 1
Binyamin_Ben-Eliezer 1 Jenny_Romero 1
Bo_Ryan 2 Heidi_Fleiss 3
Bob_Beauprez 2 Hedayat_Amin_Arsala 1
Bob_Beauprez 2 John_Norquist 1
Bob_Hayes 1 Zhu_Rongji 8
Brady_Rodgers 1 Jenna_Elfman 1
Brandon_Larson 1 Chita_Rivera 1
Brendan_Hansen 2 Dorothy_Wilson 1
Caio_Blat 1 Sanja_Papic 1
Carlos_Quintanilla_Schmidt 1 Nova_Esther_Guthrie 1
Carlos_Quintanilla_Schmidt 2 Chris_Thomas 1
Carroll_Weimer 1 Chris_Pronger 1
Carroll_Weimer 1 Debbie_Reynolds 2
Cecilia_Bolocco 1 John_Perrota 1
Cecilia_Bolocco 1 Kurt_Schottenheimer 1
Celia_Cruz 1 Rob_Ramsay 1
Charlie_Zaa 2 Theo_Epstein 2
Chris_Pronger 1 Edgar_Savisaar 1
Christian_Longo 2 David_Carradine 1
Christian_Wulff 2 Kjell_Magne_Bondevik 3
Cindy_Klassen 1 Val_Ackerman 1
Cindy_Taylor 1 Fabian_Vargas 1
Claudette_Robinson 1 Eric_Fehr 1
Clifford_Robinson 1 Magdalena_Maleeva 2
Clifford_Robinson 1 Shirley_Jones 1
Clifford_Robinson 1 Tim_Howard 1
Colin_Jackson 1 Marcelo_Ebrard 3
Colin_Jackson 2 Hunter_Bates 1
Columba_Bush 1 Larry_Anderson 1
Columba_Bush 1 Neil_Goldman 1
Craig_Fitzgibbon 1 Joe_Dumars 1
Cristian_Barros 1 Steve_Largent 1
Curtis_Strange 1 Kurt_Schottenheimer 1
Curtis_Strange 1 Raul_Chacon 1
Dan_Kellner 1 Freda_Black 1
Dan_LaCoutre 1 Gustavo_Kuerten 2
Dan_Monson 1 Jim_Flaherty 1
Dan_Monson 1 Rafael_Vinoly 1
Darrell_Porter 2 Robert_Towne 1
Dave_Campo 2 Jenny_Romero 1
David_Ballantyne 1 Diana_Taurasi 2
David_Carradine 1 Kobe_Bryant 1
David_Dodge 1 Francois_Botha 1
David_Dodge 1 Larry_Anderson 1
David_Dodge 2 Thomas_Wyman 2
David_Heyman 1 Rod_Paige 1
David_Oh 1 Desiree_McKenzie 1
David_Oh 1 Joe_Garner 1
David_Spade 2 Denise_Locke 1
David_Suazo 1 Jane_Krakowski 1
David_Wells 1 Mary_Hill 1
David_Wells 1 Yannos_Papantoniou 1
Dawna_LoPiccolo 1 Jean-Claude_Juncker 2
Debbie_Reynolds 1 Nick_Nolte 1
Deniz_Baykal 1 Kathy_Bates 1
Deniz_Baykal 1 Robin_Wagner 1
Desiree_McKenzie 1 John_Danforth 1
Dick_Devine 1 Michael_Jackson 9
Dinora_Rosales 1 Robbie_Fowler 1
Dirk_Kempthorne 1 Janusz_Kaminski 1
Donald_Evans 2 Fred_Funk 2
Dorothy_Wilson 1 Jim_Thome 1
Drew_Gooden 1 Kimi_Raikkonen 3
Dwain_Kyles 1 Gregory_Peck 1
Ed_Smart 3 Jason_Gardner 1
Edgar_Savisaar 1 Kirk_Doerger 1
Edward_Burns 1 Paul_ONeill 1
Elmar_Brok 1 Jose_Jose 1
Emily_Mortimer 1 Maria_Simon 1
Enos_Slaughter 1 Qais_al-Kazali 1
Eric_Fehr 1 Lee_Jun 2
Eric_Fehr 1 Tamara_Mowry 1
Faisal_Saleh_Hayat 1 Marwan_Barghouthi 1
Federico_Castelan_Sayre 1 Jimmy_Jimenez 1
Fiona_Milne 1 Hartmut_Mehdorn 1
Fiona_Milne 1 Josh_Kronfeld 1
Floyd_Keith 1 Halle_Berry 1
Franklin_Brown 1 Michael_Jackson 10
Franklin_Brown 1 Tamara_Mowry 1
Franklin_Brown 1 Yolanda_King 1
Freda_Black 1 Rod_Paige 1
Fruit_Chan 1 Kjell_Magne_Bondevik 3
Gary_Winnick 1 Michael_Patrick_King 2
George_Robertson 5 Robbie_Mc_Ewen 1
Gloria_Trevi 4 William_Ragland 1
Grace_Dodd 1 Henrique_Meirelles 1
Graeme_Lloyd 1 Humberto_Coelho 1
Graeme_Lloyd 1 Laura_Pausini 1
Greg_Rusedski 2 Horace_Newcomb 1
Greg_Rusedski 3 Javier_Bardem 1
Greg_Rusedski 3 Marcos_Milinkovic 1
Gregory_Peck 1 Jacqueline_Obradors 1
Guillermo_Ruiz_Polanco 1 Jon_Constance 1
Gustavo_Kuerten 1 Rani_Mukherjee 1
Halle_Berry 12 Janet_Chandler 1
Hartmut_Mehdorn 1 Natanaela_Barnova 1
Hartmut_Mehdorn 1 Sanja_Papic 1
Hartmut_Mehdorn 1 Svetlana_Belousova 1
Haydar_Aliyev 1 Nuon_Chea 1
Heather_Willson 1 Lynn_Redgrave 3
Hector_Mitelman 1 Jon_Gruden 2
Helo_Pinheiro 1 Robert_Durst 1
Herman_Edwards 1 Patrick_Eaves 1
Hermogenes_Ebdane_Jr 1 Sanja_Papic 1
Horace_Newcomb 1 Stephan_Eberharter 1
Hugo_Colace 1 Kim_Yun-kyu 1
Humberto_Coelho 1 Sue_Wicks 2
Hunter_Bates 1 Pedro_Alvarez 1
Hunter_Bates 1 William_Rosenberg 1
Igor_Trunov 1 Peter_Sejna 1
Ivan_Stambolic 1 Michael_Bloomberg 18
Jack_LaLanne 1 Yves_Brodeur 1
Jacqueline_Obradors 1 Julie_Taymor 1
Jada_Pinkett_Smith 2 Jenny_Romero 1
James_Cunningham 3 Stephen_Daldry 1
James_Gibson 1 Roger_Corbett 1
James_Parker 1 Saeed_Mortazavi 1
Jane_Krakowski 1 Shingo_Suetsugu 1
Janice_Goldfinger 1 Pyar_Jung_Thapa 1
Janusz_Kaminski 1 Lisa_Stone 1
Jason_Lezak 1 John_Bolton 4
Jason_Lezak 1 Simon_Cowell 1
Javier_Vazquez 1 Karin_Stoiber 2
Jay_Rasulo 1 Nova_Esther_Guthrie 1
Jean-Marc_Olive 1 John_Timoney 1
Jean-Marc_Olive 1 Tino_Martinez 1
Jeri_Ryan 1 Nova_Esther_Guthrie 1
Jeri_Ryan 1 Peter_Goldmark 1
Jeri_Ryan 1 Scott_Sullivan 2
Jeri_Ryan 1 Skip_Prosser 1
Jesse_James_Leija 2 Joaquin_Phoenix 1
Jesse_James_Leija 2 Nick_Nolte 4
Jesse_Ventura 2 Lela_Rochon 1
Jessica_Biel 1 Jim_Fassel 1
Jim_Flaherty 1 Mark_Andrew 1
Jim_Tressel 3 Ralf_Schumacher 3
Jimmy_Jimenez 1 Miles_Stewart 1
Jimmy_Lee 1 Nova_Esther_Guthrie 1
Joan_Laporta 3 Roy_Romanow 1
Joaquin_Phoenix 1 Rainer_Geulen 1
Joe_Dumars 2 Timothy_McVeigh 1
John_Bolton 14 Kim_Yun-kyu 1
John_Kerr 1 Li_Changchun 1
John_Swofford 2 Sok_An 1
Juan_Fernandez 1 Paul_Krueger 1
Juan_Fernandez 1 Suzanne_Mubarak 1
Justin_Wilson 1 Larry_Hagman 1
Justin_Wilson 1 Ray_Bradbury 1
Kara_Lynn_Joyce 1 Zach_Pillar 1
Kim_Chinn 1 Robert_Flodquist 1
Kim_Chinn 1 Ruth_Harlow 2
Kim_Yong-il 2 Linda_Ham 1
Kwon_Yang-sook 3 Tommy_Robredo 1
Lane_Bryant 1 Yannos_Papantoniou 1
Larry_Hagman 1 Teddy_Kollek 1
Larry_Hagman 1 Val_Ackerman 1
Laura_Gobai 1 Robin_Wagner 1
Laura_Pausini 1 Thad_Matta 1
Laura_Romero 1 Paula_Zahn 2
Lee_Jun 1 Ruth_Pearce 1
Lee_Jun 2 Stephen_Friedman 1
Lela_Rochon 1 Michael_Haneke 1
Lela_Rochon 1 Yannos_Papantoniou 1
Lesley_Flood 1 Peter_Goldmark 1
Li_Changchun 1 Pieter_Bouw 1
Lina_Krasnoroutskaya 1 Troy_Polamalu 1
Linda_Lingle 1 Victor_Hanescu 1
Lisa_Stone 1 Rod_Paige 1
Lisa_Stone 1 Scott_Sullivan 2
Lou_Lang 1 Nova_Esther_Guthrie 1
Luc_Montagnier 1 Paul_Krueger 1
Luc_Montagnier 1 Pedro_Alvarez 1
Luc_Montagnier 1 Pierre_Pettigrew 2
Luis_Guzman 1 Patsy_Kensit 1
Marcelo_Ebrard 2 Mike_Scioscia 2
Marcelo_Rios 4 Maria_Shriver 3
Marcelo_Rios 4 Pierre_Pettigrew 1
Marcelo_Rios 4 Saeed_Mortazavi 1
Margaret_Thatcher 1 Pedro_Alvarez 1
Margaret_Thatcher 1 Salman_Rushdie 2
Maria_Simon 1 Mona_Rishmawi 1
Maria_Simon 1 Robert_Durst 1
Marlon_Devonish 1 Patrick_Clawsen 1
Max_von_Sydow 1 Zhu_Rongji 1
Mel_Karmazin 1 Pierre_Pettigrew 1
Melana_Scantlin 1 William_Ragland 1
Michael_Bloomberg 15 Ozzy_Osbourne 2
Michael_J_Fox 1 Ricky_Barnes 1
Michael_J_Fox 1 Thomas_Daily 1
Micky_Ward 1 Takenori_Kanzaki 1
Mike_Babcock 1 Tony_Parker 2
Mike_Martz 5 William_Burns 1
Mira_Sorvino 1 Simon_Cowell 2
Mira_Sorvino 1 Tom_Tunney 1
Miroljub 2 Theo_Epstein 1
Mitzi_Gaynor 1 Ruth_Harlow 1
Mohammed_Dahlan 1 Ronald_White 1
Natanaela_Barnova 1 Nuon_Chea 1
Noel_Forgeard 1 Zach_Pillar 1
Normand_Legault 1 Omar_Vizquel 1
Normand_Legault 1 Rupert_Grint 3
Nova_Esther_Guthrie 1 Stephen_Joseph 1
Ontario_Lett 1 Wallace_Capel 1
Orlando_Bloom 1 Ray_Liotta 1
Patrick_Clawsen 1 Sandra_Banning 1
Paul_Coppin 2 Rick_Husband 1
Paul_Murphy 1 Qazi_Hussain_Ahmed 1
Paul_Newman 1 Robert_Blake 3
Paula_Zahn 1 Tamara_Mowry 1
Peter_Ahearn 1 Romain_Duris 1
Peter_Gabriel 1 Peter_OToole 1
Peter_Lundgren 1 William_Rosenberg 1
Peter_OToole 1 Qazi_Afzal 1
Qais_al-Kazali 1 Ringo_Starr 1
Randy_Brown 1 Val_Ackerman 1
Rani_Mukherjee 1 Timothy_McVeigh 1
Ringo_Starr 1 Zach_Pillar 1
Roger_Corbett 1 Tocker_Pudwill 1
Ruth_Harlow 1 Virgina_Ruano_Pascal 1
Sandra_Banning 1 Wolfgang_Schneiderhan 1
Scott_Wolf 2 Troy_Polamalu 1
Sergei_Alexandrovitch_Ordzhonikidze 1 Yolanda_King 1
Shane_Loux 1 Val_Ackerman 1
Shawn_Marion 1 Shirley_Jones 1
Slobodan_Milosevic 2 Sok_An 1
================================================
FILE: requirements.txt
================================================
tensorflow==1.7
scipy
scikit-learn
opencv-python
h5py
matplotlib
Pillow
requests
psutil
================================================
FILE: src/__init__.py
================================================
# flake8: noqa
================================================
FILE: src/align/__init__.py
================================================
================================================
FILE: src/align/align_dataset_mtcnn.py
================================================
"""Performs face alignment and stores face thumbnails in the output directory."""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import sys
import os
import argparse
import tensorflow as tf
import numpy as np
import facenet
import align.detect_face
import random
from time import sleep
def main(args):
sleep(random.random())
output_dir = os.path.expanduser(args.output_dir)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Store some git revision info in a text file in the log directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, output_dir, ' '.join(sys.argv))
dataset = facenet.get_dataset(args.input_dir)
print('Creating networks and loading parameters')
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
# Add a random key to the filename to allow alignment using multiple processes
random_key = np.random.randint(0, high=99999)
bounding_boxes_filename = os.path.join(output_dir, 'bounding_boxes_%05d.txt' % random_key)
with open(bounding_boxes_filename, "w") as text_file:
nrof_images_total = 0
nrof_successfully_aligned = 0
if args.random_order:
random.shuffle(dataset)
for cls in dataset:
output_class_dir = os.path.join(output_dir, cls.name)
if not os.path.exists(output_class_dir):
os.makedirs(output_class_dir)
if args.random_order:
random.shuffle(cls.image_paths)
for image_path in cls.image_paths:
nrof_images_total += 1
filename = os.path.splitext(os.path.split(image_path)[1])[0]
output_filename = os.path.join(output_class_dir, filename+'.png')
print(image_path)
if not os.path.exists(output_filename):
try:
img = misc.imread(image_path)
except (IOError, ValueError, IndexError) as e:
errorMessage = '{}: {}'.format(image_path, e)
print(errorMessage)
else:
if img.ndim<2:
print('Unable to align "%s"' % image_path)
text_file.write('%s\n' % (output_filename))
continue
if img.ndim == 2:
img = facenet.to_rgb(img)
img = img[:,:,0:3]
bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
nrof_faces = bounding_boxes.shape[0]
if nrof_faces>0:
det = bounding_boxes[:,0:4]
det_arr = []
img_size = np.asarray(img.shape)[0:2]
if nrof_faces>1:
if args.detect_multiple_faces:
for i in range(nrof_faces):
det_arr.append(np.squeeze(det[i]))
else:
bounding_box_size = (det[:,2]-det[:,0])*(det[:,3]-det[:,1])
img_center = img_size / 2
offsets = np.vstack([ (det[:,0]+det[:,2])/2-img_center[1], (det[:,1]+det[:,3])/2-img_center[0] ])
offset_dist_squared = np.sum(np.power(offsets,2.0),0)
index = np.argmax(bounding_box_size-offset_dist_squared*2.0) # some extra weight on the centering
det_arr.append(det[index,:])
else:
det_arr.append(np.squeeze(det))
for i, det in enumerate(det_arr):
det = np.squeeze(det)
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0]-args.margin/2, 0)
bb[1] = np.maximum(det[1]-args.margin/2, 0)
bb[2] = np.minimum(det[2]+args.margin/2, img_size[1])
bb[3] = np.minimum(det[3]+args.margin/2, img_size[0])
cropped = img[bb[1]:bb[3],bb[0]:bb[2],:]
scaled = misc.imresize(cropped, (args.image_size, args.image_size), interp='bilinear')
nrof_successfully_aligned += 1
filename_base, file_extension = os.path.splitext(output_filename)
if args.detect_multiple_faces:
output_filename_n = "{}_{}{}".format(filename_base, i, file_extension)
else:
output_filename_n = "{}{}".format(filename_base, file_extension)
misc.imsave(output_filename_n, scaled)
text_file.write('%s %d %d %d %d\n' % (output_filename_n, bb[0], bb[1], bb[2], bb[3]))
else:
print('Unable to align "%s"' % image_path)
text_file.write('%s\n' % (output_filename))
print('Total number of images: %d' % nrof_images_total)
print('Number of successfully aligned images: %d' % nrof_successfully_aligned)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('input_dir', type=str, help='Directory with unaligned images.')
parser.add_argument('output_dir', type=str, help='Directory with aligned face thumbnails.')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=182)
parser.add_argument('--margin', type=int,
help='Margin for the crop around the bounding box (height, width) in pixels.', default=44)
parser.add_argument('--random_order',
help='Shuffles the order of images to enable alignment using multiple processes.', action='store_true')
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
parser.add_argument('--detect_multiple_faces', type=bool,
help='Detect and align multiple faces per image.', default=False)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/align/detect_face.py
================================================
""" Tensorflow implementation of the face detection / alignment algorithm found at
https://github.com/kpzhang93/MTCNN_face_detection_alignment
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from six import string_types, iteritems
import numpy as np
import tensorflow as tf
#from math import floor
import cv2
import os
def layer(op):
"""Decorator for composable network layers."""
def layer_decorated(self, *args, **kwargs):
# Automatically set a name if not provided.
name = kwargs.setdefault('name', self.get_unique_name(op.__name__))
# Figure out the layer inputs.
if len(self.terminals) == 0:
raise RuntimeError('No input variables found for layer %s.' % name)
elif len(self.terminals) == 1:
layer_input = self.terminals[0]
else:
layer_input = list(self.terminals)
# Perform the operation and get the output.
layer_output = op(self, layer_input, *args, **kwargs)
# Add to layer LUT.
self.layers[name] = layer_output
# This output is now the input for the next layer.
self.feed(layer_output)
# Return self for chained calls.
return self
return layer_decorated
class Network(object):
def __init__(self, inputs, trainable=True):
# The input nodes for this network
self.inputs = inputs
# The current list of terminal nodes
self.terminals = []
# Mapping from layer names to layers
self.layers = dict(inputs)
# If true, the resulting variables are set as trainable
self.trainable = trainable
self.setup()
def setup(self):
"""Construct the network. """
raise NotImplementedError('Must be implemented by the subclass.')
def load(self, data_path, session, ignore_missing=False):
"""Load network weights.
data_path: The path to the numpy-serialized network weights
session: The current TensorFlow session
ignore_missing: If true, serialized weights for missing layers are ignored.
"""
data_dict = np.load(data_path, encoding='latin1').item() #pylint: disable=no-member
for op_name in data_dict:
with tf.variable_scope(op_name, reuse=True):
for param_name, data in iteritems(data_dict[op_name]):
try:
var = tf.get_variable(param_name)
session.run(var.assign(data))
except ValueError:
if not ignore_missing:
raise
def feed(self, *args):
"""Set the input(s) for the next operation by replacing the terminal nodes.
The arguments can be either layer names or the actual layers.
"""
assert len(args) != 0
self.terminals = []
for fed_layer in args:
if isinstance(fed_layer, string_types):
try:
fed_layer = self.layers[fed_layer]
except KeyError:
raise KeyError('Unknown layer name fed: %s' % fed_layer)
self.terminals.append(fed_layer)
return self
def get_output(self):
"""Returns the current network output."""
return self.terminals[-1]
def get_unique_name(self, prefix):
"""Returns an index-suffixed unique name for the given prefix.
This is used for auto-generating layer names based on the type-prefix.
"""
ident = sum(t.startswith(prefix) for t, _ in self.layers.items()) + 1
return '%s_%d' % (prefix, ident)
def make_var(self, name, shape):
"""Creates a new TensorFlow variable."""
return tf.get_variable(name, shape, trainable=self.trainable)
def validate_padding(self, padding):
"""Verifies that the padding is one of the supported ones."""
assert padding in ('SAME', 'VALID')
@layer
def conv(self,
inp,
k_h,
k_w,
c_o,
s_h,
s_w,
name,
relu=True,
padding='SAME',
group=1,
biased=True):
# Verify that the padding is acceptable
self.validate_padding(padding)
# Get the number of channels in the input
c_i = int(inp.get_shape()[-1])
# Verify that the grouping parameter is valid
assert c_i % group == 0
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:
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)
# Add the biases
if biased:
biases = self.make_var('biases', [c_o])
output = tf.nn.bias_add(output, biases)
if relu:
# ReLU non-linearity
output = tf.nn.relu(output, name=scope.name)
return output
@layer
def prelu(self, inp, name):
with tf.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))
return output
@layer
def max_pool(self, inp, k_h, k_w, s_h, s_w, name, padding='SAME'):
self.validate_padding(padding)
return tf.nn.max_pool(inp,
ksize=[1, k_h, k_w, 1],
strides=[1, s_h, s_w, 1],
padding=padding,
name=name)
@layer
def fc(self, inp, num_out, name, relu=True):
with tf.variable_scope(name):
input_shape = inp.get_shape()
if input_shape.ndims == 4:
# The input is spatial. Vectorize it first.
dim = 1
for d in input_shape[1:].as_list():
dim *= int(d)
feed_in = tf.reshape(inp, [-1, dim])
else:
feed_in, dim = (inp, input_shape[-1].value)
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)
return fc
"""
Multi dimensional softmax,
refer to https://github.com/tensorflow/tensorflow/issues/210
compute softmax along the dimension of target
the native softmax only supports batch_size x dimension
"""
@layer
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)
return softmax
class PNet(Network):
def setup(self):
(self.feed('data') #pylint: disable=no-value-for-parameter, no-member
.conv(3, 3, 10, 1, 1, padding='VALID', relu=False, name='conv1')
.prelu(name='PReLU1')
.max_pool(2, 2, 2, 2, name='pool1')
.conv(3, 3, 16, 1, 1, padding='VALID', relu=False, name='conv2')
.prelu(name='PReLU2')
.conv(3, 3, 32, 1, 1, padding='VALID', relu=False, name='conv3')
.prelu(name='PReLU3')
.conv(1, 1, 2, 1, 1, relu=False, name='conv4-1')
.softmax(3,name='prob1'))
(self.feed('PReLU3') #pylint: disable=no-value-for-parameter
.conv(1, 1, 4, 1, 1, relu=False, name='conv4-2'))
class RNet(Network):
def setup(self):
(self.feed('data') #pylint: disable=no-value-for-parameter, no-member
.conv(3, 3, 28, 1, 1, padding='VALID', relu=False, name='conv1')
.prelu(name='prelu1')
.max_pool(3, 3, 2, 2, name='pool1')
.conv(3, 3, 48, 1, 1, padding='VALID', relu=False, name='conv2')
.prelu(name='prelu2')
.max_pool(3, 3, 2, 2, padding='VALID', name='pool2')
.conv(2, 2, 64, 1, 1, padding='VALID', relu=False, name='conv3')
.prelu(name='prelu3')
.fc(128, relu=False, name='conv4')
.prelu(name='prelu4')
.fc(2, relu=False, name='conv5-1')
.softmax(1,name='prob1'))
(self.feed('prelu4') #pylint: disable=no-value-for-parameter
.fc(4, relu=False, name='conv5-2'))
class ONet(Network):
def setup(self):
(self.feed('data') #pylint: disable=no-value-for-parameter, no-member
.conv(3, 3, 32, 1, 1, padding='VALID', relu=False, name='conv1')
.prelu(name='prelu1')
.max_pool(3, 3, 2, 2, name='pool1')
.conv(3, 3, 64, 1, 1, padding='VALID', relu=False, name='conv2')
.prelu(name='prelu2')
.max_pool(3, 3, 2, 2, padding='VALID', name='pool2')
.conv(3, 3, 64, 1, 1, padding='VALID', relu=False, name='conv3')
.prelu(name='prelu3')
.max_pool(2, 2, 2, 2, name='pool3')
.conv(2, 2, 128, 1, 1, padding='VALID', relu=False, name='conv4')
.prelu(name='prelu4')
.fc(256, relu=False, name='conv5')
.prelu(name='prelu5')
.fc(2, relu=False, name='conv6-1')
.softmax(1, name='prob1'))
(self.feed('prelu5') #pylint: disable=no-value-for-parameter
.fc(4, relu=False, name='conv6-2'))
(self.feed('prelu5') #pylint: disable=no-value-for-parameter
.fc(10, relu=False, name='conv6-3'))
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')
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')
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')
onet = ONet({'data':data})
onet.load(os.path.join(model_path, 'det3.npy'), sess)
pnet_fun = lambda img : sess.run(('pnet/conv4-2/BiasAdd:0', 'pnet/prob1:0'), feed_dict={'pnet/input:0':img})
rnet_fun = lambda img : sess.run(('rnet/conv5-2/conv5-2:0', 'rnet/prob1:0'), feed_dict={'rnet/input:0':img})
onet_fun = lambda img : sess.run(('onet/conv6-2/conv6-2:0', 'onet/conv6-3/conv6-3:0', 'onet/prob1:0'), feed_dict={'onet/input:0':img})
return pnet_fun, rnet_fun, onet_fun
def detect_face(img, minsize, pnet, rnet, onet, threshold, factor):
"""Detects faces in an image, and returns bounding boxes and points for them.
img: input image
minsize: minimum faces' size
pnet, rnet, onet: caffemodel
threshold: threshold=[th1, th2, th3], th1-3 are three steps's threshold
factor: the factor used to create a scaling pyramid of face sizes to detect in the image.
"""
factor_count=0
total_boxes=np.empty((0,9))
points=np.empty(0)
h=img.shape[0]
w=img.shape[1]
minl=np.amin([h, w])
m=12.0/minsize
minl=minl*m
# create scale pyramid
scales=[]
while minl>=12:
scales += [m*np.power(factor, factor_count)]
minl = minl*factor
factor_count += 1
# first stage
for scale in scales:
hs=int(np.ceil(h*scale))
ws=int(np.ceil(w*scale))
im_data = imresample(img, (hs, ws))
im_data = (im_data-127.5)*0.0078125
img_x = np.expand_dims(im_data, 0)
img_y = np.transpose(img_x, (0,2,1,3))
out = pnet(img_y)
out0 = np.transpose(out[0], (0,2,1,3))
out1 = np.transpose(out[1], (0,2,1,3))
boxes, _ = generateBoundingBox(out1[0,:,:,1].copy(), out0[0,:,:,:].copy(), scale, threshold[0])
# inter-scale nms
pick = nms(boxes.copy(), 0.5, 'Union')
if boxes.size>0 and pick.size>0:
boxes = boxes[pick,:]
total_boxes = np.append(total_boxes, boxes, axis=0)
numbox = total_boxes.shape[0]
if numbox>0:
pick = nms(total_boxes.copy(), 0.7, 'Union')
total_boxes = total_boxes[pick,:]
regw = total_boxes[:,2]-total_boxes[:,0]
regh = total_boxes[:,3]-total_boxes[:,1]
qq1 = total_boxes[:,0]+total_boxes[:,5]*regw
qq2 = total_boxes[:,1]+total_boxes[:,6]*regh
qq3 = total_boxes[:,2]+total_boxes[:,7]*regw
qq4 = total_boxes[:,3]+total_boxes[:,8]*regh
total_boxes = np.transpose(np.vstack([qq1, qq2, qq3, qq4, total_boxes[:,4]]))
total_boxes = rerec(total_boxes.copy())
total_boxes[:,0:4] = np.fix(total_boxes[:,0:4]).astype(np.int32)
dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(total_boxes.copy(), w, h)
numbox = total_boxes.shape[0]
if numbox>0:
# second stage
tempimg = np.zeros((24,24,3,numbox))
for k in range(0,numbox):
tmp = np.zeros((int(tmph[k]),int(tmpw[k]),3))
tmp[dy[k]-1:edy[k],dx[k]-1:edx[k],:] = img[y[k]-1:ey[k],x[k]-1:ex[k],:]
if tmp.shape[0]>0 and tmp.shape[1]>0 or tmp.shape[0]==0 and tmp.shape[1]==0:
tempimg[:,:,:,k] = imresample(tmp, (24, 24))
else:
return np.empty()
tempimg = (tempimg-127.5)*0.0078125
tempimg1 = np.transpose(tempimg, (3,1,0,2))
out = rnet(tempimg1)
out0 = np.transpose(out[0])
out1 = np.transpose(out[1])
score = out1[1,:]
ipass = np.where(score>threshold[1])
total_boxes = np.hstack([total_boxes[ipass[0],0:4].copy(), np.expand_dims(score[ipass].copy(),1)])
mv = out0[:,ipass[0]]
if total_boxes.shape[0]>0:
pick = nms(total_boxes, 0.7, 'Union')
total_boxes = total_boxes[pick,:]
total_boxes = bbreg(total_boxes.copy(), np.transpose(mv[:,pick]))
total_boxes = rerec(total_boxes.copy())
numbox = total_boxes.shape[0]
if numbox>0:
# third stage
total_boxes = np.fix(total_boxes).astype(np.int32)
dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(total_boxes.copy(), w, h)
tempimg = np.zeros((48,48,3,numbox))
for k in range(0,numbox):
tmp = np.zeros((int(tmph[k]),int(tmpw[k]),3))
tmp[dy[k]-1:edy[k],dx[k]-1:edx[k],:] = img[y[k]-1:ey[k],x[k]-1:ex[k],:]
if tmp.shape[0]>0 and tmp.shape[1]>0 or tmp.shape[0]==0 and tmp.shape[1]==0:
tempimg[:,:,:,k] = imresample(tmp, (48, 48))
else:
return np.empty()
tempimg = (tempimg-127.5)*0.0078125
tempimg1 = np.transpose(tempimg, (3,1,0,2))
out = onet(tempimg1)
out0 = np.transpose(out[0])
out1 = np.transpose(out[1])
out2 = np.transpose(out[2])
score = out2[1,:]
points = out1
ipass = np.where(score>threshold[2])
points = points[:,ipass[0]]
total_boxes = np.hstack([total_boxes[ipass[0],0:4].copy(), np.expand_dims(score[ipass].copy(),1)])
mv = out0[:,ipass[0]]
w = total_boxes[:,2]-total_boxes[:,0]+1
h = total_boxes[:,3]-total_boxes[:,1]+1
points[0:5,:] = np.tile(w,(5, 1))*points[0:5,:] + np.tile(total_boxes[:,0],(5, 1))-1
points[5:10,:] = np.tile(h,(5, 1))*points[5:10,:] + np.tile(total_boxes[:,1],(5, 1))-1
if total_boxes.shape[0]>0:
total_boxes = bbreg(total_boxes.copy(), np.transpose(mv))
pick = nms(total_boxes.copy(), 0.7, 'Min')
total_boxes = total_boxes[pick,:]
points = points[:,pick]
return total_boxes, points
def bulk_detect_face(images, detection_window_size_ratio, pnet, rnet, onet, threshold, factor):
"""Detects faces in a list of images
images: list containing input images
detection_window_size_ratio: ratio of minimum face size to smallest image dimension
pnet, rnet, onet: caffemodel
threshold: threshold=[th1 th2 th3], th1-3 are three steps's threshold [0-1]
factor: the factor used to create a scaling pyramid of face sizes to detect in the image.
"""
all_scales = [None] * len(images)
images_with_boxes = [None] * len(images)
for i in range(len(images)):
images_with_boxes[i] = {'total_boxes': np.empty((0, 9))}
# create scale pyramid
for index, img in enumerate(images):
all_scales[index] = []
h = img.shape[0]
w = img.shape[1]
minsize = int(detection_window_size_ratio * np.minimum(w, h))
factor_count = 0
minl = np.amin([h, w])
if minsize <= 12:
minsize = 12
m = 12.0 / minsize
minl = minl * m
while minl >= 12:
all_scales[index].append(m * np.power(factor, factor_count))
minl = minl * factor
factor_count += 1
# # # # # # # # # # # # #
# first stage - fast proposal network (pnet) to obtain face candidates
# # # # # # # # # # # # #
images_obj_per_resolution = {}
# TODO: use some type of rounding to number module 8 to increase probability that pyramid images will have the same resolution across input images
for index, scales in enumerate(all_scales):
h = images[index].shape[0]
w = images[index].shape[1]
for scale in scales:
hs = int(np.ceil(h * scale))
ws = int(np.ceil(w * scale))
if (ws, hs) not in images_obj_per_resolution:
images_obj_per_resolution[(ws, hs)] = []
im_data = imresample(images[index], (hs, ws))
im_data = (im_data - 127.5) * 0.0078125
img_y = np.transpose(im_data, (1, 0, 2)) # caffe uses different dimensions ordering
images_obj_per_resolution[(ws, hs)].append({'scale': scale, 'image': img_y, 'index': index})
for resolution in images_obj_per_resolution:
images_per_resolution = [i['image'] for i in images_obj_per_resolution[resolution]]
outs = pnet(images_per_resolution)
for index in range(len(outs[0])):
scale = images_obj_per_resolution[resolution][index]['scale']
image_index = images_obj_per_resolution[resolution][index]['index']
out0 = np.transpose(outs[0][index], (1, 0, 2))
out1 = np.transpose(outs[1][index], (1, 0, 2))
boxes, _ = generateBoundingBox(out1[:, :, 1].copy(), out0[:, :, :].copy(), scale, threshold[0])
# inter-scale nms
pick = nms(boxes.copy(), 0.5, 'Union')
if boxes.size > 0 and pick.size > 0:
boxes = boxes[pick, :]
images_with_boxes[image_index]['total_boxes'] = np.append(images_with_boxes[image_index]['total_boxes'],
boxes,
axis=0)
for index, image_obj in enumerate(images_with_boxes):
numbox = image_obj['total_boxes'].shape[0]
if numbox > 0:
h = images[index].shape[0]
w = images[index].shape[1]
pick = nms(image_obj['total_boxes'].copy(), 0.7, 'Union')
image_obj['total_boxes'] = image_obj['total_boxes'][pick, :]
regw = image_obj['total_boxes'][:, 2] - image_obj['total_boxes'][:, 0]
regh = image_obj['total_boxes'][:, 3] - image_obj['total_boxes'][:, 1]
qq1 = image_obj['total_boxes'][:, 0] + image_obj['total_boxes'][:, 5] * regw
qq2 = image_obj['total_boxes'][:, 1] + image_obj['total_boxes'][:, 6] * regh
qq3 = image_obj['total_boxes'][:, 2] + image_obj['total_boxes'][:, 7] * regw
qq4 = image_obj['total_boxes'][:, 3] + image_obj['total_boxes'][:, 8] * regh
image_obj['total_boxes'] = np.transpose(np.vstack([qq1, qq2, qq3, qq4, image_obj['total_boxes'][:, 4]]))
image_obj['total_boxes'] = rerec(image_obj['total_boxes'].copy())
image_obj['total_boxes'][:, 0:4] = np.fix(image_obj['total_boxes'][:, 0:4]).astype(np.int32)
dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(image_obj['total_boxes'].copy(), w, h)
numbox = image_obj['total_boxes'].shape[0]
tempimg = np.zeros((24, 24, 3, numbox))
if numbox > 0:
for k in range(0, numbox):
tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
tmp[dy[k] - 1:edy[k], dx[k] - 1:edx[k], :] = images[index][y[k] - 1:ey[k], x[k] - 1:ex[k], :]
if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0:
tempimg[:, :, :, k] = imresample(tmp, (24, 24))
else:
return np.empty()
tempimg = (tempimg - 127.5) * 0.0078125
image_obj['rnet_input'] = np.transpose(tempimg, (3, 1, 0, 2))
# # # # # # # # # # # # #
# second stage - refinement of face candidates with rnet
# # # # # # # # # # # # #
bulk_rnet_input = np.empty((0, 24, 24, 3))
for index, image_obj in enumerate(images_with_boxes):
if 'rnet_input' in image_obj:
bulk_rnet_input = np.append(bulk_rnet_input, image_obj['rnet_input'], axis=0)
out = rnet(bulk_rnet_input)
out0 = np.transpose(out[0])
out1 = np.transpose(out[1])
score = out1[1, :]
i = 0
for index, image_obj in enumerate(images_with_boxes):
if 'rnet_input' not in image_obj:
continue
rnet_input_count = image_obj['rnet_input'].shape[0]
score_per_image = score[i:i + rnet_input_count]
out0_per_image = out0[:, i:i + rnet_input_count]
ipass = np.where(score_per_image > threshold[1])
image_obj['total_boxes'] = np.hstack([image_obj['total_boxes'][ipass[0], 0:4].copy(),
np.expand_dims(score_per_image[ipass].copy(), 1)])
mv = out0_per_image[:, ipass[0]]
if image_obj['total_boxes'].shape[0] > 0:
h = images[index].shape[0]
w = images[index].shape[1]
pick = nms(image_obj['total_boxes'], 0.7, 'Union')
image_obj['total_boxes'] = image_obj['total_boxes'][pick, :]
image_obj['total_boxes'] = bbreg(image_obj['total_boxes'].copy(), np.transpose(mv[:, pick]))
image_obj['total_boxes'] = rerec(image_obj['total_boxes'].copy())
numbox = image_obj['total_boxes'].shape[0]
if numbox > 0:
tempimg = np.zeros((48, 48, 3, numbox))
image_obj['total_boxes'] = np.fix(image_obj['total_boxes']).astype(np.int32)
dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(image_obj['total_boxes'].copy(), w, h)
for k in range(0, numbox):
tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
tmp[dy[k] - 1:edy[k], dx[k] - 1:edx[k], :] = images[index][y[k] - 1:ey[k], x[k] - 1:ex[k], :]
if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0:
tempimg[:, :, :, k] = imresample(tmp, (48, 48))
else:
return np.empty()
tempimg = (tempimg - 127.5) * 0.0078125
image_obj['onet_input'] = np.transpose(tempimg, (3, 1, 0, 2))
i += rnet_input_count
# # # # # # # # # # # # #
# third stage - further refinement and facial landmarks positions with onet
# # # # # # # # # # # # #
bulk_onet_input = np.empty((0, 48, 48, 3))
for index, image_obj in enumerate(images_with_boxes):
if 'onet_input' in image_obj:
bulk_onet_input = np.append(bulk_onet_input, image_obj['onet_input'], axis=0)
out = onet(bulk_onet_input)
out0 = np.transpose(out[0])
out1 = np.transpose(out[1])
out2 = np.transpose(out[2])
score = out2[1, :]
points = out1
i = 0
ret = []
for index, image_obj in enumerate(images_with_boxes):
if 'onet_input' not in image_obj:
ret.append(None)
continue
onet_input_count = image_obj['onet_input'].shape[0]
out0_per_image = out0[:, i:i + onet_input_count]
score_per_image = score[i:i + onet_input_count]
points_per_image = points[:, i:i + onet_input_count]
ipass = np.where(score_per_image > threshold[2])
points_per_image = points_per_image[:, ipass[0]]
image_obj['total_boxes'] = np.hstack([image_obj['total_boxes'][ipass[0], 0:4].copy(),
np.expand_dims(score_per_image[ipass].copy(), 1)])
mv = out0_per_image[:, ipass[0]]
w = image_obj['total_boxes'][:, 2] - image_obj['total_boxes'][:, 0] + 1
h = image_obj['total_boxes'][:, 3] - image_obj['total_boxes'][:, 1] + 1
points_per_image[0:5, :] = np.tile(w, (5, 1)) * points_per_image[0:5, :] + np.tile(
image_obj['total_boxes'][:, 0], (5, 1)) - 1
points_per_image[5:10, :] = np.tile(h, (5, 1)) * points_per_image[5:10, :] + np.tile(
image_obj['total_boxes'][:, 1], (5, 1)) - 1
if image_obj['total_boxes'].shape[0] > 0:
image_obj['total_boxes'] = bbreg(image_obj['total_boxes'].copy(), np.transpose(mv))
pick = nms(image_obj['total_boxes'].copy(), 0.7, 'Min')
image_obj['total_boxes'] = image_obj['total_boxes'][pick, :]
points_per_image = points_per_image[:, pick]
ret.append((image_obj['total_boxes'], points_per_image))
else:
ret.append(None)
i += onet_input_count
return ret
# function [boundingbox] = bbreg(boundingbox,reg)
def bbreg(boundingbox,reg):
"""Calibrate bounding boxes"""
if reg.shape[1]==1:
reg = np.reshape(reg, (reg.shape[2], reg.shape[3]))
w = boundingbox[:,2]-boundingbox[:,0]+1
h = boundingbox[:,3]-boundingbox[:,1]+1
b1 = boundingbox[:,0]+reg[:,0]*w
b2 = boundingbox[:,1]+reg[:,1]*h
b3 = boundingbox[:,2]+reg[:,2]*w
b4 = boundingbox[:,3]+reg[:,3]*h
boundingbox[:,0:4] = np.transpose(np.vstack([b1, b2, b3, b4 ]))
return boundingbox
def generateBoundingBox(imap, reg, scale, t):
"""Use heatmap to generate bounding boxes"""
stride=2
cellsize=12
imap = np.transpose(imap)
dx1 = np.transpose(reg[:,:,0])
dy1 = np.transpose(reg[:,:,1])
dx2 = np.transpose(reg[:,:,2])
dy2 = np.transpose(reg[:,:,3])
y, x = np.where(imap >= t)
if y.shape[0]==1:
dx1 = np.flipud(dx1)
dy1 = np.flipud(dy1)
dx2 = np.flipud(dx2)
dy2 = np.flipud(dy2)
score = imap[(y,x)]
reg = np.transpose(np.vstack([ dx1[(y,x)], dy1[(y,x)], dx2[(y,x)], dy2[(y,x)] ]))
if reg.size==0:
reg = np.empty((0,3))
bb = np.transpose(np.vstack([y,x]))
q1 = np.fix((stride*bb+1)/scale)
q2 = np.fix((stride*bb+cellsize-1+1)/scale)
boundingbox = np.hstack([q1, q2, np.expand_dims(score,1), reg])
return boundingbox, reg
# function pick = nms(boxes,threshold,type)
def nms(boxes, threshold, method):
if boxes.size==0:
return np.empty((0,3))
x1 = boxes[:,0]
y1 = boxes[:,1]
x2 = boxes[:,2]
y2 = boxes[:,3]
s = boxes[:,4]
area = (x2-x1+1) * (y2-y1+1)
I = np.argsort(s)
pick = np.zeros_like(s, dtype=np.int16)
counter = 0
while I.size>0:
i = I[-1]
pick[counter] = i
counter += 1
idx = I[0:-1]
xx1 = np.maximum(x1[i], x1[idx])
yy1 = np.maximum(y1[i], y1[idx])
xx2 = np.minimum(x2[i], x2[idx])
yy2 = np.minimum(y2[i], y2[idx])
w = np.maximum(0.0, xx2-xx1+1)
h = np.maximum(0.0, yy2-yy1+1)
inter = w * h
if method is 'Min':
o = inter / np.minimum(area[i], area[idx])
else:
o = inter / (area[i] + area[idx] - inter)
I = I[np.where(o<=threshold)]
pick = pick[0:counter]
return pick
# function [dy edy dx edx y ey x ex tmpw tmph] = pad(total_boxes,w,h)
def pad(total_boxes, w, h):
"""Compute the padding coordinates (pad the bounding boxes to square)"""
tmpw = (total_boxes[:,2]-total_boxes[:,0]+1).astype(np.int32)
tmph = (total_boxes[:,3]-total_boxes[:,1]+1).astype(np.int32)
numbox = total_boxes.shape[0]
dx = np.ones((numbox), dtype=np.int32)
dy = np.ones((numbox), dtype=np.int32)
edx = tmpw.copy().astype(np.int32)
edy = tmph.copy().astype(np.int32)
x = total_boxes[:,0].copy().astype(np.int32)
y = total_boxes[:,1].copy().astype(np.int32)
ex = total_boxes[:,2].copy().astype(np.int32)
ey = total_boxes[:,3].copy().astype(np.int32)
tmp = np.where(ex>w)
edx.flat[tmp] = np.expand_dims(-ex[tmp]+w+tmpw[tmp],1)
ex[tmp] = w
tmp = np.where(ey>h)
edy.flat[tmp] = np.expand_dims(-ey[tmp]+h+tmph[tmp],1)
ey[tmp] = h
tmp = np.where(x<1)
dx.flat[tmp] = np.expand_dims(2-x[tmp],1)
x[tmp] = 1
tmp = np.where(y<1)
dy.flat[tmp] = np.expand_dims(2-y[tmp],1)
y[tmp] = 1
return dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph
# function [bboxA] = rerec(bboxA)
def rerec(bboxA):
"""Convert bboxA to square."""
h = bboxA[:,3]-bboxA[:,1]
w = bboxA[:,2]-bboxA[:,0]
l = np.maximum(w, h)
bboxA[:,0] = bboxA[:,0]+w*0.5-l*0.5
bboxA[:,1] = bboxA[:,1]+h*0.5-l*0.5
bboxA[:,2:4] = bboxA[:,0:2] + np.transpose(np.tile(l,(2,1)))
return bboxA
def imresample(img, sz):
im_data = cv2.resize(img, (sz[1], sz[0]), interpolation=cv2.INTER_AREA) #@UndefinedVariable
return im_data
# This method is kept for debugging purpose
# h=img.shape[0]
# w=img.shape[1]
# hs, ws = sz
# dx = float(w) / ws
# dy = float(h) / hs
# im_data = np.zeros((hs,ws,3))
# for a1 in range(0,hs):
# for a2 in range(0,ws):
# for a3 in range(0,3):
# im_data[a1,a2,a3] = img[int(floor(a1*dy)),int(floor(a2*dx)),a3]
# return im_data
================================================
FILE: src/calculate_filtering_metrics.py
================================================
"""Calculate filtering metrics for a dataset and store in a .hdf file.
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import numpy as np
import argparse
import facenet
import os
import sys
import time
import h5py
import math
from tensorflow.python.platform import gfile
from six import iteritems
def main(args):
dataset = facenet.get_dataset(args.dataset_dir)
with tf.Graph().as_default():
# Get a list of image paths and their labels
image_list, label_list = facenet.get_image_paths_and_labels(dataset)
nrof_images = len(image_list)
image_indices = range(nrof_images)
image_batch, label_batch = facenet.read_and_augment_data(image_list,
image_indices, args.image_size, args.batch_size, None,
False, False, False, nrof_preprocess_threads=4, shuffle=False)
model_exp = os.path.expanduser(args.model_file)
with gfile.FastGFile(model_exp,'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
input_map={'input':image_batch, 'phase_train':False}
tf.import_graph_def(graph_def, input_map=input_map, name='net')
embeddings = tf.get_default_graph().get_tensor_by_name("net/embeddings:0")
with tf.Session() as sess:
tf.train.start_queue_runners(sess=sess)
embedding_size = int(embeddings.get_shape()[1])
nrof_batches = int(math.ceil(nrof_images / args.batch_size))
nrof_classes = len(dataset)
label_array = np.array(label_list)
class_names = [cls.name for cls in dataset]
nrof_examples_per_class = [ len(cls.image_paths) for cls in dataset ]
class_variance = np.zeros((nrof_classes,))
class_center = np.zeros((nrof_classes,embedding_size))
distance_to_center = np.ones((len(label_list),))*np.NaN
emb_array = np.zeros((0,embedding_size))
idx_array = np.zeros((0,), dtype=np.int32)
lab_array = np.zeros((0,), dtype=np.int32)
index_arr = np.append(0, np.cumsum(nrof_examples_per_class))
for i in range(nrof_batches):
t = time.time()
emb, idx = sess.run([embeddings, label_batch])
emb_array = np.append(emb_array, emb, axis=0)
idx_array = np.append(idx_array, idx, axis=0)
lab_array = np.append(lab_array, label_array[idx], axis=0)
for cls in set(lab_array):
cls_idx = np.where(lab_array==cls)[0]
if cls_idx.shape[0]==nrof_examples_per_class[cls]:
# We have calculated all the embeddings for this class
i2 = np.argsort(idx_array[cls_idx])
emb_class = emb_array[cls_idx,:]
emb_sort = emb_class[i2,:]
center = np.mean(emb_sort, axis=0)
diffs = emb_sort - center
dists_sqr = np.sum(np.square(diffs), axis=1)
class_variance[cls] = np.mean(dists_sqr)
class_center[cls,:] = center
distance_to_center[index_arr[cls]:index_arr[cls+1]] = np.sqrt(dists_sqr)
emb_array = np.delete(emb_array, cls_idx, axis=0)
idx_array = np.delete(idx_array, cls_idx, axis=0)
lab_array = np.delete(lab_array, cls_idx, axis=0)
print('Batch %d in %.3f seconds' % (i, time.time()-t))
print('Writing filtering data to %s' % args.data_file_name)
mdict = {'class_names':class_names, 'image_list':image_list, 'label_list':label_list, 'distance_to_center':distance_to_center }
with h5py.File(args.data_file_name, 'w') as f:
for key, value in iteritems(mdict):
f.create_dataset(key, data=value)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('dataset_dir', type=str,
help='Path to the directory containing aligned dataset.')
parser.add_argument('model_file', type=str,
help='File containing the frozen model in protobuf (.pb) format to use for feature extraction.')
parser.add_argument('data_file_name', type=str,
help='The name of the file to store filtering data in.')
parser.add_argument('--image_size', type=int,
help='Image size.', default=160)
parser.add_argument('--batch_size', type=int,
help='Number of images to process in a batch.', default=90)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/classifier.py
================================================
"""An example of how to use your own dataset to train a classifier that recognizes people.
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import numpy as np
import argparse
import facenet
import os
import sys
import math
import pickle
from sklearn.svm import SVC
def main(args):
with tf.Graph().as_default():
with tf.Session() as sess:
np.random.seed(seed=args.seed)
if args.use_split_dataset:
dataset_tmp = facenet.get_dataset(args.data_dir)
train_set, test_set = split_dataset(dataset_tmp, args.min_nrof_images_per_class, args.nrof_train_images_per_class)
if (args.mode=='TRAIN'):
dataset = train_set
elif (args.mode=='CLASSIFY'):
dataset = test_set
else:
dataset = facenet.get_dataset(args.data_dir)
# Check that there are at least one training image per class
for cls in dataset:
assert(len(cls.image_paths)>0, 'There must be at least one image for each class in the dataset')
paths, labels = facenet.get_image_paths_and_labels(dataset)
print('Number of classes: %d' % len(dataset))
print('Number of images: %d' % len(paths))
# Load the model
print('Loading feature extraction model')
facenet.load_model(args.model)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
embedding_size = embeddings.get_shape()[1]
# Run forward pass to calculate embeddings
print('Calculating features for images')
nrof_images = len(paths)
nrof_batches_per_epoch = int(math.ceil(1.0*nrof_images / args.batch_size))
emb_array = np.zeros((nrof_images, embedding_size))
for i in range(nrof_batches_per_epoch):
start_index = i*args.batch_size
end_index = min((i+1)*args.batch_size, nrof_images)
paths_batch = paths[start_index:end_index]
images = facenet.load_data(paths_batch, False, False, args.image_size)
feed_dict = { images_placeholder:images, phase_train_placeholder:False }
emb_array[start_index:end_index,:] = sess.run(embeddings, feed_dict=feed_dict)
classifier_filename_exp = os.path.expanduser(args.classifier_filename)
if (args.mode=='TRAIN'):
# Train classifier
print('Training classifier')
model = SVC(kernel='linear', probability=True)
model.fit(emb_array, labels)
# Create a list of class names
class_names = [ cls.name.replace('_', ' ') for cls in dataset]
# Saving classifier model
with open(classifier_filename_exp, 'wb') as outfile:
pickle.dump((model, class_names), outfile)
print('Saved classifier model to file "%s"' % classifier_filename_exp)
elif (args.mode=='CLASSIFY'):
# Classify images
print('Testing classifier')
with open(classifier_filename_exp, 'rb') as infile:
(model, class_names) = pickle.load(infile)
print('Loaded classifier model from file "%s"' % classifier_filename_exp)
predictions = model.predict_proba(emb_array)
best_class_indices = np.argmax(predictions, axis=1)
best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices]
for i in range(len(best_class_indices)):
print('%4d %s: %.3f' % (i, class_names[best_class_indices[i]], best_class_probabilities[i]))
accuracy = np.mean(np.equal(best_class_indices, labels))
print('Accuracy: %.3f' % accuracy)
def split_dataset(dataset, min_nrof_images_per_class, nrof_train_images_per_class):
train_set = []
test_set = []
for cls in dataset:
paths = cls.image_paths
# Remove classes with less than min_nrof_images_per_class
if len(paths)>=min_nrof_images_per_class:
np.random.shuffle(paths)
train_set.append(facenet.ImageClass(cls.name, paths[:nrof_train_images_per_class]))
test_set.append(facenet.ImageClass(cls.name, paths[nrof_train_images_per_class:]))
return train_set, test_set
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('mode', type=str, choices=['TRAIN', 'CLASSIFY'],
help='Indicates if a new classifier should be trained or a classification ' +
'model should be used for classification', default='CLASSIFY')
parser.add_argument('data_dir', type=str,
help='Path to the data directory containing aligned LFW face patches.')
parser.add_argument('model', type=str,
help='Could be either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file')
parser.add_argument('classifier_filename',
help='Classifier model file name as a pickle (.pkl) file. ' +
'For training this is the output and for classification this is an input.')
parser.add_argument('--use_split_dataset',
help='Indicates that the dataset specified by data_dir should be split into a training and test set. ' +
'Otherwise a separate test set can be specified using the test_data_dir option.', action='store_true')
parser.add_argument('--test_data_dir', type=str,
help='Path to the test data directory containing aligned images used for testing.')
parser.add_argument('--batch_size', type=int,
help='Number of images to process in a batch.', default=90)
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
parser.add_argument('--min_nrof_images_per_class', type=int,
help='Only include classes with at least this number of images in the dataset', default=20)
parser.add_argument('--nrof_train_images_per_class', type=int,
help='Use this number of images from each class for training and the rest for testing', default=10)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/compare.py
================================================
"""Performs face alignment and calculates L2 distance between the embeddings of images."""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import tensorflow as tf
import numpy as np
import sys
import os
import copy
import argparse
import facenet
import align.detect_face
def main(args):
images = load_and_align_data(args.image_files, args.image_size, args.margin, args.gpu_memory_fraction)
with tf.Graph().as_default():
with tf.Session() as sess:
# Load the model
facenet.load_model(args.model)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
# Run forward pass to calculate embeddings
feed_dict = { images_placeholder: images, phase_train_placeholder:False }
emb = sess.run(embeddings, feed_dict=feed_dict)
nrof_images = len(args.image_files)
print('Images:')
for i in range(nrof_images):
print('%1d: %s' % (i, args.image_files[i]))
print('')
# Print distance matrix
print('Distance matrix')
print(' ', end='')
for i in range(nrof_images):
print(' %1d ' % i, end='')
print('')
for i in range(nrof_images):
print('%1d ' % i, end='')
for j in range(nrof_images):
dist = np.sqrt(np.sum(np.square(np.subtract(emb[i,:], emb[j,:]))))
print(' %1.4f ' % dist, end='')
print('')
def load_and_align_data(image_paths, image_size, margin, gpu_memory_fraction):
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
print('Creating networks and loading parameters')
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
tmp_image_paths=copy.copy(image_paths)
img_list = []
for image in tmp_image_paths:
img = misc.imread(os.path.expanduser(image), mode='RGB')
img_size = np.asarray(img.shape)[0:2]
bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
if len(bounding_boxes) < 1:
image_paths.remove(image)
print("can't detect face, remove ", image)
continue
det = np.squeeze(bounding_boxes[0,0:4])
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0]-margin/2, 0)
bb[1] = np.maximum(det[1]-margin/2, 0)
bb[2] = np.minimum(det[2]+margin/2, img_size[1])
bb[3] = np.minimum(det[3]+margin/2, img_size[0])
cropped = img[bb[1]:bb[3],bb[0]:bb[2],:]
aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
prewhitened = facenet.prewhiten(aligned)
img_list.append(prewhitened)
images = np.stack(img_list)
return images
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('model', type=str,
help='Could be either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file')
parser.add_argument('image_files', type=str, nargs='+', help='Images to compare')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--margin', type=int,
help='Margin for the crop around the bounding box (height, width) in pixels.', default=44)
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/decode_msceleb_dataset.py
================================================
"""Decode the MsCelebV1 dataset in TSV (tab separated values) format downloaded from
https://www.microsoft.com/en-us/research/project/ms-celeb-1m-challenge-recognizing-one-million-celebrities-real-world/
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import numpy as np
import base64
import sys
import os
import cv2
import argparse
import facenet
# File format: text files, each line is an image record containing 6 columns, delimited by TAB.
# Column1: Freebase MID
# Column2: Query/Name
# Column3: ImageSearchRank
# Column4: ImageURL
# Column5: PageURL
# Column6: ImageData_Base64Encoded
def main(args):
output_dir = os.path.expanduser(args.output_dir)
if not os.path.exists(output_dir):
os.mkdir(output_dir)
# Store some git revision info in a text file in the output directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, output_dir, ' '.join(sys.argv))
i = 0
for f in args.tsv_files:
for line in f:
fields = line.split('\t')
class_dir = fields[0]
img_name = fields[1] + '-' + fields[4] + '.' + args.output_format
img_string = fields[5]
img_dec_string = base64.b64decode(img_string)
img_data = np.fromstring(img_dec_string, dtype=np.uint8)
img = cv2.imdecode(img_data, cv2.IMREAD_COLOR) #pylint: disable=maybe-no-member
if args.size:
img = misc.imresize(img, (args.size, args.size), interp='bilinear')
full_class_dir = os.path.join(output_dir, class_dir)
if not os.path.exists(full_class_dir):
os.mkdir(full_class_dir)
full_path = os.path.join(full_class_dir, img_name.replace('/','_'))
cv2.imwrite(full_path, img) #pylint: disable=maybe-no-member
print('%8d: %s' % (i, full_path))
i += 1
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('output_dir', type=str, help='Output base directory for the image dataset')
parser.add_argument('tsv_files', type=argparse.FileType('r'), nargs='+', help='Input TSV file name(s)')
parser.add_argument('--size', type=int, help='Images are resized to the given size')
parser.add_argument('--output_format', type=str, help='Format of the output images', default='png', choices=['png', 'jpg'])
main(parser.parse_args())
================================================
FILE: src/download_and_extract.py
================================================
import requests
import zipfile
import os
model_dict = {
'lfw-subset': '1B5BQUZuJO-paxdN8UclxeHAR1WnR_Tzi',
'20170131-234652': '0B5MzpY9kBtDVSGM0RmVET2EwVEk',
'20170216-091149': '0B5MzpY9kBtDVTGZjcWkzT3pldDA',
'20170512-110547': '0B5MzpY9kBtDVZ2RpVDYwWmxoSUk',
'20180402-114759': '1EXPBSXwTaqrSC0OhUdXNmKSh9qJUQ55-'
}
def download_and_extract_file(model_name, data_dir):
file_id = model_dict[model_name]
destination = os.path.join(data_dir, model_name + '.zip')
if not os.path.exists(destination):
print('Downloading file to %s' % destination)
download_file_from_google_drive(file_id, destination)
with zipfile.ZipFile(destination, 'r') as zip_ref:
print('Extracting file to %s' % data_dir)
zip_ref.extractall(data_dir)
def download_file_from_google_drive(file_id, destination):
URL = "https://drive.google.com/uc?export=download"
session = requests.Session()
response = session.get(URL, params = { 'id' : file_id }, stream = True)
token = get_confirm_token(response)
if token:
params = { 'id' : file_id, 'confirm' : token }
response = session.get(URL, params = params, stream = True)
save_response_content(response, destination)
def get_confirm_token(response):
for key, value in response.cookies.items():
if key.startswith('download_warning'):
return value
return None
def save_response_content(response, destination):
CHUNK_SIZE = 32768
with open(destination, "wb") as f:
for chunk in response.iter_content(CHUNK_SIZE):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
================================================
FILE: src/facenet.py
================================================
"""Functions for building the face recognition network.
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
from subprocess import Popen, PIPE
import tensorflow as tf
import numpy as np
from scipy import misc
from sklearn.model_selection import KFold
from scipy import interpolate
from tensorflow.python.training import training
import random
import re
from tensorflow.python.platform import gfile
import math
from six import iteritems
def triplet_loss(anchor, positive, negative, alpha):
"""Calculate the triplet loss according to the FaceNet paper
Args:
anchor: the embeddings for the anchor images.
positive: the embeddings for the positive images.
negative: the embeddings for the negative images.
Returns:
the triplet loss according to the FaceNet paper as a float tensor.
"""
with tf.variable_scope('triplet_loss'):
pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1)
neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1)
basic_loss = tf.add(tf.subtract(pos_dist,neg_dist), alpha)
loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
return loss
def center_loss(features, label, alfa, nrof_classes):
"""Center loss based on the paper "A Discriminative Feature Learning Approach for Deep Face Recognition"
(http://ydwen.github.io/papers/WenECCV16.pdf)
"""
nrof_features = features.get_shape()[1]
centers = tf.get_variable('centers', [nrof_classes, nrof_features], dtype=tf.float32,
initializer=tf.constant_initializer(0), trainable=False)
label = tf.reshape(label, [-1])
centers_batch = tf.gather(centers, label)
diff = (1 - alfa) * (centers_batch - features)
centers = tf.scatter_sub(centers, label, diff)
with tf.control_dependencies([centers]):
loss = tf.reduce_mean(tf.square(features - centers_batch))
return loss, centers
def get_image_paths_and_labels(dataset):
image_paths_flat = []
labels_flat = []
for i in range(len(dataset)):
image_paths_flat += dataset[i].image_paths
labels_flat += [i] * len(dataset[i].image_paths)
return image_paths_flat, labels_flat
def shuffle_examples(image_paths, labels):
shuffle_list = list(zip(image_paths, labels))
random.shuffle(shuffle_list)
image_paths_shuff, labels_shuff = zip(*shuffle_list)
return image_paths_shuff, labels_shuff
def random_rotate_image(image):
angle = np.random.uniform(low=-10.0, high=10.0)
return misc.imrotate(image, angle, 'bicubic')
# 1: Random rotate 2: Random crop 4: Random flip 8: Fixed image standardization 16: Flip
RANDOM_ROTATE = 1
RANDOM_CROP = 2
RANDOM_FLIP = 4
FIXED_STANDARDIZATION = 8
FLIP = 16
def create_input_pipeline(input_queue, image_size, nrof_preprocess_threads, batch_size_placeholder):
images_and_labels_list = []
for _ in range(nrof_preprocess_threads):
filenames, label, control = input_queue.dequeue()
images = []
for filename in tf.unstack(filenames):
file_contents = tf.read_file(filename)
image = tf.image.decode_image(file_contents, 3)
image = tf.cond(get_control_flag(control[0], RANDOM_ROTATE),
lambda:tf.py_func(random_rotate_image, [image], tf.uint8),
lambda:tf.identity(image))
image = tf.cond(get_control_flag(control[0], RANDOM_CROP),
lambda:tf.random_crop(image, image_size + (3,)),
lambda:tf.image.resize_image_with_crop_or_pad(image, image_size[0], image_size[1]))
image = tf.cond(get_control_flag(control[0], RANDOM_FLIP),
lambda:tf.image.random_flip_left_right(image),
lambda:tf.identity(image))
image = tf.cond(get_control_flag(control[0], FIXED_STANDARDIZATION),
lambda:(tf.cast(image, tf.float32) - 127.5)/128.0,
lambda:tf.image.per_image_standardization(image))
image = tf.cond(get_control_flag(control[0], FLIP),
lambda:tf.image.flip_left_right(image),
lambda:tf.identity(image))
#pylint: disable=no-member
image.set_shape(image_size + (3,))
images.append(image)
images_and_labels_list.append([images, label])
image_batch, label_batch = tf.train.batch_join(
images_and_labels_list, batch_size=batch_size_placeholder,
shapes=[image_size + (3,), ()], enqueue_many=True,
capacity=4 * nrof_preprocess_threads * 100,
allow_smaller_final_batch=True)
return image_batch, label_batch
def get_control_flag(control, field):
return tf.equal(tf.mod(tf.floor_div(control, field), 2), 1)
def _add_loss_summaries(total_loss):
"""Add summaries for losses.
Generates moving average for all losses and associated summaries for
visualizing the performance of the network.
Args:
total_loss: Total loss from loss().
Returns:
loss_averages_op: op for generating moving averages of losses.
"""
# Compute the moving average of all individual losses and the total loss.
loss_averages = tf.train.ExponentialMovingAverage(0.9, name='avg')
losses = tf.get_collection('losses')
loss_averages_op = loss_averages.apply(losses + [total_loss])
# Attach a scalar summmary to all individual losses and the total loss; do the
# same for the averaged version of the losses.
for l in losses + [total_loss]:
# Name each loss as '(raw)' and name the moving average version of the loss
# as the original loss name.
tf.summary.scalar(l.op.name +' (raw)', l)
tf.summary.scalar(l.op.name, loss_averages.average(l))
return loss_averages_op
def train(total_loss, global_step, optimizer, learning_rate, moving_average_decay, update_gradient_vars, log_histograms=True):
# Generate moving averages of all losses and associated summaries.
loss_averages_op = _add_loss_summaries(total_loss)
# Compute gradients.
with tf.control_dependencies([loss_averages_op]):
if optimizer=='ADAGRAD':
opt = tf.train.AdagradOptimizer(learning_rate)
elif optimizer=='ADADELTA':
opt = tf.train.AdadeltaOptimizer(learning_rate, rho=0.9, epsilon=1e-6)
elif optimizer=='ADAM':
opt = tf.train.AdamOptimizer(learning_rate, beta1=0.9, beta2=0.999, epsilon=0.1)
elif optimizer=='RMSPROP':
opt = tf.train.RMSPropOptimizer(learning_rate, decay=0.9, momentum=0.9, epsilon=1.0)
elif optimizer=='MOM':
opt = tf.train.MomentumOptimizer(learning_rate, 0.9, use_nesterov=True)
else:
raise ValueError('Invalid optimization algorithm')
grads = opt.compute_gradients(total_loss, update_gradient_vars)
# Apply gradients.
apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)
# Add histograms for trainable variables.
if log_histograms:
for var in tf.trainable_variables():
tf.summary.histogram(var.op.name, var)
# Add histograms for gradients.
if log_histograms:
for grad, var in grads:
if grad is not None:
tf.summary.histogram(var.op.name + '/gradients', grad)
# Track the moving averages of all trainable variables.
variable_averages = tf.train.ExponentialMovingAverage(
moving_average_decay, global_step)
variables_averages_op = variable_averages.apply(tf.trainable_variables())
with tf.control_dependencies([apply_gradient_op, variables_averages_op]):
train_op = tf.no_op(name='train')
return train_op
def prewhiten(x):
mean = np.mean(x)
std = np.std(x)
std_adj = np.maximum(std, 1.0/np.sqrt(x.size))
y = np.multiply(np.subtract(x, mean), 1/std_adj)
return y
def crop(image, random_crop, image_size):
if image.shape[1]>image_size:
sz1 = int(image.shape[1]//2)
sz2 = int(image_size//2)
if random_crop:
diff = sz1-sz2
(h, v) = (np.random.randint(-diff, diff+1), np.random.randint(-diff, diff+1))
else:
(h, v) = (0,0)
image = image[(sz1-sz2+v):(sz1+sz2+v),(sz1-sz2+h):(sz1+sz2+h),:]
return image
def flip(image, random_flip):
if random_flip and np.random.choice([True, False]):
image = np.fliplr(image)
return image
def to_rgb(img):
w, h = img.shape
ret = np.empty((w, h, 3), dtype=np.uint8)
ret[:, :, 0] = ret[:, :, 1] = ret[:, :, 2] = img
return ret
def load_data(image_paths, do_random_crop, do_random_flip, image_size, do_prewhiten=True):
nrof_samples = len(image_paths)
images = np.zeros((nrof_samples, image_size, image_size, 3))
for i in range(nrof_samples):
img = misc.imread(image_paths[i])
if img.ndim == 2:
img = to_rgb(img)
if do_prewhiten:
img = prewhiten(img)
img = crop(img, do_random_crop, image_size)
img = flip(img, do_random_flip)
images[i,:,:,:] = img
return images
def get_label_batch(label_data, batch_size, batch_index):
nrof_examples = np.size(label_data, 0)
j = batch_index*batch_size % nrof_examples
if j+batch_size<=nrof_examples:
batch = label_data[j:j+batch_size]
else:
x1 = label_data[j:nrof_examples]
x2 = label_data[0:nrof_examples-j]
batch = np.vstack([x1,x2])
batch_int = batch.astype(np.int64)
return batch_int
def get_batch(image_data, batch_size, batch_index):
nrof_examples = np.size(image_data, 0)
j = batch_index*batch_size % nrof_examples
if j+batch_size<=nrof_examples:
batch = image_data[j:j+batch_size,:,:,:]
else:
x1 = image_data[j:nrof_examples,:,:,:]
x2 = image_data[0:nrof_examples-j,:,:,:]
batch = np.vstack([x1,x2])
batch_float = batch.astype(np.float32)
return batch_float
def get_triplet_batch(triplets, batch_index, batch_size):
ax, px, nx = triplets
a = get_batch(ax, int(batch_size/3), batch_index)
p = get_batch(px, int(batch_size/3), batch_index)
n = get_batch(nx, int(batch_size/3), batch_index)
batch = np.vstack([a, p, n])
return batch
def get_learning_rate_from_file(filename, epoch):
with open(filename, 'r') as f:
for line in f.readlines():
line = line.split('#', 1)[0]
if line:
par = line.strip().split(':')
e = int(par[0])
if par[1]=='-':
lr = -1
else:
lr = float(par[1])
if e <= epoch:
learning_rate = lr
else:
return learning_rate
class ImageClass():
"Stores the paths to images for a given class"
def __init__(self, name, image_paths):
self.name = name
self.image_paths = image_paths
def __str__(self):
return self.name + ', ' + str(len(self.image_paths)) + ' images'
def __len__(self):
return len(self.image_paths)
def get_dataset(path, has_class_directories=True):
dataset = []
path_exp = os.path.expanduser(path)
classes = [path for path in os.listdir(path_exp) \
if os.path.isdir(os.path.join(path_exp, path))]
classes.sort()
nrof_classes = len(classes)
for i in range(nrof_classes):
class_name = classes[i]
facedir = os.path.join(path_exp, class_name)
image_paths = get_image_paths(facedir)
dataset.append(ImageClass(class_name, image_paths))
return dataset
def get_image_paths(facedir):
image_paths = []
if os.path.isdir(facedir):
images = os.listdir(facedir)
image_paths = [os.path.join(facedir,img) for img in images]
return image_paths
def split_dataset(dataset, split_ratio, min_nrof_images_per_class, mode):
if mode=='SPLIT_CLASSES':
nrof_classes = len(dataset)
class_indices = np.arange(nrof_classes)
np.random.shuffle(class_indices)
split = int(round(nrof_classes*(1-split_ratio)))
train_set = [dataset[i] for i in class_indices[0:split]]
test_set = [dataset[i] for i in class_indices[split:-1]]
elif mode=='SPLIT_IMAGES':
train_set = []
test_set = []
for cls in dataset:
paths = cls.image_paths
np.random.shuffle(paths)
nrof_images_in_class = len(paths)
split = int(math.floor(nrof_images_in_class*(1-split_ratio)))
if split==nrof_images_in_class:
split = nrof_images_in_class-1
if split>=min_nrof_images_per_class and nrof_images_in_class-split>=1:
train_set.append(ImageClass(cls.name, paths[:split]))
test_set.append(ImageClass(cls.name, paths[split:]))
else:
raise ValueError('Invalid train/test split mode "%s"' % mode)
return train_set, test_set
def load_model(model, input_map=None):
# Check if the model is a model directory (containing a metagraph and a checkpoint file)
# or if it is a protobuf file with a frozen graph
model_exp = os.path.expanduser(model)
if (os.path.isfile(model_exp)):
print('Model filename: %s' % model_exp)
with gfile.FastGFile(model_exp,'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, input_map=input_map, name='')
else:
print('Model directory: %s' % model_exp)
meta_file, ckpt_file = get_model_filenames(model_exp)
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))
def get_model_filenames(model_dir):
files = os.listdir(model_dir)
meta_files = [s for s in files if s.endswith('.meta')]
if len(meta_files)==0:
raise ValueError('No meta file found in the model directory (%s)' % 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)
if ckpt and ckpt.model_checkpoint_path:
ckpt_file = os.path.basename(ckpt.model_checkpoint_path)
return meta_file, ckpt_file
meta_files = [s for s in files if '.ckpt' in s]
max_step = -1
for f in files:
step_str = re.match(r'(^model-[\w\- ]+.ckpt-(\d+))', f)
if step_str is not None and len(step_str.groups())>=2:
step = int(step_str.groups()[1])
if step > max_step:
max_step = step
ckpt_file = step_str.groups()[0]
return meta_file, ckpt_file
def distance(embeddings1, embeddings2, distance_metric=0):
if distance_metric==0:
# Euclidian distance
diff = np.subtract(embeddings1, embeddings2)
dist = np.sum(np.square(diff),1)
elif distance_metric==1:
# Distance based on cosine similarity
dot = np.sum(np.multiply(embeddings1, embeddings2), axis=1)
norm = np.linalg.norm(embeddings1, axis=1) * np.linalg.norm(embeddings2, axis=1)
similarity = dot / norm
dist = np.arccos(similarity) / math.pi
else:
raise 'Undefined distance metric %d' % distance_metric
return dist
def calculate_roc(thresholds, embeddings1, embeddings2, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):
assert(embeddings1.shape[0] == embeddings2.shape[0])
assert(embeddings1.shape[1] == embeddings2.shape[1])
nrof_pairs = min(len(actual_issame), embeddings1.shape[0])
nrof_thresholds = len(thresholds)
k_fold = KFold(n_splits=nrof_folds, shuffle=False)
tprs = np.zeros((nrof_folds,nrof_thresholds))
fprs = np.zeros((nrof_folds,nrof_thresholds))
accuracy = np.zeros((nrof_folds))
indices = np.arange(nrof_pairs)
for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):
if subtract_mean:
mean = np.mean(np.concatenate([embeddings1[train_set], embeddings2[train_set]]), axis=0)
else:
mean = 0.0
dist = distance(embeddings1-mean, embeddings2-mean, distance_metric)
# Find the best threshold for the fold
acc_train = np.zeros((nrof_thresholds))
for threshold_idx, threshold in enumerate(thresholds):
_, _, acc_train[threshold_idx] = calculate_accuracy(threshold, dist[train_set], actual_issame[train_set])
best_threshold_index = np.argmax(acc_train)
for threshold_idx, threshold in enumerate(thresholds):
tprs[fold_idx,threshold_idx], fprs[fold_idx,threshold_idx], _ = calculate_accuracy(threshold, dist[test_set], actual_issame[test_set])
_, _, accuracy[fold_idx] = calculate_accuracy(thresholds[best_threshold_index], dist[test_set], actual_issame[test_set])
tpr = np.mean(tprs,0)
fpr = np.mean(fprs,0)
return tpr, fpr, accuracy
def calculate_accuracy(threshold, dist, actual_issame):
predict_issame = np.less(dist, threshold)
tp = np.sum(np.logical_and(predict_issame, actual_issame))
fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))
tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame)))
fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))
tpr = 0 if (tp+fn==0) else float(tp) / float(tp+fn)
fpr = 0 if (fp+tn==0) else float(fp) / float(fp+tn)
acc = float(tp+tn)/dist.size
return tpr, fpr, acc
def calculate_val(thresholds, embeddings1, embeddings2, actual_issame, far_target, nrof_folds=10, distance_metric=0, subtract_mean=False):
assert(embeddings1.shape[0] == embeddings2.shape[0])
assert(embeddings1.shape[1] == embeddings2.shape[1])
nrof_pairs = min(len(actual_issame), embeddings1.shape[0])
nrof_thresholds = len(thresholds)
k_fold = KFold(n_splits=nrof_folds, shuffle=False)
val = np.zeros(nrof_folds)
far = np.zeros(nrof_folds)
indices = np.arange(nrof_pairs)
for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):
if subtract_mean:
mean = np.mean(np.concatenate([embeddings1[train_set], embeddings2[train_set]]), axis=0)
else:
mean = 0.0
dist = distance(embeddings1-mean, embeddings2-mean, distance_metric)
# Find the threshold that gives FAR = far_target
far_train = np.zeros(nrof_thresholds)
for threshold_idx, threshold in enumerate(thresholds):
_, far_train[threshold_idx] = calculate_val_far(threshold, dist[train_set], actual_issame[train_set])
if np.max(far_train)>=far_target:
f = interpolate.interp1d(far_train, thresholds, kind='slinear')
threshold = f(far_target)
else:
threshold = 0.0
val[fold_idx], far[fold_idx] = calculate_val_far(threshold, dist[test_set], actual_issame[test_set])
val_mean = np.mean(val)
far_mean = np.mean(far)
val_std = np.std(val)
return val_mean, val_std, far_mean
def calculate_val_far(threshold, dist, actual_issame):
predict_issame = np.less(dist, threshold)
true_accept = np.sum(np.logical_and(predict_issame, actual_issame))
false_accept = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))
n_same = np.sum(actual_issame)
n_diff = np.sum(np.logical_not(actual_issame))
val = float(true_accept) / float(n_same)
far = float(false_accept) / float(n_diff)
return val, far
def store_revision_info(src_path, output_dir, arg_string):
try:
# Get git hash
cmd = ['git', 'rev-parse', 'HEAD']
gitproc = Popen(cmd, stdout = PIPE, cwd=src_path)
(stdout, _) = gitproc.communicate()
git_hash = stdout.strip()
except OSError as e:
git_hash = ' '.join(cmd) + ': ' + e.strerror
try:
# Get local changes
cmd = ['git', 'diff', 'HEAD']
gitproc = Popen(cmd, stdout = PIPE, cwd=src_path)
(stdout, _) = gitproc.communicate()
git_diff = stdout.strip()
except OSError as e:
git_diff = ' '.join(cmd) + ': ' + e.strerror
# Store a text file in the log directory
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)
text_file.write('tensorflow version: %s\n--------------------\n' % tf.__version__) # @UndefinedVariable
text_file.write('git hash: %s\n--------------------\n' % git_hash)
text_file.write('%s' % git_diff)
def list_variables(filename):
reader = training.NewCheckpointReader(filename)
variable_map = reader.get_variable_to_shape_map()
names = sorted(variable_map.keys())
return names
def put_images_on_grid(images, shape=(16,8)):
nrof_images = images.shape[0]
img_size = images.shape[1]
bw = 3
img = np.zeros((shape[1]*(img_size+bw)+bw, shape[0]*(img_size+bw)+bw, 3), np.float32)
for i in range(shape[1]):
x_start = i*(img_size+bw)+bw
for j in range(shape[0]):
img_index = i*shape[0]+j
if img_index>=nrof_images:
break
y_start = j*(img_size+bw)+bw
img[x_start:x_start+img_size, y_start:y_start+img_size, :] = images[img_index, :, :, :]
if img_index>=nrof_images:
break
return img
def write_arguments_to_file(args, filename):
with open(filename, 'w') as f:
for key, value in iteritems(vars(args)):
f.write('%s: %s\n' % (key, str(value)))
================================================
FILE: src/freeze_graph.py
================================================
"""Imports a model metagraph and checkpoint file, converts the variables to constants
and exports the model as a graphdef protobuf
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from tensorflow.python.framework import graph_util
import tensorflow as tf
import argparse
import os
import sys
import facenet
from six.moves import xrange # @UnresolvedImport
def main(args):
with tf.Graph().as_default():
with tf.Session() as sess:
# Load the model metagraph and checkpoint
print('Model directory: %s' % args.model_dir)
meta_file, ckpt_file = facenet.get_model_filenames(os.path.expanduser(args.model_dir))
print('Metagraph file: %s' % meta_file)
print('Checkpoint file: %s' % ckpt_file)
model_dir_exp = os.path.expanduser(args.model_dir)
saver = tf.train.import_meta_graph(os.path.join(model_dir_exp, meta_file), clear_devices=True)
tf.get_default_session().run(tf.global_variables_initializer())
tf.get_default_session().run(tf.local_variables_initializer())
saver.restore(tf.get_default_session(), os.path.join(model_dir_exp, ckpt_file))
# Retrieve the protobuf graph definition and fix the batch norm nodes
input_graph_def = sess.graph.as_graph_def()
# Freeze the graph def
output_graph_def = freeze_graph_def(sess, input_graph_def, 'embeddings,label_batch')
# Serialize and dump the output graph to the filesystem
with tf.gfile.GFile(args.output_file, 'wb') as f:
f.write(output_graph_def.SerializeToString())
print("%d ops in the final graph: %s" % (len(output_graph_def.node), args.output_file))
def freeze_graph_def(sess, input_graph_def, output_node_names):
for node in input_graph_def.node:
if node.op == 'RefSwitch':
node.op = 'Switch'
for index in xrange(len(node.input)):
if 'moving_' in node.input[index]:
node.input[index] = node.input[index] + '/read'
elif node.op == 'AssignSub':
node.op = 'Sub'
if 'use_locking' in node.attr: del node.attr['use_locking']
elif node.op == 'AssignAdd':
node.op = 'Add'
if 'use_locking' in node.attr: del node.attr['use_locking']
# Get the list of important nodes
whitelist_names = []
for node in input_graph_def.node:
if (node.name.startswith('InceptionResnet') or node.name.startswith('embeddings') or
node.name.startswith('image_batch') or node.name.startswith('label_batch') or
node.name.startswith('phase_train') or node.name.startswith('Logits')):
whitelist_names.append(node.name)
# Replace all the variables in the graph with constants of the same values
output_graph_def = graph_util.convert_variables_to_constants(
sess, input_graph_def, output_node_names.split(","),
variable_names_whitelist=whitelist_names)
return output_graph_def
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('model_dir', type=str,
help='Directory containing the metagraph (.meta) file and the checkpoint (ckpt) file containing model parameters')
parser.add_argument('output_file', type=str,
help='Filename for the exported graphdef protobuf (.pb)')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/generative/__init__.py
================================================
================================================
FILE: src/generative/calculate_attribute_vectors.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Calculate average latent variables (here called attribute vectors)
for the different attributes in CelebA
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import sys
import argparse
import importlib
import facenet
import os
import numpy as np
import math
import time
import h5py
from six import iteritems
def main(args):
img_mean = np.array([134.10714722, 102.52040863, 87.15436554])
img_stddev = np.sqrt(np.array([3941.30175781, 2856.94287109, 2519.35791016]))
vae_checkpoint = os.path.expanduser(args.vae_checkpoint)
fields, attribs_dict = read_annotations(args.annotations_filename)
vae_def = importlib.import_module(args.vae_def)
vae = vae_def.Vae(args.latent_var_size)
gen_image_size = vae.get_image_size()
with tf.Graph().as_default():
tf.set_random_seed(args.seed)
image_list = facenet.get_image_paths(os.path.expanduser(args.data_dir))
# Get attributes for images
nrof_attributes = len(fields)
attribs_list = []
for img in image_list:
key = os.path.split(img)[1].split('.')[0]
attr = attribs_dict[key]
assert len(attr)==nrof_attributes
attribs_list.append(attr)
# Create the input queue
index_list = range(len(image_list))
input_queue = tf.train.slice_input_producer([image_list, attribs_list, index_list], num_epochs=1, shuffle=False)
nrof_preprocess_threads = 4
image_per_thread = []
for _ in range(nrof_preprocess_threads):
filename = input_queue[0]
file_contents = tf.read_file(filename)
image = tf.image.decode_image(file_contents, channels=3)
image = tf.image.resize_image_with_crop_or_pad(image, 160, 160)
#image = tf.image.resize_images(image, (64,64))
image.set_shape((args.image_size, args.image_size, 3))
attrib = input_queue[1]
attrib.set_shape((nrof_attributes,))
image = tf.cast(image, tf.float32)
image_per_thread.append([image, attrib, input_queue[2]])
images, attribs, indices = tf.train.batch_join(
image_per_thread, batch_size=args.batch_size,
shapes=[(args.image_size, args.image_size, 3), (nrof_attributes,), ()], enqueue_many=False,
capacity=4 * nrof_preprocess_threads * args.batch_size,
allow_smaller_final_batch=True)
# Normalize
images_norm = (images-img_mean) / img_stddev
# Resize to appropriate size for the encoder
images_norm_resize = tf.image.resize_images(images_norm, (gen_image_size,gen_image_size))
# Create encoder network
mean, log_variance = vae.encoder(images_norm_resize, True)
epsilon = tf.random_normal((tf.shape(mean)[0], args.latent_var_size))
std = tf.exp(log_variance/2)
latent_var = mean + epsilon * std
# Create a saver
saver = tf.train.Saver(tf.trainable_variables(), max_to_keep=3)
# Start running operations on the Graph
gpu_memory_fraction = 1.0
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
coord = tf.train.Coordinator()
tf.train.start_queue_runners(coord=coord, sess=sess)
with sess.as_default():
if vae_checkpoint:
print('Restoring VAE checkpoint: %s' % vae_checkpoint)
saver.restore(sess, vae_checkpoint)
nrof_images = len(image_list)
nrof_batches = int(math.ceil(len(image_list) / args.batch_size))
latent_vars = np.zeros((nrof_images, args.latent_var_size))
attributes = np.zeros((nrof_images, nrof_attributes))
for i in range(nrof_batches):
start_time = time.time()
latent_var_, attribs_, indices_ = sess.run([latent_var, attribs, indices])
latent_vars[indices_,:] = latent_var_
attributes[indices_,:] = attribs_
duration = time.time() - start_time
print('Batch %d/%d: %.3f seconds' % (i+1, nrof_batches, duration))
# NOTE: This will print the 'Out of range' warning if the last batch is not full,
# as described by https://github.com/tensorflow/tensorflow/issues/8330
# Calculate average change in the latent variable when each attribute changes
attribute_vectors = np.zeros((nrof_attributes, args.latent_var_size), np.float32)
for i in range(nrof_attributes):
pos_idx = np.argwhere(attributes[:,i]==1)[:,0]
neg_idx = np.argwhere(attributes[:,i]==-1)[:,0]
pos_avg = np.mean(latent_vars[pos_idx,:], 0)
neg_avg = np.mean(latent_vars[neg_idx,:], 0)
attribute_vectors[i,:] = pos_avg - neg_avg
filename = os.path.expanduser(args.output_filename)
print('Writing attribute vectors, latent variables and attributes to %s' % filename)
mdict = {'latent_vars':latent_vars, 'attributes':attributes,
'fields':fields, 'attribute_vectors':attribute_vectors }
with h5py.File(filename, 'w') as f:
for key, value in iteritems(mdict):
f.create_dataset(key, data=value)
def read_annotations(filename):
attribs = {}
with open(filename, 'r') as f:
for i, line in enumerate(f.readlines()):
if i==0:
continue # First line is the number of entries in the file
elif i==1:
fields = line.strip().split() # Second line is the field names
else:
line = line.split()
img_name = line[0].split('.')[0]
img_attribs = map(int, line[1:])
attribs[img_name] = img_attribs
return fields, attribs
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('vae_def', type=str,
help='Model definition for the variational autoencoder. Points to a module containing the definition.',
default='src.generative.models.dfc_vae')
parser.add_argument('vae_checkpoint', type=str,
help='Checkpoint file of a pre-trained variational autoencoder.')
parser.add_argument('data_dir', type=str,
help='Path to the directory containing aligned face patches for the CelebA dataset.')
parser.add_argument('annotations_filename', type=str,
help='Path to the annotations file',
default='/media/deep/datasets/CelebA/Anno/list_attr_celeba.txt')
parser.add_argument('output_filename', type=str,
help='Filename to use for the file containing the attribute vectors.')
parser.add_argument('--batch_size', type=int,
help='Number of images to process in a batch.', default=128)
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=64)
parser.add_argument('--latent_var_size', type=int,
help='Dimensionality of the latent variable.', default=100)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/generative/models/__init__.py
================================================
================================================
FILE: src/generative/models/dfc_vae.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Variational autoencoder based on the paper
'Deep Feature Consistent Variational Autoencoder'
(https://arxiv.org/pdf/1610.00291.pdf)
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
import generative.models.vae_base # @UnresolvedImport
class Vae(generative.models.vae_base.Vae):
def __init__(self, latent_variable_dim):
super(Vae, self).__init__(latent_variable_dim, 64)
def encoder(self, images, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('encoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = slim.conv2d(images, 32, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_1')
net = slim.conv2d(net, 64, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_2')
net = slim.conv2d(net, 128, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_3')
net = slim.conv2d(net, 256, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_4')
net = slim.flatten(net)
fc1 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_1')
fc2 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_2')
return fc1, fc2
def decoder(self, latent_var, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('decoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = slim.fully_connected(latent_var, 4096, activation_fn=None, normalizer_fn=None, scope='Fc_1')
net = tf.reshape(net, [-1,4,4,256], name='Reshape')
net = tf.image.resize_nearest_neighbor(net, size=(8,8), name='Upsample_1')
net = slim.conv2d(net, 128, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_1')
net = tf.image.resize_nearest_neighbor(net, size=(16,16), name='Upsample_2')
net = slim.conv2d(net, 64, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_2')
net = tf.image.resize_nearest_neighbor(net, size=(32,32), name='Upsample_3')
net = slim.conv2d(net, 32, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_3')
net = tf.image.resize_nearest_neighbor(net, size=(64,64), name='Upsample_4')
net = slim.conv2d(net, 3, [3, 3], 1, activation_fn=None, scope='Conv2d_4')
return net
def leaky_relu(x):
return tf.maximum(0.1*x,x)
================================================
FILE: src/generative/models/dfc_vae_large.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Variational autoencoder based on the paper
'Deep Feature Consistent Variational Autoencoder'
(https://arxiv.org/pdf/1610.00291.pdf) but with a larger image size (128x128 pixels)
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
import generative.models.vae_base # @UnresolvedImport
class Vae(generative.models.vae_base.Vae):
def __init__(self, latent_variable_dim):
super(Vae, self).__init__(latent_variable_dim, 128)
def encoder(self, images, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('encoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = slim.conv2d(images, 32, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_1')
net = slim.conv2d(net, 64, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_2')
net = slim.conv2d(net, 128, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_3')
net = slim.conv2d(net, 256, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_4')
net = slim.conv2d(net, 512, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_5')
net = slim.flatten(net)
fc1 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_1')
fc2 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_2')
return fc1, fc2
def decoder(self, latent_var, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('decoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = slim.fully_connected(latent_var, 4096, activation_fn=None, normalizer_fn=None, scope='Fc_1')
net = tf.reshape(net, [-1,4,4,256], name='Reshape')
net = tf.image.resize_nearest_neighbor(net, size=(8,8), name='Upsample_1')
net = slim.conv2d(net, 128, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_1')
net = tf.image.resize_nearest_neighbor(net, size=(16,16), name='Upsample_2')
net = slim.conv2d(net, 64, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_2')
net = tf.image.resize_nearest_neighbor(net, size=(32,32), name='Upsample_3')
net = slim.conv2d(net, 32, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_3')
net = tf.image.resize_nearest_neighbor(net, size=(64,64), name='Upsample_4')
net = slim.conv2d(net, 3, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_4')
net = tf.image.resize_nearest_neighbor(net, size=(128,128), name='Upsample_5')
net = slim.conv2d(net, 3, [3, 3], 1, activation_fn=None, scope='Conv2d_5')
return net
def leaky_relu(x):
return tf.maximum(0.1*x,x)
================================================
FILE: src/generative/models/dfc_vae_resnet.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Variational autoencoder based on the paper
'Deep Feature Consistent Variational Autoencoder'
(https://arxiv.org/pdf/1610.00291.pdf)
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
import generative.models.vae_base # @UnresolvedImport
class Vae(generative.models.vae_base.Vae):
def __init__(self, latent_variable_dim):
super(Vae, self).__init__(latent_variable_dim, 64)
def encoder(self, images, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('encoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = images
net = slim.conv2d(net, 32, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_1a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 32, [4, 4], 1, activation_fn=activation_fn, scope='Conv2d_1b')
net = slim.conv2d(net, 64, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_2a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 64, [4, 4], 1, activation_fn=activation_fn, scope='Conv2d_2b')
net = slim.conv2d(net, 128, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_3a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 128, [4, 4], 1, activation_fn=activation_fn, scope='Conv2d_3b')
net = slim.conv2d(net, 256, [4, 4], 2, activation_fn=activation_fn, scope='Conv2d_4a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 256, [4, 4], 1, activation_fn=activation_fn, scope='Conv2d_4b')
net = slim.flatten(net)
fc1 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_1')
fc2 = slim.fully_connected(net, self.latent_variable_dim, activation_fn=None, normalizer_fn=None, scope='Fc_2')
return fc1, fc2
def decoder(self, latent_var, is_training):
activation_fn = leaky_relu # tf.nn.relu
weight_decay = 0.0
with tf.variable_scope('decoder'):
with slim.arg_scope([slim.batch_norm],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=self.batch_norm_params):
net = slim.fully_connected(latent_var, 4096, activation_fn=None, normalizer_fn=None, scope='Fc_1')
net = tf.reshape(net, [-1,4,4,256], name='Reshape')
net = tf.image.resize_nearest_neighbor(net, size=(8,8), name='Upsample_1')
net = slim.conv2d(net, 128, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_1a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 128, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_1b')
net = tf.image.resize_nearest_neighbor(net, size=(16,16), name='Upsample_2')
net = slim.conv2d(net, 64, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_2a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 64, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_2b')
net = tf.image.resize_nearest_neighbor(net, size=(32,32), name='Upsample_3')
net = slim.conv2d(net, 32, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_3a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 32, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_3b')
net = tf.image.resize_nearest_neighbor(net, size=(64,64), name='Upsample_4')
net = slim.conv2d(net, 3, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_4a')
net = slim.repeat(net, 3, conv2d_block, 0.1, 3, [3, 3], 1, activation_fn=activation_fn, scope='Conv2d_4b')
net = slim.conv2d(net, 3, [3, 3], 1, activation_fn=None, scope='Conv2d_4c')
return net
def conv2d_block(inp, scale, *args, **kwargs):
return inp + slim.conv2d(inp, *args, **kwargs) * scale
def leaky_relu(x):
return tf.maximum(0.1*x,x)
================================================
FILE: src/generative/models/vae_base.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Base class for variational autoencoders containing an encoder and a decoder
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
class Vae(object):
def __init__(self, latent_variable_dim, image_size):
self.latent_variable_dim = latent_variable_dim
self.image_size = image_size
self.batch_norm_params = {
# Decay for the moving averages.
'decay': 0.995,
# epsilon to prevent 0s in variance.
'epsilon': 0.001,
# force in-place updates of mean and variance estimates
'updates_collections': None,
# Moving averages ends up in the trainable variables collection
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
}
def encoder(self, images, is_training):
# Must be overridden in implementation classes
raise NotImplementedError
def decoder(self, latent_var, is_training):
# Must be overridden in implementation classes
raise NotImplementedError
def get_image_size(self):
return self.image_size
================================================
FILE: src/generative/modify_attribute.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Modify attributes of images using attribute vectors calculated using
'calculate_attribute_vectors.py'. Images are generated from latent variables of
the CelebA dataset.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import sys
import argparse
import importlib
import facenet
import os
import numpy as np
import h5py
import math
from scipy import misc
def main(args):
img_mean = np.array([134.10714722, 102.52040863, 87.15436554])
img_stddev = np.sqrt(np.array([3941.30175781, 2856.94287109, 2519.35791016]))
vae_def = importlib.import_module(args.vae_def)
vae = vae_def.Vae(args.latent_var_size)
gen_image_size = vae.get_image_size()
with tf.Graph().as_default():
tf.set_random_seed(args.seed)
images = tf.placeholder(tf.float32, shape=(None,gen_image_size,gen_image_size,3), name='input')
# Normalize
images_norm = (images-img_mean) / img_stddev
# Resize to appropriate size for the encoder
images_norm_resize = tf.image.resize_images(images_norm, (gen_image_size,gen_image_size))
# Create encoder network
mean, log_variance = vae.encoder(images_norm_resize, True)
epsilon = tf.random_normal((tf.shape(mean)[0], args.latent_var_size))
std = tf.exp(log_variance/2)
latent_var = mean + epsilon * std
# Create decoder
reconstructed_norm = vae.decoder(latent_var, False)
# Un-normalize
reconstructed = (reconstructed_norm*img_stddev) + img_mean
# Create a saver
saver = tf.train.Saver(tf.trainable_variables(), max_to_keep=3)
# Start running operations on the Graph
gpu_memory_fraction = 1.0
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
coord = tf.train.Coordinator()
tf.train.start_queue_runners(coord=coord, sess=sess)
with sess.as_default():
vae_checkpoint = os.path.expanduser(args.vae_checkpoint)
print('Restoring VAE checkpoint: %s' % vae_checkpoint)
saver.restore(sess, vae_checkpoint)
filename = os.path.expanduser(args.attributes_filename)
with h5py.File(filename,'r') as f:
latent_vars = np.array(f.get('latent_vars'))
attributes = np.array(f.get('attributes'))
#fields = np.array(f.get('fields'))
attribute_vectors = np.array(f.get('attribute_vectors'))
# Reconstruct faces while adding varying amount of the selected attribute vector
attribute_index = 31 # 31: 'Smiling'
image_indices = [8,11,13,18,19,26,31,39,47,54,56,57,58,59,60,73]
nrof_images = len(image_indices)
nrof_interp_steps = 10
sweep_latent_var = np.zeros((nrof_interp_steps*nrof_images, args.latent_var_size), np.float32)
for j in range(nrof_images):
image_index = image_indices[j]
idx = np.argwhere(attributes[:,attribute_index]==-1)[image_index,0]
for i in range(nrof_interp_steps):
sweep_latent_var[i+nrof_interp_steps*j,:] = latent_vars[idx,:] + 5.0*i/nrof_interp_steps*attribute_vectors[attribute_index,:]
recon = sess.run(reconstructed, feed_dict={latent_var:sweep_latent_var})
img = facenet.put_images_on_grid(recon, shape=(nrof_interp_steps*2,int(math.ceil(nrof_images/2))))
image_filename = os.path.expanduser(args.output_image_filename)
print('Writing generated image to %s' % image_filename)
misc.imsave(image_filename, img)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('vae_def', type=str,
help='Model definition for the variational autoencoder. Points to a module containing the definition.')
parser.add_argument('vae_checkpoint', type=str,
help='Checkpoint file of a pre-trained variational autoencoder.')
parser.add_argument('attributes_filename', type=str,
help='The file containing the attribute vectors, as generated by calculate_attribute_vectors.py.')
parser.add_argument('output_image_filename', type=str,
help='File to write the generated image to.')
parser.add_argument('--latent_var_size', type=int,
help='Dimensionality of the latent variable.', default=100)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/generative/train_vae.py
================================================
# MIT License
#
# Copyright (c) 2017 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Train a Variational Autoencoder
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
import sys
import time
import importlib
import argparse
import facenet
import numpy as np
import h5py
import os
from datetime import datetime
from scipy import misc
from six import iteritems
def main(args):
img_mean = np.array([134.10714722, 102.52040863, 87.15436554])
img_stddev = np.sqrt(np.array([3941.30175781, 2856.94287109, 2519.35791016]))
vae_def = importlib.import_module(args.vae_def)
vae = vae_def.Vae(args.latent_var_size)
gen_image_size = vae.get_image_size()
subdir = datetime.strftime(datetime.now(), '%Y%m%d-%H%M%S')
model_dir = os.path.join(os.path.expanduser(args.models_base_dir), subdir)
if not os.path.isdir(model_dir): # Create the model directory if it doesn't exist
os.makedirs(model_dir)
log_file_name = os.path.join(model_dir, 'logs.h5')
# Write arguments to a text file
facenet.write_arguments_to_file(args, os.path.join(model_dir, 'arguments.txt'))
# Store some git revision info in a text file in the log directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, model_dir, ' '.join(sys.argv))
with tf.Graph().as_default():
tf.set_random_seed(args.seed)
global_step = tf.Variable(0, trainable=False)
train_set = facenet.get_dataset(args.data_dir)
image_list, _ = facenet.get_image_paths_and_labels(train_set)
# Create the input queue
input_queue = tf.train.string_input_producer(image_list, shuffle=True)
nrof_preprocess_threads = 4
image_per_thread = []
for _ in range(nrof_preprocess_threads):
file_contents = tf.read_file(input_queue.dequeue())
image = tf.image.decode_image(file_contents, channels=3)
image = tf.image.resize_image_with_crop_or_pad(image, args.input_image_size, args.input_image_size)
image.set_shape((args.input_image_size, args.input_image_size, 3))
image = tf.cast(image, tf.float32)
#pylint: disable=no-member
image_per_thread.append([image])
images = tf.train.batch_join(
image_per_thread, batch_size=args.batch_size,
capacity=4 * nrof_preprocess_threads * args.batch_size,
allow_smaller_final_batch=False)
# Normalize
images_norm = (images-img_mean) / img_stddev
# Resize to appropriate size for the encoder
images_norm_resize = tf.image.resize_images(images_norm, (gen_image_size,gen_image_size))
# Create encoder network
mean, log_variance = vae.encoder(images_norm_resize, True)
epsilon = tf.random_normal((tf.shape(mean)[0], args.latent_var_size))
std = tf.exp(log_variance/2)
latent_var = mean + epsilon * std
# Create decoder network
reconstructed_norm = vae.decoder(latent_var, True)
# Un-normalize
reconstructed = (reconstructed_norm*img_stddev) + img_mean
# Create reconstruction loss
if args.reconstruction_loss_type=='PLAIN':
images_resize = tf.image.resize_images(images, (gen_image_size,gen_image_size))
reconstruction_loss = tf.reduce_mean(tf.reduce_sum(tf.pow(images_resize - reconstructed,2)))
elif args.reconstruction_loss_type=='PERCEPTUAL':
network = importlib.import_module(args.model_def)
reconstructed_norm_resize = tf.image.resize_images(reconstructed_norm, (args.input_image_size,args.input_image_size))
# Stack images from both the input batch and the reconstructed batch in a new tensor
shp = [-1] + images_norm.get_shape().as_list()[1:]
input_images = tf.reshape(tf.stack([images_norm, reconstructed_norm_resize], axis=0), shp)
_, end_points = network.inference(input_images, 1.0,
phase_train=False, bottleneck_layer_size=128, weight_decay=0.0)
# Get a list of feature names to use for loss terms
feature_names = args.loss_features.replace(' ', '').split(',')
# Calculate L2 loss between original and reconstructed images in feature space
reconstruction_loss_list = []
for feature_name in feature_names:
feature_flat = slim.flatten(end_points[feature_name])
image_feature, reconstructed_feature = tf.unstack(tf.reshape(feature_flat, [2,args.batch_size,-1]), num=2, axis=0)
reconstruction_loss = tf.reduce_mean(tf.reduce_sum(tf.pow(image_feature-reconstructed_feature, 2)), name=feature_name+'_loss')
reconstruction_loss_list.append(reconstruction_loss)
# Sum up the losses in for the different features
reconstruction_loss = tf.add_n(reconstruction_loss_list, 'reconstruction_loss')
else:
pass
# Create KL divergence loss
kl_loss = kl_divergence_loss(mean, log_variance)
kl_loss_mean = tf.reduce_mean(kl_loss)
total_loss = args.alfa*kl_loss_mean + args.beta*reconstruction_loss
learning_rate = tf.train.exponential_decay(args.initial_learning_rate, global_step,
args.learning_rate_decay_steps, args.learning_rate_decay_factor, staircase=True)
# Calculate gradients and make sure not to include parameters for the perceptual loss model
opt = tf.train.AdamOptimizer(learning_rate)
grads = opt.compute_gradients(total_loss, var_list=get_variables_to_train())
# Apply gradients
apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)
with tf.control_dependencies([apply_gradient_op]):
train_op = tf.no_op(name='train')
# Create a saver
saver = tf.train.Saver(tf.trainable_variables(), max_to_keep=3)
facenet_saver = tf.train.Saver(get_facenet_variables_to_restore())
# Start running operations on the Graph
gpu_memory_fraction = 1.0
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
coord = tf.train.Coordinator()
tf.train.start_queue_runners(coord=coord, sess=sess)
with sess.as_default():
if args.reconstruction_loss_type=='PERCEPTUAL':
if not args.pretrained_model:
raise ValueError('A pretrained model must be specified when using perceptual loss')
pretrained_model_exp = os.path.expanduser(args.pretrained_model)
print('Restoring pretrained model: %s' % pretrained_model_exp)
facenet_saver.restore(sess, pretrained_model_exp)
log = {
'total_loss': np.zeros((0,), np.float),
'reconstruction_loss': np.zeros((0,), np.float),
'kl_loss': np.zeros((0,), np.float),
'learning_rate': np.zeros((0,), np.float),
}
step = 0
print('Running training')
while step < args.max_nrof_steps:
start_time = time.time()
step += 1
save_state = step>0 and (step % args.save_every_n_steps==0 or step==args.max_nrof_steps)
if save_state:
_, reconstruction_loss_, kl_loss_mean_, total_loss_, learning_rate_, rec_ = sess.run(
[train_op, reconstruction_loss, kl_loss_mean, total_loss, learning_rate, reconstructed])
img = facenet.put_images_on_grid(rec_, shape=(16,8))
misc.imsave(os.path.join(model_dir, 'reconstructed_%06d.png' % step), img)
else:
_, reconstruction_loss_, kl_loss_mean_, total_loss_, learning_rate_ = sess.run(
[train_op, reconstruction_loss, kl_loss_mean, total_loss, learning_rate])
log['total_loss'] = np.append(log['total_loss'], total_loss_)
log['reconstruction_loss'] = np.append(log['reconstruction_loss'], reconstruction_loss_)
log['kl_loss'] = np.append(log['kl_loss'], kl_loss_mean_)
log['learning_rate'] = np.append(log['learning_rate'], learning_rate_)
duration = time.time() - start_time
print('Step: %d \tTime: %.3f \trec_loss: %.3f \tkl_loss: %.3f \ttotal_loss: %.3f' % (step, duration, reconstruction_loss_, kl_loss_mean_, total_loss_))
if save_state:
print('Saving checkpoint file')
checkpoint_path = os.path.join(model_dir, 'model.ckpt')
saver.save(sess, checkpoint_path, global_step=step, write_meta_graph=False)
print('Saving log')
with h5py.File(log_file_name, 'w') as f:
for key, value in iteritems(log):
f.create_dataset(key, data=value)
def get_variables_to_train():
train_variables = []
for var in tf.trainable_variables():
if 'Inception' not in var.name:
train_variables.append(var)
return train_variables
def get_facenet_variables_to_restore():
facenet_variables = []
for var in tf.global_variables():
if var.name.startswith('Inception'):
if 'Adam' not in var.name:
facenet_variables.append(var)
return facenet_variables
def kl_divergence_loss(mean, log_variance):
kl = 0.5 * tf.reduce_sum( tf.exp(log_variance) + tf.square(mean) - 1.0 - log_variance, reduction_indices = 1)
return kl
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('vae_def', type=str,
help='Model definition for the variational autoencoder. Points to a module containing the definition.')
parser.add_argument('data_dir', type=str,
help='Path to the data directory containing aligned face patches.')
parser.add_argument('model_def', type=str,
help='Model definition. Points to a module containing the definition of the inference graph.')
parser.add_argument('pretrained_model', type=str,
help='Pretrained model to use to calculate features for perceptual loss.')
parser.add_argument('--models_base_dir', type=str,
help='Directory where to write trained models and checkpoints.', default='~/vae')
parser.add_argument('--loss_features', type=str,
help='Comma separated list of features to use for perceptual loss. Features should be defined ' +
'in the end_points dictionary.', default='Conv2d_1a_3x3,Conv2d_2a_3x3, Conv2d_2b_3x3')
parser.add_argument('--reconstruction_loss_type', type=str, choices=['PLAIN', 'PERCEPTUAL'],
help='The type of reconstruction loss to use', default='PERCEPTUAL')
parser.add_argument('--max_nrof_steps', type=int,
help='Number of steps to run.', default=50000)
parser.add_argument('--save_every_n_steps', type=int,
help='Number of steps between storing of model checkpoint and log files', default=500)
parser.add_argument('--batch_size', type=int,
help='Number of images to process in a batch.', default=128)
parser.add_argument('--input_image_size', type=int,
help='Image size of input images (height, width) in pixels. If perceptual loss is used this '
+ 'should be the input image size for the perceptual loss model', default=160)
parser.add_argument('--latent_var_size', type=int,
help='Dimensionality of the latent variable.', default=100)
parser.add_argument('--initial_learning_rate', type=float,
help='Initial learning rate.', default=0.0005)
parser.add_argument('--learning_rate_decay_steps', type=int,
help='Number of steps between learning rate decay.', default=1)
parser.add_argument('--learning_rate_decay_factor', type=float,
help='Learning rate decay factor.', default=1.0)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
parser.add_argument('--alfa', type=float,
help='Kullback-Leibler divergence loss factor.', default=1.0)
parser.add_argument('--beta', type=float,
help='Reconstruction loss factor.', default=0.5)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/lfw.py
================================================
"""Helper for evaluation on the Labeled Faces in the Wild dataset
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import numpy as np
import facenet
def evaluate(embeddings, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):
# Calculate evaluation metrics
thresholds = np.arange(0, 4, 0.01)
embeddings1 = embeddings[0::2]
embeddings2 = embeddings[1::2]
tpr, fpr, accuracy = facenet.calculate_roc(thresholds, embeddings1, embeddings2,
np.asarray(actual_issame), nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)
thresholds = np.arange(0, 4, 0.001)
val, val_std, far = facenet.calculate_val(thresholds, embeddings1, embeddings2,
np.asarray(actual_issame), 1e-3, nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)
return tpr, fpr, accuracy, val, val_std, far
def get_paths(lfw_dir, pairs):
nrof_skipped_pairs = 0
path_list = []
issame_list = []
for pair in pairs:
if len(pair) == 3:
path0 = add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[1])))
path1 = add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[2])))
issame = True
elif len(pair) == 4:
path0 = add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[1])))
path1 = add_extension(os.path.join(lfw_dir, pair[2], pair[2] + '_' + '%04d' % int(pair[3])))
issame = False
if os.path.exists(path0) and os.path.exists(path1): # Only add the pair if both paths exist
path_list += (path0,path1)
issame_list.append(issame)
else:
nrof_skipped_pairs += 1
if nrof_skipped_pairs>0:
print('Skipped %d image pairs' % nrof_skipped_pairs)
return path_list, issame_list
def add_extension(path):
if os.path.exists(path+'.jpg'):
return path+'.jpg'
elif os.path.exists(path+'.png'):
return path+'.png'
else:
raise RuntimeError('No file "%s" with extension png or jpg.' % path)
def read_pairs(pairs_filename):
pairs = []
with open(pairs_filename, 'r') as f:
for line in f.readlines()[1:]:
pair = line.strip().split()
pairs.append(pair)
return np.array(pairs)
================================================
FILE: src/models/__init__.py
================================================
# flake8: noqa
================================================
FILE: src/models/dummy.py
================================================
"""Dummy model used only for testing
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
import numpy as np
def inference(images, keep_probability, phase_train=True, # @UnusedVariable
bottleneck_layer_size=128, bottleneck_layer_activation=None, weight_decay=0.0, reuse=None): # @UnusedVariable
batch_norm_params = {
# Decay for the moving averages.
'decay': 0.995,
# epsilon to prevent 0s in variance.
'epsilon': 0.001,
# force in-place updates of mean and variance estimates
'updates_collections': None,
# Moving averages ends up in the trainable variables collection
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
}
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=batch_norm_params):
size = np.prod(images.get_shape()[1:].as_list())
net = slim.fully_connected(tf.reshape(images, (-1,size)), bottleneck_layer_size, activation_fn=None,
scope='Bottleneck', reuse=False)
return net, None
================================================
FILE: src/models/inception_resnet_v1.py
================================================
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Contains the definition of the Inception Resnet V1 architecture.
As described in http://arxiv.org/abs/1602.07261.
Inception-v4, Inception-ResNet and the Impact of Residual Connections
on Learning
Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
# Inception-Resnet-A
def block35(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 35x35 resnet block."""
with tf.variable_scope(scope, 'Block35', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 32, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 32, 3, scope='Conv2d_0b_3x3')
with tf.variable_scope('Branch_2'):
tower_conv2_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
tower_conv2_1 = slim.conv2d(tower_conv2_0, 32, 3, scope='Conv2d_0b_3x3')
tower_conv2_2 = slim.conv2d(tower_conv2_1, 32, 3, scope='Conv2d_0c_3x3')
mixed = tf.concat([tower_conv, tower_conv1_1, tower_conv2_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
# Inception-Resnet-B
def block17(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 17x17 resnet block."""
with tf.variable_scope(scope, 'Block17', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 128, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 128, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 128, [1, 7],
scope='Conv2d_0b_1x7')
tower_conv1_2 = slim.conv2d(tower_conv1_1, 128, [7, 1],
scope='Conv2d_0c_7x1')
mixed = tf.concat([tower_conv, tower_conv1_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
# Inception-Resnet-C
def block8(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 8x8 resnet block."""
with tf.variable_scope(scope, 'Block8', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 192, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 192, [1, 3],
scope='Conv2d_0b_1x3')
tower_conv1_2 = slim.conv2d(tower_conv1_1, 192, [3, 1],
scope='Conv2d_0c_3x1')
mixed = tf.concat([tower_conv, tower_conv1_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
def reduction_a(net, k, l, m, n):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, n, 3, stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, k, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, l, 3,
scope='Conv2d_0b_3x3')
tower_conv1_2 = slim.conv2d(tower_conv1_1, m, 3,
stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_2'):
tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_1a_3x3')
net = tf.concat([tower_conv, tower_conv1_2, tower_pool], 3)
return net
def reduction_b(net):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv_1 = slim.conv2d(tower_conv, 384, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_1'):
tower_conv1 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1, 256, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_2'):
tower_conv2 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv2_1 = slim.conv2d(tower_conv2, 256, 3,
scope='Conv2d_0b_3x3')
tower_conv2_2 = slim.conv2d(tower_conv2_1, 256, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_3'):
tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_1a_3x3')
net = tf.concat([tower_conv_1, tower_conv1_1,
tower_conv2_2, tower_pool], 3)
return net
def inference(images, keep_probability, phase_train=True,
bottleneck_layer_size=128, weight_decay=0.0, reuse=None):
batch_norm_params = {
# Decay for the moving averages.
'decay': 0.995,
# epsilon to prevent 0s in variance.
'epsilon': 0.001,
# force in-place updates of mean and variance estimates
'updates_collections': None,
# Moving averages ends up in the trainable variables collection
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
}
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=slim.initializers.xavier_initializer(),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=batch_norm_params):
return inception_resnet_v1(images, is_training=phase_train,
dropout_keep_prob=keep_probability, bottleneck_layer_size=bottleneck_layer_size, reuse=reuse)
def inception_resnet_v1(inputs, is_training=True,
dropout_keep_prob=0.8,
bottleneck_layer_size=128,
reuse=None,
scope='InceptionResnetV1'):
"""Creates the Inception Resnet V1 model.
Args:
inputs: a 4-D tensor of size [batch_size, height, width, 3].
num_classes: number of predicted classes.
is_training: whether is training or not.
dropout_keep_prob: float, the fraction to keep before final layer.
reuse: whether or not the network and its variables should be reused. To be
able to reuse 'scope' must be given.
scope: Optional variable_scope.
Returns:
logits: the logits outputs of the model.
end_points: the set of end_points from the inception model.
"""
end_points = {}
with tf.variable_scope(scope, 'InceptionResnetV1', [inputs], reuse=reuse):
with slim.arg_scope([slim.batch_norm, slim.dropout],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],
stride=1, padding='SAME'):
# 149 x 149 x 32
net = slim.conv2d(inputs, 32, 3, stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
end_points['Conv2d_1a_3x3'] = net
# 147 x 147 x 32
net = slim.conv2d(net, 32, 3, padding='VALID',
scope='Conv2d_2a_3x3')
end_points['Conv2d_2a_3x3'] = net
# 147 x 147 x 64
net = slim.conv2d(net, 64, 3, scope='Conv2d_2b_3x3')
end_points['Conv2d_2b_3x3'] = net
# 73 x 73 x 64
net = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_3a_3x3')
end_points['MaxPool_3a_3x3'] = net
# 73 x 73 x 80
net = slim.conv2d(net, 80, 1, padding='VALID',
scope='Conv2d_3b_1x1')
end_points['Conv2d_3b_1x1'] = net
# 71 x 71 x 192
net = slim.conv2d(net, 192, 3, padding='VALID',
scope='Conv2d_4a_3x3')
end_points['Conv2d_4a_3x3'] = net
# 35 x 35 x 256
net = slim.conv2d(net, 256, 3, stride=2, padding='VALID',
scope='Conv2d_4b_3x3')
end_points['Conv2d_4b_3x3'] = net
# 5 x Inception-resnet-A
net = slim.repeat(net, 5, block35, scale=0.17)
end_points['Mixed_5a'] = net
# Reduction-A
with tf.variable_scope('Mixed_6a'):
net = reduction_a(net, 192, 192, 256, 384)
end_points['Mixed_6a'] = net
# 10 x Inception-Resnet-B
net = slim.repeat(net, 10, block17, scale=0.10)
end_points['Mixed_6b'] = net
# Reduction-B
with tf.variable_scope('Mixed_7a'):
net = reduction_b(net)
end_points['Mixed_7a'] = net
# 5 x Inception-Resnet-C
net = slim.repeat(net, 5, block8, scale=0.20)
end_points['Mixed_8a'] = net
net = block8(net, activation_fn=None)
end_points['Mixed_8b'] = net
with tf.variable_scope('Logits'):
end_points['PrePool'] = net
#pylint: disable=no-member
net = slim.avg_pool2d(net, net.get_shape()[1:3], padding='VALID',
scope='AvgPool_1a_8x8')
net = slim.flatten(net)
net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
scope='Dropout')
end_points['PreLogitsFlatten'] = net
net = slim.fully_connected(net, bottleneck_layer_size, activation_fn=None,
scope='Bottleneck', reuse=False)
return net, end_points
================================================
FILE: src/models/inception_resnet_v2.py
================================================
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Contains the definition of the Inception Resnet V2 architecture.
As described in http://arxiv.org/abs/1602.07261.
Inception-v4, Inception-ResNet and the Impact of Residual Connections
on Learning
Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
# Inception-Resnet-A
def block35(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 35x35 resnet block."""
with tf.variable_scope(scope, 'Block35', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 32, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 32, 3, scope='Conv2d_0b_3x3')
with tf.variable_scope('Branch_2'):
tower_conv2_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
tower_conv2_1 = slim.conv2d(tower_conv2_0, 48, 3, scope='Conv2d_0b_3x3')
tower_conv2_2 = slim.conv2d(tower_conv2_1, 64, 3, scope='Conv2d_0c_3x3')
mixed = tf.concat([tower_conv, tower_conv1_1, tower_conv2_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
# Inception-Resnet-B
def block17(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 17x17 resnet block."""
with tf.variable_scope(scope, 'Block17', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 128, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 160, [1, 7],
scope='Conv2d_0b_1x7')
tower_conv1_2 = slim.conv2d(tower_conv1_1, 192, [7, 1],
scope='Conv2d_0c_7x1')
mixed = tf.concat([tower_conv, tower_conv1_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
# Inception-Resnet-C
def block8(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
"""Builds the 8x8 resnet block."""
with tf.variable_scope(scope, 'Block8', [net], reuse=reuse):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 192, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 224, [1, 3],
scope='Conv2d_0b_1x3')
tower_conv1_2 = slim.conv2d(tower_conv1_1, 256, [3, 1],
scope='Conv2d_0c_3x1')
mixed = tf.concat([tower_conv, tower_conv1_2], 3)
up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
activation_fn=None, scope='Conv2d_1x1')
net += scale * up
if activation_fn:
net = activation_fn(net)
return net
def inference(images, keep_probability, phase_train=True,
bottleneck_layer_size=128, weight_decay=0.0, reuse=None):
batch_norm_params = {
# Decay for the moving averages.
'decay': 0.995,
# epsilon to prevent 0s in variance.
'epsilon': 0.001,
# force in-place updates of mean and variance estimates
'updates_collections': None,
# Moving averages ends up in the trainable variables collection
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
}
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=slim.initializers.xavier_initializer(),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=batch_norm_params):
return inception_resnet_v2(images, is_training=phase_train,
dropout_keep_prob=keep_probability, bottleneck_layer_size=bottleneck_layer_size, reuse=reuse)
def inception_resnet_v2(inputs, is_training=True,
dropout_keep_prob=0.8,
bottleneck_layer_size=128,
reuse=None,
scope='InceptionResnetV2'):
"""Creates the Inception Resnet V2 model.
Args:
inputs: a 4-D tensor of size [batch_size, height, width, 3].
num_classes: number of predicted classes.
is_training: whether is training or not.
dropout_keep_prob: float, the fraction to keep before final layer.
reuse: whether or not the network and its variables should be reused. To be
able to reuse 'scope' must be given.
scope: Optional variable_scope.
Returns:
logits: the logits outputs of the model.
end_points: the set of end_points from the inception model.
"""
end_points = {}
with tf.variable_scope(scope, 'InceptionResnetV2', [inputs], reuse=reuse):
with slim.arg_scope([slim.batch_norm, slim.dropout],
is_training=is_training):
with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],
stride=1, padding='SAME'):
# 149 x 149 x 32
net = slim.conv2d(inputs, 32, 3, stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
end_points['Conv2d_1a_3x3'] = net
# 147 x 147 x 32
net = slim.conv2d(net, 32, 3, padding='VALID',
scope='Conv2d_2a_3x3')
end_points['Conv2d_2a_3x3'] = net
# 147 x 147 x 64
net = slim.conv2d(net, 64, 3, scope='Conv2d_2b_3x3')
end_points['Conv2d_2b_3x3'] = net
# 73 x 73 x 64
net = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_3a_3x3')
end_points['MaxPool_3a_3x3'] = net
# 73 x 73 x 80
net = slim.conv2d(net, 80, 1, padding='VALID',
scope='Conv2d_3b_1x1')
end_points['Conv2d_3b_1x1'] = net
# 71 x 71 x 192
net = slim.conv2d(net, 192, 3, padding='VALID',
scope='Conv2d_4a_3x3')
end_points['Conv2d_4a_3x3'] = net
# 35 x 35 x 192
net = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_5a_3x3')
end_points['MaxPool_5a_3x3'] = net
# 35 x 35 x 320
with tf.variable_scope('Mixed_5b'):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 96, 1, scope='Conv2d_1x1')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 48, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 64, 5,
scope='Conv2d_0b_5x5')
with tf.variable_scope('Branch_2'):
tower_conv2_0 = slim.conv2d(net, 64, 1, scope='Conv2d_0a_1x1')
tower_conv2_1 = slim.conv2d(tower_conv2_0, 96, 3,
scope='Conv2d_0b_3x3')
tower_conv2_2 = slim.conv2d(tower_conv2_1, 96, 3,
scope='Conv2d_0c_3x3')
with tf.variable_scope('Branch_3'):
tower_pool = slim.avg_pool2d(net, 3, stride=1, padding='SAME',
scope='AvgPool_0a_3x3')
tower_pool_1 = slim.conv2d(tower_pool, 64, 1,
scope='Conv2d_0b_1x1')
net = tf.concat([tower_conv, tower_conv1_1,
tower_conv2_2, tower_pool_1], 3)
end_points['Mixed_5b'] = net
net = slim.repeat(net, 10, block35, scale=0.17)
# 17 x 17 x 1024
with tf.variable_scope('Mixed_6a'):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 384, 3, stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_1'):
tower_conv1_0 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1_0, 256, 3,
scope='Conv2d_0b_3x3')
tower_conv1_2 = slim.conv2d(tower_conv1_1, 384, 3,
stride=2, padding='VALID',
scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_2'):
tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_1a_3x3')
net = tf.concat([tower_conv, tower_conv1_2, tower_pool], 3)
end_points['Mixed_6a'] = net
net = slim.repeat(net, 20, block17, scale=0.10)
with tf.variable_scope('Mixed_7a'):
with tf.variable_scope('Branch_0'):
tower_conv = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv_1 = slim.conv2d(tower_conv, 384, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_1'):
tower_conv1 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv1_1 = slim.conv2d(tower_conv1, 288, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_2'):
tower_conv2 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
tower_conv2_1 = slim.conv2d(tower_conv2, 288, 3,
scope='Conv2d_0b_3x3')
tower_conv2_2 = slim.conv2d(tower_conv2_1, 320, 3, stride=2,
padding='VALID', scope='Conv2d_1a_3x3')
with tf.variable_scope('Branch_3'):
tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',
scope='MaxPool_1a_3x3')
net = tf.concat([tower_conv_1, tower_conv1_1,
tower_conv2_2, tower_pool], 3)
end_points['Mixed_7a'] = net
net = slim.repeat(net, 9, block8, scale=0.20)
net = block8(net, activation_fn=None)
net = slim.conv2d(net, 1536, 1, scope='Conv2d_7b_1x1')
end_points['Conv2d_7b_1x1'] = net
with tf.variable_scope('Logits'):
end_points['PrePool'] = net
#pylint: disable=no-member
net = slim.avg_pool2d(net, net.get_shape()[1:3], padding='VALID',
scope='AvgPool_1a_8x8')
net = slim.flatten(net)
net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
scope='Dropout')
end_points['PreLogitsFlatten'] = net
net = slim.fully_connected(net, bottleneck_layer_size, activation_fn=None,
scope='Bottleneck', reuse=False)
return net, end_points
================================================
FILE: src/models/squeezenet.py
================================================
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import tensorflow.contrib.slim as slim
def fire_module(inputs,
squeeze_depth,
expand_depth,
reuse=None,
scope=None,
outputs_collections=None):
with tf.variable_scope(scope, 'fire', [inputs], reuse=reuse):
with slim.arg_scope([slim.conv2d, slim.max_pool2d],
outputs_collections=None):
net = squeeze(inputs, squeeze_depth)
outputs = expand(net, expand_depth)
return outputs
def squeeze(inputs, num_outputs):
return slim.conv2d(inputs, num_outputs, [1, 1], stride=1, scope='squeeze')
def expand(inputs, num_outputs):
with tf.variable_scope('expand'):
e1x1 = slim.conv2d(inputs, num_outputs, [1, 1], stride=1, scope='1x1')
e3x3 = slim.conv2d(inputs, num_outputs, [3, 3], scope='3x3')
return tf.concat([e1x1, e3x3], 3)
def inference(images, keep_probability, phase_train=True, bottleneck_layer_size=128, weight_decay=0.0, reuse=None):
batch_norm_params = {
# Decay for the moving averages.
'decay': 0.995,
# epsilon to prevent 0s in variance.
'epsilon': 0.001,
# force in-place updates of mean and variance estimates
'updates_collections': None,
# Moving averages ends up in the trainable variables collection
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
}
with slim.arg_scope([slim.conv2d, slim.fully_connected],
weights_initializer=slim.xavier_initializer_conv2d(uniform=True),
weights_regularizer=slim.l2_regularizer(weight_decay),
normalizer_fn=slim.batch_norm,
normalizer_params=batch_norm_params):
with tf.variable_scope('squeezenet', [images], reuse=reuse):
with slim.arg_scope([slim.batch_norm, slim.dropout],
is_training=phase_train):
net = slim.conv2d(images, 96, [7, 7], stride=2, scope='conv1')
net = slim.max_pool2d(net, [3, 3], stride=2, scope='maxpool1')
net = fire_module(net, 16, 64, scope='fire2')
net = fire_module(net, 16, 64, scope='fire3')
net = fire_module(net, 32, 128, scope='fire4')
net = slim.max_pool2d(net, [2, 2], stride=2, scope='maxpool4')
net = fire_module(net, 32, 128, scope='fire5')
net = fire_module(net, 48, 192, scope='fire6')
net = fire_module(net, 48, 192, scope='fire7')
net = fire_module(net, 64, 256, scope='fire8')
net = slim.max_pool2d(net, [3, 3], stride=2, scope='maxpool8')
net = fire_module(net, 64, 256, scope='fire9')
net = slim.dropout(net, keep_probability)
net = slim.conv2d(net, 1000, [1, 1], activation_fn=None, normalizer_fn=None, scope='conv10')
net = slim.avg_pool2d(net, net.get_shape()[1:3], scope='avgpool10')
net = tf.squeeze(net, [1, 2], name='logits')
net = slim.fully_connected(net, bottleneck_layer_size, activation_fn=None,
scope='Bottleneck', reuse=False)
return net, None
================================================
FILE: src/train_softmax.py
================================================
"""Training a face recognizer with TensorFlow using softmax cross entropy loss
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from datetime import datetime
import os.path
import time
import sys
import random
import tensorflow as tf
import numpy as np
import importlib
import argparse
import facenet
import lfw
import h5py
import math
import tensorflow.contrib.slim as slim
from tensorflow.python.ops import data_flow_ops
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
def main(args):
network = importlib.import_module(args.model_def)
image_size = (args.image_size, args.image_size)
subdir = datetime.strftime(datetime.now(), '%Y%m%d-%H%M%S')
log_dir = os.path.join(os.path.expanduser(args.logs_base_dir), subdir)
if not os.path.isdir(log_dir): # Create the log directory if it doesn't exist
os.makedirs(log_dir)
model_dir = os.path.join(os.path.expanduser(args.models_base_dir), subdir)
if not os.path.isdir(model_dir): # Create the model directory if it doesn't exist
os.makedirs(model_dir)
stat_file_name = os.path.join(log_dir, 'stat.h5')
# Write arguments to a text file
facenet.write_arguments_to_file(args, os.path.join(log_dir, 'arguments.txt'))
# Store some git revision info in a text file in the log directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, log_dir, ' '.join(sys.argv))
np.random.seed(seed=args.seed)
random.seed(args.seed)
dataset = facenet.get_dataset(args.data_dir)
if args.filter_filename:
dataset = filter_dataset(dataset, os.path.expanduser(args.filter_filename),
args.filter_percentile, args.filter_min_nrof_images_per_class)
if args.validation_set_split_ratio>0.0:
train_set, val_set = facenet.split_dataset(dataset, args.validation_set_split_ratio, args.min_nrof_val_images_per_class, 'SPLIT_IMAGES')
else:
train_set, val_set = dataset, []
nrof_classes = len(train_set)
print('Model directory: %s' % model_dir)
print('Log directory: %s' % log_dir)
pretrained_model = None
if args.pretrained_model:
pretrained_model = os.path.expanduser(args.pretrained_model)
print('Pre-trained model: %s' % pretrained_model)
if args.lfw_dir:
print('LFW directory: %s' % args.lfw_dir)
# Read the file containing the pairs used for testing
pairs = lfw.read_pairs(os.path.expanduser(args.lfw_pairs))
# Get the paths for the corresponding images
lfw_paths, actual_issame = lfw.get_paths(os.path.expanduser(args.lfw_dir), pairs)
with tf.Graph().as_default():
tf.set_random_seed(args.seed)
global_step = tf.Variable(0, trainable=False)
# Get a list of image paths and their labels
image_list, label_list = facenet.get_image_paths_and_labels(train_set)
assert len(image_list)>0, 'The training set should not be empty'
val_image_list, val_label_list = facenet.get_image_paths_and_labels(val_set)
# Create a queue that produces indices into the image_list and label_list
labels = ops.convert_to_tensor(label_list, dtype=tf.int32)
range_size = array_ops.shape(labels)[0]
index_queue = tf.train.range_input_producer(range_size, num_epochs=None,
shuffle=True, seed=None, capacity=32)
index_dequeue_op = index_queue.dequeue_many(args.batch_size*args.epoch_size, 'index_dequeue')
learning_rate_placeholder = tf.placeholder(tf.float32, name='learning_rate')
batch_size_placeholder = tf.placeholder(tf.int32, name='batch_size')
phase_train_placeholder = tf.placeholder(tf.bool, name='phase_train')
image_paths_placeholder = tf.placeholder(tf.string, shape=(None,1), name='image_paths')
labels_placeholder = tf.placeholder(tf.int32, shape=(None,1), name='labels')
control_placeholder = tf.placeholder(tf.int32, shape=(None,1), name='control')
nrof_preprocess_threads = 4
input_queue = data_flow_ops.FIFOQueue(capacity=2000000,
dtypes=[tf.string, tf.int32, tf.int32],
shapes=[(1,), (1,), (1,)],
shared_name=None, name=None)
enqueue_op = input_queue.enqueue_many([image_paths_placeholder, labels_placeholder, control_placeholder], name='enqueue_op')
image_batch, label_batch = facenet.create_input_pipeline(input_queue, image_size, nrof_preprocess_threads, batch_size_placeholder)
image_batch = tf.identity(image_batch, 'image_batch')
image_batch = tf.identity(image_batch, 'input')
label_batch = tf.identity(label_batch, 'label_batch')
print('Number of classes in training set: %d' % nrof_classes)
print('Number of examples in training set: %d' % len(image_list))
print('Number of classes in validation set: %d' % len(val_set))
print('Number of examples in validation set: %d' % len(val_image_list))
print('Building training graph')
# Build the inference graph
prelogits, _ = network.inference(image_batch, args.keep_probability,
phase_train=phase_train_placeholder, bottleneck_layer_size=args.embedding_size,
weight_decay=args.weight_decay)
logits = slim.fully_connected(prelogits, len(train_set), activation_fn=None,
weights_initializer=slim.initializers.xavier_initializer(),
weights_regularizer=slim.l2_regularizer(args.weight_decay),
scope='Logits', reuse=False)
embeddings = tf.nn.l2_normalize(prelogits, 1, 1e-10, name='embeddings')
# Norm for the prelogits
eps = 1e-4
prelogits_norm = tf.reduce_mean(tf.norm(tf.abs(prelogits)+eps, ord=args.prelogits_norm_p, axis=1))
tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, prelogits_norm * args.prelogits_norm_loss_factor)
# Add center loss
prelogits_center_loss, _ = facenet.center_loss(prelogits, label_batch, args.center_loss_alfa, nrof_classes)
tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, prelogits_center_loss * args.center_loss_factor)
learning_rate = tf.train.exponential_decay(learning_rate_placeholder, global_step,
args.learning_rate_decay_epochs*args.epoch_size, args.learning_rate_decay_factor, staircase=True)
tf.summary.scalar('learning_rate', learning_rate)
# Calculate the average cross entropy loss across the batch
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=label_batch, logits=logits, name='cross_entropy_per_example')
cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
tf.add_to_collection('losses', cross_entropy_mean)
correct_prediction = tf.cast(tf.equal(tf.argmax(logits, 1), tf.cast(label_batch, tf.int64)), tf.float32)
accuracy = tf.reduce_mean(correct_prediction)
# Calculate the total losses
regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
total_loss = tf.add_n([cross_entropy_mean] + regularization_losses, name='total_loss')
# Build a Graph that trains the model with one batch of examples and updates the model parameters
train_op = facenet.train(total_loss, global_step, args.optimizer,
learning_rate, args.moving_average_decay, tf.global_variables(), args.log_histograms)
# Create a saver
saver = tf.train.Saver(tf.trainable_variables(), max_to_keep=3)
# Build the summary operation based on the TF collection of Summaries.
summary_op = tf.summary.merge_all()
# Start running operations on the Graph.
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
summary_writer = tf.summary.FileWriter(log_dir, sess.graph)
coord = tf.train.Coordinator()
tf.train.start_queue_runners(coord=coord, sess=sess)
with sess.as_default():
if pretrained_model:
print('Restoring pretrained model: %s' % pretrained_model)
saver.restore(sess, pretrained_model)
# Training and validation loop
print('Running training')
nrof_steps = args.max_nrof_epochs*args.epoch_size
nrof_val_samples = int(math.ceil(args.max_nrof_epochs / args.validate_every_n_epochs)) # Validate every validate_every_n_epochs as well as in the last epoch
stat = {
'loss': np.zeros((nrof_steps,), np.float32),
'center_loss': np.zeros((nrof_steps,), np.float32),
'reg_loss': np.zeros((nrof_steps,), np.float32),
'xent_loss': np.zeros((nrof_steps,), np.float32),
'prelogits_norm': np.zeros((nrof_steps,), np.float32),
'accuracy': np.zeros((nrof_steps,), np.float32),
'val_loss': np.zeros((nrof_val_samples,), np.float32),
'val_xent_loss': np.zeros((nrof_val_samples,), np.float32),
'val_accuracy': np.zeros((nrof_val_samples,), np.float32),
'lfw_accuracy': np.zeros((args.max_nrof_epochs,), np.float32),
'lfw_valrate': np.zeros((args.max_nrof_epochs,), np.float32),
'learning_rate': np.zeros((args.max_nrof_epochs,), np.float32),
'time_train': np.zeros((args.max_nrof_epochs,), np.float32),
'time_validate': np.zeros((args.max_nrof_epochs,), np.float32),
'time_evaluate': np.zeros((args.max_nrof_epochs,), np.float32),
'prelogits_hist': np.zeros((args.max_nrof_epochs, 1000), np.float32),
}
for epoch in range(1,args.max_nrof_epochs+1):
step = sess.run(global_step, feed_dict=None)
# Train for one epoch
t = time.time()
cont = train(args, sess, epoch, image_list, label_list, index_dequeue_op, enqueue_op, image_paths_placeholder, labels_placeholder,
learning_rate_placeholder, phase_train_placeholder, batch_size_placeholder, control_placeholder, global_step,
total_loss, train_op, summary_op, summary_writer, regularization_losses, args.learning_rate_schedule_file,
stat, cross_entropy_mean, accuracy, learning_rate,
prelogits, prelogits_center_loss, args.random_rotate, args.random_crop, args.random_flip, prelogits_norm, args.prelogits_hist_max, args.use_fixed_image_standardization)
stat['time_train'][epoch-1] = time.time() - t
if not cont:
break
t = time.time()
if len(val_image_list)>0 and ((epoch-1) % args.validate_every_n_epochs == args.validate_every_n_epochs-1 or epoch==args.max_nrof_epochs):
validate(args, sess, epoch, val_image_list, val_label_list, enqueue_op, image_paths_placeholder, labels_placeholder, control_placeholder,
phase_train_placeholder, batch_size_placeholder,
stat, total_loss, regularization_losses, cross_entropy_mean, accuracy, args.validate_every_n_epochs, args.use_fixed_image_standardization)
stat['time_validate'][epoch-1] = time.time() - t
# Save variables and the metagraph if it doesn't exist already
save_variables_and_metagraph(sess, saver, summary_writer, model_dir, subdir, epoch)
# Evaluate on LFW
t = time.time()
if args.lfw_dir:
evaluate(sess, enqueue_op, image_paths_placeholder, labels_placeholder, phase_train_placeholder, batch_size_placeholder, control_placeholder,
embeddings, label_batch, lfw_paths, actual_issame, args.lfw_batch_size, args.lfw_nrof_folds, log_dir, step, summary_writer, stat, epoch,
args.lfw_distance_metric, args.lfw_subtract_mean, args.lfw_use_flipped_images, args.use_fixed_image_standardization)
stat['time_evaluate'][epoch-1] = time.time() - t
print('Saving statistics')
with h5py.File(stat_file_name, 'w') as f:
for key, value in stat.iteritems():
f.create_dataset(key, data=value)
return model_dir
def find_threshold(var, percentile):
hist, bin_edges = np.histogram(var, 100)
cdf = np.float32(np.cumsum(hist)) / np.sum(hist)
bin_centers = (bin_edges[:-1]+bin_edges[1:])/2
#plt.plot(bin_centers, cdf)
threshold = np.interp(percentile*0.01, cdf, bin_centers)
return threshold
def filter_dataset(dataset, data_filename, percentile, min_nrof_images_per_class):
with h5py.File(data_filename,'r') as f:
distance_to_center = np.array(f.get('distance_to_center'))
label_list = np.array(f.get('label_list'))
image_list = np.array(f.get('image_list'))
distance_to_center_threshold = find_threshold(distance_to_center, percentile)
indices = np.where(distance_to_center>=distance_to_center_threshold)[0]
filtered_dataset = dataset
removelist = []
for i in indices:
label = label_list[i]
image = image_list[i]
if image in filtered_dataset[label].image_paths:
filtered_dataset[label].image_paths.remove(image)
if len(filtered_dataset[label].image_paths)0.0:
lr = args.learning_rate
else:
lr = facenet.get_learning_rate_from_file(learning_rate_schedule_file, epoch)
if lr<=0:
return False
index_epoch = sess.run(index_dequeue_op)
label_epoch = np.array(label_list)[index_epoch]
image_epoch = np.array(image_list)[index_epoch]
# Enqueue one epoch of image paths and labels
labels_array = np.expand_dims(np.array(label_epoch),1)
image_paths_array = np.expand_dims(np.array(image_epoch),1)
control_value = facenet.RANDOM_ROTATE * random_rotate + facenet.RANDOM_CROP * random_crop + facenet.RANDOM_FLIP * random_flip + facenet.FIXED_STANDARDIZATION * use_fixed_image_standardization
control_array = np.ones_like(labels_array) * control_value
sess.run(enqueue_op, {image_paths_placeholder: image_paths_array, labels_placeholder: labels_array, control_placeholder: control_array})
# Training loop
train_time = 0
while batch_number < args.epoch_size:
start_time = time.time()
feed_dict = {learning_rate_placeholder: lr, phase_train_placeholder:True, batch_size_placeholder:args.batch_size}
tensor_list = [loss, train_op, step, reg_losses, prelogits, cross_entropy_mean, learning_rate, prelogits_norm, accuracy, prelogits_center_loss]
if batch_number % 100 == 0:
loss_, _, step_, reg_losses_, prelogits_, cross_entropy_mean_, lr_, prelogits_norm_, accuracy_, center_loss_, summary_str = sess.run(tensor_list + [summary_op], feed_dict=feed_dict)
summary_writer.add_summary(summary_str, global_step=step_)
else:
loss_, _, step_, reg_losses_, prelogits_, cross_entropy_mean_, lr_, prelogits_norm_, accuracy_, center_loss_ = sess.run(tensor_list, feed_dict=feed_dict)
duration = time.time() - start_time
stat['loss'][step_-1] = loss_
stat['center_loss'][step_-1] = center_loss_
stat['reg_loss'][step_-1] = np.sum(reg_losses_)
stat['xent_loss'][step_-1] = cross_entropy_mean_
stat['prelogits_norm'][step_-1] = prelogits_norm_
stat['learning_rate'][epoch-1] = lr_
stat['accuracy'][step_-1] = accuracy_
stat['prelogits_hist'][epoch-1,:] += np.histogram(np.minimum(np.abs(prelogits_), prelogits_hist_max), bins=1000, range=(0.0, prelogits_hist_max))[0]
duration = time.time() - start_time
print('Epoch: [%d][%d/%d]\tTime %.3f\tLoss %2.3f\tXent %2.3f\tRegLoss %2.3f\tAccuracy %2.3f\tLr %2.5f\tCl %2.3f' %
(epoch, batch_number+1, args.epoch_size, duration, loss_, cross_entropy_mean_, np.sum(reg_losses_), accuracy_, lr_, center_loss_))
batch_number += 1
train_time += duration
# Add validation loss and accuracy to summary
summary = tf.Summary()
#pylint: disable=maybe-no-member
summary.value.add(tag='time/total', simple_value=train_time)
summary_writer.add_summary(summary, global_step=step_)
return True
def validate(args, sess, epoch, image_list, label_list, enqueue_op, image_paths_placeholder, labels_placeholder, control_placeholder,
phase_train_placeholder, batch_size_placeholder,
stat, loss, regularization_losses, cross_entropy_mean, accuracy, validate_every_n_epochs, use_fixed_image_standardization):
print('Running forward pass on validation set')
nrof_batches = len(label_list) // args.lfw_batch_size
nrof_images = nrof_batches * args.lfw_batch_size
# Enqueue one epoch of image paths and labels
labels_array = np.expand_dims(np.array(label_list[:nrof_images]),1)
image_paths_array = np.expand_dims(np.array(image_list[:nrof_images]),1)
control_array = np.ones_like(labels_array, np.int32)*facenet.FIXED_STANDARDIZATION * use_fixed_image_standardization
sess.run(enqueue_op, {image_paths_placeholder: image_paths_array, labels_placeholder: labels_array, control_placeholder: control_array})
loss_array = np.zeros((nrof_batches,), np.float32)
xent_array = np.zeros((nrof_batches,), np.float32)
accuracy_array = np.zeros((nrof_batches,), np.float32)
# Training loop
start_time = time.time()
for i in range(nrof_batches):
feed_dict = {phase_train_placeholder:False, batch_size_placeholder:args.lfw_batch_size}
loss_, cross_entropy_mean_, accuracy_ = sess.run([loss, cross_entropy_mean, accuracy], feed_dict=feed_dict)
loss_array[i], xent_array[i], accuracy_array[i] = (loss_, cross_entropy_mean_, accuracy_)
if i % 10 == 9:
print('.', end='')
sys.stdout.flush()
print('')
duration = time.time() - start_time
val_index = (epoch-1)//validate_every_n_epochs
stat['val_loss'][val_index] = np.mean(loss_array)
stat['val_xent_loss'][val_index] = np.mean(xent_array)
stat['val_accuracy'][val_index] = np.mean(accuracy_array)
print('Validation Epoch: %d\tTime %.3f\tLoss %2.3f\tXent %2.3f\tAccuracy %2.3f' %
(epoch, duration, np.mean(loss_array), np.mean(xent_array), np.mean(accuracy_array)))
def evaluate(sess, enqueue_op, image_paths_placeholder, labels_placeholder, phase_train_placeholder, batch_size_placeholder, control_placeholder,
embeddings, labels, image_paths, actual_issame, batch_size, nrof_folds, log_dir, step, summary_writer, stat, epoch, distance_metric, subtract_mean, use_flipped_images, use_fixed_image_standardization):
start_time = time.time()
# Run forward pass to calculate embeddings
print('Runnning forward pass on LFW images')
# Enqueue one epoch of image paths and labels
nrof_embeddings = len(actual_issame)*2 # nrof_pairs * nrof_images_per_pair
nrof_flips = 2 if use_flipped_images else 1
nrof_images = nrof_embeddings * nrof_flips
labels_array = np.expand_dims(np.arange(0,nrof_images),1)
image_paths_array = np.expand_dims(np.repeat(np.array(image_paths),nrof_flips),1)
control_array = np.zeros_like(labels_array, np.int32)
if use_fixed_image_standardization:
control_array += np.ones_like(labels_array)*facenet.FIXED_STANDARDIZATION
if use_flipped_images:
# Flip every second image
control_array += (labels_array % 2)*facenet.FLIP
sess.run(enqueue_op, {image_paths_placeholder: image_paths_array, labels_placeholder: labels_array, control_placeholder: control_array})
embedding_size = int(embeddings.get_shape()[1])
assert nrof_images % batch_size == 0, 'The number of LFW images must be an integer multiple of the LFW batch size'
nrof_batches = nrof_images // batch_size
emb_array = np.zeros((nrof_images, embedding_size))
lab_array = np.zeros((nrof_images,))
for i in range(nrof_batches):
feed_dict = {phase_train_placeholder:False, batch_size_placeholder:batch_size}
emb, lab = sess.run([embeddings, labels], feed_dict=feed_dict)
lab_array[lab] = lab
emb_array[lab, :] = emb
if i % 10 == 9:
print('.', end='')
sys.stdout.flush()
print('')
embeddings = np.zeros((nrof_embeddings, embedding_size*nrof_flips))
if use_flipped_images:
# Concatenate embeddings for flipped and non flipped version of the images
embeddings[:,:embedding_size] = emb_array[0::2,:]
embeddings[:,embedding_size:] = emb_array[1::2,:]
else:
embeddings = emb_array
assert np.array_equal(lab_array, np.arange(nrof_images))==True, 'Wrong labels used for evaluation, possibly caused by training examples left in the input pipeline'
_, _, accuracy, val, val_std, far = lfw.evaluate(embeddings, actual_issame, nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)
print('Accuracy: %2.5f+-%2.5f' % (np.mean(accuracy), np.std(accuracy)))
print('Validation rate: %2.5f+-%2.5f @ FAR=%2.5f' % (val, val_std, far))
lfw_time = time.time() - start_time
# Add validation loss and accuracy to summary
summary = tf.Summary()
#pylint: disable=maybe-no-member
summary.value.add(tag='lfw/accuracy', simple_value=np.mean(accuracy))
summary.value.add(tag='lfw/val_rate', simple_value=val)
summary.value.add(tag='time/lfw', simple_value=lfw_time)
summary_writer.add_summary(summary, step)
with open(os.path.join(log_dir,'lfw_result.txt'),'at') as f:
f.write('%d\t%.5f\t%.5f\n' % (step, np.mean(accuracy), val))
stat['lfw_accuracy'][epoch-1] = np.mean(accuracy)
stat['lfw_valrate'][epoch-1] = val
def save_variables_and_metagraph(sess, saver, summary_writer, model_dir, model_name, step):
# Save the model checkpoint
print('Saving variables')
start_time = time.time()
checkpoint_path = os.path.join(model_dir, 'model-%s.ckpt' % model_name)
saver.save(sess, checkpoint_path, global_step=step, write_meta_graph=False)
save_time_variables = time.time() - start_time
print('Variables saved in %.2f seconds' % save_time_variables)
metagraph_filename = os.path.join(model_dir, 'model-%s.meta' % model_name)
save_time_metagraph = 0
if not os.path.exists(metagraph_filename):
print('Saving metagraph')
start_time = time.time()
saver.export_meta_graph(metagraph_filename)
save_time_metagraph = time.time() - start_time
print('Metagraph saved in %.2f seconds' % save_time_metagraph)
summary = tf.Summary()
#pylint: disable=maybe-no-member
summary.value.add(tag='time/save_variables', simple_value=save_time_variables)
summary.value.add(tag='time/save_metagraph', simple_value=save_time_metagraph)
summary_writer.add_summary(summary, step)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--logs_base_dir', type=str,
help='Directory where to write event logs.', default='~/logs/facenet')
parser.add_argument('--models_base_dir', type=str,
help='Directory where to write trained models and checkpoints.', default='~/models/facenet')
parser.add_argument('--gpu_memory_fraction', type=float,
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
parser.add_argument('--pretrained_model', type=str,
help='Load a pretrained model before training starts.')
parser.add_argument('--data_dir', type=str,
help='Path to the data directory containing aligned face patches.',
default='~/datasets/casia/casia_maxpy_mtcnnalign_182_160')
parser.add_argument('--model_def', type=str,
help='Model definition. Points to a module containing the definition of the inference graph.', default='models.inception_resnet_v1')
parser.add_argument('--max_nrof_epochs', type=int,
help='Number of epochs to run.', default=500)
parser.add_argument('--batch_size', type=int,
help='Number of images to process in a batch.', default=90)
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=160)
parser.add_argument('--epoch_size', type=int,
help='Number of batches per epoch.', default=1000)
parser.add_argument('--embedding_size', type=int,
help='Dimensionality of the embedding.', default=128)
parser.add_argument('--random_crop',
help='Performs random cropping of training images. If false, the center image_size pixels from the training images are used. ' +
'If the size of the images in the data directory is equal to image_size no cropping is performed', action='store_true')
parser.add_argument('--random_flip',
help='Performs random horizontal flipping of training images.', action='store_true')
parser.add_argument('--random_rotate',
help='Performs random rotations of training images.', action='store_true')
parser.add_argument('--use_fixed_image_standardization',
help='Performs fixed standardization of images.', action='store_true')
parser.add_argument('--keep_probability', type=float,
help='Keep probability of dropout for the fully connected layer(s).', default=1.0)
parser.add_argument('--weight_decay', type=float,
help='L2 weight regularization.', default=0.0)
parser.add_argument('--center_loss_factor', type=float,
help='Center loss factor.', default=0.0)
parser.add_argument('--center_loss_alfa', type=float,
help='Center update rate for center loss.', default=0.95)
parser.add_argument('--prelogits_norm_loss_factor', type=float,
help='Loss based on the norm of the activations in the prelogits layer.', default=0.0)
parser.add_argument('--prelogits_norm_p', type=float,
help='Norm to use for prelogits norm loss.', default=1.0)
parser.add_argument('--prelogits_hist_max', type=float,
help='The max value for the prelogits histogram.', default=10.0)
parser.add_argument('--optimizer', type=str, choices=['ADAGRAD', 'ADADELTA', 'ADAM', 'RMSPROP', 'MOM'],
help='The optimization algorithm to use', default='ADAGRAD')
parser.add_argument('--learning_rate', type=float,
help='Initial learning rate. If set to a negative value a learning rate ' +
'schedule can be specified in the file "learning_rate_schedule.txt"', default=0.1)
parser.add_argument('--learning_rate_decay_epochs', type=int,
help='Number of epochs between learning rate decay.', default=100)
parser.add_argument('--learning_rate_decay_factor', type=float,
help='Learning rate decay factor.', default=1.0)
parser.add_argument('--moving_average_decay', type=float,
help='Exponential decay for tracking of training parameters.', default=0.9999)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
parser.add_argument('--nrof_preprocess_threads', type=int,
help='Number of preprocessing (data loading and augmentation) threads.', default=4)
parser.add_argument('--log_histograms',
help='Enables logging of weight/bias histograms in tensorboard.', action='store_true')
parser.add_argument('--learning_rate_schedule_file', type=str,
help='File containing the learning rate schedule that is used when learning_rate is set to to -1.', default='data/learning_rate_schedule.txt')
parser.add_argument('--filter_filename', type=str,
help='File containing image data used for dataset filtering', default='')
parser.add_argument('--filter_percentile', type=float,
help='Keep only the percentile images closed to its class center', default=100.0)
parser.add_argument('--filter_min_nrof_images_per_class', type=int,
help='Keep only the classes with this number of examples or more', default=0)
parser.add_argument('--validate_every_n_epochs', type=int,
help='Number of epoch between validation', default=5)
parser.add_argument('--validation_set_split_ratio', type=float,
help='The ratio of the total dataset to use for validation', default=0.0)
parser.add_argument('--min_nrof_val_images_per_class', type=float,
help='Classes with fewer images will be removed from the validation set', default=0)
# Parameters for validation on LFW
parser.add_argument('--lfw_pairs', type=str,
help='The file containing the pairs to use for validation.', default='data/pairs.txt')
parser.add_argument('--lfw_dir', type=str,
help='Path to the data directory containing aligned face patches.', default='')
parser.add_argument('--lfw_batch_size', type=int,
help='Number of images to process in a batch in the LFW test set.', default=100)
parser.add_argument('--lfw_nrof_folds', type=int,
help='Number of folds to use for cross validation. Mainly used for testing.', default=10)
parser.add_argument('--lfw_distance_metric', type=int,
help='Type of distance metric to use. 0: Euclidian, 1:Cosine similarity distance.', default=0)
parser.add_argument('--lfw_use_flipped_images',
help='Concatenates embeddings for the image and its horizontally flipped counterpart.', action='store_true')
parser.add_argument('--lfw_subtract_mean',
help='Subtract feature mean before calculating distance.', action='store_true')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: src/train_tripletloss.py
================================================
"""Training a face recognizer with TensorFlow based on the FaceNet paper
FaceNet: A Unified Embedding for Face Recognition and Clustering: http://arxiv.org/abs/1503.03832
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from datetime import datetime
import os.path
import time
import sys
import tensorflow as tf
import numpy as np
import importlib
import itertools
import argparse
import facenet
import lfw
from tensorflow.python.ops import data_flow_ops
from six.moves import xrange # @UnresolvedImport
def main(args):
network = importlib.import_module(args.model_def)
subdir = datetime.strftime(datetime.now(), '%Y%m%d-%H%M%S')
log_dir = os.path.join(os.path.expanduser(args.logs_base_dir), subdir)
if not os.path.isdir(log_dir): # Create the log directory if it doesn't exist
os.makedirs(log_dir)
model_dir = os.path.join(os.path.expanduser(args.models_base_dir), subdir)
if not os.path.isdir(model_dir): # Create the model directory if it doesn't exist
os.makedirs(model_dir)
# Write arguments to a text file
facenet.write_arguments_to_file(args, os.path.join(log_dir, 'arguments.txt'))
# Store some git revision info in a text file in the log directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, log_dir, ' '.join(sys.argv))
np.random.seed(seed=args.seed)
train_set = facenet.get_dataset(args.data_dir)
print('Model directory: %s' % model_dir)
print('Log directory: %s' % log_dir)
if args.pretrained_model:
print('Pre-trained model: %s' % os.path.expanduser(args.pretrained_model))
if args.lfw_dir:
print('LFW directory: %s' % args.lfw_dir)
# Read the file containing the pairs used for testing
pairs = lfw.read_pairs(os.path.expanduser(args.lfw_pairs))
# Get the paths for the corresponding images
lfw_paths, actual_issame = lfw.get_paths(os.path.expanduser(args.lfw_dir), pairs)
with tf.Graph().as_default():
tf.set_random_seed(args.seed)
global_step = tf.Variable(0, trainable=False)
# Placeholder for the learning rate
learning_rate_placeholder = tf.placeholder(tf.float32, name='learning_rate')
batch_size_placeholder = tf.placeholder(tf.int32, name='batch_size')
phase_train_placeholder = tf.placeholder(tf.bool, name='phase_train')
image_paths_placeholder = tf.placeholder(tf.string, shape=(None,3), name='image_paths')
labels_placeholder = tf.placeholder(tf.int64, shape=(None,3), name='labels')
input_queue = data_flow_ops.FIFOQueue(capacity=100000,
dtypes=[tf.string, tf.int64],
shapes=[(3,), (3,)],
shared_name=None, name=None)
enqueue_op = input_queue.enqueue_many([image_paths_placeholder, labels_placeholder])
nrof_preprocess_threads = 4
images_and_labels = []
for _ in range(nrof_preprocess_threads):
filenames, label = input_queue.dequeue()
images = []
for filename in tf.unstack(filenames):
file_contents = tf.read_file(filename)
image = tf.image.decode_image(file_contents, channels=3)
if args.random_crop:
image = tf.random_crop(image, [args.image_size, args.image_size, 3])
else:
image = tf.image.resize_image_with_crop_or_pad(image, args.image_size, args.image_size)
if args.random_flip:
image = tf.image.random_flip_left_right(image)
#pylint: disable=no-member
image.set_shape((args.image_size, args.image_size, 3))
images.append(tf.image.per_image_standardization(image))
images_and_labels.append([images, label])
image_batch, labels_batch = tf.train.batch_join(
images_and_labels, batch_size=batch_size_placeholder,
shapes=[(args.image_size, args.image_size, 3), ()], enqueue_many=True,
capacity=4 * nrof_preprocess_threads * args.batch_size,
allow_smaller_final_batch=True)
image_batch = tf.identity(image_batch, 'image_batch')
image_batch = tf.identity(image_batch, 'input')
labels_batch = tf.identity(labels_batch, 'label_batch')
# Build the inference graph
prelogits, _ = network.inference(image_batch, args.keep_probability,
phase_train=phase_train_placeholder, bottleneck_layer_size=args.embedding_size,
weight_decay=args.weight_decay)
embeddings = tf.nn.l2_normalize(prelogits, 1, 1e-10, name='embeddings')
# Split embeddings into anchor, positive and negative and calculate triplet loss
anchor, positive, negative = tf.unstack(tf.reshape(embeddings, [-1,3,args.embedding_size]), 3, 1)
triplet_loss = facenet.triplet_loss(anchor, positive, negative, args.alpha)
learning_rate = tf.train.exponential_decay(learning_rate_placeholder, global_step,
args.learning_rate_decay_epochs*args.epoch_size, args.learning_rate_decay_factor, staircase=True)
tf.summary.scalar('learning_rate', learning_rate)
# Calculate the total losses
regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
total_loss = tf.add_n([triplet_loss] + regularization_losses, name='total_loss')
# Build a Graph that trains the model with one batch of examples and updates the model parameters
train_op = facenet.train(total_loss, global_step, args.optimizer,
learning_rate, args.moving_average_decay, tf.global_variables())
# Create a saver
saver = tf.train.Saver(tf.trainable_variables(), max_to_keep=3)
# Build the summary operation based on the TF collection of Summaries.
summary_op = tf.summary.merge_all()
# Start running operations on the Graph.
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
# Initialize variables
sess.run(tf.global_variables_initializer(), feed_dict={phase_train_placeholder:True})
sess.run(tf.local_variables_initializer(), feed_dict={phase_train_placeholder:True})
summary_writer = tf.summary.FileWriter(log_dir, sess.graph)
coord = tf.train.Coordinator()
tf.train.start_queue_runners(coord=coord, sess=sess)
with sess.as_default():
if args.pretrained_model:
print('Restoring pretrained model: %s' % args.pretrained_model)
saver.restore(sess, os.path.expanduser(args.pretrained_model))
# Training and validation loop
epoch = 0
while epoch < args.max_nrof_epochs:
step = sess.run(global_step, feed_dict=None)
epoch = step // args.epoch_size
# Train for one epoch
train(args, sess, train_set, epoch, image_paths_placeholder, labels_placeholder, labels_batch,
batch_size_placeholder, learning_rate_placeholder, phase_train_placeholder, enqueue_op, input_queue, global_step,
embeddings, total_loss, train_op, summary_op, summary_writer, args.learning_rate_schedule_file,
args.embedding_size, anchor, positive, negative, triplet_loss)
# Save variables and the metagraph if it doesn't exist already
save_variables_and_metagraph(sess, saver, summary_writer, model_dir, subdir, step)
# Evaluate on LFW
if args.lfw_dir:
evaluate(sess, lfw_paths, embeddings, labels_batch, image_paths_placeholder, labels_placeholder,
batch_size_placeholder, learning_rate_placeholder, phase_train_placeholder, enqueue_op, actual_issame, args.batch_size,
args.lfw_nrof_folds, log_dir, step, summary_writer, args.embedding_size)
return model_dir
def train(args, sess, dataset, epoch, image_paths_placeholder, labels_placeholder, labels_batch,
batch_size_placeholder, learning_rate_placeholder, phase_train_placeholder, enqueue_op, input_queue, global_step,
embeddings, loss, train_op, summary_op, summary_writer, learning_rate_schedule_file,
embedding_size, anchor, positive, negative, triplet_loss):
batch_number = 0
if args.learning_rate>0.0:
lr = args.learning_rate
else:
lr = facenet.get_learning_rate_from_file(learning_rate_schedule_file, epoch)
while batch_number < args.epoch_size:
# Sample people randomly from the dataset
image_paths, num_per_class = sample_people(dataset, args.people_per_batch, args.images_per_person)
print('Running forward pass on sampled images: ', end='')
start_time = time.time()
nrof_examples = args.people_per_batch * args.images_per_person
labels_array = np.reshape(np.arange(nrof_examples),(-1,3))
image_paths_array = np.reshape(np.expand_dims(np.array(image_paths),1), (-1,3))
sess.run(enqueue_op, {image_paths_placeholder: image_paths_array, labels_placeholder: labels_array})
emb_array = np.zeros((nrof_examples, embedding_size))
nrof_batches = int(np.ceil(nrof_examples / args.batch_size))
for i in range(nrof_batches):
batch_size = min(nrof_examples-i*args.batch_size, args.batch_size)
emb, lab = sess.run([embeddings, labels_batch], feed_dict={batch_size_placeholder: batch_size,
learning_rate_placeholder: lr, phase_train_placeholder: True})
emb_array[lab,:] = emb
print('%.3f' % (time.time()-start_time))
# Select triplets based on the embeddings
print('Selecting suitable triplets for training')
triplets, nrof_random_negs, nrof_triplets = select_triplets(emb_array, num_per_class,
image_paths, args.people_per_batch, args.alpha)
selection_time = time.time() - start_time
print('(nrof_random_negs, nrof_triplets) = (%d, %d): time=%.3f seconds' %
(nrof_random_negs, nrof_triplets, selection_time))
# Perform training on the selected triplets
nrof_batches = int(np.ceil(nrof_triplets*3/args.batch_size))
triplet_paths = list(itertools.chain(*triplets))
labels_array = np.reshape(np.arange(len(triplet_paths)),(-1,3))
triplet_paths_array = np.reshape(np.expand_dims(np.array(triplet_paths),1), (-1,3))
sess.run(enqueue_op, {image_paths_placeholder: triplet_paths_array, labels_placeholder: labels_array})
nrof_examples = len(triplet_paths)
train_time = 0
i = 0
emb_array = np.zeros((nrof_examples, embedding_size))
loss_array = np.zeros((nrof_triplets,))
summary = tf.Summary()
step = 0
while i < nrof_batches:
start_time = time.time()
batch_size = min(nrof_examples-i*args.batch_size, args.batch_size)
feed_dict = {batch_size_placeholder: batch_size, learning_rate_placeholder: lr, phase_train_placeholder: True}
err, _, step, emb, lab = sess.run([loss, train_op, global_step, embeddings, labels_batch], feed_dict=feed_dict)
emb_array[lab,:] = emb
loss_array[i] = err
duration = time.time() - start_time
print('Epoch: [%d][%d/%d]\tTime %.3f\tLoss %2.3f' %
(epoch, batch_number+1, args.epoch_size, duration, err))
batch_number += 1
i += 1
train_time += duration
summary.value.add(tag='loss', simple_value=err)
# Add validation loss and accuracy to summary
#pylint: disable=maybe-no-member
summary.value.add(tag='time/selection', simple_value=selection_time)
summary_writer.add_summary(summary, step)
return step
def select_triplets(embeddings, nrof_images_per_class, image_paths, people_per_batch, alpha):
""" Select the triplets for training
"""
trip_idx = 0
emb_start_idx = 0
num_trips = 0
triplets = []
# VGG Face: Choosing good triplets is crucial and should strike a balance between
# selecting informative (i.e. challenging) examples and swamping training with examples that
# are too hard. This is achieve by extending each pair (a, p) to a triplet (a, p, n) by sampling
# the image n at random, but only between the ones that violate the triplet loss margin. The
# latter is a form of hard-negative mining, but it is not as aggressive (and much cheaper) than
# choosing the maximally violating example, as often done in structured output learning.
for i in xrange(people_per_batch):
nrof_images = int(nrof_images_per_class[i])
for j in xrange(1,nrof_images):
a_idx = emb_start_idx + j - 1
neg_dists_sqr = np.sum(np.square(embeddings[a_idx] - embeddings), 1)
for pair in xrange(j, nrof_images): # For every possible positive pair.
p_idx = emb_start_idx + pair
pos_dist_sqr = np.sum(np.square(embeddings[a_idx]-embeddings[p_idx]))
neg_dists_sqr[emb_start_idx:emb_start_idx+nrof_images] = np.NaN
#all_neg = np.where(np.logical_and(neg_dists_sqr-pos_dist_sqr0:
rnd_idx = np.random.randint(nrof_random_negs)
n_idx = all_neg[rnd_idx]
triplets.append((image_paths[a_idx], image_paths[p_idx], image_paths[n_idx]))
#print('Triplet %d: (%d, %d, %d), pos_dist=%2.6f, neg_dist=%2.6f (%d, %d, %d, %d, %d)' %
# (trip_idx, a_idx, p_idx, n_idx, pos_dist_sqr, neg_dists_sqr[n_idx], nrof_random_negs, rnd_idx, i, j, emb_start_idx))
trip_idx += 1
num_trips += 1
emb_start_idx += nrof_images
np.random.shuffle(triplets)
return triplets, num_trips, len(triplets)
def sample_people(dataset, people_per_batch, images_per_person):
nrof_images = people_per_batch * images_per_person
# Sample classes from the dataset
nrof_classes = len(dataset)
class_indices = np.arange(nrof_classes)
np.random.shuffle(class_indices)
i = 0
image_paths = []
num_per_class = []
sampled_class_indices = []
# Sample images from these classes until we have enough
while len(image_paths)0
if nrof_faces>1
% select the faces with the largest bounding box
% closest to the image center
bounding_box_size = (det(:,3)-det(:,1)).*(det(:,4)-det(:,2));
img_center = img_size / 2;
offsets = [ (det(:,1)+det(:,3))/2 (det(:,2)+det(:,4))/2 ] - ones(nrof_faces,1)*img_center;
offset_dist_squared = sum(offsets.^2,2);
[a, index] = max(bounding_box_size-offset_dist_squared*2.0); % some extra weight on the centering
det = det(index,:);
points = points(:,index);
end;
% if nrof_faces>0
% figure(1); clf;
% imshow(img);
% hold on;
% plot(points(1:5,1),points(6:10,1),'g.','MarkerSize',10);
% bb = round(det(1:4));
% rectangle('Position',[bb(1) bb(2) bb(3)-bb(1) bb(4)-bb(2)],'LineWidth',2,'LineStyle','-')
% xxx = 1;
% end;
det(1) = max(det(1)-margin/2, 1);
det(2) = max(det(2)-margin/2, 1);
det(3) = min(det(3)+margin/2, img_size(1));
det(4) = min(det(4)+margin/2, img_size(2));
det(1:4) = round(det(1:4));
img = img(det(2):det(4),det(1):det(3),:);
img = imresize(img, [image_size, image_size]);
imwrite(img, target_img_path);
k = k + 1;
else
fprintf('Detection failed: %s\n', source_img_path);
fid = fopen(failed_images_list,'at');
if fid>=0
fprintf(fid, '%s\n', source_img_path);
fclose(fid);
end;
end;
if mod(k,100)==0
xxx = 1;
end;
end;
end;
end;
end;
end;
================================================
FILE: tmp/align_dataset.py
================================================
"""Performs face alignment and stores face thumbnails in the output directory."""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import sys
import os
import argparse
import random
import align_dlib # @UnresolvedImport
import facenet
def main(args):
align = align_dlib.AlignDlib(os.path.expanduser(args.dlib_face_predictor))
landmarkIndices = align_dlib.AlignDlib.OUTER_EYES_AND_NOSE
output_dir = os.path.expanduser(args.output_dir)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Store some git revision info in a text file in the log directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, output_dir, ' '.join(sys.argv))
dataset = facenet.get_dataset(args.input_dir)
random.shuffle(dataset)
# Scale the image such that the face fills the frame when cropped to crop_size
scale = float(args.face_size) / args.image_size
nrof_images_total = 0
nrof_prealigned_images = 0
nrof_successfully_aligned = 0
for cls in dataset:
output_class_dir = os.path.join(output_dir, cls.name)
if not os.path.exists(output_class_dir):
os.makedirs(output_class_dir)
random.shuffle(cls.image_paths)
for image_path in cls.image_paths:
nrof_images_total += 1
filename = os.path.splitext(os.path.split(image_path)[1])[0]
output_filename = os.path.join(output_class_dir, filename+'.png')
if not os.path.exists(output_filename):
try:
img = misc.imread(image_path)
except (IOError, ValueError, IndexError) as e:
errorMessage = '{}: {}'.format(image_path, e)
print(errorMessage)
else:
if img.ndim == 2:
img = facenet.to_rgb(img)
if args.use_center_crop:
scaled = misc.imresize(img, args.prealigned_scale, interp='bilinear')
sz1 = scaled.shape[1]/2
sz2 = args.image_size/2
aligned = scaled[(sz1-sz2):(sz1+sz2),(sz1-sz2):(sz1+sz2),:]
else:
aligned = align.align(args.image_size, img, landmarkIndices=landmarkIndices,
skipMulti=False, scale=scale)
if aligned is not None:
print(image_path)
nrof_successfully_aligned += 1
misc.imsave(output_filename, aligned)
elif args.prealigned_dir:
# Face detection failed. Use center crop from pre-aligned dataset
class_name = os.path.split(output_class_dir)[1]
image_path_without_ext = os.path.join(os.path.expanduser(args.prealigned_dir),
class_name, filename)
# Find the extension of the image
exts = ('jpg', 'png')
for ext in exts:
temp_path = image_path_without_ext + '.' + ext
image_path = ''
if os.path.exists(temp_path):
image_path = temp_path
break
try:
img = misc.imread(image_path)
except (IOError, ValueError, IndexError) as e:
errorMessage = '{}: {}'.format(image_path, e)
print(errorMessage)
else:
scaled = misc.imresize(img, args.prealigned_scale, interp='bilinear')
sz1 = scaled.shape[1]/2
sz2 = args.image_size/2
cropped = scaled[(sz1-sz2):(sz1+sz2),(sz1-sz2):(sz1+sz2),:]
print(image_path)
nrof_prealigned_images += 1
misc.imsave(output_filename, cropped)
else:
print('Unable to align "%s"' % image_path)
print('Total number of images: %d' % nrof_images_total)
print('Number of successfully aligned images: %d' % nrof_successfully_aligned)
print('Number of pre-aligned images: %d' % nrof_prealigned_images)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('input_dir', type=str, help='Directory with unaligned images.')
parser.add_argument('output_dir', type=str, help='Directory with aligned face thumbnails.')
parser.add_argument('--dlib_face_predictor', type=str,
help='File containing the dlib face predictor.', default='../data/shape_predictor_68_face_landmarks.dat')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=110)
parser.add_argument('--face_size', type=int,
help='Size of the face thumbnail (height, width) in pixels.', default=96)
parser.add_argument('--use_center_crop',
help='Use the center crop of the original image after scaling the image using prealigned_scale.', action='store_true')
parser.add_argument('--prealigned_dir', type=str,
help='Replace image with a pre-aligned version when face detection fails.', default='')
parser.add_argument('--prealigned_scale', type=float,
help='The amount of scaling to apply to prealigned images before taking the center crop.', default=0.87)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/align_dlib.py
================================================
# Copyright 2015-2016 Carnegie Mellon University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module for dlib-based alignment."""
# NOTE: This file has been copied from the openface project.
# https://github.com/cmusatyalab/openface/blob/master/openface/align_dlib.py
import cv2
import dlib
import numpy as np
TEMPLATE = np.float32([
(0.0792396913815, 0.339223741112), (0.0829219487236, 0.456955367943),
(0.0967927109165, 0.575648016728), (0.122141515615, 0.691921601066),
(0.168687863544, 0.800341263616), (0.239789390707, 0.895732504778),
(0.325662452515, 0.977068762493), (0.422318282013, 1.04329000149),
(0.531777802068, 1.06080371126), (0.641296298053, 1.03981924107),
(0.738105872266, 0.972268833998), (0.824444363295, 0.889624082279),
(0.894792677532, 0.792494155836), (0.939395486253, 0.681546643421),
(0.96111933829, 0.562238253072), (0.970579841181, 0.441758925744),
(0.971193274221, 0.322118743967), (0.163846223133, 0.249151738053),
(0.21780354657, 0.204255863861), (0.291299351124, 0.192367318323),
(0.367460241458, 0.203582210627), (0.4392945113, 0.233135599851),
(0.586445962425, 0.228141644834), (0.660152671635, 0.195923841854),
(0.737466449096, 0.182360984545), (0.813236546239, 0.192828009114),
(0.8707571886, 0.235293377042), (0.51534533827, 0.31863546193),
(0.516221448289, 0.396200446263), (0.517118861835, 0.473797687758),
(0.51816430343, 0.553157797772), (0.433701156035, 0.604054457668),
(0.475501237769, 0.62076344024), (0.520712933176, 0.634268222208),
(0.565874114041, 0.618796581487), (0.607054002672, 0.60157671656),
(0.252418718401, 0.331052263829), (0.298663015648, 0.302646354002),
(0.355749724218, 0.303020650651), (0.403718978315, 0.33867711083),
(0.352507175597, 0.349987615384), (0.296791759886, 0.350478978225),
(0.631326076346, 0.334136672344), (0.679073381078, 0.29645404267),
(0.73597236153, 0.294721285802), (0.782865376271, 0.321305281656),
(0.740312274764, 0.341849376713), (0.68499850091, 0.343734332172),
(0.353167761422, 0.746189164237), (0.414587777921, 0.719053835073),
(0.477677654595, 0.706835892494), (0.522732900812, 0.717092275768),
(0.569832064287, 0.705414478982), (0.635195811927, 0.71565572516),
(0.69951672331, 0.739419187253), (0.639447159575, 0.805236879972),
(0.576410514055, 0.835436670169), (0.525398405766, 0.841706377792),
(0.47641545769, 0.837505914975), (0.41379548902, 0.810045601727),
(0.380084785646, 0.749979603086), (0.477955996282, 0.74513234612),
(0.523389793327, 0.748924302636), (0.571057789237, 0.74332894691),
(0.672409137852, 0.744177032192), (0.572539621444, 0.776609286626),
(0.5240106503, 0.783370783245), (0.477561227414, 0.778476346951)])
INV_TEMPLATE = np.float32([
(-0.04099179660567834, -0.008425234314031194, 2.575498465013183),
(0.04062510634554352, -0.009678089746831375, -1.2534351452524177),
(0.0003666902601348179, 0.01810332406086298, -0.32206331976076663)])
TPL_MIN, TPL_MAX = np.min(TEMPLATE, axis=0), np.max(TEMPLATE, axis=0)
MINMAX_TEMPLATE = (TEMPLATE - TPL_MIN) / (TPL_MAX - TPL_MIN)
class AlignDlib:
"""
Use `dlib's landmark estimation `_ to align faces.
The alignment preprocess faces for input into a neural network.
Faces are resized to the same size (such as 96x96) and transformed
to make landmarks (such as the eyes and nose) appear at the same
location on every image.
Normalized landmarks:
.. image:: ../images/dlib-landmark-mean.png
"""
#: Landmark indices corresponding to the inner eyes and bottom lip.
INNER_EYES_AND_BOTTOM_LIP = [39, 42, 57]
#: Landmark indices corresponding to the outer eyes and nose.
OUTER_EYES_AND_NOSE = [36, 45, 33]
def __init__(self, facePredictor):
"""
Instantiate an 'AlignDlib' object.
:param facePredictor: The path to dlib's
:type facePredictor: str
"""
assert facePredictor is not None
#pylint: disable=no-member
self.detector = dlib.get_frontal_face_detector()
self.predictor = dlib.shape_predictor(facePredictor)
def getAllFaceBoundingBoxes(self, rgbImg):
"""
Find all face bounding boxes in an image.
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:return: All face bounding boxes in an image.
:rtype: dlib.rectangles
"""
assert rgbImg is not None
try:
return self.detector(rgbImg, 1)
except Exception as e: #pylint: disable=broad-except
print("Warning: {}".format(e))
# In rare cases, exceptions are thrown.
return []
def getLargestFaceBoundingBox(self, rgbImg, skipMulti=False):
"""
Find the largest face bounding box in an image.
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param skipMulti: Skip image if more than one face detected.
:type skipMulti: bool
:return: The largest face bounding box in an image, or None.
:rtype: dlib.rectangle
"""
assert rgbImg is not None
faces = self.getAllFaceBoundingBoxes(rgbImg)
if (not skipMulti and len(faces) > 0) or len(faces) == 1:
return max(faces, key=lambda rect: rect.width() * rect.height())
else:
return None
def findLandmarks(self, rgbImg, bb):
"""
Find the landmarks of a face.
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param bb: Bounding box around the face to find landmarks for.
:type bb: dlib.rectangle
:return: Detected landmark locations.
:rtype: list of (x,y) tuples
"""
assert rgbImg is not None
assert bb is not None
points = self.predictor(rgbImg, bb)
#return list(map(lambda p: (p.x, p.y), points.parts()))
return [(p.x, p.y) for p in points.parts()]
#pylint: disable=dangerous-default-value
def align(self, imgDim, rgbImg, bb=None,
landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP,
skipMulti=False, scale=1.0):
r"""align(imgDim, rgbImg, bb=None, landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP)
Transform and align a face in an image.
:param imgDim: The edge length in pixels of the square the image is resized to.
:type imgDim: int
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param bb: Bounding box around the face to align. \
Defaults to the largest face.
:type bb: dlib.rectangle
:param landmarks: Detected landmark locations. \
Landmarks found on `bb` if not provided.
:type landmarks: list of (x,y) tuples
:param landmarkIndices: The indices to transform to.
:type landmarkIndices: list of ints
:param skipMulti: Skip image if more than one face detected.
:type skipMulti: bool
:param scale: Scale image before cropping to the size given by imgDim.
:type scale: float
:return: The aligned RGB image. Shape: (imgDim, imgDim, 3)
:rtype: numpy.ndarray
"""
assert imgDim is not None
assert rgbImg is not None
assert landmarkIndices is not None
if bb is None:
bb = self.getLargestFaceBoundingBox(rgbImg, skipMulti)
if bb is None:
return
if landmarks is None:
landmarks = self.findLandmarks(rgbImg, bb)
npLandmarks = np.float32(landmarks)
npLandmarkIndices = np.array(landmarkIndices)
#pylint: disable=maybe-no-member
H = cv2.getAffineTransform(npLandmarks[npLandmarkIndices],
imgDim * MINMAX_TEMPLATE[npLandmarkIndices]*scale + imgDim*(1-scale)/2)
thumbnail = cv2.warpAffine(rgbImg, H, (imgDim, imgDim))
return thumbnail
================================================
FILE: tmp/cacd2000_split_identities.py
================================================
import shutil
import argparse
import os
import sys
def main(args):
src_path_exp = os.path.expanduser(args.src_path)
dst_path_exp = os.path.expanduser(args.dst_path)
if not os.path.exists(dst_path_exp):
os.makedirs(dst_path_exp)
files = os.listdir(src_path_exp)
for f in files:
file_name = '.'.join(f.split('.')[0:-1])
x = file_name.split('_')
dir_name = '_'.join(x[1:-1])
class_dst_path = os.path.join(dst_path_exp, dir_name)
if not os.path.exists(class_dst_path):
os.makedirs(class_dst_path)
src_file_path = os.path.join(src_path_exp, f)
dst_file = os.path.join(class_dst_path, f)
print('%s -> %s' % (src_file_path, dst_file))
shutil.copyfile(src_file_path, dst_file)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('src_path', type=str, help='Path to the source directory.')
parser.add_argument('dst_path', type=str, help='Path to the destination directory.')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/dataset_read_speed.py
================================================
import facenet
import argparse
import sys
import time
import numpy as np
def main(args):
dataset = facenet.get_dataset(args.dir)
paths, _ = facenet.get_image_paths_and_labels(dataset)
t = np.zeros((len(paths)))
x = time.time()
for i, path in enumerate(paths):
start_time = time.time()
with open(path, mode='rb') as f:
_ = f.read()
duration = time.time() - start_time
t[i] = duration
if i % 1000 == 0 or i==len(paths)-1:
print('File %d/%d Total time: %.2f Avg: %.3f Std: %.3f' % (i, len(paths), time.time()-x, np.mean(t[0:i])*1000, np.std(t[0:i])*1000))
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('dir', type=str,
help='Directory with dataset to test')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/deepdream.py
================================================
# boilerplate code
import numpy as np
from functools import partial
import PIL.Image
import tensorflow as tf
import matplotlib.pyplot as plt
import urllib2
import os
import zipfile
def main():
# download pre-trained model by running the command below in a shell
# wget https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip && unzip inception5h.zip
url = 'https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip'
data_dir = '../data/'
model_name = os.path.split(url)[-1]
local_zip_file = os.path.join(data_dir, model_name)
if not os.path.exists(local_zip_file):
# Download
model_url = urllib2.urlopen(url)
with open(local_zip_file, 'wb') as output:
output.write(model_url.read())
# Extract
with zipfile.ZipFile(local_zip_file, 'r') as zip_ref:
zip_ref.extractall(data_dir)
# start with a gray image with a little noise
img_noise = np.random.uniform(size=(224,224,3)) + 100.0
model_fn = 'tensorflow_inception_graph.pb'
# creating TensorFlow session and loading the model
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)
with tf.gfile.FastGFile(os.path.join(data_dir, model_fn), 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
t_input = tf.placeholder(np.float32, name='input') # define the input tensor
imagenet_mean = 117.0
t_preprocessed = tf.expand_dims(t_input-imagenet_mean, 0)
tf.import_graph_def(graph_def, {'input':t_preprocessed})
layers = [op.name for op in graph.get_operations() if op.type=='Conv2D' and 'import/' in op.name]
feature_nums = [int(graph.get_tensor_by_name(name+':0').get_shape()[-1]) for name in layers]
print('Number of layers', len(layers))
print('Total number of feature channels:', sum(feature_nums))
# Helper functions for TF Graph visualization
#pylint: disable=unused-variable
def strip_consts(graph_def, max_const_size=32):
"""Strip large constant values from graph_def."""
strip_def = tf.GraphDef()
for n0 in graph_def.node:
n = strip_def.node.add() #pylint: disable=maybe-no-member
n.MergeFrom(n0)
if n.op == 'Const':
tensor = n.attr['value'].tensor
size = len(tensor.tensor_content)
if size > max_const_size:
tensor.tensor_content = ""%size
return strip_def
def rename_nodes(graph_def, rename_func):
res_def = tf.GraphDef()
for n0 in graph_def.node:
n = res_def.node.add() #pylint: disable=maybe-no-member
n.MergeFrom(n0)
n.name = rename_func(n.name)
for i, s in enumerate(n.input):
n.input[i] = rename_func(s) if s[0]!='^' else '^'+rename_func(s[1:])
return res_def
def showarray(a):
a = np.uint8(np.clip(a, 0, 1)*255)
plt.imshow(a)
plt.show()
def visstd(a, s=0.1):
'''Normalize the image range for visualization'''
return (a-a.mean())/max(a.std(), 1e-4)*s + 0.5
def T(layer):
'''Helper for getting layer output tensor'''
return graph.get_tensor_by_name("import/%s:0"%layer)
def render_naive(t_obj, img0=img_noise, iter_n=20, step=1.0):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
img = img0.copy()
for _ in range(iter_n):
g, _ = sess.run([t_grad, t_score], {t_input:img})
# normalizing the gradient, so the same step size should work
g /= g.std()+1e-8 # for different layers and networks
img += g*step
showarray(visstd(img))
def tffunc(*argtypes):
'''Helper that transforms TF-graph generating function into a regular one.
See "resize" function below.
'''
placeholders = list(map(tf.placeholder, argtypes))
def wrap(f):
out = f(*placeholders)
def wrapper(*args, **kw):
return out.eval(dict(zip(placeholders, args)), session=kw.get('session'))
return wrapper
return wrap
# Helper function that uses TF to resize an image
def resize(img, size):
img = tf.expand_dims(img, 0)
return tf.image.resize_bilinear(img, size)[0,:,:,:]
resize = tffunc(np.float32, np.int32)(resize)
def calc_grad_tiled(img, t_grad, tile_size=512):
'''Compute the value of tensor t_grad over the image in a tiled way.
Random shifts are applied to the image to blur tile boundaries over
multiple iterations.'''
sz = tile_size
h, w = img.shape[:2]
sx, sy = np.random.randint(sz, size=2)
img_shift = np.roll(np.roll(img, sx, 1), sy, 0)
grad = np.zeros_like(img)
for y in range(0, max(h-sz//2, sz),sz):
for x in range(0, max(w-sz//2, sz),sz):
sub = img_shift[y:y+sz,x:x+sz]
g = sess.run(t_grad, {t_input:sub})
grad[y:y+sz,x:x+sz] = g
return np.roll(np.roll(grad, -sx, 1), -sy, 0)
def render_multiscale(t_obj, img0=img_noise, iter_n=10, step=1.0, octave_n=3, octave_scale=1.4):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
img = img0.copy()
for octave in range(octave_n):
if octave>0:
hw = np.float32(img.shape[:2])*octave_scale
img = resize(img, np.int32(hw))
for _ in range(iter_n):
g = calc_grad_tiled(img, t_grad)
# normalizing the gradient, so the same step size should work
g /= g.std()+1e-8 # for different layers and networks
img += g*step
showarray(visstd(img))
def lap_split(img):
'''Split the image into lo and hi frequency components'''
with tf.name_scope('split'):
lo = tf.nn.conv2d(img, k5x5, [1,2,2,1], 'SAME')
lo2 = tf.nn.conv2d_transpose(lo, k5x5*4, tf.shape(img), [1,2,2,1])
hi = img-lo2
return lo, hi
def lap_split_n(img, n):
'''Build Laplacian pyramid with n splits'''
levels = []
for _ in range(n):
img, hi = lap_split(img)
levels.append(hi)
levels.append(img)
return levels[::-1]
def lap_merge(levels):
'''Merge Laplacian pyramid'''
img = levels[0]
for hi in levels[1:]:
with tf.name_scope('merge'):
img = tf.nn.conv2d_transpose(img, k5x5*4, tf.shape(hi), [1,2,2,1]) + hi
return img
def normalize_std(img, eps=1e-10):
'''Normalize image by making its standard deviation = 1.0'''
with tf.name_scope('normalize'):
std = tf.sqrt(tf.reduce_mean(tf.square(img)))
return img/tf.maximum(std, eps)
def lap_normalize(img, scale_n=4):
'''Perform the Laplacian pyramid normalization.'''
img = tf.expand_dims(img,0)
tlevels = lap_split_n(img, scale_n)
tlevels = list(map(normalize_std, tlevels))
out = lap_merge(tlevels)
return out[0,:,:,:]
def render_lapnorm(t_obj, img0=img_noise, visfunc=visstd,
iter_n=10, step=1.0, octave_n=3, octave_scale=1.4, lap_n=4):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
# build the laplacian normalization graph
lap_norm_func = tffunc(np.float32)(partial(lap_normalize, scale_n=lap_n))
img = img0.copy()
for octave in range(octave_n):
if octave>0:
hw = np.float32(img.shape[:2])*octave_scale
img = resize(img, np.int32(hw))
for _ in range(iter_n):
g = calc_grad_tiled(img, t_grad)
g = lap_norm_func(g)
img += g*step
showarray(visfunc(img))
def render_deepdream(t_obj, img0=img_noise,
iter_n=10, step=1.5, octave_n=4, octave_scale=1.4):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
# split the image into a number of octaves
img = img0
octaves = []
for _ in range(octave_n-1):
hw = img.shape[:2]
lo = resize(img, np.int32(np.float32(hw)/octave_scale))
hi = img-resize(lo, hw)
img = lo
octaves.append(hi)
# generate details octave by octave
for octave in range(octave_n):
if octave>0:
hi = octaves[-octave]
img = resize(img, hi.shape[:2])+hi
for _ in range(iter_n):
g = calc_grad_tiled(img, t_grad)
img += g*(step / (np.abs(g).mean()+1e-7))
showarray(img/255.0)
# Picking some internal layer. Note that we use outputs before applying the ReLU nonlinearity
# to have non-zero gradients for features with negative initial activations.
layer = 'mixed4d_3x3_bottleneck_pre_relu'
channel = 139 # picking some feature channel to visualize
render_naive(T(layer)[:,:,:,channel])
render_multiscale(T(layer)[:,:,:,channel])
k = np.float32([1,4,6,4,1])
k = np.outer(k, k)
k5x5 = k[:,:,None,None]/k.sum()*np.eye(3, dtype=np.float32)
render_lapnorm(T(layer)[:,:,:,channel])
render_lapnorm(T(layer)[:,:,:,65])
render_lapnorm(T('mixed3b_1x1_pre_relu')[:,:,:,101])
render_lapnorm(T(layer)[:,:,:,65]+T(layer)[:,:,:,139], octave_n=4)
img0 = PIL.Image.open('pilatus800.jpg')
img0 = np.float32(img0)
showarray(img0/255.0)
render_deepdream(tf.square(T('mixed4c')), img0)
render_deepdream(T(layer)[:,:,:,139], img0)
if __name__ == '__main__':
main()
================================================
FILE: tmp/detect_face_v1.m
================================================
% MIT License
%
% Copyright (c) 2016 Kaipeng Zhang
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.
function [total_boxes, points] = detect_face_v1(img,minsize,PNet,RNet,ONet,threshold,fastresize,factor)
%im: input image
%minsize: minimum of faces' size
%pnet, rnet, onet: caffemodel
%threshold: threshold=[th1 th2 th3], th1-3 are three steps's threshold
%fastresize: resize img from last scale (using in high-resolution images) if fastresize==true
factor_count=0;
total_boxes=[];
points=[];
h=size(img,1);
w=size(img,2);
minl=min([w h]);
img=single(img);
if fastresize
im_data=(single(img)-127.5)*0.0078125;
end
m=12/minsize;
minl=minl*m;
%creat scale pyramid
scales=[];
while (minl>=12)
scales=[scales m*factor^(factor_count)];
minl=minl*factor;
factor_count=factor_count+1;
end
%first stage
for j = 1:size(scales,2)
scale=scales(j);
hs=ceil(h*scale);
ws=ceil(w*scale);
if fastresize
im_data=imResample(im_data,[hs ws],'bilinear');
else
im_data=(imResample(img,[hs ws],'bilinear')-127.5)*0.0078125;
end
PNet.blobs('data').reshape([hs ws 3 1]);
out=PNet.forward({im_data});
boxes=generateBoundingBox(out{2}(:,:,2),out{1},scale,threshold(1));
%inter-scale nms
pick=nms(boxes,0.5,'Union');
boxes=boxes(pick,:);
if ~isempty(boxes)
total_boxes=[total_boxes;boxes];
end
end
numbox=size(total_boxes,1);
if ~isempty(total_boxes)
pick=nms(total_boxes,0.7,'Union');
total_boxes=total_boxes(pick,:);
regw=total_boxes(:,3)-total_boxes(:,1);
regh=total_boxes(:,4)-total_boxes(:,2);
total_boxes=[total_boxes(:,1)+total_boxes(:,6).*regw total_boxes(:,2)+total_boxes(:,7).*regh total_boxes(:,3)+total_boxes(:,8).*regw total_boxes(:,4)+total_boxes(:,9).*regh total_boxes(:,5)];
total_boxes=rerec(total_boxes);
total_boxes(:,1:4)=fix(total_boxes(:,1:4));
[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
end
numbox=size(total_boxes,1);
if numbox>0
%second stage
tempimg=zeros(24,24,3,numbox);
for k=1:numbox
tmp=zeros(tmph(k),tmpw(k),3);
tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
if size(tmp,1)>0 && size(tmp,2)>0 || size(tmp,1)==0 && size(tmp,2)==0
tempimg(:,:,:,k)=imResample(tmp,[24 24],'bilinear');
else
total_boxes = [];
return;
end;
end
tempimg=(tempimg-127.5)*0.0078125;
RNet.blobs('data').reshape([24 24 3 numbox]);
out=RNet.forward({tempimg});
score=squeeze(out{2}(2,:));
pass=find(score>threshold(2));
total_boxes=[total_boxes(pass,1:4) score(pass)'];
mv=out{1}(:,pass);
if size(total_boxes,1)>0
pick=nms(total_boxes,0.7,'Union');
total_boxes=total_boxes(pick,:);
total_boxes=bbreg(total_boxes,mv(:,pick)');
total_boxes=rerec(total_boxes);
end
numbox=size(total_boxes,1);
if numbox>0
%third stage
total_boxes=fix(total_boxes);
[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
tempimg=zeros(48,48,3,numbox);
for k=1:numbox
tmp=zeros(tmph(k),tmpw(k),3);
tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
if size(tmp,1)>0 && size(tmp,2)>0 || size(tmp,1)==0 && size(tmp,2)==0
tempimg(:,:,:,k)=imResample(tmp,[48 48],'bilinear');
else
total_boxes = [];
return;
end;
end
tempimg=(tempimg-127.5)*0.0078125;
ONet.blobs('data').reshape([48 48 3 numbox]);
out=ONet.forward({tempimg});
score=squeeze(out{3}(2,:));
points=out{2};
pass=find(score>threshold(3));
points=points(:,pass);
total_boxes=[total_boxes(pass,1:4) score(pass)'];
mv=out{1}(:,pass);
w=total_boxes(:,3)-total_boxes(:,1)+1;
h=total_boxes(:,4)-total_boxes(:,2)+1;
points(1:5,:)=repmat(w',[5 1]).*points(1:5,:)+repmat(total_boxes(:,1)',[5 1])-1;
points(6:10,:)=repmat(h',[5 1]).*points(6:10,:)+repmat(total_boxes(:,2)',[5 1])-1;
if size(total_boxes,1)>0
total_boxes=bbreg(total_boxes,mv(:,:)');
pick=nms(total_boxes,0.7,'Min');
total_boxes=total_boxes(pick,:);
points=points(:,pick);
end
end
end
end
function [boundingbox] = bbreg(boundingbox,reg)
%calibrate bouding boxes
if size(reg,2)==1
reg=reshape(reg,[size(reg,3) size(reg,4)])';
end
w=[boundingbox(:,3)-boundingbox(:,1)]+1;
h=[boundingbox(:,4)-boundingbox(:,2)]+1;
boundingbox(:,1:4)=[boundingbox(:,1)+reg(:,1).*w boundingbox(:,2)+reg(:,2).*h boundingbox(:,3)+reg(:,3).*w boundingbox(:,4)+reg(:,4).*h];
end
function [boundingbox reg] = generateBoundingBox(map,reg,scale,t)
%use heatmap to generate bounding boxes
stride=2;
cellsize=12;
boundingbox=[];
map=map';
dx1=reg(:,:,1)';
dy1=reg(:,:,2)';
dx2=reg(:,:,3)';
dy2=reg(:,:,4)';
[y x]=find(map>=t);
a=find(map>=t);
if size(y,1)==1
y=y';x=x';score=map(a)';dx1=dx1';dy1=dy1';dx2=dx2';dy2=dy2';
else
score=map(a);
end
reg=[dx1(a) dy1(a) dx2(a) dy2(a)];
if isempty(reg)
reg=reshape([],[0 3]);
end
boundingbox=[y x];
boundingbox=[fix((stride*(boundingbox-1)+1)/scale) fix((stride*(boundingbox-1)+cellsize-1+1)/scale) score reg];
end
function pick = nms(boxes,threshold,type)
%NMS
if isempty(boxes)
pick = [];
return;
end
x1 = boxes(:,1);
y1 = boxes(:,2);
x2 = boxes(:,3);
y2 = boxes(:,4);
s = boxes(:,5);
area = (x2-x1+1) .* (y2-y1+1);
[vals, I] = sort(s);
pick = s*0;
counter = 1;
while ~isempty(I)
last = length(I);
i = I(last);
pick(counter) = i;
counter = counter + 1;
xx1 = max(x1(i), x1(I(1:last-1)));
yy1 = max(y1(i), y1(I(1:last-1)));
xx2 = min(x2(i), x2(I(1:last-1)));
yy2 = min(y2(i), y2(I(1:last-1)));
w = max(0.0, xx2-xx1+1);
h = max(0.0, yy2-yy1+1);
inter = w.*h;
if strcmp(type,'Min')
o = inter ./ min(area(i),area(I(1:last-1)));
else
o = inter ./ (area(i) + area(I(1:last-1)) - inter);
end
I = I(find(o<=threshold));
end
pick = pick(1:(counter-1));
end
function [dy edy dx edx y ey x ex tmpw tmph] = pad(total_boxes,w,h)
%compute the padding coordinates (pad the bounding boxes to square)
tmpw=total_boxes(:,3)-total_boxes(:,1)+1;
tmph=total_boxes(:,4)-total_boxes(:,2)+1;
numbox=size(total_boxes,1);
dx=ones(numbox,1);dy=ones(numbox,1);
edx=tmpw;edy=tmph;
x=total_boxes(:,1);y=total_boxes(:,2);
ex=total_boxes(:,3);ey=total_boxes(:,4);
tmp=find(ex>w);
edx(tmp)=-ex(tmp)+w+tmpw(tmp);ex(tmp)=w;
tmp=find(ey>h);
edy(tmp)=-ey(tmp)+h+tmph(tmp);ey(tmp)=h;
tmp=find(x<1);
dx(tmp)=2-x(tmp);x(tmp)=1;
tmp=find(y<1);
dy(tmp)=2-y(tmp);y(tmp)=1;
end
function [bboxA] = rerec(bboxA)
%convert bboxA to square
bboxB=bboxA(:,1:4);
h=bboxA(:,4)-bboxA(:,2);
w=bboxA(:,3)-bboxA(:,1);
l=max([w h]')';
bboxA(:,1)=bboxA(:,1)+w.*0.5-l.*0.5;
bboxA(:,2)=bboxA(:,2)+h.*0.5-l.*0.5;
bboxA(:,3:4)=bboxA(:,1:2)+repmat(l,[1 2]);
end
================================================
FILE: tmp/detect_face_v2.m
================================================
% MIT License
%
% Copyright (c) 2016 Kaipeng Zhang
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.
function [total_boxes, points] = detect_face_v2(img,minsize,PNet,RNet,ONet,LNet,threshold,fastresize,factor)
%im: input image
%minsize: minimum of faces' size
%pnet, rnet, onet: caffemodel
%threshold: threshold=[th1 th2 th3], th1-3 are three steps's threshold
%fastresize: resize img from last scale (using in high-resolution images) if fastresize==true
factor_count=0;
total_boxes=[];
points=[];
h=size(img,1);
w=size(img,2);
minl=min([w h]);
img=single(img);
if fastresize
im_data=(single(img)-127.5)*0.0078125;
end
m=12/minsize;
minl=minl*m;
%creat scale pyramid
scales=[];
while (minl>=12)
scales=[scales m*factor^(factor_count)];
minl=minl*factor;
factor_count=factor_count+1;
end
%first stage
for j = 1:size(scales,2)
scale=scales(j);
hs=ceil(h*scale);
ws=ceil(w*scale);
if fastresize
im_data=imResample(im_data,[hs ws],'bilinear');
else
im_data=(imResample(img,[hs ws],'bilinear')-127.5)*0.0078125;
end
PNet.blobs('data').reshape([hs ws 3 1]);
out=PNet.forward({im_data});
boxes=generateBoundingBox(out{2}(:,:,2),out{1},scale,threshold(1));
%inter-scale nms
pick=nms(boxes,0.5,'Union');
boxes=boxes(pick,:);
if ~isempty(boxes)
total_boxes=[total_boxes;boxes];
end
end
numbox=size(total_boxes,1);
if ~isempty(total_boxes)
pick=nms(total_boxes,0.7,'Union');
total_boxes=total_boxes(pick,:);
bbw=total_boxes(:,3)-total_boxes(:,1);
bbh=total_boxes(:,4)-total_boxes(:,2);
total_boxes=[total_boxes(:,1)+total_boxes(:,6).*bbw total_boxes(:,2)+total_boxes(:,7).*bbh total_boxes(:,3)+total_boxes(:,8).*bbw total_boxes(:,4)+total_boxes(:,9).*bbh total_boxes(:,5)];
total_boxes=rerec(total_boxes);
total_boxes(:,1:4)=fix(total_boxes(:,1:4));
[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
end
numbox=size(total_boxes,1);
if numbox>0
%second stage
tempimg=zeros(24,24,3,numbox);
for k=1:numbox
tmp=zeros(tmph(k),tmpw(k),3);
tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
tempimg(:,:,:,k)=imResample(tmp,[24 24],'bilinear');
end
tempimg=(tempimg-127.5)*0.0078125;
RNet.blobs('data').reshape([24 24 3 numbox]);
out=RNet.forward({tempimg});
score=squeeze(out{2}(2,:));
pass=find(score>threshold(2));
total_boxes=[total_boxes(pass,1:4) score(pass)'];
mv=out{1}(:,pass);
if size(total_boxes,1)>0
pick=nms(total_boxes,0.7,'Union');
total_boxes=total_boxes(pick,:);
total_boxes=bbreg(total_boxes,mv(:,pick)');
total_boxes=rerec(total_boxes);
end
numbox=size(total_boxes,1);
if numbox>0
%third stage
total_boxes=fix(total_boxes);
[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
tempimg=zeros(48,48,3,numbox);
for k=1:numbox
tmp=zeros(tmph(k),tmpw(k),3);
tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
tempimg(:,:,:,k)=imResample(tmp,[48 48],'bilinear');
end
tempimg=(tempimg-127.5)*0.0078125;
ONet.blobs('data').reshape([48 48 3 numbox]);
out=ONet.forward({tempimg});
score=squeeze(out{3}(2,:));
points=out{2};
pass=find(score>threshold(3));
points=points(:,pass);
total_boxes=[total_boxes(pass,1:4) score(pass)'];
mv=out{1}(:,pass);
bbw=total_boxes(:,3)-total_boxes(:,1)+1;
bbh=total_boxes(:,4)-total_boxes(:,2)+1;
points(1:5,:)=repmat(bbw',[5 1]).*points(1:5,:)+repmat(total_boxes(:,1)',[5 1])-1;
points(6:10,:)=repmat(bbh',[5 1]).*points(6:10,:)+repmat(total_boxes(:,2)',[5 1])-1;
if size(total_boxes,1)>0
total_boxes=bbreg(total_boxes,mv(:,:)');
pick=nms(total_boxes,0.7,'Min');
total_boxes=total_boxes(pick,:);
points=points(:,pick);
end
end
numbox=size(total_boxes,1);
%extended stage
if numbox>0
tempimg=zeros(24,24,15,numbox);
patchw=max([total_boxes(:,3)-total_boxes(:,1)+1 total_boxes(:,4)-total_boxes(:,2)+1]');
patchw=fix(0.25*patchw);
tmp=find(mod(patchw,2)==1);
patchw(tmp)=patchw(tmp)+1;
pointx=ones(numbox,5);
pointy=ones(numbox,5);
for k=1:5
tmp=[points(k,:);points(k+5,:)];
x=fix(tmp(1,:)-0.5*patchw);
y=fix(tmp(2,:)-0.5*patchw);
[dy edy dx edx y ey x ex tmpw tmph]=pad([x' y' x'+patchw' y'+patchw'],w,h);
for j=1:numbox
tmpim=zeros(tmpw(j),tmpw(j),3);
tmpim(dy(j):edy(j),dx(j):edx(j),:)=img(y(j):ey(j),x(j):ex(j),:);
tempimg(:,:,(k-1)*3+1:(k-1)*3+3,j)=imResample(tmpim,[24 24],'bilinear');
end
end
LNet.blobs('data').reshape([24 24 15 numbox]);
tempimg=(tempimg-127.5)*0.0078125;
out=LNet.forward({tempimg});
score=squeeze(out{3}(2,:));
for k=1:5
tmp=[points(k,:);points(k+5,:)];
%do not make a large movement
temp=find(abs(out{k}(1,:)-0.5)>0.35);
if ~isempty(temp)
l=length(temp);
out{k}(:,temp)=ones(2,l)*0.5;
end
temp=find(abs(out{k}(2,:)-0.5)>0.35);
if ~isempty(temp)
l=length(temp);
out{k}(:,temp)=ones(2,l)*0.5;
end
pointx(:,k)=(tmp(1,:)-0.5*patchw+out{k}(1,:).*patchw)';
pointy(:,k)=(tmp(2,:)-0.5*patchw+out{k}(2,:).*patchw)';
end
for j=1:numbox
points(:,j)=[pointx(j,:)';pointy(j,:)'];
end
end
end
end
function [boundingbox] = bbreg(boundingbox,reg)
%calibrate bouding boxes
if size(reg,2)==1
reg=reshape(reg,[size(reg,3) size(reg,4)])';
end
w=[boundingbox(:,3)-boundingbox(:,1)]+1;
h=[boundingbox(:,4)-boundingbox(:,2)]+1;
boundingbox(:,1:4)=[boundingbox(:,1)+reg(:,1).*w boundingbox(:,2)+reg(:,2).*h boundingbox(:,3)+reg(:,3).*w boundingbox(:,4)+reg(:,4).*h];
end
function [boundingbox reg] = generateBoundingBox(map,reg,scale,t)
%use heatmap to generate bounding boxes
stride=2;
cellsize=12;
boundingbox=[];
map=map';
dx1=reg(:,:,1)';
dy1=reg(:,:,2)';
dx2=reg(:,:,3)';
dy2=reg(:,:,4)';
[y x]=find(map>=t);
a=find(map>=t);
if size(y,1)==1
y=y';x=x';score=map(a)';dx1=dx1';dy1=dy1';dx2=dx2';dy2=dy2';
else
score=map(a);
end
reg=[dx1(a) dy1(a) dx2(a) dy2(a)];
if isempty(reg)
reg=reshape([],[0 3]);
end
boundingbox=[y x];
boundingbox=[fix((stride*(boundingbox-1)+1)/scale) fix((stride*(boundingbox-1)+cellsize-1+1)/scale) score reg];
end
function pick = nms(boxes,threshold,type)
%NMS
if isempty(boxes)
pick = [];
return;
end
x1 = boxes(:,1);
y1 = boxes(:,2);
x2 = boxes(:,3);
y2 = boxes(:,4);
s = boxes(:,5);
area = (x2-x1+1) .* (y2-y1+1);
[vals, I] = sort(s);
pick = s*0;
counter = 1;
while ~isempty(I)
last = length(I);
i = I(last);
pick(counter) = i;
counter = counter + 1;
xx1 = max(x1(i), x1(I(1:last-1)));
yy1 = max(y1(i), y1(I(1:last-1)));
xx2 = min(x2(i), x2(I(1:last-1)));
yy2 = min(y2(i), y2(I(1:last-1)));
w = max(0.0, xx2-xx1+1);
h = max(0.0, yy2-yy1+1);
inter = w.*h;
if strcmp(type,'Min')
o = inter ./ min(area(i),area(I(1:last-1)));
else
o = inter ./ (area(i) + area(I(1:last-1)) - inter);
end
I = I(find(o<=threshold));
end
pick = pick(1:(counter-1));
end
function [dy edy dx edx y ey x ex tmpw tmph] = pad(total_boxes,w,h)
%compute the padding coordinates (pad the bounding boxes to square)
tmpw=total_boxes(:,3)-total_boxes(:,1)+1;
tmph=total_boxes(:,4)-total_boxes(:,2)+1;
numbox=size(total_boxes,1);
dx=ones(numbox,1);dy=ones(numbox,1);
edx=tmpw;edy=tmph;
x=total_boxes(:,1);y=total_boxes(:,2);
ex=total_boxes(:,3);ey=total_boxes(:,4);
tmp=find(ex>w);
edx(tmp)=-ex(tmp)+w+tmpw(tmp);ex(tmp)=w;
tmp=find(ey>h);
edy(tmp)=-ey(tmp)+h+tmph(tmp);ey(tmp)=h;
tmp=find(x<1);
dx(tmp)=2-x(tmp);x(tmp)=1;
tmp=find(y<1);
dy(tmp)=2-y(tmp);y(tmp)=1;
end
function [bboxA] = rerec(bboxA)
%convert bboxA to square
bboxB=bboxA(:,1:4);
h=bboxA(:,4)-bboxA(:,2);
w=bboxA(:,3)-bboxA(:,1);
l=max([w h]')';
bboxA(:,1)=bboxA(:,1)+w.*0.5-l.*0.5;
bboxA(:,2)=bboxA(:,2)+h.*0.5-l.*0.5;
bboxA(:,3:4)=bboxA(:,1:2)+repmat(l,[1 2]);
end
================================================
FILE: tmp/download_vgg_face_dataset.py
================================================
"""Download the VGG face dataset from URLs given by http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import numpy as np
from skimage import io
import sys
import argparse
import os
import socket
from urllib2 import HTTPError, URLError
from httplib import HTTPException
def main(args):
socket.setdefaulttimeout(30)
textfile_names = os.listdir(args.dataset_descriptor)
for textfile_name in textfile_names:
if textfile_name.endswith('.txt'):
with open(os.path.join(args.dataset_descriptor, textfile_name), 'rt') as f:
lines = f.readlines()
dir_name = textfile_name.split('.')[0]
class_path = os.path.join(args.dataset_descriptor, dir_name)
if not os.path.exists(class_path):
os.makedirs(class_path)
for line in lines:
x = line.split(' ')
filename = x[0]
url = x[1]
box = np.rint(np.array(map(float, x[2:6]))) # x1,y1,x2,y2
image_path = os.path.join(args.dataset_descriptor, dir_name, filename+'.'+args.output_format)
error_path = os.path.join(args.dataset_descriptor, dir_name, filename+'.err')
if not os.path.exists(image_path) and not os.path.exists(error_path):
try:
img = io.imread(url, mode='RGB')
except (HTTPException, HTTPError, URLError, IOError, ValueError, IndexError, OSError) as e:
error_message = '{}: {}'.format(url, e)
save_error_message_file(error_path, error_message)
else:
try:
if img.ndim == 2:
img = to_rgb(img)
if img.ndim != 3:
raise ValueError('Wrong number of image dimensions')
hist = np.histogram(img, 255, density=True)
if hist[0][0]>0.9 and hist[0][254]>0.9:
raise ValueError('Image is mainly black or white')
else:
# Crop image according to dataset descriptor
img_cropped = img[int(box[1]):int(box[3]),int(box[0]):int(box[2]),:]
# Scale to 256x256
img_resized = misc.imresize(img_cropped, (args.image_size,args.image_size))
# Save image as .png
misc.imsave(image_path, img_resized)
except ValueError as e:
error_message = '{}: {}'.format(url, e)
save_error_message_file(error_path, error_message)
def save_error_message_file(filename, error_message):
print(error_message)
with open(filename, "w") as textfile:
textfile.write(error_message)
def to_rgb(img):
w, h = img.shape
ret = np.empty((w, h, 3), dtype=np.uint8)
ret[:, :, 0] = ret[:, :, 1] = ret[:, :, 2] = img
return ret
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('dataset_descriptor', type=str,
help='Directory containing the text files with the image URLs. Image files will also be placed in this directory.')
parser.add_argument('--output_format', type=str, help='Format of the output images', default='png', choices=['png', 'jpg'])
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=256)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/funnel_dataset.py
================================================
"""Performs face alignment and stores face thumbnails in the output directory."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy import misc
import sys
import os
import argparse
import facenet
import subprocess
from contextlib import contextmanager
import tempfile
import shutil
import numpy as np
@contextmanager
def TemporaryDirectory():
name = tempfile.mkdtemp()
try:
yield name
finally:
shutil.rmtree(name)
def main(args):
funnel_cmd = 'funnelReal'
funnel_model = 'people.train'
output_dir = os.path.expanduser(args.output_dir)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Store some git revision info in a text file in the output directory
src_path,_ = os.path.split(os.path.realpath(__file__))
facenet.store_revision_info(src_path, output_dir, ' '.join(sys.argv))
dataset = facenet.get_dataset(args.input_dir)
np.random.shuffle(dataset)
# Scale the image such that the face fills the frame when cropped to crop_size
#scale = float(args.face_size) / args.image_size
with TemporaryDirectory() as tmp_dir:
for cls in dataset:
output_class_dir = os.path.join(output_dir, cls.name)
tmp_output_class_dir = os.path.join(tmp_dir, cls.name)
if not os.path.exists(output_class_dir) and not os.path.exists(tmp_output_class_dir):
print('Aligning class %s:' % cls.name)
tmp_filenames = []
if not os.path.exists(tmp_output_class_dir):
os.makedirs(tmp_output_class_dir)
input_list_filename = os.path.join(tmp_dir, 'input_list.txt')
output_list_filename = os.path.join(tmp_dir, 'output_list.txt')
input_file = open(input_list_filename, 'w')
output_file = open(output_list_filename,'w')
for image_path in cls.image_paths:
filename = os.path.split(image_path)[1]
input_file.write(image_path+'\n')
output_filename = os.path.join(tmp_output_class_dir, filename)
output_file.write(output_filename+'\n')
tmp_filenames.append(output_filename)
input_file.close()
output_file.close()
cmd = args.funnel_dir+funnel_cmd + ' ' + input_list_filename + ' ' + args.funnel_dir+funnel_model + ' ' + output_list_filename
subprocess.call(cmd, shell=True)
# Resize and crop images
if not os.path.exists(output_class_dir):
os.makedirs(output_class_dir)
scale = 1.0
for tmp_filename in tmp_filenames:
img = misc.imread(tmp_filename)
img_scale = misc.imresize(img, scale)
sz1 = img.shape[1]/2
sz2 = args.image_size/2
img_crop = img_scale[int(sz1-sz2):int(sz1+sz2),int(sz1-sz2):int(sz1+sz2),:]
filename = os.path.splitext(os.path.split(tmp_filename)[1])[0]
output_filename = os.path.join(output_class_dir, filename+'.png')
print('Saving image %s' % output_filename)
misc.imsave(output_filename, img_crop)
# Remove tmp directory with images
shutil.rmtree(tmp_output_class_dir)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('input_dir', type=str, help='Directory with unaligned images.')
parser.add_argument('output_dir', type=str, help='Directory with aligned face thumbnails.')
parser.add_argument('funnel_dir', type=str, help='Directory containing the funnelReal binary and the people.train model file')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=110)
parser.add_argument('--face_size', type=int,
help='Size of the face thumbnail (height, width) in pixels.', default=96)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/invariance_test.txt
================================================
Accuracy: 0.860±0.009
Accuracy: 0.861±0.008
Accuracy: 0.870±0.011
Accuracy: 0.885±0.012
Accuracy: 0.896±0.013
Accuracy: 0.899±0.015
Accuracy: 0.887±0.011
Accuracy: 0.885±0.011
Accuracy: 0.890±0.011
Accuracy: 0.910±0.014
Accuracy: 0.918±0.012
Accuracy: 0.904±0.013
Accuracy: 0.895±0.012
Accuracy: 0.884±0.018
Accuracy: 0.891±0.012
Accuracy: 0.891±0.008
Accuracy: 0.889±0.009
Accuracy: 0.871±0.012
Accuracy: 0.844±0.012
Accuracy: 0.835±0.016
Accuracy: 0.823±0.015
Hoffset: Accuracy:
-30.0000 0.8600
-27.0000 0.8607
-24.0000 0.8697
-21.0000 0.8848
-18.0000 0.8963
-15.0000 0.8992
-12.0000 0.8865
-9.0000 0.8853
-6.0000 0.8900
-3.0000 0.9097
0.0000 0.9182
3.0000 0.9040
6.0000 0.8953
9.0000 0.8843
12.0000 0.8905
15.0000 0.8913
18.0000 0.8888
21.0000 0.8708
24.0000 0.8440
27.0000 0.8348
30.0000 0.8233
Accuracy: 0.823±0.014
Accuracy: 0.800±0.010
Accuracy: 0.800±0.015
Accuracy: 0.818±0.018
Accuracy: 0.852±0.012
Accuracy: 0.864±0.011
Accuracy: 0.844±0.016
Accuracy: 0.851±0.014
Accuracy: 0.875±0.012
Accuracy: 0.898±0.010
Accuracy: 0.918±0.012
Accuracy: 0.886±0.015
Accuracy: 0.849±0.012
Accuracy: 0.812±0.015
Accuracy: 0.780±0.012
Accuracy: 0.787±0.012
Accuracy: 0.755±0.016
Accuracy: 0.709±0.010
Accuracy: 0.676±0.017
Accuracy: 0.653±0.011
Accuracy: 0.648±0.016
Voffset: Accuracy:
-30.0000 0.8230
-27.0000 0.7997
-24.0000 0.7995
-21.0000 0.8183
-18.0000 0.8523
-15.0000 0.8638
-12.0000 0.8442
-9.0000 0.8507
-6.0000 0.8755
-3.0000 0.8982
0.0000 0.9182
3.0000 0.8862
6.0000 0.8493
9.0000 0.8118
12.0000 0.7803
15.0000 0.7868
18.0000 0.7548
21.0000 0.7093
24.0000 0.6763
27.0000 0.6533
30.0000 0.6483
================================================
FILE: tmp/mnist_center_loss.py
================================================
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Simple, end-to-end, LeNet-5-like convolutional MNIST model example.
This should achieve a test error of 0.7%. Please keep this model as simple and
linear as possible, it is meant as a tutorial for simple convolutional models.
Run with --self_test on the command line to execute a short self-test.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import gzip
import os
import sys
import time
from six.moves import urllib # @UnresolvedImport
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.python.ops import control_flow_ops
import facenet
from six.moves import xrange
SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'
WORK_DIRECTORY = 'data'
IMAGE_SIZE = 28
NUM_CHANNELS = 1
PIXEL_DEPTH = 255
NUM_LABELS = 10
VALIDATION_SIZE = 5000 # Size of the validation set.
SEED = 66478 # Set to None for random seed.
BATCH_SIZE = 64
NUM_EPOCHS = 10
EVAL_BATCH_SIZE = 64
EVAL_FREQUENCY = 100 # Number of steps between evaluations.
tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.")
tf.app.flags.DEFINE_boolean('use_fp16', False,
"Use half floats instead of full floats if True.")
FLAGS = tf.app.flags.FLAGS
def data_type():
"""Return the type of the activations, weights, and placeholder variables."""
if FLAGS.use_fp16:
return tf.float16
else:
return tf.float32
def maybe_download(filename):
"""Download the data from Yann's website, unless it's already here."""
if not tf.gfile.Exists(WORK_DIRECTORY):
tf.gfile.MakeDirs(WORK_DIRECTORY)
filepath = os.path.join(WORK_DIRECTORY, filename)
if not tf.gfile.Exists(filepath):
filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)
with tf.gfile.GFile(filepath) as f:
size = f.size()
print('Successfully downloaded', filename, size, 'bytes.')
return filepath
def extract_data(filename, num_images):
"""Extract the images into a 4D tensor [image index, y, x, channels].
Values are rescaled from [0, 255] down to [-0.5, 0.5].
"""
print('Extracting', filename)
with gzip.open(filename) as bytestream:
bytestream.read(16)
buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS)
data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH
data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)
return data
def extract_labels(filename, num_images):
"""Extract the labels into a vector of int64 label IDs."""
print('Extracting', filename)
with gzip.open(filename) as bytestream:
bytestream.read(8)
buf = bytestream.read(1 * num_images)
labels = np.frombuffer(buf, dtype=np.uint8).astype(np.int64)
return labels
def fake_data(num_images):
"""Generate a fake dataset that matches the dimensions of MNIST."""
data = np.ndarray(
shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS),
dtype=np.float32)
labels = np.zeros(shape=(num_images,), dtype=np.int64)
for image in range(num_images):
label = image % 2
data[image, :, :, 0] = label - 0.5
labels[image] = label
return data, labels
def error_rate(predictions, labels):
"""Return the error rate based on dense predictions and sparse labels."""
return 100.0 - (
100.0 *
np.sum(np.argmax(predictions, 1) == labels) /
predictions.shape[0])
def main(argv=None): # pylint: disable=unused-argument
if FLAGS.self_test:
print('Running self-test.')
train_data, train_labels = fake_data(256)
validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE)
test_data, test_labels = fake_data(EVAL_BATCH_SIZE)
num_epochs = 1
else:
# Get the data.
train_data_filename = maybe_download('train-images-idx3-ubyte.gz')
train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz')
test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz')
test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz')
# Extract it into numpy arrays.
train_data = extract_data(train_data_filename, 60000)
train_labels = extract_labels(train_labels_filename, 60000)
test_data = extract_data(test_data_filename, 10000)
test_labels = extract_labels(test_labels_filename, 10000)
# Generate a validation set.
validation_data = train_data[:VALIDATION_SIZE, ...]
validation_labels = train_labels[:VALIDATION_SIZE]
train_data = train_data[VALIDATION_SIZE:, ...]
train_labels = train_labels[VALIDATION_SIZE:]
num_epochs = NUM_EPOCHS
train_size = train_labels.shape[0]
# This is where training samples and labels are fed to the graph.
# These placeholder nodes will be fed a batch of training data at each
# training step using the {feed_dict} argument to the Run() call below.
train_data_node = tf.placeholder(
data_type(),
shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))
train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,))
eval_data = tf.placeholder(
data_type(),
shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))
# The variables below hold all the trainable weights. They are passed an
# initial value which will be assigned when we call:
# {tf.global_variables_initializer().run()}
conv1_weights = tf.Variable(
tf.truncated_normal([5, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32.
stddev=0.1,
seed=SEED, dtype=data_type()))
conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type()))
conv2_weights = tf.Variable(tf.truncated_normal(
[5, 5, 32, 64], stddev=0.1,
seed=SEED, dtype=data_type()))
conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type()))
fc1_weights = tf.Variable( # fully connected, depth 512.
tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512],
stddev=0.1,
seed=SEED,
dtype=data_type()))
fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type()))
fc1p_weights = tf.Variable( # fully connected, depth 512.
tf.truncated_normal([512, 2],
stddev=0.1,
seed=SEED,
dtype=data_type()))
fc1p_biases = tf.Variable(tf.constant(0.1, shape=[2], dtype=data_type()))
fc2_weights = tf.Variable(tf.truncated_normal([2, NUM_LABELS],
stddev=0.1,
seed=SEED,
dtype=data_type()))
fc2_biases = tf.Variable(tf.constant(
0.1, shape=[NUM_LABELS], dtype=data_type()))
def batch_norm(x, phase_train): #pylint: disable=unused-variable
"""
Batch normalization on convolutional maps.
Args:
x: Tensor, 4D BHWD input maps
n_out: integer, depth of input maps
phase_train: boolean tf.Variable, true indicates training phase
scope: string, variable scope
affn: whether to affn-transform outputs
Return:
normed: batch-normalized maps
Ref: http://stackoverflow.com/questions/33949786/how-could-i-use-batch-normalization-in-tensorflow/33950177
"""
name = 'batch_norm'
with tf.variable_scope(name):
phase_train = tf.convert_to_tensor(phase_train, dtype=tf.bool)
n_out = int(x.get_shape()[-1])
beta = tf.Variable(tf.constant(0.0, shape=[n_out], dtype=x.dtype),
name=name+'/beta', trainable=True, dtype=x.dtype)
gamma = tf.Variable(tf.constant(1.0, shape=[n_out], dtype=x.dtype),
name=name+'/gamma', trainable=True, dtype=x.dtype)
batch_mean, batch_var = tf.nn.moments(x, [0], name='moments')
ema = tf.train.ExponentialMovingAverage(decay=0.9)
def mean_var_with_update():
ema_apply_op = ema.apply([batch_mean, batch_var])
with tf.control_dependencies([ema_apply_op]):
return tf.identity(batch_mean), tf.identity(batch_var)
mean, var = control_flow_ops.cond(phase_train,
mean_var_with_update,
lambda: (ema.average(batch_mean), ema.average(batch_var)))
normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, 1e-3)
return normed
# We will replicate the model structure for the training subgraph, as well
# as the evaluation subgraphs, while sharing the trainable parameters.
def model(data, train=False):
"""The Model definition."""
# 2D convolution, with 'SAME' padding (i.e. the output feature map has
# the same size as the input). Note that {strides} is a 4D array whose
# shape matches the data layout: [image index, y, x, depth].
conv = tf.nn.conv2d(data,
conv1_weights,
strides=[1, 1, 1, 1],
padding='SAME')
# Bias and rectified linear non-linearity.
relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases))
# Max pooling. The kernel size spec {ksize} also follows the layout of
# the data. Here we have a pooling window of 2, and a stride of 2.
pool = tf.nn.max_pool(relu,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
conv = tf.nn.conv2d(pool,
conv2_weights,
strides=[1, 1, 1, 1],
padding='SAME')
relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases))
pool = tf.nn.max_pool(relu,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
# Reshape the feature map cuboid into a 2D matrix to feed it to the
# fully connected layers.
pool_shape = pool.get_shape().as_list() #pylint: disable=no-member
reshape = tf.reshape(
pool,
[pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]])
# Fully connected layer. Note that the '+' operation automatically
# broadcasts the biases.
hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases)
# Add a 50% dropout during training only. Dropout also scales
# activations such that no rescaling is needed at evaluation time.
if train:
hidden = tf.nn.dropout(hidden, 0.5, seed=SEED)
hidden = tf.matmul(hidden, fc1p_weights) + fc1p_biases
return tf.nn.relu(tf.matmul(hidden, fc2_weights) + fc2_biases), hidden
# Training computation: logits + cross-entropy loss.
logits, hidden = model(train_data_node, True)
#logits = batch_norm(logits, True)
xent_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
logits, train_labels_node))
beta = 1e-3
#center_loss, update_centers = center_loss_op(hidden, train_labels_node)
center_loss, _ = facenet.center_loss(hidden, train_labels_node, 0.95, NUM_LABELS)
loss = xent_loss + beta * center_loss
# L2 regularization for the fully connected parameters.
regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) +
tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases))
# Add the regularization term to the loss.
loss += 5e-4 * regularizers
# Optimizer: set up a variable that's incremented once per batch and
# controls the learning rate decay.
batch = tf.Variable(0, dtype=data_type())
# Decay once per epoch, using an exponential schedule starting at 0.01.
learning_rate = tf.train.exponential_decay(
0.01, # Base learning rate.
batch * BATCH_SIZE, # Current index into the dataset.
train_size, # Decay step.
0.95, # Decay rate.
staircase=True)
# Use simple momentum for the optimization.
optimizer = tf.train.MomentumOptimizer(learning_rate,
0.9).minimize(loss,
global_step=batch)
# Predictions for the current training minibatch.
train_prediction = tf.nn.softmax(logits)
# Predictions for the test and validation, which we'll compute less often.
eval_logits, eval_embeddings = model(eval_data)
eval_prediction = tf.nn.softmax(eval_logits)
# Small utility function to evaluate a dataset by feeding batches of data to
# {eval_data} and pulling the results from {eval_predictions}.
# Saves memory and enables this to run on smaller GPUs.
def eval_in_batches(data, sess):
"""Get all predictions for a dataset by running it in small batches."""
size = data.shape[0]
if size < EVAL_BATCH_SIZE:
raise ValueError("batch size for evals larger than dataset: %d" % size)
predictions = np.ndarray(shape=(size, NUM_LABELS), dtype=np.float32)
for begin in xrange(0, size, EVAL_BATCH_SIZE):
end = begin + EVAL_BATCH_SIZE
if end <= size:
predictions[begin:end, :] = sess.run(
eval_prediction,
feed_dict={eval_data: data[begin:end, ...]})
else:
batch_predictions = sess.run(
eval_prediction,
feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]})
predictions[begin:, :] = batch_predictions[begin - size:, :]
return predictions
def calculate_embeddings(data, sess):
"""Get all predictions for a dataset by running it in small batches."""
size = data.shape[0]
if size < EVAL_BATCH_SIZE:
raise ValueError("batch size for evals larger than dataset: %d" % size)
predictions = np.ndarray(shape=(size, 2), dtype=np.float32)
for begin in xrange(0, size, EVAL_BATCH_SIZE):
end = begin + EVAL_BATCH_SIZE
if end <= size:
predictions[begin:end, :] = sess.run(
eval_embeddings,
feed_dict={eval_data: data[begin:end, ...]})
else:
batch_predictions = sess.run(
eval_embeddings,
feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]})
predictions[begin:, :] = batch_predictions[begin - size:, :]
return predictions
# Create a local session to run the training.
start_time = time.time()
with tf.Session() as sess:
# Run all the initializers to prepare the trainable parameters.
tf.global_variables_initializer().run() #pylint: disable=no-member
print('Initialized!')
# Loop through training steps.
for step in xrange(int(num_epochs * train_size) // BATCH_SIZE):
# Compute the offset of the current minibatch in the data.
# Note that we could use better randomization across epochs.
offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)
batch_data = train_data[offset:(offset + BATCH_SIZE), ...]
batch_labels = train_labels[offset:(offset + BATCH_SIZE)]
# This dictionary maps the batch data (as a numpy array) to the
# node in the graph it should be fed to.
feed_dict = {train_data_node: batch_data,
train_labels_node: batch_labels}
# Run the graph and fetch some of the nodes.
#_, l, lr, predictions = sess.run([optimizer, loss, learning_rate, train_prediction], feed_dict=feed_dict)
_, cl, l, lr, predictions = sess.run([optimizer, center_loss, loss, learning_rate, train_prediction], feed_dict=feed_dict)
if step % EVAL_FREQUENCY == 0:
elapsed_time = time.time() - start_time
start_time = time.time()
print('Step %d (epoch %.2f), %.1f ms' %
(step, float(step) * BATCH_SIZE / train_size,
1000 * elapsed_time / EVAL_FREQUENCY))
print('Minibatch loss: %.3f %.3f, learning rate: %.6f' % (l, cl*beta, lr))
print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels))
print('Validation error: %.1f%%' % error_rate(
eval_in_batches(validation_data, sess), validation_labels))
sys.stdout.flush()
# Finally print the result!
test_error = error_rate(eval_in_batches(test_data, sess), test_labels)
print('Test error: %.1f%%' % test_error)
if FLAGS.self_test:
print('test_error', test_error)
assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % (
test_error,)
train_embeddings = calculate_embeddings(train_data, sess)
color_list = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'b', 'g', 'r', 'c' ]
plt.figure(1)
for n in range(0,10):
idx = np.where(train_labels[0:10000]==n)
plt.plot(train_embeddings[idx,0], train_embeddings[idx,1], color_list[n]+'.')
plt.show()
if __name__ == '__main__':
tf.app.run()
================================================
FILE: tmp/mnist_noise_labels.py
================================================
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Simple, end-to-end, LeNet-5-like convolutional MNIST model example.
This should achieve a test error of 0.7%. Please keep this model as simple and
linear as possible, it is meant as a tutorial for simple convolutional models.
Run with --self_test on the command line to execute a short self-test.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import gzip
import os
import sys
import time
from six.moves import urllib # @UnresolvedImport
import tensorflow as tf
import numpy as np
from six.moves import xrange
SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'
WORK_DIRECTORY = 'data'
IMAGE_SIZE = 28
NUM_CHANNELS = 1
PIXEL_DEPTH = 255
NUM_LABELS = 10
VALIDATION_SIZE = 5000 # Size of the validation set.
SEED = 66478 # Set to None for random seed.
BATCH_SIZE = 64
NUM_EPOCHS = 10
EVAL_BATCH_SIZE = 64
EVAL_FREQUENCY = 100 # Number of steps between evaluations.
NOISE_FACTOR = 0.2
BETA = 0.8
tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.")
tf.app.flags.DEFINE_boolean('use_fp16', False,
"Use half floats instead of full floats if True.")
FLAGS = tf.app.flags.FLAGS
def data_type():
"""Return the type of the activations, weights, and placeholder variables."""
if FLAGS.use_fp16:
return tf.float16
else:
return tf.float32
def maybe_download(filename):
"""Download the data from Yann's website, unless it's already here."""
if not tf.gfile.Exists(WORK_DIRECTORY):
tf.gfile.MakeDirs(WORK_DIRECTORY)
filepath = os.path.join(WORK_DIRECTORY, filename)
if not tf.gfile.Exists(filepath):
filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)
with tf.gfile.GFile(filepath) as f:
size = f.size()
print('Successfully downloaded', filename, size, 'bytes.')
return filepath
def extract_data(filename, num_images):
"""Extract the images into a 4D tensor [image index, y, x, channels].
Values are rescaled from [0, 255] down to [-0.5, 0.5].
"""
print('Extracting', filename)
with gzip.open(filename) as bytestream:
bytestream.read(16)
buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS)
data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH
data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)
return data
def extract_labels(filename, num_images):
"""Extract the labels into a vector of int64 label IDs."""
print('Extracting', filename)
with gzip.open(filename) as bytestream:
bytestream.read(8)
buf = bytestream.read(1 * num_images)
labels = np.frombuffer(buf, dtype=np.uint8).astype(np.int64)
return labels
def fake_data(num_images):
"""Generate a fake dataset that matches the dimensions of MNIST."""
data = np.ndarray(
shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS),
dtype=np.float32)
labels = np.zeros(shape=(num_images,), dtype=np.int64)
for image in range(num_images):
label = image % 2
data[image, :, :, 0] = label - 0.5
labels[image] = label
return data, labels
def error_rate(predictions, labels):
"""Return the error rate based on dense predictions and sparse labels."""
return 100.0 - (
100.0 *
np.sum(np.argmax(predictions, 1) == labels) /
predictions.shape[0])
def main(argv=None): # pylint: disable=unused-argument
if FLAGS.self_test:
print('Running self-test.')
train_data, train_labels = fake_data(256)
validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE)
test_data, test_labels = fake_data(EVAL_BATCH_SIZE)
num_epochs = 1
else:
# Get the data.
train_data_filename = maybe_download('train-images-idx3-ubyte.gz')
train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz')
test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz')
test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz')
# Extract it into numpy arrays.
train_data = extract_data(train_data_filename, 60000)
train_labels = extract_labels(train_labels_filename, 60000)
test_data = extract_data(test_data_filename, 10000)
test_labels = extract_labels(test_labels_filename, 10000)
# Generate a validation set.
validation_data = train_data[:VALIDATION_SIZE, ...]
validation_labels = train_labels[:VALIDATION_SIZE]
train_data = train_data[VALIDATION_SIZE:, ...]
train_labels = train_labels[VALIDATION_SIZE:]
nrof_training_examples = train_labels.shape[0]
nrof_changed_labels = int(nrof_training_examples*NOISE_FACTOR)
shuf = np.arange(0,nrof_training_examples)
np.random.shuffle(shuf)
change_idx = shuf[0:nrof_changed_labels]
train_labels[change_idx] = (train_labels[change_idx] + np.random.randint(1,9,size=(nrof_changed_labels,))) % NUM_LABELS
num_epochs = NUM_EPOCHS
train_size = train_labels.shape[0]
# This is where training samples and labels are fed to the graph.
# These placeholder nodes will be fed a batch of training data at each
# training step using the {feed_dict} argument to the Run() call below.
train_data_node = tf.placeholder(
data_type(),
shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))
train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,))
eval_data = tf.placeholder(
data_type(),
shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))
# The variables below hold all the trainable weights. They are passed an
# initial value which will be assigned when we call:
# {tf.global_variables_initializer().run()}
conv1_weights = tf.Variable(
tf.truncated_normal([5, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32.
stddev=0.1,
seed=SEED, dtype=data_type()))
conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type()))
conv2_weights = tf.Variable(tf.truncated_normal(
[5, 5, 32, 64], stddev=0.1,
seed=SEED, dtype=data_type()))
conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type()))
fc1_weights = tf.Variable( # fully connected, depth 512.
tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512],
stddev=0.1,
seed=SEED,
dtype=data_type()))
fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type()))
fc2_weights = tf.Variable(tf.truncated_normal([512, NUM_LABELS],
stddev=0.1,
seed=SEED,
dtype=data_type()))
fc2_biases = tf.Variable(tf.constant(
0.1, shape=[NUM_LABELS], dtype=data_type()))
# We will replicate the model structure for the training subgraph, as well
# as the evaluation subgraphs, while sharing the trainable parameters.
def model(data, train=False):
"""The Model definition."""
# 2D convolution, with 'SAME' padding (i.e. the output feature map has
# the same size as the input). Note that {strides} is a 4D array whose
# shape matches the data layout: [image index, y, x, depth].
conv = tf.nn.conv2d(data,
conv1_weights,
strides=[1, 1, 1, 1],
padding='SAME')
# Bias and rectified linear non-linearity.
relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases))
# Max pooling. The kernel size spec {ksize} also follows the layout of
# the data. Here we have a pooling window of 2, and a stride of 2.
pool = tf.nn.max_pool(relu,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
conv = tf.nn.conv2d(pool,
conv2_weights,
strides=[1, 1, 1, 1],
padding='SAME')
relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases))
pool = tf.nn.max_pool(relu,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
# Reshape the feature map cuboid into a 2D matrix to feed it to the
# fully connected layers.
pool_shape = pool.get_shape().as_list() #pylint: disable=no-member
reshape = tf.reshape(
pool,
[pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]])
# Fully connected layer. Note that the '+' operation automatically
# broadcasts the biases.
hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases)
# Add a 50% dropout during training only. Dropout also scales
# activations such that no rescaling is needed at evaluation time.
if train:
hidden = tf.nn.dropout(hidden, 0.5, seed=SEED)
return tf.matmul(hidden, fc2_weights) + fc2_biases
# Training computation: logits + cross-entropy loss.
logits = model(train_data_node, True)
# t: observed noisy labels
# q: estimated class probabilities (output from softmax)
# z: argmax of q
t = tf.one_hot(train_labels_node, NUM_LABELS)
q = tf.nn.softmax(logits)
qqq = tf.arg_max(q, dimension=1)
z = tf.one_hot(qqq, NUM_LABELS)
#cross_entropy = -tf.reduce_sum(t*tf.log(q),reduction_indices=1)
cross_entropy = -tf.reduce_sum((BETA*t+(1-BETA)*z)*tf.log(q),reduction_indices=1)
loss = tf.reduce_mean(cross_entropy)
# loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
# logits, train_labels_node))
# L2 regularization for the fully connected parameters.
regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) +
tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases))
# Add the regularization term to the loss.
loss += 5e-4 * regularizers
# Optimizer: set up a variable that's incremented once per batch and
# controls the learning rate decay.
batch = tf.Variable(0, dtype=data_type())
# Decay once per epoch, using an exponential schedule starting at 0.01.
learning_rate = tf.train.exponential_decay(
0.01, # Base learning rate.
batch * BATCH_SIZE, # Current index into the dataset.
train_size, # Decay step.
0.95, # Decay rate.
staircase=True)
# Use simple momentum for the optimization.
optimizer = tf.train.MomentumOptimizer(learning_rate,
0.9).minimize(loss,
global_step=batch)
# Predictions for the current training minibatch.
train_prediction = tf.nn.softmax(logits)
# Predictions for the test and validation, which we'll compute less often.
eval_prediction = tf.nn.softmax(model(eval_data))
# Small utility function to evaluate a dataset by feeding batches of data to
# {eval_data} and pulling the results from {eval_predictions}.
# Saves memory and enables this to run on smaller GPUs.
def eval_in_batches(data, sess):
"""Get all predictions for a dataset by running it in small batches."""
size = data.shape[0]
if size < EVAL_BATCH_SIZE:
raise ValueError("batch size for evals larger than dataset: %d" % size)
predictions = np.ndarray(shape=(size, NUM_LABELS), dtype=np.float32)
for begin in xrange(0, size, EVAL_BATCH_SIZE):
end = begin + EVAL_BATCH_SIZE
if end <= size:
predictions[begin:end, :] = sess.run(
eval_prediction,
feed_dict={eval_data: data[begin:end, ...]})
else:
batch_predictions = sess.run(
eval_prediction,
feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]})
predictions[begin:, :] = batch_predictions[begin - size:, :]
return predictions
# Create a local session to run the training.
start_time = time.time()
with tf.Session() as sess:
# Run all the initializers to prepare the trainable parameters.
tf.global_variables_initializer().run() #pylint: disable=no-member
print('Initialized!')
# Loop through training steps.
for step in xrange(int(num_epochs * train_size) // BATCH_SIZE):
# Compute the offset of the current minibatch in the data.
# Note that we could use better randomization across epochs.
offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)
batch_data = train_data[offset:(offset + BATCH_SIZE), ...]
batch_labels = train_labels[offset:(offset + BATCH_SIZE)]
# This dictionary maps the batch data (as a numpy array) to the
# node in the graph it should be fed to.
feed_dict = {train_data_node: batch_data,
train_labels_node: batch_labels}
# Run the graph and fetch some of the nodes.
_, l, lr, predictions = sess.run(
[optimizer, loss, learning_rate, train_prediction],
feed_dict=feed_dict)
if step % EVAL_FREQUENCY == 0:
elapsed_time = time.time() - start_time
start_time = time.time()
print('Step %d (epoch %.2f), %.1f ms' %
(step, float(step) * BATCH_SIZE / train_size,
1000 * elapsed_time / EVAL_FREQUENCY))
print('Minibatch loss: %.3f, learning rate: %.6f' % (l, lr))
print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels))
print('Validation error: %.1f%%' % error_rate(
eval_in_batches(validation_data, sess), validation_labels))
sys.stdout.flush()
# Finally print the result!
test_error = error_rate(eval_in_batches(test_data, sess), test_labels)
print('Test error: %.1f%%' % test_error)
if FLAGS.self_test:
print('test_error', test_error)
assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % (
test_error,)
if __name__ == '__main__':
tf.app.run()
================================================
FILE: tmp/mtcnn.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import align.detect_face
from scipy import misc
with tf.Graph().as_default():
sess = tf.Session()
with sess.as_default():
with tf.variable_scope('pnet'):
data = tf.placeholder(tf.float32, (None,None,None,3), 'input')
pnet = align.detect_face.PNet({'data':data})
pnet.load('../../data/det1.npy', sess)
with tf.variable_scope('rnet'):
data = tf.placeholder(tf.float32, (None,24,24,3), 'input')
rnet = align.detect_face.RNet({'data':data})
rnet.load('../../data/det2.npy', sess)
with tf.variable_scope('onet'):
data = tf.placeholder(tf.float32, (None,48,48,3), 'input')
onet = align.detect_face.ONet({'data':data})
onet.load('../../data/det3.npy', sess)
pnet_fun = lambda img : sess.run(('pnet/conv4-2/BiasAdd:0', 'pnet/prob1:0'), feed_dict={'pnet/input:0':img})
rnet_fun = lambda img : sess.run(('rnet/conv5-2/conv5-2:0', 'rnet/prob1:0'), feed_dict={'rnet/input:0':img})
onet_fun = lambda img : sess.run(('onet/conv6-2/conv6-2:0', 'onet/conv6-3/conv6-3:0', 'onet/prob1:0'), feed_dict={'onet/input:0':img})
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
source_path = '/home/david/datasets/casia/CASIA-maxpy-clean/0000045/002.jpg'
img = misc.imread(source_path)
bounding_boxes, points = align.detect_face.detect_face(img, minsize, pnet_fun, rnet_fun, onet_fun, threshold, factor)
print('Bounding box: %s' % bounding_boxes)
================================================
FILE: tmp/mtcnn_test.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import numpy as np
import align.detect_face
g1 = tf.Graph()
with g1.as_default():
data = tf.placeholder(tf.float32, (None,None,None,3), 'input')
pnet = align.detect_face.PNet({'data':data})
sess1 = tf.Session(graph=g1)
pnet.load('../../data/det1.npy', sess1)
pnet_fun = lambda img : sess1.run(('conv4-2/BiasAdd:0', 'prob1:0'), feed_dict={'input:0':img})
np.random.seed(666)
img = np.random.rand(1,3,150,150)
img = np.transpose(img, (0,2,3,1))
np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
# prob1=sess1.run('prob1:0', feed_dict={data:img})
# print(prob1[0,0,0,:])
# conv42=sess1.run('conv4-2/BiasAdd:0', feed_dict={data:img})
# print(conv42[0,0,0,:])
# conv42, prob1 = pnet_fun(img)
# print(prob1[0,0,0,:])
# print(conv42[0,0,0,:])
# [ 0.9929 0.0071] prob1, caffe
# [ 0.9929 0.0071] prob1, tensorflow
# [ 0.1207 -0.0116 -0.1231 -0.0463] conv4-2, caffe
# [ 0.1207 -0.0116 -0.1231 -0.0463] conv4-2, tensorflow
g2 = tf.Graph()
with g2.as_default():
data = tf.placeholder(tf.float32, (None,24,24,3), 'input')
rnet = align.detect_face.RNet({'data':data})
sess2 = tf.Session(graph=g2)
rnet.load('../../data/det2.npy', sess2)
rnet_fun = lambda img : sess2.run(('conv5-2/conv5-2:0', 'prob1:0'), feed_dict={'input:0':img})
np.random.seed(666)
img = np.random.rand(73,3,24,24)
img = np.transpose(img, (0,2,3,1))
# np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
#
# prob1=sess2.run('prob1:0', feed_dict={data:img})
# print(prob1[0,:])
#
# conv52=sess2.run('conv5-2/conv5-2:0', feed_dict={data:img})
# print(conv52[0,:])
# [ 0.9945 0.0055] prob1, caffe
# [ 0.1108 -0.0038 -0.1631 -0.0890] conv5-2, caffe
# [ 0.9945 0.0055] prob1, tensorflow
# [ 0.1108 -0.0038 -0.1631 -0.0890] conv5-2, tensorflow
g3 = tf.Graph()
with g3.as_default():
data = tf.placeholder(tf.float32, (None,48,48,3), 'input')
onet = align.detect_face.ONet({'data':data})
sess3 = tf.Session(graph=g3)
onet.load('../../data/det3.npy', sess3)
onet_fun = lambda img : sess3.run(('conv6-2/conv6-2:0', 'conv6-3/conv6-3:0', 'prob1:0'), feed_dict={'input:0':img})
np.random.seed(666)
img = np.random.rand(11,3,48,48)
img = np.transpose(img, (0,2,3,1))
# np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
#
# prob1=sess3.run('prob1:0', feed_dict={data:img})
# print(prob1[0,:])
# print('prob1, tensorflow')
#
# conv62=sess3.run('conv6-2/conv6-2:0', feed_dict={data:img})
# print(conv62[0,:])
# print('conv6-2, tensorflow')
#
# conv63=sess3.run('conv6-3/conv6-3:0', feed_dict={data:img})
# print(conv63[0,:])
# print('conv6-3, tensorflow')
# [ 0.9988 0.0012] prob1, caffe
# [ 0.0446 -0.0968 -0.1091 -0.0212] conv6-2, caffe
# [ 0.2429 0.6104 0.4074 0.3104 0.5939 0.2729 0.2132 0.5462 0.7863 0.7568] conv6-3, caffe
# [ 0.9988 0.0012] prob1, tensorflow
# [ 0.0446 -0.0968 -0.1091 -0.0212] conv6-2, tensorflow
# [ 0.2429 0.6104 0.4074 0.3104 0.5939 0.2729 0.2132 0.5462 0.7863 0.7568] conv6-3, tensorflow
#pnet_fun = lambda img : sess1.run(('conv4-2/BiasAdd:0', 'prob1:0'), feed_dict={'input:0':img})
================================================
FILE: tmp/mtcnn_test_pnet_dbg.py
================================================
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import numpy as np
import scipy.io as io
import align.detect_face
#ref = io.loadmat('pnet_dbg.mat')
with tf.Graph().as_default():
sess = tf.Session()
with sess.as_default():
with tf.variable_scope('pnet'):
# data = tf.placeholder(tf.float32, (None,None,None,3), 'input')
data = tf.placeholder(tf.float32, (1,1610, 1901,3), 'input')
pnet = align.detect_face.PNet({'data':data})
pnet.load('../../data/det1.npy', sess)
# with tf.variable_scope('rnet'):
# data = tf.placeholder(tf.float32, (None,24,24,3), 'input')
# rnet = align.detect_face.RNet({'data':data})
# rnet.load('../../data/det2.npy', sess)
# with tf.variable_scope('onet'):
# data = tf.placeholder(tf.float32, (None,48,48,3), 'input')
# onet = align.detect_face.ONet({'data':data})
# onet.load('../../data/det3.npy', sess)
pnet_fun = lambda img : sess.run(('pnet/conv4-2/BiasAdd:0', 'pnet/prob1:0'), feed_dict={'pnet/input:0':img})
# rnet_fun = lambda img : sess.run(('rnet/conv5-2/conv5-2:0', 'rnet/prob1:0'), feed_dict={'rnet/input:0':img})
# onet_fun = lambda img : sess.run(('onet/conv6-2/conv6-2:0', 'onet/conv6-3/conv6-3:0', 'onet/prob1:0'), feed_dict={'onet/input:0':img})
ref = io.loadmat('pnet_dbg.mat')
img_x = np.expand_dims(ref['im_data'], 0)
img_y = np.transpose(img_x, (0,2,1,3))
out = pnet_fun(img_y)
out0 = np.transpose(out[0], (0,2,1,3))
out1 = np.transpose(out[1], (0,2,1,3))
#np.where(abs(out0[0,:,:,:]-ref['out0'])>1e-18)
qqq3 = np.where(abs(out1[0,:,:,:]-ref['out1'])>1e-7) # 3390 diffs with softmax2
print(qqq3[0].shape)
np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
# prob1=sess1.run('prob1:0', feed_dict={data:img})
# print(prob1[0,0,0,:])
# conv42=sess1.run('conv4-2/BiasAdd:0', feed_dict={data:img})
# print(conv42[0,0,0,:])
# conv42, prob1 = pnet_fun(img)
# print(prob1[0,0,0,:])
# print(conv42[0,0,0,:])
# [ 0.9929 0.0071] prob1, caffe
# [ 0.9929 0.0071] prob1, tensorflow
# [ 0.1207 -0.0116 -0.1231 -0.0463] conv4-2, caffe
# [ 0.1207 -0.0116 -0.1231 -0.0463] conv4-2, tensorflow
# g2 = tf.Graph()
# with g2.as_default():
# data = tf.placeholder(tf.float32, (None,24,24,3), 'input')
# rnet = align.detect_face.RNet({'data':data})
# sess2 = tf.Session(graph=g2)
# rnet.load('../../data/det2.npy', sess2)
# rnet_fun = lambda img : sess2.run(('conv5-2/conv5-2:0', 'prob1:0'), feed_dict={'input:0':img})
# np.random.seed(666)
# img = np.random.rand(73,3,24,24)
# img = np.transpose(img, (0,2,3,1))
# np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
#
# prob1=sess2.run('prob1:0', feed_dict={data:img})
# print(prob1[0,:])
#
# conv52=sess2.run('conv5-2/conv5-2:0', feed_dict={data:img})
# print(conv52[0,:])
# [ 0.9945 0.0055] prob1, caffe
# [ 0.1108 -0.0038 -0.1631 -0.0890] conv5-2, caffe
# [ 0.9945 0.0055] prob1, tensorflow
# [ 0.1108 -0.0038 -0.1631 -0.0890] conv5-2, tensorflow
# g3 = tf.Graph()
# with g3.as_default():
# data = tf.placeholder(tf.float32, (None,48,48,3), 'input')
# onet = align.detect_face.ONet({'data':data})
# sess3 = tf.Session(graph=g3)
# onet.load('../../data/det3.npy', sess3)
# onet_fun = lambda img : sess3.run(('conv6-2/conv6-2:0', 'conv6-3/conv6-3:0', 'prob1:0'), feed_dict={'input:0':img})
# np.random.seed(666)
# img = np.random.rand(11,3,48,48)
# img = np.transpose(img, (0,2,3,1))
# np.set_printoptions(formatter={'float': '{: 0.4f}'.format})
#
# prob1=sess3.run('prob1:0', feed_dict={data:img})
# print(prob1[0,:])
# print('prob1, tensorflow')
#
# conv62=sess3.run('conv6-2/conv6-2:0', feed_dict={data:img})
# print(conv62[0,:])
# print('conv6-2, tensorflow')
#
# conv63=sess3.run('conv6-3/conv6-3:0', feed_dict={data:img})
# print(conv63[0,:])
# print('conv6-3, tensorflow')
# [ 0.9988 0.0012] prob1, caffe
# [ 0.0446 -0.0968 -0.1091 -0.0212] conv6-2, caffe
# [ 0.2429 0.6104 0.4074 0.3104 0.5939 0.2729 0.2132 0.5462 0.7863 0.7568] conv6-3, caffe
# [ 0.9988 0.0012] prob1, tensorflow
# [ 0.0446 -0.0968 -0.1091 -0.0212] conv6-2, tensorflow
# [ 0.2429 0.6104 0.4074 0.3104 0.5939 0.2729 0.2132 0.5462 0.7863 0.7568] conv6-3, tensorflow
#pnet_fun = lambda img : sess1.run(('conv4-2/BiasAdd:0', 'prob1:0'), feed_dict={'input:0':img})
================================================
FILE: tmp/network.py
================================================
"""Functions for building the face recognition network.
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import control_flow_ops
def conv(inpOp, nIn, nOut, kH, kW, dH, dW, padType, name, phase_train=True, use_batch_norm=True, weight_decay=0.0):
with tf.variable_scope(name):
l2_regularizer = lambda t: l2_loss(t, weight=weight_decay)
kernel = tf.get_variable("weights", [kH, kW, nIn, nOut],
initializer=tf.truncated_normal_initializer(stddev=1e-1),
regularizer=l2_regularizer, dtype=inpOp.dtype)
cnv = tf.nn.conv2d(inpOp, kernel, [1, dH, dW, 1], padding=padType)
if use_batch_norm:
conv_bn = batch_norm(cnv, phase_train)
else:
conv_bn = cnv
biases = tf.get_variable("biases", [nOut], initializer=tf.constant_initializer(), dtype=inpOp.dtype)
bias = tf.nn.bias_add(conv_bn, biases)
conv1 = tf.nn.relu(bias)
return conv1
def affine(inpOp, nIn, nOut, name, weight_decay=0.0):
with tf.variable_scope(name):
l2_regularizer = lambda t: l2_loss(t, weight=weight_decay)
weights = tf.get_variable("weights", [nIn, nOut],
initializer=tf.truncated_normal_initializer(stddev=1e-1),
regularizer=l2_regularizer, dtype=inpOp.dtype)
biases = tf.get_variable("biases", [nOut], initializer=tf.constant_initializer(), dtype=inpOp.dtype)
affine1 = tf.nn.relu_layer(inpOp, weights, biases)
return affine1
def l2_loss(tensor, weight=1.0, scope=None):
"""Define a L2Loss, useful for regularize, i.e. weight decay.
Args:
tensor: tensor to regularize.
weight: an optional weight to modulate the loss.
scope: Optional scope for op_scope.
Returns:
the L2 loss op.
"""
with tf.name_scope(scope):
weight = tf.convert_to_tensor(weight,
dtype=tensor.dtype.base_dtype,
name='loss_weight')
loss = tf.multiply(weight, tf.nn.l2_loss(tensor), name='value')
return loss
def lppool(inpOp, pnorm, kH, kW, dH, dW, padding, name):
with tf.variable_scope(name):
if pnorm == 2:
pwr = tf.square(inpOp)
else:
pwr = tf.pow(inpOp, pnorm)
subsamp = tf.nn.avg_pool(pwr,
ksize=[1, kH, kW, 1],
strides=[1, dH, dW, 1],
padding=padding)
subsamp_sum = tf.multiply(subsamp, kH*kW)
if pnorm == 2:
out = tf.sqrt(subsamp_sum)
else:
out = tf.pow(subsamp_sum, 1/pnorm)
return out
def mpool(inpOp, kH, kW, dH, dW, padding, name):
with tf.variable_scope(name):
maxpool = tf.nn.max_pool(inpOp,
ksize=[1, kH, kW, 1],
strides=[1, dH, dW, 1],
padding=padding)
return maxpool
def apool(inpOp, kH, kW, dH, dW, padding, name):
with tf.variable_scope(name):
avgpool = tf.nn.avg_pool(inpOp,
ksize=[1, kH, kW, 1],
strides=[1, dH, dW, 1],
padding=padding)
return avgpool
def batch_norm(x, phase_train):
"""
Batch normalization on convolutional maps.
Args:
x: Tensor, 4D BHWD input maps
n_out: integer, depth of input maps
phase_train: boolean tf.Variable, true indicates training phase
scope: string, variable scope
affn: whether to affn-transform outputs
Return:
normed: batch-normalized maps
Ref: http://stackoverflow.com/questions/33949786/how-could-i-use-batch-normalization-in-tensorflow/33950177
"""
name = 'batch_norm'
with tf.variable_scope(name):
phase_train = tf.convert_to_tensor(phase_train, dtype=tf.bool)
n_out = int(x.get_shape()[3])
beta = tf.Variable(tf.constant(0.0, shape=[n_out], dtype=x.dtype),
name=name+'/beta', trainable=True, dtype=x.dtype)
gamma = tf.Variable(tf.constant(1.0, shape=[n_out], dtype=x.dtype),
name=name+'/gamma', trainable=True, dtype=x.dtype)
batch_mean, batch_var = tf.nn.moments(x, [0,1,2], name='moments')
ema = tf.train.ExponentialMovingAverage(decay=0.9)
def mean_var_with_update():
ema_apply_op = ema.apply([batch_mean, batch_var])
with tf.control_dependencies([ema_apply_op]):
return tf.identity(batch_mean), tf.identity(batch_var)
mean, var = control_flow_ops.cond(phase_train,
mean_var_with_update,
lambda: (ema.average(batch_mean), ema.average(batch_var)))
normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, 1e-3)
return normed
def inception(inp, inSize, ks, o1s, o2s1, o2s2, o3s1, o3s2, o4s1, o4s2, o4s3, poolType, name,
phase_train=True, use_batch_norm=True, weight_decay=0.0):
print('name = ', name)
print('inputSize = ', inSize)
print('kernelSize = {3,5}')
print('kernelStride = {%d,%d}' % (ks,ks))
print('outputSize = {%d,%d}' % (o2s2,o3s2))
print('reduceSize = {%d,%d,%d,%d}' % (o2s1,o3s1,o4s2,o1s))
print('pooling = {%s, %d, %d, %d, %d}' % (poolType, o4s1, o4s1, o4s3, o4s3))
if (o4s2>0):
o4 = o4s2
else:
o4 = inSize
print('outputSize = ', o1s+o2s2+o3s2+o4)
print()
net = []
with tf.variable_scope(name):
with tf.variable_scope('branch1_1x1'):
if o1s>0:
conv1 = conv(inp, inSize, o1s, 1, 1, 1, 1, 'SAME', 'conv1x1', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
net.append(conv1)
with tf.variable_scope('branch2_3x3'):
if o2s1>0:
conv3a = conv(inp, inSize, o2s1, 1, 1, 1, 1, 'SAME', 'conv1x1', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
conv3 = conv(conv3a, o2s1, o2s2, 3, 3, ks, ks, 'SAME', 'conv3x3', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
net.append(conv3)
with tf.variable_scope('branch3_5x5'):
if o3s1>0:
conv5a = conv(inp, inSize, o3s1, 1, 1, 1, 1, 'SAME', 'conv1x1', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
conv5 = conv(conv5a, o3s1, o3s2, 5, 5, ks, ks, 'SAME', 'conv5x5', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
net.append(conv5)
with tf.variable_scope('branch4_pool'):
if poolType=='MAX':
pool = mpool(inp, o4s1, o4s1, o4s3, o4s3, 'SAME', 'pool')
elif poolType=='L2':
pool = lppool(inp, 2, o4s1, o4s1, o4s3, o4s3, 'SAME', 'pool')
else:
raise ValueError('Invalid pooling type "%s"' % poolType)
if o4s2>0:
pool_conv = conv(pool, inSize, o4s2, 1, 1, 1, 1, 'SAME', 'conv1x1', phase_train=phase_train, use_batch_norm=use_batch_norm, weight_decay=weight_decay)
else:
pool_conv = pool
net.append(pool_conv)
incept = array_ops.concat(net, 3, name=name)
return incept
================================================
FILE: tmp/nn2.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import models.network as network
def inference(images, keep_probability, phase_train=True, weight_decay=0.0):
""" Define an inference network for face recognition based
on inception modules using batch normalization
Args:
images: The images to run inference on, dimensions batch_size x height x width x channels
phase_train: True if batch normalization should operate in training mode
"""
endpoints = {}
net = network.conv(images, 3, 64, 7, 7, 2, 2, 'SAME', 'conv1_7x7', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv1'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool1')
endpoints['pool1'] = net
net = network.conv(net, 64, 64, 1, 1, 1, 1, 'SAME', 'conv2_1x1', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv2_1x1'] = net
net = network.conv(net, 64, 192, 3, 3, 1, 1, 'SAME', 'conv3_3x3', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv3_3x3'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool3')
endpoints['pool3'] = net
net = network.inception(net, 192, 1, 64, 96, 128, 16, 32, 3, 32, 1, 'MAX', 'incept3a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3a'] = net
net = network.inception(net, 256, 1, 64, 96, 128, 32, 64, 3, 64, 1, 'MAX', 'incept3b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3b'] = net
net = network.inception(net, 320, 2, 0, 128, 256, 32, 64, 3, 0, 2, 'MAX', 'incept3c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3c'] = net
net = network.inception(net, 640, 1, 256, 96, 192, 32, 64, 3, 128, 1, 'MAX', 'incept4a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4a'] = net
net = network.inception(net, 640, 1, 224, 112, 224, 32, 64, 3, 128, 1, 'MAX', 'incept4b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4b'] = net
net = network.inception(net, 640, 1, 192, 128, 256, 32, 64, 3, 128, 1, 'MAX', 'incept4c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4c'] = net
net = network.inception(net, 640, 1, 160, 144, 288, 32, 64, 3, 128, 1, 'MAX', 'incept4d', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4d'] = net
net = network.inception(net, 640, 2, 0, 160, 256, 64, 128, 3, 0, 2, 'MAX', 'incept4e', phase_train=phase_train, use_batch_norm=True)
endpoints['incept4e'] = net
net = network.inception(net, 1024, 1, 384, 192, 384, 48, 128, 3, 128, 1, 'MAX', 'incept5a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5a'] = net
net = network.inception(net, 1024, 1, 384, 192, 384, 48, 128, 3, 128, 1, 'MAX', 'incept5b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5b'] = net
net = network.apool(net, 7, 7, 1, 1, 'VALID', 'pool6')
endpoints['pool6'] = net
net = tf.reshape(net, [-1, 1024])
endpoints['prelogits'] = net
net = tf.nn.dropout(net, keep_probability)
endpoints['dropout'] = net
return net, endpoints
================================================
FILE: tmp/nn3.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import models.network as network
def inference(images, keep_probability, phase_train=True, weight_decay=0.0):
""" Define an inference network for face recognition based
on inception modules using batch normalization
Args:
images: The images to run inference on, dimensions batch_size x height x width x channels
phase_train: True if batch normalization should operate in training mode
"""
endpoints = {}
net = network.conv(images, 3, 64, 7, 7, 2, 2, 'SAME', 'conv1_7x7', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv1'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool1')
endpoints['pool1'] = net
net = network.conv(net, 64, 64, 1, 1, 1, 1, 'SAME', 'conv2_1x1', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv2_1x1'] = net
net = network.conv(net, 64, 192, 3, 3, 1, 1, 'SAME', 'conv3_3x3', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv3_3x3'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool3')
endpoints['pool3'] = net
net = network.inception(net, 192, 1, 64, 96, 128, 16, 32, 3, 32, 1, 'MAX', 'incept3a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3a'] = net
net = network.inception(net, 256, 1, 64, 96, 128, 32, 64, 3, 64, 1, 'MAX', 'incept3b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3b'] = net
net = network.inception(net, 320, 2, 0, 128, 256, 32, 64, 3, 0, 2, 'MAX', 'incept3c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3c'] = net
net = network.inception(net, 640, 1, 256, 96, 192, 32, 64, 3, 128, 1, 'MAX', 'incept4a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4a'] = net
net = network.inception(net, 640, 1, 224, 112, 224, 32, 64, 3, 128, 1, 'MAX', 'incept4b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4b'] = net
net = network.inception(net, 640, 1, 192, 128, 256, 32, 64, 3, 128, 1, 'MAX', 'incept4c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4c'] = net
net = network.inception(net, 640, 1, 160, 144, 288, 32, 64, 3, 128, 1, 'MAX', 'incept4d', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4d'] = net
net = network.inception(net, 640, 2, 0, 160, 256, 64, 128, 3, 0, 2, 'MAX', 'incept4e', phase_train=phase_train, use_batch_norm=True)
endpoints['incept4e'] = net
net = network.inception(net, 1024, 1, 384, 192, 384, 48, 128, 3, 128, 1, 'MAX', 'incept5a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5a'] = net
net = network.inception(net, 1024, 1, 384, 192, 384, 48, 128, 3, 128, 1, 'MAX', 'incept5b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5b'] = net
net = network.apool(net, 5, 5, 1, 1, 'VALID', 'pool6')
endpoints['pool6'] = net
net = tf.reshape(net, [-1, 1024])
endpoints['prelogits'] = net
net = tf.nn.dropout(net, keep_probability)
endpoints['dropout'] = net
return net, endpoints
================================================
FILE: tmp/nn4.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import models.network as network
def inference(images, keep_probability, phase_train=True, weight_decay=0.0):
""" Define an inference network for face recognition based
on inception modules using batch normalization
Args:
images: The images to run inference on, dimensions batch_size x height x width x channels
phase_train: True if batch normalization should operate in training mode
"""
endpoints = {}
net = network.conv(images, 3, 64, 7, 7, 2, 2, 'SAME', 'conv1_7x7', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv1'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool1')
endpoints['pool1'] = net
net = network.conv(net, 64, 64, 1, 1, 1, 1, 'SAME', 'conv2_1x1', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv2_1x1'] = net
net = network.conv(net, 64, 192, 3, 3, 1, 1, 'SAME', 'conv3_3x3', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv3_3x3'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool3')
endpoints['pool3'] = net
net = network.inception(net, 192, 1, 64, 96, 128, 16, 32, 3, 32, 1, 'MAX', 'incept3a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3a'] = net
net = network.inception(net, 256, 1, 64, 96, 128, 32, 64, 3, 64, 1, 'MAX', 'incept3b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3b'] = net
net = network.inception(net, 320, 2, 0, 128, 256, 32, 64, 3, 0, 2, 'MAX', 'incept3c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3c'] = net
net = network.inception(net, 640, 1, 256, 96, 192, 32, 64, 3, 128, 1, 'MAX', 'incept4a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4a'] = net
net = network.inception(net, 640, 1, 224, 112, 224, 32, 64, 3, 128, 1, 'MAX', 'incept4b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4b'] = net
net = network.inception(net, 640, 1, 192, 128, 256, 32, 64, 3, 128, 1, 'MAX', 'incept4c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4c'] = net
net = network.inception(net, 640, 1, 160, 144, 288, 32, 64, 3, 128, 1, 'MAX', 'incept4d', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4d'] = net
net = network.inception(net, 640, 2, 0, 160, 256, 64, 128, 3, 0, 2, 'MAX', 'incept4e', phase_train=phase_train, use_batch_norm=True)
endpoints['incept4e'] = net
net = network.inception(net, 1024, 1, 384, 192, 384, 0, 0, 3, 128, 1, 'MAX', 'incept5a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5a'] = net
net = network.inception(net, 896, 1, 384, 192, 384, 0, 0, 3, 128, 1, 'MAX', 'incept5b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5b'] = net
net = network.apool(net, 3, 3, 1, 1, 'VALID', 'pool6')
endpoints['pool6'] = net
net = tf.reshape(net, [-1, 896])
endpoints['prelogits'] = net
net = tf.nn.dropout(net, keep_probability)
endpoints['dropout'] = net
return net, endpoints
================================================
FILE: tmp/nn4_small2_v1.py
================================================
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import models.network as network
def inference(images, keep_probability, phase_train=True, weight_decay=0.0):
""" Define an inference network for face recognition based
on inception modules using batch normalization
Args:
images: The images to run inference on, dimensions batch_size x height x width x channels
phase_train: True if batch normalization should operate in training mode
"""
endpoints = {}
net = network.conv(images, 3, 64, 7, 7, 2, 2, 'SAME', 'conv1_7x7', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv1'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool1')
endpoints['pool1'] = net
net = network.conv(net, 64, 64, 1, 1, 1, 1, 'SAME', 'conv2_1x1', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv2_1x1'] = net
net = network.conv(net, 64, 192, 3, 3, 1, 1, 'SAME', 'conv3_3x3', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['conv3_3x3'] = net
net = network.mpool(net, 3, 3, 2, 2, 'SAME', 'pool3')
endpoints['pool3'] = net
net = network.inception(net, 192, 1, 64, 96, 128, 16, 32, 3, 32, 1, 'MAX', 'incept3a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3a'] = net
net = network.inception(net, 256, 1, 64, 96, 128, 32, 64, 3, 64, 1, 'MAX', 'incept3b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3b'] = net
net = network.inception(net, 320, 2, 0, 128, 256, 32, 64, 3, 0, 2, 'MAX', 'incept3c', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept3c'] = net
net = network.inception(net, 640, 1, 256, 96, 192, 32, 64, 3, 128, 1, 'MAX', 'incept4a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4a'] = net
net = network.inception(net, 640, 2, 0, 160, 256, 64, 128, 3, 0, 2, 'MAX', 'incept4e', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept4e'] = net
net = network.inception(net, 1024, 1, 256, 96, 384, 0, 0, 3, 96, 1, 'MAX', 'incept5a', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5a'] = net
net = network.inception(net, 736, 1, 256, 96, 384, 0, 0, 3, 96, 1, 'MAX', 'incept5b', phase_train=phase_train, use_batch_norm=True, weight_decay=weight_decay)
endpoints['incept5b'] = net
net = network.apool(net, 3, 3, 1, 1, 'VALID', 'pool6')
endpoints['pool6'] = net
net = tf.reshape(net, [-1, 736])
endpoints['prelogits'] = net
net = tf.nn.dropout(net, keep_probability)
endpoints['dropout'] = net
return net, endpoints
================================================
FILE: tmp/random_test.py
================================================
import tensorflow as tf
import numpy as np
from six.moves import xrange
with tf.Graph().as_default():
tf.set_random_seed(666)
# Placeholder for input images
input_placeholder = tf.placeholder(tf.float32, shape=(9, 7), name='input')
# Split example embeddings into anchor, positive and negative
#anchor, positive, negative = tf.split(0, 3, input)
resh1 = tf.reshape(input_placeholder, [3,3,7])
anchor = resh1[0,:,:]
positive = resh1[1,:,:]
negative = resh1[2,:,:]
# Build an initialization operation to run below.
init = tf.global_variables_initializer()
# Start running operations on the Graph.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=False))
sess.run(init)
with sess.as_default():
batch = np.zeros((9,7))
batch[0,:] = 1.1
batch[1,:] = 2.1
batch[2,:] = 3.1
batch[3,:] = 1.2
batch[4,:] = 2.2
batch[5,:] = 3.2
batch[6,:] = 1.3
batch[7,:] = 2.3
batch[8,:] = 3.3
feed_dict = {input_placeholder: batch }
print(batch)
print(sess.run([anchor, positive, negative], feed_dict=feed_dict))
#feed_dict = { images_placeholder: np.zeros((90,96,96,3)), phase_train_placeholder: True }
#vars_eval = sess.run(tf.global_variables(), feed_dict=feed_dict)
#for gt in vars_eval:
#print('%.20f' % (np.sum(gt)))
#for gt, gv in zip(grads_eval, grad_vars):
#print('%40s: %.20f' % (gv.op.name, np.sum(gt)))
#import h5py
#myFile = h5py.File('/home/david/repo/TensorFace/network.h5', 'r')
## The '...' means retrieve the whole tensor
#data = myFile[...]
#print(data)
#import h5py # HDF5 support
#fileName = "/home/david/repo/TensorFace/network.h5"
#f = h5py.File(fileName, "r")
##for item in f.keys():
##print item
#for item in f.values():
#print item
#import tensorflow as tf
#import numpy as np
#import matplotlib.pyplot as plt
#import math
#import facenet
#import os
#import glob
#from scipy import misc
#def plot_triplet(apn, idx):
#plt.subplot(1,3,1)
#plt.imshow(np.multiply(apn[idx*3+0,:,:,:],1/256))
#plt.subplot(1,3,2)
#plt.imshow(np.multiply(apn[idx*3+1,:,:,:],1/256))
#plt.subplot(1,3,3)
#plt.imshow(np.multiply(apn[idx*3+2,:,:,:],1/256))
#input_image = tf.placeholder(tf.float32, name='input_image')
#phase_train = tf.placeholder(tf.bool, name='phase_train')
#n_in, n_out = 3, 16
#ksize = 3
#stride = 1
#kernel = tf.Variable(tf.truncated_normal([ksize, ksize, n_in, n_out],
#stddev=math.sqrt(2/(ksize*ksize*n_out))),
#name='kernel')
#conv = tf.nn.conv2d(input_image, kernel, [1,stride,stride,1], padding="SAME")
#conv_bn = facenet.batch_norm(conv, n_out, phase_train)
#relu = tf.nn.relu(conv_bn)
## Build an initialization operation to run below.
#init = tf.global_variables_initializer()
## Start running operations on the Graph.
#sess = tf.Session()
#sess.run(init)
#path = '/home/david/datasets/fs_aligned/Zooey_Deschanel/'
#files = glob.glob(os.path.join(path, '*.png'))
#nrof_samples = 30
#img_list = [None] * nrof_samples
#for i in xrange(nrof_samples):
#img_list[i] = misc.imread(files[i])
#images = np.stack(img_list)
#feed_dict = {
#input_image: images.astype(np.float32),
#phase_train: True
#}
#out = sess.run([relu], feed_dict=feed_dict)
#print(out[0].shape)
##print(out)
#plot_triplet(images, 0)
#import matplotlib.pyplot as plt
#import numpy as np
#a=[3,4,5,6]
#b = [1,a[1:3]]
#print(b)
## Generate some data...
#x, y = np.meshgrid(np.linspace(-2,2,200), np.linspace(-2,2,200))
#x, y = x - x.mean(), y - y.mean()
#z = x * np.exp(-x**2 - y**2)
#print(z.shape)
## Plot the grid
#plt.imshow(z)
#plt.gray()
#plt.show()
#import numpy as np
#np.random.seed(123)
#rnd = 1.0*np.random.randint(1,2**32)/2**32
#print(rnd)
================================================
FILE: tmp/rename_casia_directories.py
================================================
import shutil
import argparse
import os
import sys
def main(args):
identity_map = {}
with open(os.path.expanduser(args.map_file_name), "r") as f:
for line in f:
fields = line.split(' ')
dir_name = fields[0]
class_name = fields[1].replace('\n', '').replace('\r', '')
if class_name not in identity_map.values():
identity_map[dir_name] = class_name
else:
print('Duplicate class names: %s' % class_name)
dataset_path_exp = os.path.expanduser(args.dataset_path)
dirs = os.listdir(dataset_path_exp)
for f in dirs:
old_path = os.path.join(dataset_path_exp, f)
if f in identity_map:
new_path = os.path.join(dataset_path_exp, identity_map[f])
if os.path.isdir(old_path):
print('Renaming %s to %s' % (old_path, new_path))
shutil.move(old_path, new_path)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('map_file_name', type=str, help='Name of the text file that contains the directory to class name mappings.')
parser.add_argument('dataset_path', type=str, help='Path to the dataset directory.')
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/seed_test.py
================================================
import tensorflow as tf
import numpy as np
import sys
import time
sys.path.append('../src')
import facenet
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import array_ops
from six.moves import xrange
tf.app.flags.DEFINE_integer('batch_size', 90,
"""Number of images to process in a batch.""")
tf.app.flags.DEFINE_integer('image_size', 96,
"""Image size (height, width) in pixels.""")
tf.app.flags.DEFINE_float('alpha', 0.2,
"""Positive to negative triplet distance margin.""")
tf.app.flags.DEFINE_float('learning_rate', 0.1,
"""Initial learning rate.""")
tf.app.flags.DEFINE_float('moving_average_decay', 0.9999,
"""Expontential decay for tracking of training parameters.""")
FLAGS = tf.app.flags.FLAGS
def run_train():
with tf.Graph().as_default():
# Set the seed for the graph
tf.set_random_seed(666)
# Placeholder for input images
images_placeholder = tf.placeholder(tf.float32, shape=(FLAGS.batch_size, FLAGS.image_size, FLAGS.image_size, 3), name='input')
# Build the inference graph
embeddings = inference_conv_test(images_placeholder)
#embeddings = inference_affine_test(images_placeholder)
# Split example embeddings into anchor, positive and negative
anchor, positive, negative = tf.split(0, 3, embeddings)
# Alternative implementation of the split operation
# This produces the same error
#resh1 = tf.reshape(embeddings, [3,int(FLAGS.batch_size/3), 128])
#anchor = resh1[0,:,:]
#positive = resh1[1,:,:]
#negative = resh1[2,:,:]
# Calculate triplet loss
pos_dist = tf.reduce_sum(tf.square(tf.sub(anchor, positive)), 1)
neg_dist = tf.reduce_sum(tf.square(tf.sub(anchor, negative)), 1)
basic_loss = tf.add(tf.sub(pos_dist,neg_dist), FLAGS.alpha)
loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
# Build a Graph that trains the model with one batch of examples and updates the model parameters
opt = tf.train.GradientDescentOptimizer(FLAGS.learning_rate)
#opt = tf.train.AdagradOptimizer(FLAGS.learning_rate) # Optimizer does not seem to matter
grads = opt.compute_gradients(loss)
train_op = opt.apply_gradients(grads)
# Initialize the variables
init = tf.global_variables_initializer()
# Launch the graph.
sess = tf.Session()
sess.run(init)
# Set the numpy seed
np.random.seed(666)
with sess.as_default():
grads_eval = []
all_vars = []
for step in xrange(1):
# Generate some random input data
batch = np.random.random((FLAGS.batch_size, FLAGS.image_size, FLAGS.image_size, 3))
feed_dict = { images_placeholder: batch }
# Get the variables
var_names = tf.global_variables()
all_vars += sess.run(var_names, feed_dict=feed_dict)
# Get the gradients
grad_tensors, grad_vars = zip(*grads)
grads_eval += sess.run(grad_tensors, feed_dict=feed_dict)
# Run training
sess.run(train_op, feed_dict=feed_dict)
sess.close()
return (var_names, all_vars, grad_vars, grads_eval)
def _conv(inpOp, nIn, nOut, kH, kW, dH, dW, padType):
kernel = tf.Variable(tf.truncated_normal([kH, kW, nIn, nOut],
dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(inpOp, kernel, [1, dH, dW, 1], padding=padType)
biases = tf.Variable(tf.constant(0.0, shape=[nOut], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.reshape(tf.nn.bias_add(conv, biases), conv.get_shape())
conv1 = tf.nn.relu(bias)
return conv1
def _affine(inpOp, nIn, nOut):
kernel = tf.Variable(tf.truncated_normal([nIn, nOut],
dtype=tf.float32,
stddev=1e-1), name='weights')
biases = tf.Variable(tf.constant(0.0, shape=[nOut], dtype=tf.float32),
trainable=True, name='biases')
affine1 = tf.nn.relu_layer(inpOp, kernel, biases)
return affine1
def inference_conv_test(images):
conv1 = _conv(images, 3, 64, 7, 7, 2, 2, 'SAME')
resh1 = tf.reshape(conv1, [-1, 147456])
affn = _affine(resh1, 147456, 128) # Affine layer not needed to reproduce the error
return affn
def inference_affine_test(images):
resh1 = tf.reshape(images, [-1, 27648])
affn1 = _affine(resh1, 27648, 1024)
affn2 = _affine(affn1, 1024, 1024)
affn3 = _affine(affn2, 1024, 1024)
affn4 = _affine(affn3, 1024, 128)
return affn4
# Run two sessions with the same seed. These runs should produce the same result.
var_names1, all_vars1, grad_names1, all_grads1 = run_train()
var_names2, all_vars2, grad_names2, all_grads2 = run_train()
all_vars_close = [None] * len(all_vars1)
for i in range(len(all_vars1)):
all_vars_close[i] = np.allclose(all_vars1[i], all_vars2[i], rtol=1.e-16)
print('%d var %s: %s' % (i, var_names1[i].op.name, all_vars_close[i]))
all_grads_close = [None] * len(all_grads1)
for i in range(len(all_grads1)):
all_grads_close[i] = np.allclose(all_grads1[i], all_grads2[i], rtol=1.e-16)
print('%d grad %s: %s' % (i, grad_names1[i].op.name, all_grads_close[i]))
assert all(all_vars_close), 'Variable values differ between the two sessions (with the same seed)'
assert all(all_grads_close), 'Gradient values differ between the two sessions (with the same seed)'
================================================
FILE: tmp/select_triplets_test.py
================================================
import facenet
import numpy as np
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_integer('people_per_batch', 45,
"""Number of people per batch.""")
tf.app.flags.DEFINE_integer('alpha', 0.2,
"""Positive to negative triplet distance margin.""")
embeddings = np.zeros((1800,128))
np.random.seed(123)
for ix in range(embeddings.shape[0]):
for jx in range(embeddings.shape[1]):
rnd = 1.0*np.random.randint(1,2**32)/2**32
embeddings[ix][jx] = rnd
emb_array = embeddings
image_data = np.zeros((1800,96,96,3))
num_per_class = [40 for i in range(45)]
np.random.seed(123)
apn, nrof_random_negs, nrof_triplets = facenet.select_triplets(emb_array, num_per_class, image_data)
================================================
FILE: tmp/test1.py
================================================
print('Hello world')
================================================
FILE: tmp/test_align.py
================================================
import facenet
import os
import matplotlib.pyplot as plt
import numpy as np
def main():
image_size = 96
old_dataset = '/home/david/datasets/facescrub/fs_aligned_new_oean/'
new_dataset = '/home/david/datasets/facescrub/facescrub_110_96/'
eq = 0
num = 0
l = []
dataset = facenet.get_dataset(old_dataset)
for cls in dataset:
new_class_dir = os.path.join(new_dataset, cls.name)
for image_path in cls.image_paths:
try:
filename = os.path.splitext(os.path.split(image_path)[1])[0]
new_filename = os.path.join(new_class_dir, filename+'.png')
#print(image_path)
if os.path.exists(new_filename):
a = facenet.load_data([image_path, new_filename], False, False, image_size, do_prewhiten=False)
if np.array_equal(a[0], a[1]):
eq+=1
num+=1
err = np.sum(np.square(np.subtract(a[0], a[1])))
#print(err)
l.append(err)
if err>2000:
fig = plt.figure(1)
p1 = fig.add_subplot(121)
p1.imshow(a[0])
p2 = fig.add_subplot(122)
p2.imshow(a[1])
print('%6.1f: %s\n' % (err, new_filename))
pass
else:
pass
#print('File not found: %s' % new_filename)
except:
pass
if __name__ == '__main__':
main()
================================================
FILE: tmp/test_invariance_on_lfw.py
================================================
"""Test invariance to translation, scaling and rotation on the "Labeled Faces in the Wild" dataset (http://vis-www.cs.umass.edu/lfw/).
This requires test images to be cropped a bit wider than the normal to give some room for the transformations.
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import numpy as np
import argparse
import facenet
import lfw
import matplotlib.pyplot as plt
from scipy import misc
import os
import sys
import math
def main(args):
pairs = lfw.read_pairs(os.path.expanduser(args.lfw_pairs))
paths, actual_issame = lfw.get_paths(os.path.expanduser(args.lfw_dir), pairs)
result_dir = '../data/'
plt.ioff() # Disable interactive plotting mode
with tf.Graph().as_default():
with tf.Session() as sess:
# Load the model
print('Loading model "%s"' % args.model_file)
facenet.load_model(args.model_file)
# Get input and output tensors
images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
image_size = int(images_placeholder.get_shape()[1])
# Run test on LFW to check accuracy for different horizontal/vertical translations of input images
if args.nrof_offsets>0:
step = 3
offsets = np.asarray([x*step for x in range(-args.nrof_offsets//2+1, args.nrof_offsets//2+1)])
horizontal_offset_accuracy = [None] * len(offsets)
for idx, offset in enumerate(offsets):
accuracy = evaluate_accuracy(sess, images_placeholder, phase_train_placeholder, image_size, embeddings,
paths, actual_issame, translate_images, (offset,0), 60, args.orig_image_size, args.seed)
print('Hoffset: %1.3f Accuracy: %1.3f+-%1.3f' % (offset, np.mean(accuracy), np.std(accuracy)))
horizontal_offset_accuracy[idx] = np.mean(accuracy)
vertical_offset_accuracy = [None] * len(offsets)
for idx, offset in enumerate(offsets):
accuracy = evaluate_accuracy(sess, images_placeholder, phase_train_placeholder, image_size, embeddings,
paths, actual_issame, translate_images, (0,offset), 60, args.orig_image_size, args.seed)
print('Voffset: %1.3f Accuracy: %1.3f+-%1.3f' % (offset, np.mean(accuracy), np.std(accuracy)))
vertical_offset_accuracy[idx] = np.mean(accuracy)
fig = plt.figure(1)
plt.plot(offsets, horizontal_offset_accuracy, label='Horizontal')
plt.plot(offsets, vertical_offset_accuracy, label='Vertical')
plt.legend()
plt.grid(True)
plt.title('Translation invariance on LFW')
plt.xlabel('Offset [pixels]')
plt.ylabel('Accuracy')
# plt.show()
print('Saving results in %s' % result_dir)
fig.savefig(os.path.join(result_dir, 'invariance_translation.png'))
save_result(offsets, horizontal_offset_accuracy, os.path.join(result_dir, 'invariance_translation_horizontal.txt'))
save_result(offsets, vertical_offset_accuracy, os.path.join(result_dir, 'invariance_translation_vertical.txt'))
# Run test on LFW to check accuracy for different rotation of input images
if args.nrof_angles>0:
step = 3
angles = np.asarray([x*step for x in range(-args.nrof_offsets//2+1, args.nrof_offsets//2+1)])
rotation_accuracy = [None] * len(angles)
for idx, angle in enumerate(angles):
accuracy = evaluate_accuracy(sess, images_placeholder, phase_train_placeholder, image_size, embeddings,
paths, actual_issame, rotate_images, angle, 60, args.orig_image_size, args.seed)
print('Angle: %1.3f Accuracy: %1.3f+-%1.3f' % (angle, np.mean(accuracy), np.std(accuracy)))
rotation_accuracy[idx] = np.mean(accuracy)
fig = plt.figure(2)
plt.plot(angles, rotation_accuracy)
plt.grid(True)
plt.title('Rotation invariance on LFW')
plt.xlabel('Angle [deg]')
plt.ylabel('Accuracy')
# plt.show()
print('Saving results in %s' % result_dir)
fig.savefig(os.path.join(result_dir, 'invariance_rotation.png'))
save_result(angles, rotation_accuracy, os.path.join(result_dir, 'invariance_rotation.txt'))
# Run test on LFW to check accuracy for different scaling of input images
if args.nrof_scales>0:
step = 0.05
scales = np.asarray([x*step+1 for x in range(-args.nrof_offsets//2+1, args.nrof_offsets//2+1)])
scale_accuracy = [None] * len(scales)
for scale_idx, scale in enumerate(scales):
accuracy = evaluate_accuracy(sess, images_placeholder, phase_train_placeholder, image_size, embeddings,
paths, actual_issame, scale_images, scale, 60, args.orig_image_size, args.seed)
print('Scale: %1.3f Accuracy: %1.3f+-%1.3f' % (scale, np.mean(accuracy), np.std(accuracy)))
scale_accuracy[scale_idx] = np.mean(accuracy)
fig = plt.figure(3)
plt.plot(scales, scale_accuracy)
plt.grid(True)
plt.title('Scale invariance on LFW')
plt.xlabel('Scale')
plt.ylabel('Accuracy')
# plt.show()
print('Saving results in %s' % result_dir)
fig.savefig(os.path.join(result_dir, 'invariance_scale.png'))
save_result(scales, scale_accuracy, os.path.join(result_dir, 'invariance_scale.txt'))
def save_result(aug, acc, filename):
with open(filename, "w") as f:
for i in range(aug.size):
f.write('%6.4f %6.4f\n' % (aug[i], acc[i]))
def evaluate_accuracy(sess, images_placeholder, phase_train_placeholder, image_size, embeddings,
paths, actual_issame, augment_images, aug_value, batch_size, orig_image_size, seed):
nrof_images = len(paths)
nrof_batches = int(math.ceil(1.0*nrof_images / batch_size))
emb_list = []
for i in range(nrof_batches):
start_index = i*batch_size
end_index = min((i+1)*batch_size, nrof_images)
paths_batch = paths[start_index:end_index]
images = facenet.load_data(paths_batch, False, False, orig_image_size)
images_aug = augment_images(images, aug_value, image_size)
feed_dict = { images_placeholder: images_aug, phase_train_placeholder: False }
emb_list += sess.run([embeddings], feed_dict=feed_dict)
emb_array = np.vstack(emb_list) # Stack the embeddings to a nrof_examples_per_epoch x 128 matrix
thresholds = np.arange(0, 4, 0.01)
embeddings1 = emb_array[0::2]
embeddings2 = emb_array[1::2]
_, _, accuracy = facenet.calculate_roc(thresholds, embeddings1, embeddings2, np.asarray(actual_issame), seed)
return accuracy
def scale_images(images, scale, image_size):
images_scale_list = [None] * images.shape[0]
for i in range(images.shape[0]):
images_scale_list[i] = misc.imresize(images[i,:,:,:], scale)
images_scale = np.stack(images_scale_list,axis=0)
sz1 = images_scale.shape[1]/2
sz2 = image_size/2
images_crop = images_scale[:,(sz1-sz2):(sz1+sz2),(sz1-sz2):(sz1+sz2),:]
return images_crop
def rotate_images(images, angle, image_size):
images_list = [None] * images.shape[0]
for i in range(images.shape[0]):
images_list[i] = misc.imrotate(images[i,:,:,:], angle)
images_rot = np.stack(images_list,axis=0)
sz1 = images_rot.shape[1]/2
sz2 = image_size/2
images_crop = images_rot[:,(sz1-sz2):(sz1+sz2),(sz1-sz2):(sz1+sz2),:]
return images_crop
def translate_images(images, offset, image_size):
h, v = offset
sz1 = images.shape[1]/2
sz2 = image_size/2
images_crop = images[:,(sz1-sz2+v):(sz1+sz2+v),(sz1-sz2+h):(sz1+sz2+h),:]
return images_crop
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--model_file', type=str,
help='File containing the model parameters as well as the model metagraph (with extension ".meta")',
default='~/models/facenet/20160514-234418/model.ckpt-500000')
parser.add_argument('--nrof_offsets', type=int,
help='Number of horizontal and vertical offsets to evaluate.', default=21)
parser.add_argument('--nrof_angles', type=int,
help='Number of angles to evaluate.', default=21)
parser.add_argument('--nrof_scales', type=int,
help='Number of scales to evaluate.', default=21)
parser.add_argument('--lfw_pairs', type=str,
help='The file containing the pairs to use for validation.', default='../data/pairs.txt')
parser.add_argument('--lfw_dir', type=str,
help='Path to the data directory containing aligned face patches.', default='~/datasets/lfw/lfw_realigned/')
parser.add_argument('--orig_image_size', type=int,
help='Image size (height, width) in pixels of the original (uncropped/unscaled) images.', default=224)
parser.add_argument('--lfw_nrof_folds', type=int,
help='Number of folds to use for cross validation. Mainly used for testing.', default=10)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/vggface16.py
================================================
"""Load the VGG Face model into TensorFlow.
Download the model from http://www.robots.ox.ac.uk/~vgg/software/vgg_face/
and point to the file 'vgg_face.mat'
"""
import numpy as np
from scipy import io
import tensorflow as tf
def load(filename, images):
#filename = '../data/vgg_face_matconvnet/data/vgg_face.mat'
vgg16 = io.loadmat(filename)
vgg16Layers = vgg16['net'][0][0]['layers']
# A function to get the weights of the VGG layers
def vbbWeights(layerNumber):
W = vgg16Layers[0][layerNumber][0][0][2][0][0]
W = tf.constant(W)
return W
def vbbConstants(layerNumber):
b = vgg16Layers[0][layerNumber][0][0][2][0][1].T
b = tf.constant(np.reshape(b, (b.size)))
return b
modelGraph = {}
modelGraph['input'] = images
modelGraph['conv1_1'] = tf.nn.conv2d(modelGraph['input'], filter = vbbWeights(0), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu1_1'] = tf.nn.relu(modelGraph['conv1_1'] + vbbConstants(0))
modelGraph['conv1_2'] = tf.nn.conv2d(modelGraph['relu1_1'], filter = vbbWeights(2), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu1_2'] = tf.nn.relu(modelGraph['conv1_2'] + vbbConstants(2))
modelGraph['pool1'] = tf.nn.max_pool(modelGraph['relu1_2'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv2_1'] = tf.nn.conv2d(modelGraph['pool1'], filter = vbbWeights(5), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu2_1'] = tf.nn.relu(modelGraph['conv2_1'] + vbbConstants(5))
modelGraph['conv2_2'] = tf.nn.conv2d(modelGraph['relu2_1'], filter = vbbWeights(7), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu2_2'] = tf.nn.relu(modelGraph['conv2_2'] + vbbConstants(7))
modelGraph['pool2'] = tf.nn.max_pool(modelGraph['relu2_2'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv3_1'] = tf.nn.conv2d(modelGraph['pool2'], filter = vbbWeights(10), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu3_1'] = tf.nn.relu(modelGraph['conv3_1'] + vbbConstants(10))
modelGraph['conv3_2'] = tf.nn.conv2d(modelGraph['relu3_1'], filter = vbbWeights(12), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu3_2'] = tf.nn.relu(modelGraph['conv3_2'] + vbbConstants(12))
modelGraph['conv3_3'] = tf.nn.conv2d(modelGraph['relu3_2'], filter = vbbWeights(14), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu3_3'] = tf.nn.relu(modelGraph['conv3_3'] + vbbConstants(14))
modelGraph['pool3'] = tf.nn.max_pool(modelGraph['relu3_3'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv4_1'] = tf.nn.conv2d(modelGraph['pool3'], filter = vbbWeights(17), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu4_1'] = tf.nn.relu(modelGraph['conv4_1'] + vbbConstants(17))
modelGraph['conv4_2'] = tf.nn.conv2d(modelGraph['relu4_1'], filter = vbbWeights(19), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu4_2'] = tf.nn.relu(modelGraph['conv4_2'] + vbbConstants(19))
modelGraph['conv4_3'] = tf.nn.conv2d(modelGraph['relu4_2'], filter = vbbWeights(21), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu4_3'] = tf.nn.relu(modelGraph['conv4_3'] + vbbConstants(21))
modelGraph['pool4'] = tf.nn.max_pool(modelGraph['relu4_3'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv5_1'] = tf.nn.conv2d(modelGraph['pool4'], filter = vbbWeights(24), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu5_1'] = tf.nn.relu(modelGraph['conv5_1'] + vbbConstants(24))
modelGraph['conv5_2'] = tf.nn.conv2d(modelGraph['relu5_1'], filter = vbbWeights(26), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu5_2'] = tf.nn.relu(modelGraph['conv5_2'] + vbbConstants(26))
modelGraph['conv5_3'] = tf.nn.conv2d(modelGraph['relu5_2'], filter = vbbWeights(28), strides = [1, 1, 1, 1], padding = 'SAME')
modelGraph['relu5_3'] = tf.nn.relu(modelGraph['conv5_3'] + vbbConstants(28))
modelGraph['pool5'] = tf.nn.max_pool(modelGraph['relu5_3'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['resh1'] = tf.reshape(modelGraph['pool5'], [-1, 25088])
modelGraph['fc6'] = tf.nn.relu_layer(modelGraph['resh1'], tf.reshape(vbbWeights(31), [25088, 4096]), vbbConstants(31))
modelGraph['dropout1'] = tf.nn.dropout(modelGraph['fc6'], 0.5)
modelGraph['fc7'] = tf.nn.relu_layer(modelGraph['dropout1'], tf.squeeze(vbbWeights(34), [0, 1]), vbbConstants(34))
modelGraph['dropout2'] = tf.nn.dropout(modelGraph['fc7'], 0.5)
modelGraph['fc8'] = tf.nn.relu_layer(modelGraph['dropout2'], tf.squeeze(vbbWeights(37), [0, 1]), vbbConstants(37))
return modelGraph
================================================
FILE: tmp/vggverydeep19.py
================================================
"""Load the VGG imagenet model into TensorFlow.
Download the model from http://www.robots.ox.ac.uk/~vgg/research/very_deep/
and point to the file 'imagenet-vgg-verydeep-19.mat'
"""
import numpy as np
from scipy import io
import tensorflow as tf
def load(filename, images):
vgg19 = io.loadmat(filename)
vgg19Layers = vgg19['layers']
# A function to get the weights of the VGG layers
def vbbWeights(layerNumber):
W = vgg19Layers[0][layerNumber][0][0][2][0][0]
W = tf.constant(W)
return W
def vbbConstants(layerNumber):
b = vgg19Layers[0][layerNumber][0][0][2][0][1].T
b = tf.constant(np.reshape(b, (b.size)))
return b
modelGraph = {}
modelGraph['input'] = images
modelGraph['conv1_1'] = tf.nn.relu(tf.nn.conv2d(modelGraph['input'], filter = vbbWeights(0), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(0))
modelGraph['conv1_2'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv1_1'], filter = vbbWeights(2), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(2))
modelGraph['avgpool1'] = tf.nn.avg_pool(modelGraph['conv1_2'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv2_1'] = tf.nn.relu(tf.nn.conv2d(modelGraph['avgpool1'], filter = vbbWeights(5), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(5))
modelGraph['conv2_2'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv2_1'], filter = vbbWeights(7), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(7))
modelGraph['avgpool2'] = tf.nn.avg_pool(modelGraph['conv2_2'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv3_1'] = tf.nn.relu(tf.nn.conv2d(modelGraph['avgpool2'], filter = vbbWeights(10), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(10))
modelGraph['conv3_2'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv3_1'], filter = vbbWeights(12), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(12))
modelGraph['conv3_3'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv3_2'], filter = vbbWeights(14), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(14))
modelGraph['conv3_4'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv3_3'], filter = vbbWeights(16), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(16))
modelGraph['avgpool3'] = tf.nn.avg_pool(modelGraph['conv3_4'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv4_1'] = tf.nn.relu(tf.nn.conv2d(modelGraph['avgpool3'], filter = vbbWeights(19), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(19))
modelGraph['conv4_2'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv4_1'], filter = vbbWeights(21), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(21))
modelGraph['conv4_3'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv4_2'], filter = vbbWeights(23), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(23))
modelGraph['conv4_4'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv4_3'], filter = vbbWeights(25), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(25))
modelGraph['avgpool4'] = tf.nn.avg_pool(modelGraph['conv4_4'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
modelGraph['conv5_1'] = tf.nn.relu(tf.nn.conv2d(modelGraph['avgpool4'], filter = vbbWeights(28), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(28))
modelGraph['conv5_2'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv5_1'], filter = vbbWeights(30), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(30))
modelGraph['conv5_3'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv5_2'], filter = vbbWeights(32), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(32))
modelGraph['conv5_4'] = tf.nn.relu(tf.nn.conv2d(modelGraph['conv5_3'], filter = vbbWeights(34), strides = [1, 1, 1, 1], padding = 'SAME') + vbbConstants(34))
modelGraph['avgpool5'] = tf.nn.avg_pool(modelGraph['conv5_4'], ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
return modelGraph
================================================
FILE: tmp/visualize.py
================================================
"""Visualize individual feature channels and their combinations to explore the space of patterns learned by the neural network
Based on http://nbviewer.jupyter.org/github/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb
"""
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import numpy as np
import sys
import argparse
import tensorflow as tf
import importlib
from scipy import misc
def main(args):
network = importlib.import_module(args.model_def, 'inference')
# Start with a gray image with a little noise
np.random.seed(seed=args.seed)
img_noise = np.random.uniform(size=(args.image_size,args.image_size,3)) + 100.0
sess = tf.Session()
t_input = tf.placeholder(np.float32, shape=(args.image_size,args.image_size,3), name='input') # define the input tensor
image_mean = 117.0
t_preprocessed = tf.expand_dims(t_input-image_mean, 0)
# Build the inference graph
network.inference(t_preprocessed, 1.0,
phase_train=True, weight_decay=0.0)
# Create a saver for restoring variables
saver = tf.train.Saver(tf.global_variables())
# Restore the parameters
saver.restore(sess, args.model_file)
layers = [op.name for op in tf.get_default_graph().get_operations() if op.type=='Conv2D']
feature_nums = {layer: int(T(layer).get_shape()[-1]) for layer in layers}
print('Number of layers: %d' % len(layers))
for layer in sorted(feature_nums.keys()):
print('%s%d' % ((layer+': ').ljust(40), feature_nums[layer]))
# Picking some internal layer. Note that we use outputs before applying the ReLU nonlinearity
# to have non-zero gradients for features with negative initial activations.
layer = 'InceptionResnetV1/Repeat_2/block8_3/Conv2d_1x1/Conv2D'
#layer = 'incept4b/in4_conv1x1_31/Conv2D'
result_dir = '../data/'
print('Number of features in layer "%s": %d' % (layer, feature_nums[layer]))
channels = range(feature_nums[layer])
np.random.shuffle(channels)
for i in range(32):
print('Rendering feature %d' % channels[i])
channel = channels[i]
img = render_naive(sess, t_input, T(layer)[:,:,:,channel], img_noise)
filename = '%s_%03d.png' % (layer.replace('/', '_'), channel)
misc.imsave(os.path.join(result_dir, filename), img)
def T(layer):
'''Helper for getting layer output tensor'''
return tf.get_default_graph().get_tensor_by_name('%s:0' % layer)
def visstd(a, s=0.1):
'''Normalize the image range for visualization'''
return (a-a.mean())/max(a.std(), 1e-4)*s + 0.5
def render_naive(sess, t_input, t_obj, img0, iter_n=20, step=1.0):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
img = img0.copy()
for _ in range(iter_n):
g, _ = sess.run([t_grad, t_score], {t_input:img})
# normalizing the gradient, so the same step size should work
g /= g.std()+1e-8 # for different layers and networks
img += g*step
return visstd(img)
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument('model_file', type=str,
help='Directory containing the graph definition and checkpoint files.')
parser.add_argument('--model_def', type=str,
help='Model definition. Points to a module containing the definition of the inference graph.',
default='models.nn4')
parser.add_argument('--image_size', type=int,
help='Image size (height, width) in pixels.', default=96)
parser.add_argument('--seed', type=int,
help='Random seed.', default=666)
return parser.parse_args(argv)
if __name__ == '__main__':
main(parse_arguments(sys.argv[1:]))
================================================
FILE: tmp/visualize_vgg_model.py
================================================
import numpy as np
from scipy import misc
import tensorflow as tf
from matplotlib import pyplot, image
import vggverydeep19
paintingStyleImage = image.imread("../data/schoolofathens.jpg")
pyplot.imshow(paintingStyleImage)
inputImage = image.imread("../data/grandcentral.jpg")
pyplot.imshow(inputImage)
outputWidth = 800
outputHeight = 600
# Beta constant
beta = 5
# Alpha constant
alpha = 100
# Noise ratio
noiseRatio = 0.6
nodes = vggverydeep19.load('../data/imagenet-vgg-verydeep-19.mat', (600, 800))
# Mean VGG-19 image
meanImage19 = np.array([103.939, 116.779, 123.68]).reshape((1,1,1,3)) #pylint: disable=no-member
# Squared-error loss of content between the two feature representations
def sqErrorLossContent(sess, modelGraph, layer):
p = session.run(modelGraph[layer])
#pylint: disable=maybe-no-member
N = p.shape[3]
M = p.shape[1] * p.shape[2]
return (1 / (4 * N * M)) * tf.reduce_sum(tf.pow(modelGraph[layer] - sess.run(modelGraph[layer]), 2))
# Squared-error loss of style between the two feature representations
styleLayers = [
('conv1_1', 0.2),
('conv2_1', 0.2),
('conv3_1', 0.2),
('conv4_1', 0.2),
('conv5_1', 0.2),
]
def sqErrorLossStyle(sess, modelGraph):
def intermediateCalc(x, y):
N = x.shape[3]
M = x.shape[1] * x.shape[2]
A = tf.matmul(tf.transpose(tf.reshape(x, (M, N))), tf.reshape(x, (M, N)))
G = tf.matmul(tf.transpose(tf.reshape(y, (M, N))), tf.reshape(y, (M, N)))
return (1 / (4 * N**2 * M**2)) * tf.reduce_sum(tf.pow(G - A, 2))
E = [intermediateCalc(sess.run(modelGraph[layerName]), modelGraph[layerName]) for layerName, _ in styleLayers]
W = [w for _, w in styleLayers]
return sum([W[layerNumber] * E[layerNumber] for layerNumber in range(len(styleLayers))])
session = tf.InteractiveSession()
# Addition of extra dimension to image
inputImage = np.reshape(inputImage, ((1,) + inputImage.shape))
inputImage = inputImage - meanImage19
# Display image
pyplot.imshow(inputImage[0])
# Addition of extra dimension to image
paintingStyleImage = np.reshape(paintingStyleImage, ((1,) + paintingStyleImage.shape))
paintingStyleImage = paintingStyleImage - meanImage19
# Display image
pyplot.imshow(paintingStyleImage[0])
imageNoise = np.random.uniform(-20, 20, (1, outputHeight, outputWidth, 3)).astype('float32')
pyplot.imshow(imageNoise[0])
mixedImage = imageNoise * noiseRatio + inputImage * (1 - noiseRatio)
pyplot.imshow(inputImage[0])
session.run(tf.global_variables_initializer())
session.run(nodes['input'].assign(inputImage))
contentLoss = sqErrorLossContent(session, nodes, 'conv4_2')
session.run(nodes['input'].assign(paintingStyleImage))
styleLoss = sqErrorLossStyle(session, nodes)
totalLoss = beta * contentLoss + alpha * styleLoss
optimizer = tf.train.AdamOptimizer(2.0)
trainStep = optimizer.minimize(totalLoss)
session.run(tf.global_variables_initializer())
session.run(nodes['input'].assign(inputImage))
# Number of iterations to run.
iterations = 2000
session.run(tf.global_variables_initializer())
session.run(nodes['input'].assign(inputImage))
for iters in range(iterations):
session.run(trainStep)
if iters%50 == 0:
# Output every 50 iterations for animation
filename = 'output%d.png' % (iters)
im = mixedImage + meanImage19
im = im[0]
im = np.clip(im, 0, 255).astype('uint8')
misc.imsave(filename, im)
im = mixedImage + meanImage19
im = im[0]
im = np.clip(im, 0, 255).astype('uint8')
misc.imsave('finalImage.png', im)
================================================
FILE: tmp/visualize_vggface.py
================================================
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import tmp.vggface16
def main():
sess = tf.Session()
t_input = tf.placeholder(np.float32, name='input') # define the input tensor
image_mean = 117.0
t_preprocessed = tf.expand_dims(t_input-image_mean, 0)
# Build the inference graph
nodes = tmp.vggface16.load('data/vgg_face.mat', t_preprocessed)
img_noise = np.random.uniform(size=(224,224,3)) + 117.0
# Picking some internal layer. Note that we use outputs before applying the ReLU nonlinearity
# to have non-zero gradients for features with negative initial activations.
layer = 'conv5_3'
channel = 140 # picking some feature channel to visualize
img = render_naive(sess, t_input, nodes[layer][:,:,:,channel], img_noise)
showarray(img)
def showarray(a):
a = np.uint8(np.clip(a, 0, 1)*255)
plt.imshow(a)
plt.show()
def visstd(a, s=0.1):
'''Normalize the image range for visualization'''
return (a-a.mean())/max(a.std(), 1e-4)*s + 0.5
def render_naive(sess, t_input, t_obj, img0, iter_n=20, step=1.0):
t_score = tf.reduce_mean(t_obj) # defining the optimization objective
t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation!
img = img0.copy()
for _ in range(iter_n):
g, _ = sess.run([t_grad, t_score], {t_input:img})
# normalizing the gradient, so the same step size should work
g /= g.std()+1e-8 # for different layers and networks
img += g*step
return visstd(img)
if __name__ == '__main__':
main()
================================================
FILE: util/plot_learning_curves.m
================================================
% Plots the lerning curves for the specified training runs from data in the
% file "lfw_result.txt" stored in the log directory for the respective
% model.
% MIT License
%
% Copyright (c) 2016 David Sandberg
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.
%%
addpath('/home/david/git/facenet/util/');
log_dirs = { '/home/david/logs/facenet' };
%%
res = { ...
{ '20180402-114759', 'vggface2, wd=5e-4, center crop, fixed image standardization' }, ...
};
%%
res = { ...
{ '20180408-102900', 'casia, wd=5e-4, pnlf=5e-4, fixed image standardization' }, ...
};
%%
colors = {'b', 'g', 'r', 'c', 'm', 'y', 'k'};
markers = {'.', 'o', 'x', '+', '*', 's', 'd' };
lines = {'-', '-.', '--', ':' };
fontSize = 6;
lineWidth = 2;
lineStyles = combineStyles(colors, markers);
lineStyles2 = combineStyles(colors, {''}, lines);
legends = cell(length(res),1);
legends_accuracy = cell(length(res),1);
legends_valrate = cell(length(res),1);
var = cell(length(res),1);
for i=1:length(res),
for k=1:length(log_dirs)
if exist(fullfile(log_dirs{k}, res{i}{1}), 'dir')
ld = log_dirs{k};
end
end
filename = fullfile(ld, res{i}{1}, 'stat.h5');
var{i} = readlogs(filename,{'loss', 'reg_loss', 'xent_loss', 'lfw_accuracy', ...
'lfw_valrate', 'val_loss', 'val_xent_loss', 'val_accuracy', ...
'accuracy', 'prelogits_norm', 'learning_rate', 'center_loss', ...
'prelogits_hist', 'accuracy'});
var{i}.steps = 1:length(var{i}.loss);
epoch = find(var{i}.lfw_accuracy,1,'last');
var{i}.epochs = 1:epoch;
legends{i} = sprintf('%s: %s', res{i}{1}, res{i}{2});
start_epoch = max(1,epoch-10);
legends_accuracy{i} = sprintf('%s: %s (%.2f%%)', res{i}{1}, res{i}{2}, mean(var{i}.lfw_accuracy(start_epoch:epoch))*100 );
legends_valrate{i} = sprintf('%s: %s (%.2f%%)', res{i}{1}, res{i}{2}, mean(var{i}.lfw_valrate(start_epoch:epoch))*100 );
arguments_filename = fullfile(ld, res{i}{1}, 'arguments.txt');
if exist(arguments_filename)
str = fileread(arguments_filename);
var{i}.wd = getParameter(str, 'weight_decay', '0.0');
var{i}.cl = getParameter(str, 'center_loss_factor', '0.0');
var{i}.fixed_std = getParameter(str, 'use_fixed_image_standardization', '0');
var{i}.data_dir = getParameter(str, 'data_dir', '');
var{i}.lr = getParameter(str, 'learning_rate', '0.1');
var{i}.epoch_size = str2double(getParameter(str, 'epoch_size', '1000'));
var{i}.batch_size = str2double(getParameter(str, 'batch_size', '90'));
var{i}.examples_per_epoch = var{i}.epoch_size*var{i}.batch_size;
var{i}.mnipc = getParameter(str, 'filter_min_nrof_images_per_class', '-1');
var{i}.val_step = str2num(getParameter(str, 'validate_every_n_epochs', '10'));
var{i}.pnlf = getParameter(str, 'prelogits_norm_loss_factor', '-1');
var{i}.emb_size = getParameter(str, 'embedding_size', '-1');
fprintf('%s: wd=%s lr=%s, pnlf=%s, data_dir=%s, emb_size=%s\n', ...
res{i}{1}, var{i}.wd, var{i}.lr, var{i}.pnlf, var{i}.data_dir, var{i}.emb_size);
end
end;
timestr = datestr(now,'yyyymmdd_HHMMSS');
h = 1; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('LFW accuracy');
xlabel('Steps');
ylabel('Accuracy');
grid on;
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
plot(var{i}.epochs*1000, filter(flt, 1, var{i}.lfw_accuracy(var{i}.epochs)), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends_accuracy,'Location','SouthEast','FontSize',fontSize);
v=axis;
v(3:4) = [ 0.95 1.0 ];
axis(v);
accuracy_file_name = sprintf('lfw_accuracy_%s',timestr);
%print(accuracy_file_name,'-dpng')
if 0
%%
%h = 2; figure(h); close(h); figure(h); hold on; setsize(1.5);
h = 1; figure(h); hold on;
title('LFW validation rate');
xlabel('Step');
ylabel('VAL @ FAR = 10^{-3}');
grid on;
for i=1:length(var),
plot(var{i}.epochs*1000, var{i}.lfw_valrate(var{i}.epochs), lineStyles{i}, 'LineWidth', lineWidth);
end;
legend(legends_valrate,'Location','SouthEast','FontSize',fontSize);
v=axis;
v(3:4) = [ 0.5 1.0 ];
axis(v);
valrate_file_name = sprintf('lfw_valrate_%s',timestr);
% print(valrate_file_name,'-dpng')
end
if 0
%% Plot cross-entropy loss
h = 3; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('Training/validation set cross-entropy loss');
xlabel('Step');
title('Training/validation set cross-entropy loss');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
var{i}.xent_loss(var{i}.xent_loss==0) = NaN;
plot(var{i}.steps, filter(flt, 1, var{i}.xent_loss), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
% Plot cross-entropy loss on validation set
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
v = var{i}.val_xent_loss;
val_steps = (1:length(v))*var{i}.val_step*1000;
v(v==0) = NaN;
plot(val_steps, filter(flt, 1, v), [ lineStyles2{i} '.' ], 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
hold off
xent_file_name = sprintf('xent_%s',timestr);
%print(xent_file_name,'-dpng')
end
if 0
%% Plot accuracy on training set
h = 32; figure(h); clf; hold on;
title('Training/validation set accuracy');
xlabel('Step');
ylabel('Training/validation set accuracy');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
var{i}.accuracy(var{i}.accuracy==0) = NaN;
plot(var{i}.steps*1000, filter(flt, 1, var{i}.accuracy), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'SouthEast','FontSize',fontSize);
grid on;
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
v = var{i}.val_accuracy;
val_steps = (1:length(v))*var{i}.val_step*1000;
v(v==0) = NaN;
plot(val_steps*1000, filter(flt, 1, v), [ lineStyles2{i} '.' ], 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'SouthEast','FontSize',fontSize);
hold off
acc_file_name = sprintf('accuracy_%s',timestr);
%print(acc_file_name,'-dpng')
end
if 0
%% Plot prelogits CDF
h = 35; figure(h); clf; hold on;
title('Prelogits histogram');
xlabel('Epoch');
ylabel('Prelogits histogram');
grid on;
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
epoch = var{i}.epochs(end);
q = cumsum(var{i}.prelogits_hist(:,epoch));
q2 = q / q(end);
plot(linspace(0,10,1000), q2, lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'SouthEast','FontSize',fontSize);
hold off
end
if 0
%% Plot prelogits norm
h = 32; figure(h); clf; hold on;
title('Prelogits norm');
xlabel('Step');
ylabel('Prelogits norm');
grid on;
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
plot(var{i}.steps, filter(flt, 1, var{i}.prelogits_norm), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
hold off
end
if 0
%% Plot learning rate
h = 42; figure(h); clf; hold on;
title('Learning rate');
xlabel('Step');
ylabel('Learning rate');
grid on;
N = 1; flt = ones(1,N)/N;
for i=1:length(var),
semilogy(var{i}.epochs, filter(flt, 1, var{i}.learning_rate(var{i}.epochs)), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
hold off
end
if 0
%% Plot center loss
h = 9; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('Center loss');
xlabel('Epochs');
ylabel('Center loss');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
if isempty(var{i}.center_loss)
var{i}.center_loss = ones(size(var{i}.steps))*NaN;
end;
var{i}.center_loss(var{i}.center_loss==0) = NaN;
plot(var{i}.steps/var{i}.epoch_size, filter(flt, 1, var{i}.center_loss), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
end
if 0
%% Plot center loss with factor
h = 9; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('Center loss with factor');
xlabel('Epochs');
ylabel('Center loss * center loss factor');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
if isempty(var{i}.center_loss)
var{i}.center_loss = ones(size(var{i}.steps))*NaN;
end;
var{i}.center_loss(var{i}.center_loss==0) = NaN;
plot(var{i}.steps/var{i}.epoch_size, filter(flt, 1, var{i}.center_loss*str2num(var{i}.cl)), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
end
if 0
%% Plot total loss
h = 4; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('Total loss');
xlabel('Epochs');
ylabel('Total loss');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
var{i}.loss(var{i}.loss==0) = NaN;
plot(var{i}.steps/var{i}.epoch_size, filter(flt, 1, var{i}.loss), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
end
if 0
%% Plot regularization loss
h = 5; figure(h); close(h); figure(h); hold on; setsize(1.5);
title('Regularization loss');
xlabel('Epochs');
ylabel('Regularization loss');
grid on;
N = 500; flt = ones(1,N)/N;
for i=1:length(var),
var{i}.reg_loss(var{i}.reg_loss==0) = NaN;
plot(var{i}.steps/var{i}.epoch_size, filter(flt, 1, var{i}.reg_loss), lineStyles2{i}, 'LineWidth', lineWidth);
end;
legend(legends, 'Location', 'NorthEast','FontSize',fontSize);
end