接着1.1来。
昨天回去之后取得了同学的脸部图像(和昨天取自己的一样),这样就可以通过机器学习在我和同学之间做一个分类。
首先,我们要把我和其他人的照片做一个分类,分别加上label,并且放到一个dataset里。在这之前,由于我们取的人脸大小不一(前面函数中有说到,识别时有参数scale factor),我们要把每张图片变成一个大小,长宽不一的我们要加上黑边使长宽相同,再做resize。具体代码如下:
def resize_image(image, height = IMAGE_SIZE, width = IMAGE_SIZE):
top, bottom, left, right = (0, 0, 0, 0)
h, w, _ = image.shape
longest_edge = max(h, w)
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass
BLACK = [0, 0, 0]
constant = cv2.copyMakeBorder(image, top , bottom, left, right, cv2.BORDER_CONSTANT, value = BLACK)
return cv2.resize(constant, (height, width))
定义了这个函数之后,我们要对每一个图片进行这个操作,首先要依次读到照片所在目录下所有的图片数据:
def read_path(path_name):
for dir_item in os.listdir(path_name):
full_path = os.path.abspath(os.path.join(path_name, dir_item))
if os.path.isdir(full_path): #如果是文件夹,继续递归调用
read_path(full_path)
else: #如果是文件
if dir_item.endswith('.jpg'):
image = cv2.imread(full_path)
image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)
images.append(image)
labels.append(path_name)
return images,labels
这时候images就存了根目录下所有的图片文件(resize后),而labels保存了图片文件的full_path。
我们再对labels做一个判断,由于我和同学的文件放在不同的文件夹下,那么就应该对labels里面的每个字符串做末尾几位字符的判断:
def load_dataset(path_name):
images,labels = read_path(path_name)
#将输入的所有图片转成四维数组
images = np.array(images)
#末尾是me的赋为0,其他都是1
labels = np.array([0 if label.endswith('me') else 1 for label in labels])
return images, labels
然后就完事了,后面用到的时候直接调用py这个文件就ok。
后面就是搭建一个深度学习的框架,由于我也是初学者,所以用了最简单的,卷积+relu+池化+全连接这种基础的结构。
首先,在架构神经网络之前,我们要先分图片为训练集、验证集、测试集。
值得注意的是,keras这个api是支持两个后端的,分别是tensorflow(tf)和theano(th),而我们用的是tf。这两种方式集的维度顺序不同,要注意区分。
我们把这些函数放在一个class里:
class Dataset:
def __init__(self, path_name):
#训练集
self.train_images = None
self.train_labels = None
#验证集
self.valid_images = None
self.valid_labels = None
#测试集
self.test_images = None
self.test_labels = None
#数据集加载路径
self.path_name = path_name
#当前库采用的维度顺序
self.input_shape = None
def load(self, img_rows = IMAGE_SIZE, img_cols = IMAGE_SIZE,
img_channels = 3, nb_classes = 2):
#加载数据集到内存
images, labels = load_dataset(self.path_name)
train_images, valid_images, train_labels, valid_labels = train_test_split(images, labels, test_size = 0.3, random_state = random.randint(0, 100))
_, test_images, _, test_labels = train_test_split(images, labels, t