百度 PaddlePaddle

传统图像识别

语义鸿沟:

  • 相似的视觉特征,不同的语义概念。
  • 不同的视觉特征,相同的语义概念。

传统识别方法:测量空间 – 特征表示 – 特征空间 – 特征匹配 – 类别空间

早期识别技术:采集图像,采集特征,相似度计算。
采用全局特征提取:颜色,形状,纹理。
特征变换:提高特征表示性能,降维。Manifold Learning/embedding:映射为低维空间下的向量表示,PCA MDS ISOMAP LLE Laplacian Eigenmap等。
索引技术:穷举搜索(效率低),临近搜索(牺牲精度)。KD-Tree LSH。二进制哈希,通过哈希编码特征,快速查找(减少特征存储空间,计算复杂度)。
相关反馈:通过用户反馈学习调整。Explicit Feedback(正负反馈),Implicit Feedback(根据可观察的行为推断用户意图)。
重排序:将接近的结果放到前面。
主要问题:全局特征丢失了图像细节。

中期图形识别:文本,词袋模型,倒排索引。图像,视觉词袋。
特征提取,生成视觉词典,词袋向量,倒排索引,特征提取,查询。
特征提取:局部特征,图像区块向量,特征检测子Harris Dog SURF HarrisAffine,特征描述子Sift glof shape context orb。
向量化:视觉词典生成。用特征向量,聚类(k means,affinity,propagation),找类中心,就是视觉关键词。每个图像可以找到多个视觉关键词直方图,直方图维度=聚类中心的个数,维度值=图像落在聚类中心的特征数量。
索引技术:倒排索引。提取局部描述,在索引中查找关键词。然后排序(tf-idf),对相似的图像投票。
后处理:局部几何验证,弱空间关系验证,乘积量化。提高一致性高的匹配结果,降低一致性低的匹配结果。

人工智能

时期:会推理 – 拥有知识 – 会学习 – 统计学习和神经网络

机器学习:对某个任务T可以从经验E中学习,经过经验E改进,使得任务T的性能有所提升。

一般过程:训练数据,测试数据,训练结果(策略,模型,算法),求函数F的过程。

深度学习:学习人的神经网络,解决机器学习问题。
优势:在特征空间中,由人提取特征变为由深度学习提取。

深度学习

滤波器提取:像素,边缘,特征。
图像识别:建立模型,损失函数(误差最小),参数学习。
建立模型:选择什么样的网络结构,多少层,每层多少神经元。

  • 线性函数:f=wa+b,
  • 激活函数(非线性)
    损失函数:选择常用的损失函数,平方误差,交叉熵
    参数学习:梯度下降法,反向传播

模型:

  • 前馈神经网络:多隐藏层(多少层,多少结点),输出层(激活函数:softmax,概率)

分类任务要最后接全连接层。

卷积网络

传统全连接结构不够灵活,参数量巨大,不适合二维图形。采用卷积网络,前后层部分连接,权值共享,下采样。卷积网络,就是学习滤波器的值。

建立模型:局部连接,权值共享,下采样。为了减少参数。
局部连接:采用卷积核对图形(上一层)卷积,得到卷积后的结果(下一层)。
权值共享:卷积核的参数固定,为w1到wn。
下采样:缩小宽和高,常用最大值或平均值。

卷积计算后,图像会缩小,新尺寸为:w-c+1
卷积层:input_image * kernel = feature_map
一个卷积层可以有多个卷积核,一个图像产生多个特征图。

经典结构:LeNet-5

损失函数:
目标分类与检测:图像经过卷积池化,再经过卷积提取特征图,之后经过全连接网络。分类损失(交叉熵损失函数),回归损失(平方损失函数)。

一般结构示例:((卷积层+激活层)*2+池化层)*3+全连接层*3
计算机视觉的几种任务:图像分类(为图像赋予语义标签),目标检测(把物体位置标注出来),图像语义分割(精确勾勒出其轮廓和位置),图像实例分割(多物体时,将他们区分出来)

数据集:

  • Cifar-10:比MNIST更高级的数据集,彩色的,50000训练+10000测试图片,几十种类别。
  • ImageNet:强大的数据集,1281167训练+50000验证+100000测试(不对外公布),1000多个类别。

