在学习了python中的一些机器学习的相关模块后,再一次开始了深度学习之旅。不过与上次的TensorFlow框架不同,这一次接触的是fast.ai这样一个东西。这个框架还不稳定,网上也没有相关的中文文档。唯一一个学习站点就是 fastai 这样一个论坛,另外就是里面的公开课程


性别识别模型使用体验: http://www.ctsch.cn/?page_id=11

请确认上传的图片中有人,否则对于其他类型的图片,也就当男女论处,目前在它的世界中只有男女。

附上fastai项目的相关连接:

注意:

  • 在配置环境时使用 Anaconda,安装方法可以自行百度
  • 使用安装fastai训练模型时要安装GPU版本(前提是你有支持GPU的显卡),否则建议你不要用来训练模型,使用cpu训练会非常非常慢。当然GPU需要安装cuda和cudnn(安装步骤可以自行百度)。

Github上有相关的安装教程,能够成功安装,有问题可以在本文后留言,我会尽力回复。


在该课程的第一课就是一个利用神经网络识别猫狗。在这中间使用了resnet34模型进行训练。这个模型是在ImageNet数据集比赛上获得过优异成绩的模型,这个预训练使我们不需要自己构建神经网络,只要我们能会使用就可以了。这也算是第一课的基础导入吧。

下面要讲的内容,在视频中都可以找到,这里主要写一些我觉的使用fastai比较重要和特殊的地方

 
1
2
3
4
5
6
# 在fastai要建立一个model,只需要下面的三行就可以了,第四行是训练model
arch=resnet34 # 使用model
data = ImageClassifierData.from_paths(PATH, tfms=tfms_from_model(arch, sz)) # 图片数的组织类别
learn = ConvLearner.pretrained(arch, data, precompute=True) # 卷积神经网络的容器
learn.fit(0.01, 3) # 训练model
 
  • 要点一:训练、验证和预测数据的文件组织架构
    图片数据的存放形式:

    在每个分类(如:male、female)中存放的就是样本图片了。
  • 要点二: 解释上面代码中的learn.fit(0.01, 3)
    我们现在使用的resnet34模型是一个在ImageNet数据集上训练好了的model,里面权重数据一个非常好了,不需要我们在进行改善什么,但我们需要根据我们自己的实际数据训练神经网络的最后一层权重。所以上面这个代码是训练model的最后一层。至于为什么,那是因为,resnet34预训练模型是使用ImageNet数据集训练的,他们的类别可能有1000类,所以模型的最后一层默认是1000维的,但是我们的数据分类只有两类—猫和狗。因此我们需要这一步骤。

  • 要点三: fastai中ConvLearner类有一个自动寻找最优学习率的函数 learn.lr_fint()
    我们知道,在神经网络中,学习率是一个非常重要的超参数,调节的不好,会导致模型不能收敛或者收敛的太慢。通过这个函数,它可以帮助我们在指定范围内自动找到最合适的学习率。我们可以通过learn.sched.plot_lr()函数绘制出学习率与训练轮数的关系;也可以通过learn.sched.plot()绘制出学习率与损失值得变化情况,从而选择出最合适的学习率。

以上是一些学习记录,下面开始训练性别识别模型。

使用resnet34训练性别识别模型

在训练之前首先要做的就是收集数据,数据是使用 GoogleImageDownloader 工具自动爬取的,在Google上爬了大概3500张图片,里面有些图片质量不够好,删除了之后大概还有2400张左右。

data and code url:  链接: https://pan.baidu.com/s/1TbvupSigvKJoQp8JrIFFOA 密码: sxqc

具体代码:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import sys
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
sys.path.append("/Volumes/05/jupyter/fastai")
 
from fastai.imports import *
from fastai.torch_imports import *
from fastai.transforms import *
from fastai.conv_learner import *
from fastai.model import *
from fastai.dataset import *
from fastai.sgdr import *
from fastai.plots import *
 
PATH = 'data/malefemale/'
sz = 224
 
