python - 如何训练 tensorflow 模型准确区分睁眼和闭眼?

标签 python tensorflow machine-learning computer-vision

我正在尝试训练一个 tensorflow 模型来为我的学校项目对睁眼和闭眼进行分类。

我使用 OpenCV 库从网络摄像头录制的视频中提取了我的眼睛。我有大约 4000 张睁眼图像和 4000 张闭眼图像。一半是左眼,一半是右眼。

数据集如下所示:

睁开眼睛:

open_eyes_1

open_eyes_2

闭上眼睛:

closed_eyes_1

enter image description here

我有 8000 张这样的图像,具有不同的光照条件和角度。

我的代码:

我使用此代码将数据集导入为数组。

import numpy as np
import cv2
import os
from random import shuffle
from tqdm import tqdm
import matplotlib.pyplot as plt
Training_Data = []
Eyes_Open_Data = []
Eyes_Closed_Data=[]
Labels_Data=[]
only_eyes_open = 'C:/Users/Ibrahim/Desktop/Staj 2020/only_eyes_open'
only_eyes_closed = 'C:/Users/Ibrahim/Desktop/Staj 2020/only_eyes_closed'


for item in os.listdir('only_eyes_open'):
    img_array= cv2.imread(os.path.join(only_eyes_open, item), cv2.IMREAD_GRAYSCALE)
    new_array = cv2.resize(img_array, (50,50))
    Eyes_Open_Data.append(new_array)
    Labels_Data.append(1)


for item in os.listdir('only_eyes_closed'):
    img_array= cv2.imread(os.path.join(only_eyes_closed, item), cv2.IMREAD_GRAYSCALE)
    new_array = cv2.resize(img_array, (50,50))
    Eyes_Closed_Data.append(new_array)
    Labels_Data.append(0)

我使用这段代码合并了左眼和右眼数据以及标签。 然后我将其打乱并将其分离为训练数据和标签。

Training_Data = Eyes_Open_Data + Eyes_Closed_Data

Training_Data = list(zip(Training_Data, Labels_Data))


shuffle(Training_Data)

Labels_Data = [b for a,b in Training_Data]

Training_Data = [a for a,b in Training_Data]

X = []
y = []

X = Training_Data
y = Labels_Data

X = np.array(X).reshape(-1, 50, 50, 1)

我使用以下代码创建了我的模型:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D


X = np.array(X/255.0)
y= np.array(y)

model = Sequential()

model.add(Conv2D(32, (3, 3), input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors

model.add(Dense(128))

model.add(Dense(1))
model.add(Activation('sigmoid'))

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

model.fit(X, y, batch_size=32, epochs=1, verbose=1, validation_split=0.1, shuffle=True)

上面代码的输出:

226/226 [==============================] - 11s 47ms/step - loss: 0.0908 - accuracy: 0.9582 - val_loss: 0.0028 - val_accuracy: 1.0000
<tensorflow.python.keras.callbacks.History at 0x1ac4c2e55b0>

在我用不同的数据实际测试模型之前,到目前为止一切似乎都还不错。 就像我的数据集中的图像一样,我又拍摄了四张我眼睛的图像。前两个是睁眼,后两个是闭眼。

所以我希望预测是这样的:[1,1,0,0]

我使用这段代码来导入测试数据:

test_data = 'C:/Users/Ibrahim/Desktop/Staj 2020/testing'

test_array = []
for item in os.listdir(test_data):
    img_array = cv2.imread(os.path.join(test_data,item), cv2.IMREAD_GRAYSCALE)
    new_array = cv2.resize(img_array,(50,50))
    plt.imshow(new_array)
    test_array.append(new_array)

test_array = np.array(test_array).reshape(-1,50,50,1)

我运行这段代码来预测:

model.predict(test_array)

这是输出:

array([[1.],
       [1.],
       [1.],
       [1.]], dtype=float32)

如果我没记错的话,这意味着它预测所有的人都是睁着眼睛。所以我决定尝试使用我在训练中使用的图像进行预测。

我将测试数据位置更改为我的数据集位置:

test_data = 'C:/Users/Ibrahim/Desktop/Staj 2020/only_eyes_closed'

输出正确:

array([[0.],
       [0.],
       [0.],
       ...,
       [0.],
       [0.],
       [0.]], dtype=float32)

在这一点之后,无论我使用什么数据进行测试,它都只会预测 1。唯一的异常(exception)是我用于训练的数据。

最佳答案

好的,需要研究的可能场景:

  • 训练多个 epochs
  • 使用衰减学习率函数调整您的超参数。
  • 尝试 tf.keras.layers.BatchNormalizationtf.keras.layers.Dropout
  • 研究 tf.keras.preprocessing.image.ImageDataGenerator 以了解图像增强技术。
  • 如果问题仍然存在,请尝试为闭眼数据赋予更多权重。
  • 微调预定义架构(VGG19/EfficientNet),即保持其起始层卡住(因为它们捕获基本特征)。
  • 由于这是二元分类,您应该查看其他指标,例如 ROC/Precision/Recall 等。
  • 至少正确查看您的真实数据集和训练数据集,看看它们有多少不同。

关于python - 如何训练 tensorflow 模型准确区分睁眼和闭眼?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63014116/

相关文章:

python - 导入错误 : TensorBoard

python - 如何使用 scikit learn 向量化标记的二元组?

python - 属性错误 : 'Model' object has no attribute 'name'

python - 在 Python3 中使用 `random.shuffle` 作为关键字参数时 `random.random` 的运行时间更短

python - Keras 的 NaN 随机搜索的调谐器分数

python - logits 和标签必须是可广播的

machine-learning - 最大输出神经元 : are the weights in the maxout function referring to 2 unique sets of weights?

machine-learning - 机器学习准确性的最佳衡量标准是什么

python - 使用Python登录谷歌账号进入网站

python - Epochs Vs Pass Vs Iteration