经典CNN:Hubel&Wiesel -> LeNet -> AlexNet -> NIN,GoogleNet,InceptionV3,V4 & VGG & InceptionV2,BN -> ResetNet
LeNet:使用MNIST数据集,早期用于数字识别。只接受32*32大小图像。
AlexNet:加入激活层。后来被ZF Net改进。接受227*227*3图像大小。卷积核11*11,每一层输出:(图像尺寸-卷积核尺寸)/步长+1,如果有padding边界延拓再修改大小。经过几轮,加一个池化,再经过几次,进入全连接。在训练过程中,使用了一些技巧:分组卷积,使用激活函数ReLU(解决梯度消失),DataAugmentation(数据增强,给图像产生噪声,形变,翻转,裁剪,防止过拟合),DropOut(解决过拟合0.5),BatchSize(批训练128),SGD-Momentum(随机梯度下降0.9),LearningRate(学习率0.01),L2 Weight-Dccay(5e-4)
NIN,GoogleNet,InceptionV3,V4:
VGG:
InceptionV2,BN:
ResetNet:

PaddlePaddle 安装

快速安装教程

支持Windows,MacOS,Ubuntu,CentOS。
支持Pip,Docker等。
支持CUDA 9,10,CPU版本。

例如:
Windows + pip + Python 3 + CUDA 10 + cuDNN 7.3+

1
python -m pip install paddlepaddle-gpu==1.7.1.post107 -i https://mirror.baidu.com/pypi/simple

安装验证

1
2
import paddle.fluid
print(paddle.fluid.install_check.run_check())

语法

基本数据类型

目前支持的基本数据类型有:

1
2
3
4
5
6
7
8
9
float16 # 部分操作支持
float32 # 主要实数类型
float64 # 次要实数类型,支持大部分操作
int32 # 次要标签类型
int64 # 主要标签类型
uint64 # 次要标签类型
bool # 控制流数据类型
int16 # 次要标签类型
uint8 # 输入数据类型,可用于图像像素

Variable

一般可以认为Variable等价于Tensor。
Variable可分为三种:

模型中的可学习参数:网络权重,偏置等

1
2
3
4
# 创建可学习参数
w = fluid.layers.create_parameter(name="w",shape=[1],dtype='float32')
# 一部分常见的神经网络基本计算模块被提供了封装。例如全连接模型中创建 权值,偏置 两个可学习参数:
y = fluid.layers.fc(input=x, size=128, bias_attr=True)

占位Variable:表示待提供输入的Variable

1
2
3
4
5
6
#定义x的维度为[3,None],其中我们只能确定x的第一的维度为3,第二个维度未知,要在程序执行过程中才能确定
x = fluid.data(name="x", shape=[3,None], dtype="int64")

#若图片的宽度和高度在运行时可变,将宽度和高度定义为None。
#shape的三个维度含义分别是:batch_size, channel、图片的宽度、图片的高度
b = fluid.data(name="image",shape=[None, 3,None,None],dtype="float32")

常量Variable:常量

1
data = fluid.layers.fill_constant(shape=[1], value=0, dtype='int64')

Tensor数据

对于一些batch内样本大小不一样的问题(有的大有的小),Paddle可以通过两种方式解决:

  • Padding:修改到同样大小(推荐)
  • Lod-Tensor:记录每个样本的大小,以便减少无用的计算量。如果前一个方法不可行,可以用这种方法。

LoD Tensor

Level of Detail Tensor 是Paddle的高级特性,是对Tensor的一种扩充。大部分情况下可以不必关注。

Operator

这里囊括所有对数据的操作,可以到以下模块中使用。但是Operator并不是实时的,而仅仅是提交操作,等待最后统一计算:

1
2
import paddle.fluid.layers
import paddle.fluid.nets

加法运算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 定义执行器
cpu = fluid.core.CPUPlace()
exe = fluid.Executor(cpu)
exe.run(fluid.default_startup_program())

# 定义Tensor和运算
a = fluid.data(name="a",shape=[1],dtype='float32')
b = fluid.data(name="b",shape=[1],dtype='float32')
result = fluid.layers.elementwise_add(a,b)

