使用深度学习进行性别检测和年龄分类

问题描述 投票:0回答:3

我正在开展一个项目,目标是检测性别并对图像进行分类。我做了一些研究,发现了一篇研究论文:Gil Levi 和 Tal Hassnar 的 AgeandGender Classificationusing Convolutional Neural Networks。我尝试在 Keras 中复制他们最初在 Caffe 中创建的深度网络。但问题是模型的准确率停留在 50%(基本上是随机抛硬币)。我做错了什么。任何帮助深表感谢。 顺便说一句,我使用 adience 数据集作为原始论文。 PS:我已经完全删除了 LRN 层,因为它们在 Keras 中不可用。 (我认为他们的缺席不应该损害模型的准确性) 这是代码。

#imports
import os
import numpy as np
from PIL import Image
import pickle
from keras.models import Sequential 
from keras.callbacks import  ModelCheckpoint
from keras.layers import Dense , Conv2D , Flatten , MaxPooling2D , Dropout , AveragePooling2D
from keras import initializers
from keras import optimizers

# creating the model object
gender_model = Sequential()

# adding layers to the model
# first convolutional layer
gender_model.add( Conv2D(96 , kernel_size=(7,7) , activation='relu' , strides=4 , input_shape=(227,227,3),
                            kernel_initializer= initializers.random_normal(stddev=0.01), use_bias = 1,
                            bias_initializer = 'Zeros' , data_format='channels_last'))

gender_model.add( MaxPooling2D(pool_size=3 , strides=2) )

gender_model.add( Conv2D(256, kernel_size=(5,5) , activation='relu', strides=1 , padding='same' , input_shape=(27,27,96), 
                            kernel_initializer= initializers.random_normal(stddev=0.01) , use_bias=1,
                            bias_initializer='Ones' , data_format='channels_last') )
gender_model.add( MaxPooling2D(pool_size=3 , strides=2) )
# third convolutional layer

gender_model.add( Conv2D(384,kernel_size=(3,3) , activation='relu', strides=1 ,padding='same', input_shape=(13,13,256),
                    kernel_initializer= initializers.random_normal(stddev=0.01), use_bias=1,
                    bias_initializer = 'Zeros' , data_format='channels_last') )
gender_model.add( MaxPooling2D(pool_size=3 , strides=2) )

# Now we flatten the output of last convolutional layer
gender_model.add( Flatten() )

# Now we connect the fully connected layers
gender_model.add( Dense(512, activation='relu' , use_bias=1, kernel_initializer=initializers.random_normal(stddev=0.005),
                    bias_initializer='Ones') )
gender_model.add( Dropout(0.5))

# connecting another fully connected layer
gender_model.add( Dense(512 , activation='relu' , use_bias=1, kernel_initializer=initializers.random_normal(stddev=0.005),
                    bias_initializer='Ones'))
gender_model.add( Dropout(0.5))

# connecting the final layer
gender_model.add( Dense(2, activation='softmax' , use_bias=1, kernel_initializer=initializers.random_normal(stddev=0.01),
                    bias_initializer='Zeros'))

# compiling the model
sgd_optimizer = optimizers.SGD(lr= 0.0001 , decay=1e-7 , momentum=0.0, nesterov=False)
gender_model.compile(optimizer=sgd_optimizer , loss= 'categorical_crossentropy' , metrics=['accuracy'])
gender_model.summary()


# partioning the loaded data
X = np.load('/content/drive/My Drive/X.npy')
y = np.load('/content/drive/My Drive/y_m.npy')

X_train = X[:15000]
y_train = y[:15000]

X_val = X[15000:] 
y_val = y[15000:]

## creating chkpt path
chkpt_path = 'weights-improvement-{epoch:02d}--{val_acc:.2f}.hdf5'

checkpoint = ModelCheckpoint(chkpt_path , monitor='val_acc' , verbose=1 , save_best_only=True , mode='max')
callback_list = [checkpoint]

#finally training the model
gender_model.fit(X_train, y_train,
          batch_size=50,
          epochs=100,
          validation_data=(X_val , y_val),
          shuffle=1,
          callbacks = callback_list
          )
tensorflow keras deep-learning classification conv-neural-network
3个回答
2
投票

Python 的 Deepface 包提供了开箱即用的年龄和性别预测功能。

