<jupyter_start><jupyter_text>Predicting the similar actor  The neural network that identifies the gender of the person from the picture we have already downloaded 500 pics for each gender (the code in the file download.ipynb)<jupyter_code>"""
I wrote "man" and "woman" in the dict in russian because the request 
with "man" gave a lot of not male persons on pics or no persons at all 
and were FOR men bit not WITH men
"""
gender_dict={'мужчина':0, 'женщина':1}<jupyter_output><empty_output><jupyter_text>make the embeding for each pic, except ones that have more than 1 or no faces<jupyter_code>embedings = np.empty(128)
target = [] #the y column

for gender in list(gender_dict.keys()):
    # the list of the pics in the folder
    images = os.listdir(f"gender/{gender}")

    for img in images:
        # load the img
        face = face_recognition.load_image_file(f"gender/{gender}/{img}")
        # have the coordinates of the face
        face_bounding_boxes = face_recognition.face_locations(face)

        # if there're more than 1 face or noone skip the pic
        if len(face_bounding_boxes) == 1:
            try:
                # getting the embeding
                face_enc = face_recognition.face_encodings(face)[0]
                # add to the matrix
                embedings = np.vstack((embedings, face_enc))
                # add the gender to the y 
                target.append(gender_dict[gender])
            except Exception as ex:
                print(f'Error message {ex}')

# drop the 1 empty element
embedings = embedings[1:].astype(np.float)
target= np.array(target)
target=tf.keras.utils.to_categorical(target, num_classes=2, dtype='int8')<jupyter_output><empty_output><jupyter_text>divide into train and test samples and teach the neural network<jupyter_code>X_train, X_test, y_train, y_test = train_test_split(embedings, target, test_size=0.3, 
                                                    stratify=target,  random_state=5)
tf.random.set_seed(930)
init=initializers.RandomNormal(mean=0.0, stddev=0.05, seed=560)
init1=initializers.Constant(value=1e-3)

model = Sequential() 
model.add(Dense(70, input_dim=embedings.shape[1], activation='relu', 
                kernel_initializer=init, bias_initializer=init1)) 