# Numpy 数据
x = numpy.array([5]).astype("float32")
y = numpy.array([7]).astype("float32")

# 提交数据并运行,fetch_list 为希望查看的变量
outs = exe.run(
feed={'a':x,'b':y},
fetch_list=[result])

Program

用于描述整个计算过程。Operator会被按顺序放入Program中。一般有这几种结构

  • 顺序结构
  • 条件分支
  • 循环
  • 动态 RNN
  • 静态 RNN

用户完成网络定义后,一段 Paddle 程序中通常存在 2 个 Program。

1
2
3
4
# 定义模型参数初始化等操作,可以由框架自动生成,使用时无需显式地创建。如果调用修改了参数的默认初始化方式,框架会自动的将相关的修改加入default_startup_program
fluid.default_startup_program
# 定义神经网络模型,前向反向计算,参数更新等操作,构建这个也是用户的主要任务
fluid.default_main_program

Executor

该部分相当于对Program的编译和执行。Executor将Program转换为C++后端的可执行程序FluidProgram,完成编译操作;Executor再执行编译好的FluidProgram程序。

动态图机制

可以通过这个机制,无需构建整个图,就可以立即执行结果。这个机制能够方便用户及时调试模型,减少大量用于构建静态图的代码。

使用这一机制,需要在guard上下文环境下:

1
2
3
4
5
6
7
8
9
10
11
12
x = np.ones([2, 2], np.float32)
with fluid.dygraph.guard():
# 编辑动态图代码
inputs = []
for _ in range(10):
inputs.append(fluid.dygraph.to_variable(x)) # ndarray 转 Variable
ret = fluid.layers.sums(inputs)
print(ret.numpy())
# 反向计算
loss = fluid.layers.reduce_sum(ret)
loss.backward()
print(loss.gradient())

疫情数据可视化(爬虫,Pyecharts)

爬取数据

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import json
import re
import requests
import datetime

today = datetime.date.today().strftime('%Y%m%d') #20200315

def crawl_dxy_data():
"""
爬取丁香园实时统计数据,保存到data目录下,以当前日期作为文件名,存JSON文件
"""
response = requests.get('https://ncov.dxy.cn/ncovh5/view/pneumonia') #request.get()用于请求目标网站
print(response.status_code) # 打印状态码


try:
url_text = response.content.decode() #更推荐使用response.content.deocde()的方式获取响应的html页面
#print(url_text)
url_content = re.search(r'window.getAreaStat = (.*?)}]}catch', #re.search():扫描字符串以查找正则表达式模式产生匹配项的第一个位置 ,然后返回相应的match对象。
url_text, re.S) #在字符串a中,包含换行符\n,在这种情况下:如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始;
#而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。
texts = url_content.group() #获取匹配正则表达式的整体结果
content = texts.replace('window.getAreaStat = ', '').replace('}catch', '') #去除多余的字符
json_data = json.loads(content)
with open('data/' + today + '.json', 'w', encoding='UTF-8') as f:
json.dump(json_data, f, ensure_ascii=False)
except:
print('<Response [%s]>' % response.status_code)


def crawl_statistics_data():
"""
获取各个省份历史统计数据,保存到data目录下,存JSON文件
"""
with open('data/'+ today + '.json', 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())

statistics_data = {}
for province in json_array:
response = requests.get(province['statisticsData'])
try:
statistics_data[province['provinceShortName']] = json.loads(response.content.decode())['data']
except:
print('<Response [%s]> for url: [%s]' % (response.status_code, province['statisticsData']))

with open("data/statistics_data.json", "w", encoding='UTF-8') as f:
json.dump(statistics_data, f, ensure_ascii=False)


if __name__ == '__main__':
crawl_dxy_data()
crawl_statistics_data()

疫情地图

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import json
import datetime
from pyecharts.charts import Map
from pyecharts import options as opts

# 读原始数据文件
today = datetime.date.today().strftime('%Y%m%d') #20200315
datafile = 'data/'+ today + '.json'
with open(datafile, 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())

