选题简介
这次我们做的是一个人脸对比并返回相似度的网页,部署在Linux的环境下。我们选题的原因是在实验七学习到了一些有关于人脸识别的知识,再加上之前个人实验中学习的知识,包括python、mysql、nginx容器的使用,所以我们打算综合这些知识做一个网页。
设计与使用的容器
设计
用flask结构写前后端交互,然后将各个文件分别部署到对应的容器内
用到的容器
首先分别拉取nginx、mysql和python的镜像,然后在此基础上分别构建nginx、mysql和python的容器。然后将之前编写好的html界面放入nginx容器中,在python容器中导入所需要的库,将py文件放入python容器中,在mysql容器中将数据库建立。
图片对比代码
def load_and_align_data(image_paths, image_size, margin, gpu_memory_fraction):
minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ] # three steps's threshold
factor = 0.709 # scale factor
print('Creating networks and loading parameters')
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)
tmp_image_paths=copy.copy(image_paths)
img_list = []
for image in tmp_image_paths:
img = imageio.imread(os.path.expanduser(image), pilmode='RGB')
img_size = np.asarray(img.shape)[0:2]
bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
if len(bounding_boxes) < 1:
image_paths.remove(image)
print("can't detect face, remove ", image)
continue
det = np.squeeze(bounding_boxes[0,0:4])
bb = np.zeros(4, dtype=np.int32)
bb[0] = np.maximum(det[0]-margin/2, 0)
bb[1] = np.maximum(det[1]-margin/2, 0)
bb[2] = np.minimum(det[2]+margin/2, img_size[1])
bb[3] = np.minimum(det[3]+margin/2, img_size[0])
cropped = img[bb[1]:bb[3],bb[0]:bb[2],:]
aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
prewhitened = facenet.prewhiten(aligned)
img_list.append(prewhitened)
images = np.stack(img_list)
return images
运行结果
整个项目AI:
子文件1:数据库MySQL
MySQL的dockerfile:
Setup.sh(容器启动时执行的文件):
子文件2:Python
Python的dockerfile:
需要装载的第三方库的相关文件:Requirement.txt
子文件3:Nginx
Nginx的dockerfile:
Nginx的default.conf:
映射的相关html文件:
本次实验相关镜像文件:
运行时的相关容器:
运行时的默认界面,本次实验实现的两个功能,功能一……
功能一:人脸对比
功能二:人脸搜索
Mysql内的相关内容:
最终分工+贡献比
学号
姓名
分工
贡献比
031702340
张逸杰
负责后端代码的编写,数据库的构建,处理部署过程中出现的题
30%
031702331
杨锦镔
前端界面的编写,前后端数据通信问题的处理,处理部署过程中出现的题
30%
031702341
黄彬煌
负责部署微服务,以及处理部署过程中出现的问题
40%
总结
张逸杰:
首先是对代码,因为自己没有怎么学习过机器学习的内容。所以即使是在facenet提供的开源代码上进行修改,也是感觉到比较困难。中途遇到了很多的问题,比如:存放测试模型用绝对路径就无法运行,只能用相对路径;计算到欧式距离以后不知道该怎么转化为人脸相似度;在pycharm的terminal和Linux的terminal的环境不同导致要输入执行的指令也不同的问题。在这次实验之后,我真的是对docker有了进一步的认识,对镜像,容器的构建过程以及运行过程的认识都有了提升。
黄彬煌:
这一次实验收获比较大的方面主要是在于更加熟悉docker的部署,以及Flask框架的运用。由于一开始不知道选题实际上相当于是要占据一周的时间,所以一开始还是比较悠哉悠哉,打算先准备完硬件实践课的考试再来做,考完试后才发现实际上只剩下一周多,当时就比较茫然了。然后开始和小组成员拼上差不多一周的除去吃饭睡觉的时间来攻克最后的大作业。整个过程在一开始是先找一份能够在本地上跑的开源代码,差不多符合我们想要的功能,然后再去解读这一个代码大概的思路过程,改成我们想要的代码。幸运的是,在这个过程找到的感觉ok的第三份代码成功在本地上跑了起来(前两份”bugs”调不过来,实在尽力了),期间解决了部分包的难下载以及版本兼容问题。在得到可用的代码后,便开始想说在本地先把整个项目运行起来,再部署到docker容器中。接下来就是前端代码的编写,flask框架的搭建以及后端和数据库的连接,顺带复习了数据库的相关知识。部署到容器前,我们翻了前几次博客的内容,根据自己当前的项目,想着是用Nginx+Python+MySQL的框架来完成作业。使用Nginx设定一个端口,通过其能够访问写好的前端代码,前后端数据通过Ajax来实现传输。期间遇到一个卡了很久的问题就是Ajax的URL到底怎么填,在docker上运行和本地太不一样了,其实说到底还是没能比较彻底的掌握相关知识。最终是发觉可以用容器的IP,一开始并不是很清楚关于容器IP的相关知识,导致一直有点晕乎。直到后来可以用后,再想起第五次作业python要连接MySQL时就是用”sudo docker inspect 容器ID”来查看MySQL容器的IP,这才恍然,但在搭载好的第二天有个报错是”address error”,查看相关IP内容后,发觉了docker容器的IP其实是在”172.17.0.0”网段的,根据先开启的先赋予,所以一个容器的IP实际上是可变的。后来想的办法是我们项目建立的三个容器要按照一定的顺序开启,虽然不是根本之法,但香。之后就是一点一点完善整个作业,虽然到最后似乎还是有点简陋,但是个人觉得中间”loading”这一点子和加载动画都蛮不错的。最后就是三人行,合作太愉快了。
杨锦镔:
本次大作业实验,我们没有运用树莓派,而是采用了在linux上的docker进行实验,在这次实验中,我主要负责前端代码的编写,以及前后端数据通信问题的处理。虽然本次实验的核心不是在我的电脑上进行部署,但每次作业时,我们组都进行了屏幕分享,视频等方式进行交流、沟通、探讨。进行库的安装、网上找开运代码的本地运行、容器的部署等遇到各种问题时,一起想办法解决,也起到了一个相互促进,相互学习的效果。本次实验使我对docker容器的部署有了更加深入的了解,当然也涉猎了人工智能如facenet等方面的知识,收获颇丰。