# 使用resnet34model
arch = resnet34
data = ImageClassifierData.from_paths(PATH,tfms=tfms_from_model(arch, sz))
learn = ConvLearner.pretrained(arch, data, precompute=True)
 
# 第一次轻微训练最后一层
learn.fit(0.01, 3)
 
learn.fit(0.05, 5, cycle_len=1, cycle_mult=2)
 


在这一次的训练中,发现模型损失还有0.29,模型在验证上的正确率才到93%,模型还有优化的空间。

下面再一次构造模型并训练:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
tfms = tfms_from_model(resnet34, sz,aug_tfms=transforms_side_on, max_zoom=1.1) # 通过转变角度,增加样本
data = ImageClassifierData.from_paths(PATH, tfms=tfms)
learn = ConvLearner.pretrained(resnet34, data, precompute=True)
 
learn.fit(0.01, 3)# 第一次训练最后一层,试探性
 
learn.fit(0.05, 5, cycle_len=1, cycle_mult=2) # 发现第一次训练有效果,在进一步训练
 
learn.precompute = False # 开启全部层都可以训练,对每层进行微训练
learn.fit([1e-4,1e-3,1e-2], 4, cycle_len=1) # 初步训练
 
learn.unfreeze()
learn.fit([1e-3,1e-3, 1e-2], 5, cycle_len=1, cycle_mult=2) # 发现上一次有效果,在进行深度训练
 


最后 模型在训练集上的loss到达了0.025,在验证集上的loss达到了0.18,在验证集上的正确率达到了 94.9%。在我多次训练后,发现这是最好的了,所以就没有再进行改进了。

但是,现在还没有完,我们现在要看看模型在数据集上的表现到底怎么样。下面,使用matplotlib库进行可视化分析:

可视化分析

首先获得模型的预测数据:

 
1
2
3
4
5
6
7
8
9
log_preds = learn.predict() # 预测所有的验证集,返回的 ln pi的数据
prob_preds = np.exp(log_preds) # 将对数概率转回正常的概率
y_pred = np.argmax(np.exp(prob_preds), 1) # 获取预测的分类,这里面是0,1数据,0表示女性,1表示男性
 
 
male_df = pd.DataFrame({'image':data.val_ds.fnames,'y_true':data.val_y, 'y_pred':y_pred, 'y_prob_female':prob_preds[:,0], 'y_prob_male':prob_preds[:,1]}) # 将所有的数据合并成pandas的DataFrame
 
male_df.head() # 输出下DataFrame
 

说明:

  • image 图片样本的路径
  • y_true 样本的真实类别
  • y_pred 样本的预测类别
  • y_prob_female 模型预测该样本为女性的概率
  • y_prob_male 模型预测该样本为男性的概率

1、查看模型的混淆矩阵

 
1
2
3
4
5
6
from sklearn.metrics import confusion_matrix
import seaborn as sns
 
mat = confusion_matrix(data.val_y, y_pred)
plot_confusion_matrix(mat, data.classes)
 


可以看到,在152个女性样本和143个男性样本中,有10张女性样本被错误的分成了男性,但仅有5个男性样本被错误的分词女性,可以看出模型在男性特征的学习中学习的较充足,到对女性特征学习还有待提高。出现这个情况的原因是在训练样本中男性样本比女多了近200个样本,因此模型学习男性的特征较多,因此判断更有把握。

2、查看模型在验证集中预测最有把握的样本

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 最有把握的女性
mostly_female = male_df[male_df['y_true']==0].sort_values(by='y_prob_female', ascending=False)
print('mostly female:')
 
fig, axes = plt.subplots(4,4, figsize=(20, 10))
for i,ax in enumerate(axes.flat):
    src = mostly_female.iloc[i]['image']
    ax.imshow(plt.imread(f'{PATH}{src}'))
    ax.text(0, 0, str(mostly_female.iloc[i]['y_prob_female']), fontsize=16)
    ax.axis('off')
 