# 分析全国实时确诊数据:'confirmedCount'字段
china_data = []
for province in json_array:
china_data.append((province['provinceShortName'], province['confirmedCount']))
china_data = sorted(china_data, key=lambda x: x[1], reverse=True) #reverse=True,表示降序,反之升序

print(china_data)
# 全国疫情地图
# 自定义的每一段的范围,以及每一段的特别的样式。
pieces = [
{'min': 10000, 'color': '#540d0d'},
{'max': 9999, 'min': 1000, 'color': '#9c1414'},
{'max': 999, 'min': 500, 'color': '#d92727'},
{'max': 499, 'min': 100, 'color': '#ed3232'},
{'max': 99, 'min': 10, 'color': '#f27777'},
{'max': 9, 'min': 1, 'color': '#f7adad'},
{'max': 0, 'color': '#f7e4e4'},
]
labels = [data[0] for data in china_data]
counts = [data[1] for data in china_data]

m = Map()
m.add("累计确诊", [list(z) for z in zip(labels, counts)], 'china')

#系列配置项,可配置图元样式、文字样式、标签样式、点线样式等
m.set_series_opts(label_opts=opts.LabelOpts(font_size=12),
is_show=False)
#全局配置项,可配置标题、动画、坐标轴、图例等
m.set_global_opts(title_opts=opts.TitleOpts(title='全国实时确诊数据',
subtitle='数据来源:丁香园'),
legend_opts=opts.LegendOpts(is_show=False),
visualmap_opts=opts.VisualMapOpts(pieces=pieces,
is_piecewise=True, #是否为分段型
is_show=True)) #是否显示视觉映射配置
#render()会生成本地 HTML 文件,默认会在当前目录生成 render.html 文件,也可以传入路径参数,如 m.render("mycharts.html")
m.render(path='/home/aistudio/data/全国实时确诊数据.html')
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import json
import datetime
from pyecharts.charts import Map
from pyecharts import options as opts

# 读原始数据文件
today = datetime.date.today().strftime('%Y%m%d') #20200315
datafile = 'data/'+ today + '.json'
with open(datafile, 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())

# 分析湖北省实时确诊数据
# 读入规范化的城市名称,用于规范化丁香园数据中的城市简称
with open('/home/aistudio/data/data24815/pycharts_city.txt', 'r', encoding='UTF-8') as f:
defined_cities = [line.strip() for line in f.readlines()]


def format_city_name(name, defined_cities):
for defined_city in defined_cities:
if len((set(defined_city) & set(name))) == len(name):
name = defined_city
if name.endswith('市') or name.endswith('区') or name.endswith('县') or name.endswith('自治州'):
return name
return name + '市'
return None


province_name = '湖北'
for province in json_array:
if province['provinceName'] == province_name or province['provinceShortName'] == province_name:
json_array_province = province['cities']
hubei_data = [(format_city_name(city['cityName'], defined_cities), city['confirmedCount']) for city in
json_array_province]
hubei_data = sorted(hubei_data, key=lambda x: x[1], reverse=True)

print(hubei_data)

labels = [data[0] for data in hubei_data]
counts = [data[1] for data in hubei_data]
pieces = [
{'min': 10000, 'color': '#540d0d'},
{'max': 9999, 'min': 1000, 'color': '#9c1414'},
{'max': 999, 'min': 500, 'color': '#d92727'},
{'max': 499, 'min': 100, 'color': '#ed3232'},
{'max': 99, 'min': 10, 'color': '#f27777'},
{'max': 9, 'min': 1, 'color': '#f7adad'},
{'max': 0, 'color': '#f7e4e4'},
]

m = Map()
m.add("累计确诊", [list(z) for z in zip(labels, counts)], '湖北')
m.set_series_opts(label_opts=opts.LabelOpts(font_size=12),
is_show=False)
m.set_global_opts(title_opts=opts.TitleOpts(title='湖北省实时确诊数据',
subtitle='数据来源:丁香园'),
legend_opts=opts.LegendOpts(is_show=False),
visualmap_opts=opts.VisualMapOpts(pieces=pieces,
is_piecewise=True,
is_show=True))
m.render(path='/home/aistudio/data/湖北省实时确诊数据.html')

