我是物体检测的新手。而且我不知道如何训练模型来识别图片中的人脸。有很多mnist教程和预训练的模型教程,但没有这样的情况。
我将为我的问题分配编号。
folderpath = "G:/Datasets/FACE/"
face = "face.JPG"
people = "people.JPG"
maskdict = {}
nfaces = 0
image= Image.open(folderpath+face)
image = image.convert('L')
image= np.array(image)
print(image.shape) # (239, 162)
我将“脸部”变成了灰度,这样工作起来会更容易。
def create_mask(image, plotimg=False):
height, width = image.shape
mask = np.empty((height, width))
topcroph = int(height*0.9)
botcroph = height-topcroph
rightcropw = int(width*0.9)
leftcropw = width - rightcropw
mask[botcroph:topcroph, leftcropw:rightcropw] = 1
img = image.copy()
if plotimg:
img[botcroph:topcroph, leftcropw:rightcropw] = 1
plt.imshow(img, cmap='gray')
return mask.astype(np.uint8)
创建蒙版
假设输入始终是一张特写脸,create_mask函数会在该脸所在的位置大致创建一个遮罩,因此我可以将该遮罩用作“ y”(标签)
1-这是创建用于检测的“ y”(标签)的正确方法吗?
def resizer(img, msk, size):
img = np.array(Image.fromarray(img).resize((size,size)))
msk = np.array(Image.fromarray(msk).resize((size,size)))
return img, msk
调整图像和蒙版的大小。
mask = create_mask(image, plotimg=True)
img, msk = resizer(image, mask, 128) # img & mask.shape would be (128,128)
img = np.expand_dims(img, axis=2) # add one more dimension
msk = np.expand_dims(msk, axis=2) # (128, 128, 1)
增强
在下面的代码中,我想将图像相乘,因此我可以拥有一个数据集。
2-从技术上讲,您不能训练一张图像,对吧?
datasize=120
data = np.empty((datasize, 128, 128, 1))
maskage = np.empty((datasize, 128, 128, 1))
for i in range(0, 40):
np.random.seed(i)
img_r = keras.preprocessing.image.random_rotation(img, 30)
msk_r = keras.preprocessing.image.random_rotation(msk, 30)
maskage[i,:,:] = msk_r
data[i,:,:] = img_r
for i in range(40,80):
np.random.seed(i)
img_b = keras.preprocessing.image.random_brightness(img, (.5, 1.5))
maskage[i,:,:] = msk
data[i,:,:] = img_b
for i in range(80,120):
np.random.seed(i)
img_z = keras.preprocessing.image.random_zoom(img, (.7, 1))
msk_r = keras.preprocessing.image.random_zoom(msk, (.7, 1))
data[i,:,:] = img_z
maskage[i,:,:] = msk_r
模型
Keras模型引发ValueError。我不知道如何配置图层,这如何工作?
from keras import layers
from keras import models
from keras import optimizers
model = models.Sequential()
model.add(layers.Conv2D(16, (3,3), padding="same", input_shape=(128,128,1)))
model.add(layers.Activation('relu'))
model.add(layers.Conv2D(16, (3,3), padding="same"))
model.add(layers.Activation("sigmoid"))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 128, 128, 16) 160
_________________________________________________________________
activation_1 (Activation) (None, 128, 128, 16) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 128, 128, 16) 2320
_________________________________________________________________
activation_2 (Activation) (None, 128, 128, 16) 0
=================================================================
Total params: 2,480
Trainable params: 2,480
Non-trainable params: 0
# Input shapes are:
data.shape # (120, 128, 128, 1)
maskage.shape # (120, 128, 128, 1)
#Run the model
model.fit(data, maskage)
ValueError:检查目标时出错:预期Activation_6具有 形状(128,128,16),但数组的形状为(128,128,1)
3。此时我该怎么办?
4。即使模型能够进行训练,基于“ people.JPG”的model.predict也会起作用吗? 如何在人脸预测输出上绘制矩形?这种方法行得通吗?
编辑:将第二个conv2d图层变量从16更改为1后,模型开始训练。但是找不到面部。
答案 0 :(得分:3)
在开始您的问题之前,让我先说明一些重要的事情。据我了解,您的目标是同时达到classification
和localization
。这两个都需要不同的模型进行训练,并且从头开始更高级。假设您只需要分类,让我尝试回答您的问题。
1)y标签应为案例face
或background
的二进制文件,并且应为一维列数组。
2)是的,没错,翻转或旋转图像是丰富数据集的好策略。
3)发生此错误是由于model.fit(data, maskage)
的第二个参数,即掩码。由于您的标签需要是一列,而不是128x128x1数组,因此会发生此错误。
4)正如我在问题之前解释的那样,此方法不起作用。您正在寻找localization
和classification
据我了解,您已经检查了MNIST教程以修改您的问题,但是首先也是最重要的一点是您应该更改y标签。此外,由于我没有足够的知识来执行如何正确地对对象进行本地化的工作,因此我将无法提供太多有关如何成功完成项目的本地化部分的信息。
编辑:对于不熟悉localization
的人,link中有一个有关Keras的有用指南