# 最有把握的男性
mostly_male = male_df[male_df['y_true']==1].sort_values(by='y_prob_male', ascending=False)
print('mostly male:')
 
fig, axes = plt.subplots(4,4, figsize=(20, 10))
for i,ax in enumerate(axes.flat):
    src = mostly_male.iloc[i]['image']
    ax.imshow(plt.imread(f'{PATH}{src}'))
    ax.text(0, 0, str(mostly_male.iloc[i]['y_prob_male']), fontsize=16)
    ax.axis('off')
 



在这些样本中,男性和女性的外在特征都比较明显的显示出来了,因此模型的判断概率都是100%。

3、查看模型在验证集中预测错误最明显的的样本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 预测出错最明显的女性
incorrect_female = male_df[(male_df['y_true']==0) & (male_df['y_pred']==1)].sort_values(by='y_prob_female', ascending=False)
print('incorrect female  to predict male:')
 
fig, axes = plt.subplots(2,4, figsize=(20, 10))
for i,ax in enumerate(axes.flat):
    src = incorrect_female.iloc[-i-1]['image']
    ax.imshow(plt.imread(f'{PATH}{src}'))
    ax.text(0, 0, str(incorrect_female.iloc[-i-1]['y_prob_female']), fontsize=16)
    ax.axis('off')
 
# 预测出错最明显的男性
incorrect_male = male_df[(male_df['y_true']==1) & (male_df['y_pred']==0)].sort_values(by='y_prob_male', ascending=False)
print('incorrect male  to predict female:')
 
fig, axes = plt.subplots(1,4, figsize=(20, 10))
for i,ax in enumerate(axes.flat):
    src = incorrect_male.iloc[-i-1]['image']
    ax.imshow(plt.imread(f'{PATH}{src}'))
    ax.text(0, 0, str(incorrect_male.iloc[-i-1]['y_prob_male']), fontsize=16)
    ax.axis('off')
 



从上面两幅图中可以看出,模型对于男女特征没有明显展示出来的样本(如马尾头发的样本)出错概率最大,另外从第一幅图的第四个样本看出,模型将具有肌肉的这样特征的样本认为是男性,这与我们生活中一般常识—–女性一般没有肌肉是吻合的。
在男性的错误样本中,我们可以看出模型在男性样本上的预测是很不错的。男性的第一个样本具有欺骗性,包括人类去识别可能也会出错,其他几个样本就是没有显示出男性特征,所以这个出错是可以容忍的。

总的来说,模型在预测时的表现是非常不错的,一般的有特征的图片都能正确识别,读者可以自行上传图片去试试。地址就在下面。

体验地址,上传图片就可以使用了。 http://www.ctsch.cn/?page_id=11