增长曲线

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import numpy as np
import json
from pyecharts.charts import Line
from pyecharts import options as opts

# 读原始数据文件
datafile = 'data/statistics_data.json'
with open(datafile, 'r', encoding='UTF-8') as file:
json_dict = json.loads(file.read())

# 分析各省份2月1日至今的新增确诊数据:'confirmedIncr'
statistics__data = {}
for province in json_dict:
statistics__data[province] = []
for da in json_dict[province]:
if da['dateId'] >= 20200201:
statistics__data[province].append(da['confirmedIncr'])

# 获取日期列表
dateId = [str(da['dateId'])[4:6] + '-' + str(da['dateId'])[6:8] for da in json_dict['湖北'] if
da['dateId'] >= 20200201]

# 全国新增趋势
all_statis = np.array([0] * len(dateId))
for province in statistics__data:
all_statis = all_statis + np.array(statistics__data[province])

all_statis = all_statis.tolist()
# 湖北新增趋势
hubei_statis = statistics__data['湖北']
# 湖北以外的新增趋势
other_statis = [all_statis[i] - hubei_statis[i] for i in range(len(dateId))]

line = Line()
line.add_xaxis(dateId)
line.add_yaxis("全国新增确诊病例", #图例
all_statis, #数据
is_smooth=True, #是否平滑曲线
linestyle_opts=opts.LineStyleOpts(width=4, color='#B44038'),#线样式配置项
itemstyle_opts=opts.ItemStyleOpts(color='#B44038', #图元样式配置项
border_color="#B44038", #颜色
border_width=10)) #图元的大小
line.add_yaxis("湖北新增确诊病例", hubei_statis, is_smooth=True,
linestyle_opts=opts.LineStyleOpts(width=2, color='#4E87ED'),
label_opts=opts.LabelOpts(position='bottom'), #标签在折线的底部
itemstyle_opts=opts.ItemStyleOpts(color='#4E87ED',
border_color="#4E87ED",
border_width=3))
line.add_yaxis("其他省份新增病例", other_statis, is_smooth=True,
linestyle_opts=opts.LineStyleOpts(width=2, color='#F1A846'),
label_opts=opts.LabelOpts(position='bottom'), #标签在折线的底部
itemstyle_opts=opts.ItemStyleOpts(color='#F1A846',
border_color="#F1A846",
border_width=3))
line.set_global_opts(title_opts=opts.TitleOpts(title="新增确诊病例", subtitle='数据来源:丁香园'),
yaxis_opts=opts.AxisOpts(max_=16000, min_=1, type_="log", #坐标轴配置项
splitline_opts=opts.SplitLineOpts(is_show=True),#分割线配置项
axisline_opts=opts.AxisLineOpts(is_show=True)))#坐标轴刻度线配置项
line.render(path='/home/aistudio/data/新增确诊趋势图.html')

手势识别

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import os
import time
import random
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import paddle
import paddle.fluid as fluid
import paddle.fluid.layers as layers
from multiprocessing import cpu_count
from paddle.fluid.dygraph import Pool2D,Conv2D
from paddle.fluid.dygraph import Linear

# 生成图像列表
data_path = '/home/aistudio/data/data23668/Dataset'
character_folders = os.listdir(data_path)
# print(character_folders)
if(os.path.exists('./train_data.list')):
os.remove('./train_data.list')
if(os.path.exists('./test_data.list')):
os.remove('./test_data.list')

for character_folder in character_folders:
# 生成测试集和训练集
with open('./train_data.list', 'a') as f_train:
with open('./test_data.list', 'a') as f_test:
if character_folder == '.DS_Store':
continue
character_imgs = os.listdir(os.path.join(data_path,character_folder))
count = 0
for img in character_imgs:
if img =='.DS_Store':
continue
if count%10 == 0:
f_test.write(os.path.join(data_path,character_folder,img) + '\t' + character_folder + '\n')
else:
f_train.write(os.path.join(data_path,character_folder,img) + '\t' + character_folder + '\n')
count +=1
print('列表已生成')