model.add(Dropout(0.25))
model.add(Dense(2, activation='softmax'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(X_train, y_train, epochs=6, batch_size=100, verbose=1)
print('\n')
scores=model.evaluate(tf.expand_dims(X_test, axis=-1), y_test)<jupyter_output>Epoch 1/6
5/5 [==============================] - 1s 6ms/step - loss: 0.6854 - accuracy: 0.6580
Epoch 2/6
5/5 [==============================] - 0s 7ms/step - loss: 0.6705 - accuracy: 0.7480
Epoch 3/6
5/5 [==============================] - 0s 5ms/step - loss: 0.6543 - accuracy: 0.7340
Epoch 4/6
5/5 [==============================] - 0s 7ms/step - loss: 0.6351 - accuracy: 0.8220
Epoch 5/6
5/5 [==============================] - 0s 5ms/step - loss: 0.6165 - accuracy: 0.9060
Epoch 6/6
5/5 [==============================] - 0s 7ms/step - loss: 0.5932 - accuracy: 0.9640


7/7 [==============================] - 0s 3ms/step - loss: 0.5825 - accuracy: 0.9860<jupyter_text>The model that predicts the actor we have already downloaded 10 pics for each actor (the code in the file download.ipynb)check that face_recognition identifies faces correctly<jupyter_code># load the pic
image = face_recognition.load_image_file(".\dataset\Emma_Watson\Emma Watson_7.jpeg")

# get the coordinates of the face
face_locations = face_recognition.face_locations(image)
xy = (face_locations[0][3], face_locations[0][0])

width = face_locations[0][1] - face_locations[0][3]
height = face_locations[0][2] - face_locations[0][0]

plt.imshow(image)

# Get the current axes
ax = plt.gca()

# rectangle on the face
rect = patches.Rectangle(xy, width, height, linewidth=2, edgecolor='r', facecolor='none')
ax.add_patch(rect);
with open('actors.txt') as json_file:
    actors = json.load(json_file)
#give the id to each actor
dict_man = dict()
for i, key in enumerate(actors['man']):
    dict_man[key] = i
    

dict_woman = dict()
for i, key in enumerate(actors['woman']):
    dict_woman[key] = i

dict_woman
# embedings for actors
embedings_man=np.empty(128)
target_man=[]

for person in tqdm_notebook(list(dict_man.keys())):
    files = len(glob.glob(f'dataset/{person}/*'))   
    if files < 2:  #because too few for train and test at the same time
        print(f'Delete from dataset: {person}')
    else:
        # get the list of pics from the folder
        images = os.listdir(f"./dataset/{person}")
        len_images = len(images)

        for num, person_img in enumerate(images):
            # loading the image
            face = face_recognition.load_image_file(
                f"dataset/{person}/{person_img}")
            # get the coordinates of the face
            face_bounding_boxes = face_recognition.face_locations(face)

            # miss the pic if there are more than 1 face or noone
            if len(face_bounding_boxes) == 1:
                try:
                    # make embeding
                    face_enc = face_recognition.face_encodings(face)[0]
                    embedings_man = np.vstack((embedings_man, face_enc))
                    # add the name of the actor to y column
                    target_man.append(dict_man[person])

                except Exception as ex:
                    print(f'Error message {ex}')
            
embedings_man = embedings_man[1:] #delete the 1 empty element
# embedings for actresses
embedings_woman=np.empty(128)
target_woman=[]

for person in tqdm_notebook(list(dict_woman.keys())):
    files = len(glob.glob(f'dataset/{person}/*'))   
    if files < 2: 
        print(f'Delete from dataset: {person}')
    else:
        # get the list of pics from the folder
        images = os.listdir(f"./dataset/{person}")
        len_images = len(images)

        for num, person_img in enumerate(images):
            # loading the image
            face = face_recognition.load_image_file(
                f"dataset/{person}/{person_img}")
            # get the coordinates of the face
            face_bounding_boxes = face_recognition.face_locations(face)

            # miss the pic if there are more than 1 face or noone
            if len(face_bounding_boxes) == 1:
                try:
                    # make embeding
                    face_enc = face_recognition.face_encodings(face)[0]
                    embedings_woman = np.vstack((embedings_woman, face_enc))
                    # add the name of the actor to y column
                    target_woman.append(dict_woman[person])

                except Exception as ex:
                    print(f'Error message {ex}')
            
embedings_woman = embedings_woman[1:] #delete the 1 empty element<jupyter_output><empty_output><jupyter_text>Training the model<jupyter_code>X_train_w, X_test_w, y_train_w, y_test_w = train_test_split(
    embedings_woman, target_woman, test_size=0.3, stratify=target_woman, random_state=42)

mod_woman = LogisticRegression(solver='liblinear', fit_intercept=False, class_weight='balanced')

mod_woman.fit(X_train_w, y_train_w)

acc=accuracy_score(y_test_w, mod_woman.predict(X_test_w))
print(f'accuracy score = {acc}')
X_train_m, X_test_m, y_train_m, y_test_m = train_test_split(
    embedings_man, target_man, test_size=0.3, stratify=target_man, random_state=42)

mod_man = LogisticRegression(solver='liblinear', fit_intercept=False, class_weight='balanced')
mod_man.fit(X_train_m, y_train_m)

acc=accuracy_score(y_test_m, mod_man.predict(X_test_m))
print(f'accuracy score = {acc}')<jupyter_output>accuracy score = 0.8870056497175142<jupyter_text>Predicting **here write the addres of the pic you want to predict the actor for**<jupyter_code>PATH='test_pic.jpg' 
SIZE=256     #the size for resizing the pic<jupyter_output><empty_output><jupyter_text>the function that make the pic smaller for quicker work<jupyter_code>def resize_image(SIZE, image):
    # get the size
    size = image.size

    # get the coeff to reshape one of the pict to needed size
    coef = SIZE / size[0]
    # changing the size
    resized_image = image.resize(
        (int(size[0] * coef), int(size[1] * coef)))
    res_image = resized_image.convert('RGB')
    return res_image
image = Image.open(PATH)
res_image = resize_image(SIZE, image)
res_image.save(PATH)<jupyter_output><empty_output><jupyter_text>predicting the gender<jupyter_code>emb=np.empty(128)
face = face_recognition.load_image_file(PATH)
face_bounding_boxes = face_recognition.face_locations(face)

if len(face_bounding_boxes) != 1:
    print('Problem with find face')
else:
    # embeding making
    face_enc = face_recognition.face_encodings(face)[0]
    emb = np.vstack((emb, face_enc))
    emb=emb[1:].astype(np.float)

    predict = model.predict([emb])
    predict=np.argmax(predict)
if predict==0:
    
    #the  variable that gets the predicted gender
    identified_g='man'
    print(identified_g)
else:
    identified_g='woman'
    print(identified_g)
plt.imshow(Image.open(PATH));<jupyter_output>woman<jupyter_text>if the person on the pic is a man predict only between actors, for women - only actresses<jupyter_code>if identified_g=='man':
    actor_model=mod_man
    dict_labels=dict_man
elif identified_g=='woman':
    actor_model=mod_woman
    dict_labels=dict_woman
def predict_actor(path, model, dict_labels):
    face = face_recognition.load_image_file(path)
    face_bounding_boxes = face_recognition.face_locations(face)
    
    if len(face_bounding_boxes) != 1:
        print('Problem with find face')
    else:
        # make embeding 
        face_enc = face_recognition.face_encodings(face)[0]
        
        # predict actress/actor
        predict = model.predict([face_enc])
        predict_labels = list(dict_labels.keys())[list(dict_labels.values()).index(predict)]
        
        predict_proba = model.predict_proba([face_enc])
        
        return predict_labels, predict_proba
predict_name, predict_proba = predict_actor(PATH, actor_model, dict_labels)
predict_name
# таблица со скорами
df = pd.DataFrame()

df['act'] = list(dict_labels.keys())
df['score'] = predict_proba[0]

df.sort_values(by='score')[::-1]
num_image = 5
name=predict_name.replace('_', ' ')

image1 = face_recognition.load_image_file(PATH)
image2 = face_recognition.load_image_file(f"dataset/{predict_name}/{name}_{num_image}.jpeg")

fig, ax = plt.subplots(1, 2, figsize=(15,15))

ax[0].imshow(image1)
ax[1].imshow(image2);<jupyter_output><empty_output><jupyter_text>Getting the mean cosine<jupyter_code>def comparison(path_test, name_act, num_image):
    # the test face
    face_1 = face_recognition.load_image_file(path_test)
    face_enc_1 = face_recognition.face_encodings(face_1)[0]
    
    # the actor
    path_act = f"dataset/{predict_name}/{name}_{num_image}.jpeg"
    
    face_2 = face_recognition.load_image_file(path_act)
    face_enc_2 = face_recognition.face_encodings(face_2)[0]
    
    return cosine_similarity(face_enc_1.reshape(1, -1), face_enc_2.reshape(1, -1))[0]
len_files = len(glob.glob(f'dataset/{predict_name}/*'))
cos = []

for i in tqdm_notebook(range(1, len_files+1, 1)):
    try:
        cos_ = comparison(PATH, predict_name, i)
        cos.append(cos_)
        print(i, cos_)
    except Exception as ex:
        print(f'message: {ex}')
        
print(f'Mean score = {np.mean(cos)}')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12693310165073848, 'fraction_numerical': 0.022936576889661164, 'mean_word_length': 3.5751192368839426, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '581623', 'license': 'MIT', 'n_tokens_mistral': 4009, 'n_tokens_neox': 3784, 'n_words': 875, 'path': 'face.ipynb', 'repo_name': 'KokaNatalya/Predicting-the-similar-actor', 'size': '11510'}