使用fastai训练的一个性别识别模型的更多相关文章

  1. 人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型

    人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型 经过前面稍显罗嗦的准备工作,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的te ...

  2. 怎么训练出一个NB的Prophet模型

    上篇<神器の争>主要是介绍Prophet的特点以及prophet入门的一些注意事项,但离真正的实际运用还有段距离.本篇主要讲解实际运用中Prophet调参的主要步骤以及一些本人实际经验. ...

  3. 基于深度学习的人脸性别识别系统(含UI界面,Python代码)

    摘要:人脸性别识别是人脸识别领域的一个热门方向,本文详细介绍基于深度学习的人脸性别识别系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的UI界面.在界面中可以选择人脸图片.视频进行检 ...

  4. tensorflow训练验证码识别模型

    tensorflow训练验证码识别模型的样本可以使用captcha生成,captcha在linux中的安装也很简单: pip install captcha 生成验证码: # -*- coding: ...

  5. 一个使用fasttext训练的新闻文本分类器/模型

    fastext是什么? Facebook AI Research Lab 发布的一个用于快速进行文本分类和单词表示的库.优点是很快,可以进行分钟级训练,这意味着你可以在几分钟时间内就训练好一个分类模型 ...

  6. 基于OpenCV性别识别

    叙述性说明 所谓的性别识别推断检测到的面部是男性还是女性.它是一个二值分类问题. 识别算法可以用于SVM,BP神经网络.LDA,PCA,PCA+LDA等等.OpenCV官网给出的文档是基于Fisher ...

  7. 使用ML.NET模型生成器来完成图片性别识别

    什么是ML.NET? ML.NET 使你能够在联机或脱机场景中将机器学习添加到 .NET 应用程序中. 借助此功能,可以使用应用程序的可用数据进行自动预测. 机器学习应用程序利用数据中的模式来进行预测 ...

  8. 从零到一:caffe-windows(CPU)配置与利用mnist数据集训练第一个caffemodel

    一.前言 本文会详细地阐述caffe-windows的配置教程.由于博主自己也只是个在校学生,目前也写不了太深入的东西,所以准备从最基础的开始一步步来.个人的计划是分成配置和运行官方教程,利用自己的数 ...

  9. Python自然语言处理学习笔记之性别识别

    从今天起开始写自然语言处理的实践用法,今天学了文本分类,并没用什么创新的东西,只是把学到的知识点复习一下 性别识别(根据给定的名字确定性别) 第一步是创建一个特征提取函数(feature extrac ...

随机推荐

  1. ClassNotFoundException: org.springframework.web.context.ContextLoadServlet

    web.xml中配置 <!-- 配置spring核心监听器,默认会以 /WEB-INF/applicationContext.xml作为配置文件 --> <listener> ...

  2. NULL 是什么意思 ?

    NULL 这个值表示 UNKNOWN(未知):它不表示""(空字符串).对 NULL 这 个值的任何比较都会生产一个 NULL 值.您不能把任何值与一个 NULL 值进行比 较,并 ...

  3. spring 自动装配 bean 有哪些方式?

    Spring容器负责创建应用程序中的bean同时通过ID来协调这些对象之间的关系.作为开发人员,我们需要告诉Spring要创建哪些bean并且如何将其装配到一起. spring中bean装配有两种方式 ...

  4. log4J——在Spring中的使用

    log4J简介 1.通过 log4j 可以看到程序运行过程中更详细的信息 (1)经常使用 log4j 查看日志 2.使用 (1)导入 log4j 的jar包 (2)复制 log4j 的配置文件,复制到 ...

  5. 学习Squid(一)

    第1章 Squid介绍 1.1 缓存服务器介绍 缓存服务器(英文意思cache server),即用来存储(介质为内存及硬盘)用户访问的网页,图片,文件等等信息的专用服务器.这种服务器不仅可以使用户可 ...

  6. window onerror 各浏览器下表现总结

    window onerror 各浏览器下表现总结 做前端错误上报,必然离不开window onerror,但window onerror在不同设备上表现并不一致,浏览器为避免信息泄露,在一些情况下并不 ...

  7. IMWEB 前端面试题汇总

    1.什么是盒子模型? CSS中的思维模型,每一个元素都包含margin,padding,boder,content区域,占一个盒子形状,整体称为盒模型. 2.简述一下src与href的区别? Href ...

  8. 从零搭建react开发环境

    早在六年前,前端开发已经实现了模块化.工程化开发,既然是模块化工程化开发那就少不了包管理工具,所以我们的第一步就是先从安装nodejs开始(安装nodejs携带JavaScript的包管理工具npm) ...

  9. c++对于c的扩展_冒号作用域

    冒号作用域 ::(该运算符为作用域):如果::前面什么都没加代表全局作用域 #include <iostream> using namespace stu; int a=10; viod ...

  10. python---冒泡排序的实现

    冒泡排序 思想 ​ 列表中有n个数, 每两个相邻的数, 如果前边的数比后边的数大, 就交换. ​ 关键点: ​ 趟: 总共执行 n-1趟 ​ 无序区: 第 i 趟时, 索引 0~ n-1-i 为无序区 ...