# 用于训练的数据提供器
train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=data_reader('./train_data.list'), buf_size=256), batch_size=32)
# 用于测试的数据提供器
test_reader = paddle.batch(reader=data_reader('./test_data.list'), batch_size=32)

#定义DNN网络
class MyDNN(fluid.dygraph.Layer):
def __init__(self):
super(MyDNN,self).__init__()
super(MyDNN, self).__init__()
self.hidden1 = Linear(100, 100, act='relu')
self.hidden2 = Linear(100, 100, act='relu')
self.hidden3 = Linear(100, 100, act='relu')
self.hidden4 = Linear(3*100*100, 10, act='softmax')
def forward(self,input):
x=self.hidden1(input)
x=self.hidden2(x)
x=self.hidden3(x)
x=fluid.layers.reshape(x, shape=[-1,3*100*100])
y=self.hidden4(x)

return y

#用动态图进行训练
with fluid.dygraph.guard():
model=MyDNN() #模型实例化
model.train() #训练模式
opt=fluid.optimizer.SGDOptimizer(learning_rate=0.01, parameter_list=model.parameters())#优化器选用SGD随机梯度下降,学习率为0.001.

epochs_num=10 #迭代次数

for pass_num in range(epochs_num):

for batch_id,data in enumerate(train_reader()):

images=np.array([x[0].reshape(3,100,100) for x in data],np.float32)

labels = np.array([x[1] for x in data]).astype('int64')
labels = labels[:, np.newaxis]
# print(images.shape)
image=fluid.dygraph.to_variable(images)
label=fluid.dygraph.to_variable(labels)
predict=model(image)#预测
# print(predict)
loss=fluid.layers.cross_entropy(predict,label)
avg_loss=fluid.layers.mean(loss)#获取loss值

acc=fluid.layers.accuracy(predict,label)#计算精度

if batch_id!=0 and batch_id%50==0:
print("train_pass:{},batch_id:{},train_loss:{},train_acc:{}".format(pass_num,batch_id,avg_loss.numpy(),acc.numpy()))

avg_loss.backward()
opt.minimize(avg_loss)
model.clear_gradients()

fluid.save_dygraph(model.state_dict(),'MyDNN')#保存模型

#模型校验
with fluid.dygraph.guard():
accs = []
model_dict, _ = fluid.load_dygraph('MyDNN')
model = MyDNN()
model.load_dict(model_dict) #加载模型参数
model.eval() #训练模式
for batch_id,data in enumerate(test_reader()):#测试集
images=np.array([x[0].reshape(3,100,100) for x in data],np.float32)
labels = np.array([x[1] for x in data]).astype('int64')
labels = labels[:, np.newaxis]

image=fluid.dygraph.to_variable(images)
label=fluid.dygraph.to_variable(labels)

predict=model(image)
acc=fluid.layers.accuracy(predict,label)
accs.append(acc.numpy()[0])
avg_acc = np.mean(accs)
print(avg_acc)

#读取预测图像,进行预测

def load_image(path):
img = Image.open(path)
img = img.resize((100, 100), Image.ANTIALIAS)
img = np.array(img).astype('float32')
img = img.transpose((2, 0, 1))
img = img/255.0
print(img.shape)
return img

#构建预测动态图过程
with fluid.dygraph.guard():
infer_path = '手势.JPG'
model=MyDNN()#模型实例化
model_dict,_=fluid.load_dygraph('MyDNN')
model.load_dict(model_dict)#加载模型参数
model.eval()#评估模式
infer_img = load_image(infer_path)
infer_img=np.array(infer_img).astype('float32')
infer_img=infer_img[np.newaxis,:, : ,:]
infer_img = fluid.dygraph.to_variable(infer_img)
result=model(infer_img)
display(Image.open('手势.JPG'))
print(np.argmax(result.numpy()))

车牌识别

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#导入需要的包

import numpy as np
import paddle as paddle
import paddle.fluid as fluid
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import os
from multiprocessing import cpu_count
from paddle.fluid.dygraph import Pool2D,Conv2D
# from paddle.fluid.dygraph import FC
from paddle.fluid.dygraph import Linear

