如何训练TensorFlow模型准确分类睁眼和闭眼?

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

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

数据集看起来像这样:

睁眼:

open_eyes_1

open_eyes_2

闭眼:

closed_eyes_1

enter image description here

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

我的代码:

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

import numpy as npimport cv2import osfrom random import shufflefrom tqdm import tqdmimport matplotlib.pyplot as pltTraining_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_DataTraining_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_Datay = Labels_DataX = np.array(X).reshape(-1, 50, 50, 1)

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

import tensorflow as tffrom tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2DX = 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 vectorsmodel.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。唯一的例外是我用于训练的数据。


回答:

好的,可能需要考虑的场景包括:

  • 训练多个epochs
  • 调整超参数,使用学习率衰减函数。
  • 尝试tf.keras.layers.BatchNormalizationtf.keras.layers.Dropout
  • 查看tf.keras.preprocessing.image.ImageDataGenerator以了解图像增强技术。
  • 如果问题仍然存在,尝试给闭眼数据更多的权重。
  • 微调预定义的架构(VGG19/EfficientNet),即保持其起始层冻结(因为它们捕捉基本特征)。
  • 由于这是一个二元分类,你应该查看其他指标,如ROC/精确度/召回率等。
  • 至少仔细查看你的现实世界数据集和训练数据集,看看它们有多少不同之处。

Related Posts

神经网络反向传播代码不工作

我需要编写一个简单的由1个输出节点、1个包含3个节点的…

值错误:y 包含先前未见过的标签:

我使用了 决策树分类器,我想将我的 输入 作为 字符串…

使用不平衡数据集进行特征选择时遇到的问题

我正在使用不平衡数据集(54:38:7%)进行特征选择…

广义随机森林/因果森林在Python上的应用

我在寻找Python上的广义随机森林/因果森林算法,但…

如何用PyTorch仅用标量损失来训练神经网络?

假设我们有一个神经网络,我们希望它能根据输入预测三个值…

什么是RNN中间隐藏状态的良好用途?

我已经以三种不同的方式使用了RNN/LSTM: 多对多…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注