!pip install deepface
from deepface import DeepFace
obj = DeepFace.analyze("img1.jpg", actions = ["age", "gender", "emotion", "race"])
print(obj["age"], " years old ", obj["gender"])

它还可以分析情感和种族。您可以删除不必要的操作。


1
投票

我的方法有问题。我没有裁剪脸部。因此,该模型无法理解每张图像中的随机背景。


0
投票

def process_image(image_path, gender_net):
    # gender_list = ['Male', 'Female']
    font = cv2.FONT_HERSHEY_SIMPLEX

    # Initialize MTCNN face detection model
    mtcnn = MTCNN(keep_all=True, device='cuda' if torch.cuda.is_available() else 'cpu')

    image = cv2.imread(image_path)
    # Convert the image to RGB
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    # Detect faces in the image
    boxes, face_confidence = mtcnn.detect(image_rgb)

    # frame = cv2.imread(image_path)
    org_frame = image.copy()

    male_count = 0
    female_count = 0
    face_count = 0

    # Showing count
    st.header("Photo Analysis")
    # print ("Photo Analysis")
    col1, col2 = st.columns([1,3])
    data = {
        'Track Id': [],
        'faces': []
    }
    df = pd.DataFrame(data)

    with col1:
        st.write("Count of detected Faces")
        table_placeholder = st.empty()

    with col2:
        st.write("Display Photo")
        # print ("Photo place-holder")
        photo_placeholder = st.empty()

    for rect in boxes:
        if face_confidence[face_count] > 0.9:
            x1, y1, x2, y2 = map(int, rect)

            # Given padding values (top, bottom, left, right)
            # padding=50
            padding_top = 12
            padding_bottom = 12
            padding_left = 12
            padding_right = 12

            # Calculate new bounding box coordinates with padding
            new_x1 = x1 - padding_left
            new_y1 = y1 - padding_top
            new_x2 = x2 + padding_right
            new_y2 = y2 + padding_bottom

            # Calculate width and height of the bounding box
            new_width = new_x2 - new_x1
            new_height = new_y2 - new_y1

            x = new_x1 
            y = new_y1 
            w = new_width 
            h = new_height
            if y < 0:
                continue

            face_image = image_rgb[y:y+h, x:x+w].copy()

            # Convert the face image to PIL Image
            pil_image = Image.fromarray(face_image)

            # Preprocess the face image
            face_tensor = preprocess(pil_image)
            face_tensor = face_tensor.unsqueeze(0).to(device)  # Add batch dimension and move to device

            # Set the threshold value (between 0 and 1)
            threshold = 0.51

            # Pass the preprocessed face image through the gender classification model
            with torch.no_grad():
                outputs = gender_net(face_tensor)
                probabilities = nn.functional.softmax(outputs, dim=1)[0]
                print ("probabilities - ",probabilities)
                confidence, predicted = torch.max(probabilities, 0)
                if confidence.item() > threshold:
                    predicted_gender = 'FeMale' if predicted.item() == 0 else 'male'

                    if predicted_gender == 'FeMale':
                        print ("Female")
                        female_count += 1
                        overlay_text = "%s" % (predicted_gender)
                        cv2.putText(org_frame, overlay_text, (x, y), font, 1, (255, 0, 0), 2, cv2.LINE_AA)
                        cv2.rectangle(org_frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
                    else: 
                        print ("Male")
                        male_count += 1
                        overlay_text = "%s" % (predicted_gender)
                        cv2.putText(org_frame, overlay_text, (x, y), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
                        cv2.rectangle(org_frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

                else:
                    predicted_gender = 'Unknown'

        face_count = face_count + 1

    # # Convert frame to PIL Image and display
    frame = cv2.cvtColor(org_frame, cv2.COLOR_BGR2RGB)  # Convert from BGR to RGB color space
    pil_image = Image.fromarray(frame)
    photo_placeholder.image(pil_image, use_column_width=True)

    # Update the table with male and female count
    df = pd.DataFrame({'Track Id': ['Male', 'Female'], 'faces': [male_count, female_count]})
    table_placeholder.write(df)

git-hub 链接到以下 - https://github.com/ndb796/Face-Gender-Classification-PyTorch

© www.soinside.com 2019 - 2024. All rights reserved.