# 生成车牌字符图像列表
data_path = '/home/aistudio/data'
character_folders = os.listdir(data_path)
label = 0
LABEL_temp = {}
if(os.path.exists('./train_data.list')):
os.remove('./train_data.list')
if(os.path.exists('./test_data.list')):
os.remove('./test_data.list')
for character_folder in character_folders:
with open('./train_data.list', 'a') as f_train:
with open('./test_data.list', 'a') as f_test:
if character_folder == '.DS_Store' or character_folder == '.ipynb_checkpoints' or character_folder == 'data23617':
continue
print(character_folder + " " + str(label))
LABEL_temp[str(label)] = character_folder #存储一下标签的对应关系
character_imgs = os.listdir(os.path.join(data_path, character_folder))
for i in range(len(character_imgs)):
if i%10 == 0:
f_test.write(os.path.join(os.path.join(data_path, character_folder), character_imgs[i]) + "\t" + str(label) + '\n')
else:
f_train.write(os.path.join(os.path.join(data_path, character_folder), character_imgs[i]) + "\t" + str(label) + '\n')
label = label + 1
print('图像列表已生成')

# 用上一步生成的图像列表定义车牌字符训练集和测试集的reader
def data_mapper(sample):
img, label = sample
img = paddle.dataset.image.load_image(file=img, is_color=False)
img = img.flatten().astype('float32') / 255.0
return img, label
def data_reader(data_list_path):
def reader():
with open(data_list_path, 'r') as f:
lines = f.readlines()
for line in lines:
img, label = line.split('\t')
yield img, int(label)
return paddle.reader.xmap_readers(data_mapper, reader, cpu_count(), 1024)

# 用于训练的数据提供器
train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=data_reader('./train_data.list'), buf_size=512), batch_size=128)
# 用于测试的数据提供器
test_reader = paddle.batch(reader=data_reader('./test_data.list'), batch_size=128)

#定义网络
class MyLeNet(fluid.dygraph.Layer):
def __init__(self):
super(MyLeNet,self).__init__()
self.hidden1_1 = Conv2D(1, 28, 5, 1)
self.hidden1_2 = Pool2D(pool_size=2, pool_type="max", pool_stride=1)
self.hidden2_1 = Conv2D(28, 32, 3, 1)
self.hidden2_2 = Pool2D(pool_size=2, pool_type="max", pool_stride=1)
self.hidden3 = Conv2D(32, 32, 3, 1)
self.hidden4 = Linear(32*10*10, 65, act="softmax")
def forward(self,input):
x = self.hidden1_1(input)
x = self.hidden1_2(x)
x = self.hidden2_1(x)
x = self.hidden2_2(x)
x = self.hidden3(x)
x = fluid.layers.reshape(x, shape=[-1, 32*10*10])
y = self.hidden4(x)
return y

with fluid.dygraph.guard():
lr = 0.005
model=MyLeNet() #模型实例化
model.train() #训练模式
opt=fluid.optimizer.SGDOptimizer(learning_rate=0.001, parameter_list=model.parameters())#优化器选用SGD随机梯度下降,学习率为0.001.
epochs_num=100 #迭代次数为2

for pass_num in range(epochs_num):
if pass_num > 10:
lr = 0.002
if pass_num > 30:
lr = 0.001
if pass_num > 60:
lr = 0.0005
for batch_id,data in enumerate(train_reader()):
images=np.array([x[0].reshape(1,20,20) for x in data],np.float32)
labels = np.array([x[1] for x in data]).astype('int64')
labels = labels[:, np.newaxis]
image=fluid.dygraph.to_variable(images)
label=fluid.dygraph.to_variable(labels)

predict=model(image)#预测

loss=fluid.layers.cross_entropy(predict,label)
avg_loss=fluid.layers.mean(loss)#获取loss值

acc=fluid.layers.accuracy(predict,label)#计算精度

if batch_id!=0 and batch_id%50==0:
print("train_pass:{},batch_id:{},train_loss:{},train_acc:{}".format(pass_num,batch_id,avg_loss.numpy(),acc.numpy()))

avg_loss.backward()
opt.minimize(avg_loss)
model.clear_gradients()

fluid.save_dygraph(model.state_dict(),'MyLeNet')#保存模型

