Rock It 《Armbian》九‧二

見著人臉辨識範例中有一個『基準』測試程式

face_recognition/examples/benchmark.py

,何不就看看 ROCK64 表現如何哩︰

rock64@rock64:~/face_recognition/examplespython3 benchmark.py  Benchmarks (Note: All benchmarks are only using a single CPU core)  Timings at 240p:  - Face locations: 0.5073s (1.97 fps)  - Face landmarks: 0.0152s (65.92 fps)  - Encode face (inc. landmarks): 1.1598s (0.86 fps)  - End-to-end: 1.6672s (0.60 fps)  Timings at 480p:  - Face locations: 1.9778s (0.51 fps)  - Face landmarks: 0.0156s (63.96 fps)  - Encode face (inc. landmarks): 1.1604s (0.86 fps)  - End-to-end: 3.1380s (0.32 fps)  Timings at 720p:  - Face locations: 4.5431s (0.22 fps)  - Face landmarks: 0.0159s (63.02 fps)  - Encode face (inc. landmarks): 1.1630s (0.86 fps)  - End-to-end: 5.7056s (0.18 fps)  Timings at 1080p:  - Face locations: 10.4224s (0.10 fps)  - Face landmarks: 0.0161s (62.19 fps)  - Encode face (inc. landmarks): 1.1640s (0.86 fps)  - End-to-end: 11.5861s (0.09 fps) </pre>    <span style="color: #666699;">心想為何只用一顆 CPU 呢?</span>  <span style="color: #666699;">猶記命令列工具 face_recognition </span> <pre class="lang:default decode:true">rock64@rock64:~ face_recognition --help
Usage: face_recognition [OPTIONS] KNOWN_PEOPLE_FOLDER IMAGE_TO_CHECK

Options:
  --cpus INTEGER           number of CPU cores to use in parallel (can speed
                           up processing lots of images). -1 means "use all in
                           system"
  --tolerance FLOAT        Tolerance for face comparisons. Default is 0.6.
                           Lower this if you get multiple matches for the same
                           person.
  --show-distance BOOLEAN  Output face distance. Useful for tweaking tolerance
                           setting.
  --help                   Show this message and exit.

 

不是可以給定幾顆 CPU 參數嗎?

※  註︰

Usage

Command-Line Interface

When you install face_recognition, you get two simple command-line programs:

  • face_recognition – Recognize faces in a photograph or folder full for photographs.
  • face_detection – Find faces in a photograph or folder full for photographs.

face_recognition command line tool

The face_recognition command lets you recognize faces in a photograph or folder full for photographs.

First, you need to provide a folder with one picture of each person you already know. There should be one image file for each person with the files named according to who is in the picture:

known

Next, you need a second folder with the files you want to identify:

unknown

Then in you simply run the command face_recognition, passing in the folder of known people and the folder (or single image) with unknown people and it tells you who is in each image:

face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/  /unknown_pictures/unknown.jpg,Barack Obama /face_recognition_test/unknown_pictures/unknown.jpg,unknown_person</pre> <span style="color: #808080;">……</span> <h5><span style="color: #808080;">Speeding up Face Recognition</span></h5> <span style="color: #808080;">Face recognition can be done in parallel if you have a computer with multiple CPU cores. For example, if your system has 4 CPU cores, you can process about 4 times as many images in the same amount of time by using all your CPU cores in parallel.</span>  <span style="color: #808080;">If you are using Python 3.4 or newer, pass in a <code>--cpus <number_of_cpu_cores_to_use></code> parameter:</span> <pre class="lang:default decode:true "> face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/

───

 

閱讀 API 文件後,確定沒有也!

Python Module

You can import the face_recognition module and then easily manipulate
faces with just a couple of lines of code. It’s super easy!

API Docs: https://face-recognition.readthedocs.io.

 

故而只能考察原始碼呦?

face_recognition_cli.py

def process_images_in_process_pool(images_to_check, known_names, known_face_encodings, number_of_cpus, tolerance, show_distance):
    if number_of_cpus == -1:
        processes = None
    else:
        processes = number_of_cpus

    # macOS will crash due to a bug in libdispatch if you don't use 'forkserver'
    context = multiprocessing
    if "forkserver" in multiprocessing.get_all_start_methods():
        context = multiprocessing.get_context("forkserver")

    pool = context.Pool(processes=processes)

    function_parameters = zip(
        images_to_check,
        itertools.repeat(known_names),
        itertools.repeat(known_face_encodings),
        itertools.repeat(tolerance),
        itertools.repeat(show_distance)
    )

    pool.starmap(test_image, function_parameters)

 

原來那用的是派生三

17.2. multiprocessing — Process-based parallelism

17.2.1. Introduction

multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

The multiprocessing module also introduces APIs which do not have analogs in the threading module. A prime example of this is the Pool object which offers a convenient means of parallelizing the execution of a function across multiple input values, distributing the input data across processes (data parallelism). The following example demonstrates the common practice of defining such functions in a module so that child processes can successfully import that module. This basic example of data parallelism using Pool,

rock64@rock64:~$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from multiprocessing import Pool
>>> def f(x):
...     return x*x
... 
>>> if __name__ == '__main__':
...     with Pool(4) as p:
...         print(p.map(f, [1, 2, 3]))
... 
[1, 4, 9]
>>>

will print to standard output

[1, 4, 9]

……

17.2.1.2. Contexts and start methods

Depending on the platform, multiprocessing supports three ways to start a process. These start methods are

spawn

The parent process starts a fresh python interpreter process. The child process will only inherit those resources necessary to run the process objects run() method. In particular, unnecessary file descriptors and handles from the parent process will not be inherited. Starting a process using this method is rather slow compared to using fork or forkserver.

Available on Unix and Windows. The default on Windows.

fork

The parent process uses os.fork() to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process. Note that safely forking a multithreaded process is problematic.

Available on Unix only. The default on Unix.

forkserver

When the program starts and selects the forkserver start method, a server process is started. From then on, whenever a new process is needed, the parent process connects to the server and requests that it fork a new process. The fork server process is single threaded so it is safe for it to useos.fork(). No unnecessary resources are inherited.

Available on Unix platforms which support passing file descriptors over Unix pipes.

Changed in version 3.4: spawn added on all unix platforms, and forkserver added for some unix platforms. Child processes no longer inherit all of the parents inheritable handles on Windows.

On Unix using the spawn or forkserver start methods will also start a semaphore tracker process which tracks the unlinked named semaphores created by processes of the program. When all processes have exited the semaphore tracker unlinks any remaining semaphores. Usually there should be none, but if a process was killed by a signal there may some “leaked” semaphores. (Unlinking the named semaphores is a serious matter since the system allows only a limited number, and they will not be automatically unlinked until the next reboot.)

 

程式庫呀!