#模型校验
with fluid.dygraph.guard():
accs = []
model=MyLeNet()#模型实例化
model_dict,_=fluid.load_dygraph('MyLeNet')
model.load_dict(model_dict)#加载模型参数
model.eval()#评估模式
for batch_id,data in enumerate(test_reader()):#测试集
images=np.array([x[0].reshape(1,20,20) for x in data],np.float32)
labels = np.array([x[1] for x in data]).astype('int64')
labels = labels[:, np.newaxis]

image=fluid.dygraph.to_variable(images)
label=fluid.dygraph.to_variable(labels)

predict=model(image)#预测
acc=fluid.layers.accuracy(predict,label)
accs.append(acc.numpy()[0])
avg_acc = np.mean(accs)
print(avg_acc)

# 对车牌图片进行处理,分割出车牌中的每一个字符并保存
license_plate = cv2.imread('./车牌.png')
gray_plate = cv2.cvtColor(license_plate, cv2.COLOR_RGB2GRAY)
ret, binary_plate = cv2.threshold(gray_plate, 175, 255, cv2.THRESH_BINARY)
result = []
for col in range(binary_plate.shape[1]):
result.append(0)
for row in range(binary_plate.shape[0]):
result[col] = result[col] + binary_plate[row][col]/255
character_dict = {}
num = 0
i = 0
while i < len(result):
if result[i] == 0:
i += 1
else:
index = i + 1
while result[index] != 0:
index += 1
character_dict[num] = [i, index-1]
num += 1
i = index

for i in range(8):
if i==2:
continue
padding = (170 - (character_dict[i][1] - character_dict[i][0])) / 2
ndarray = np.pad(binary_plate[:,character_dict[i][0]:character_dict[i][1]], ((0,0), (int(padding), int(padding))), 'constant', constant_values=(0,0))
ndarray = cv2.resize(ndarray, (20,20))
cv2.imwrite('./' + str(i) + '.png', ndarray)

def load_image(path):
img = paddle.dataset.image.load_image(file=path, is_color=False)
img = img.astype('float32')
img = img[np.newaxis, ] / 255.0
return img

#将标签进行转换
print('Label:',LABEL_temp)
match = {'A':'A','B':'B','C':'C','D':'D','E':'E','F':'F','G':'G','H':'H','I':'I','J':'J','K':'K','L':'L','M':'M','N':'N',
'O':'O','P':'P','Q':'Q','R':'R','S':'S','T':'T','U':'U','V':'V','W':'W','X':'X','Y':'Y','Z':'Z',
'yun':'云','cuan':'川','hei':'黑','zhe':'浙','ning':'宁','jin':'津','gan':'赣','hu':'沪','liao':'辽','jl':'吉','qing':'青','zang':'藏',
'e1':'鄂','meng':'蒙','gan1':'甘','qiong':'琼','shan':'陕','min':'闽','su':'苏','xin':'新','wan':'皖','jing':'京','xiang':'湘','gui':'贵',
'yu1':'渝','yu':'豫','ji':'冀','yue':'粤','gui1':'桂','sx':'晋','lu':'鲁',
'0':'0','1':'1','2':'2','3':'3','4':'4','5':'5','6':'6','7':'7','8':'8','9':'9'}
L = 0
LABEL ={}

for V in LABEL_temp.values():
LABEL[str(L)] = match[V]
L += 1
print(LABEL)

#构建预测动态图过程
with fluid.dygraph.guard():
model=MyLeNet()#模型实例化
model_dict,_=fluid.load_dygraph('MyLeNet')
model.load_dict(model_dict)#加载模型参数
model.eval()#评估模式
lab=[]
for i in range(8):
if i==2:
continue
infer_imgs = []
infer_imgs.append(load_image('./' + str(i) + '.png'))
infer_imgs = np.array(infer_imgs)
infer_imgs = fluid.dygraph.to_variable(infer_imgs)
result=model(infer_imgs)
lab.append(np.argmax(result.numpy()))
# print(lab)


display(Image.open('./车牌.png'))
print('\n车牌识别结果为:',end='')
for i in range(len(lab)):
print(LABEL[str(lab[i])],end='')