DNN|CNN|百度paddle学习

深度学习三个步骤:

  • 建立模型
    • 选择什么样的网络结构
    • 选择多少层,每层选择多少神经元
  • 损失函数
    • 选择常用损失函数,平方误差,交叉熵…..
  • 参数学习
    • 梯度下降
    • 反向传播算法

全连接神经网络DNN由于模型结构不够灵活,模型参数太多,通过模型改进,就出现了卷积神经网络CNN。
CNN在结构上有三大特性:

  1. 局部连接,在我们进行图像识别的时候,不需要对整个图像进行处理,只需要关注图像中某些特殊的区域,一张640x480的图片,可能其中的16x16个像素

  2. 权重共享

  3. 下采样,减小图片的尺寸,
    可以减少网络参数,加快训练速度。
    在这里插入图片描述)在这里插入图片描述
    Pooling 池化层
    通过下采样缩减feature map尺度。常用maxpooling和averagepooling.

    卷积神经网络的一般结构

    1. 卷积层+激活层和池化层的组合多次出现,用来提取特征
    2. 多个全连接或特殊的CNN结构作为输出层,用作分类器/检测器/分割器

      经典的CNN结构

      在这里插入图片描述

      AlexNet

      在这里插入图片描述
      在这里插入图片描述

      VGG

      在这里插入图片描述
      在这里插入图片描述
      在AlexNet中用到一些非常大的卷积核,比如11x11、5x5的,感受野越大,看到的图片信息就越多,获得的特征会越好。但是随着参数和计算量的增加,如何衡量该使用多大的卷积核呢
      Methods:学习到使用2个3x3的卷积核的组合比仅使用1个5x5的卷积核效果更佳,并且参数量降低。
      在这里插入图片描述

这几天参加了百度飞桨举办的深度学习7日入门-CV疫情特辑课程,通过几个疫情AI实战案例,轻松入门深度学习。

Day01 新冠疫情可视化

利用python爬取丁香园公开的统计数据,根据累计确诊数,使用pyecharts绘制疫情分布图,通过查阅Pycharts api比较容易实现

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
import json
import datetime
from pyecharts.charts import Pie
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)
# 全国疫情地图
# 自定义的每一段的范围,以及每一段的特别的样式。

labels = [data[0] for data in china_data]
counts = [data[1] for data in china_data]

m = Pie()
m.add("", [list(z) for z in zip(labels, counts)])

#系列配置项,可配置图元样式、文字样式、标签样式、点线样式等
m.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")
)
#全局配置项,可配置标题、动画、坐标轴、图例等
m.set_global_opts(title_opts=opts.TitleOpts(title='全国实时确诊数据',
subtitle='数据来源:丁香园'),
legend_opts=opts.LegendOpts(is_show=False))
#render()会生成本地 HTML 文件,默认会在当前目录生成 render.html 文件,也可以传入路径参数,如 m.render("mycharts.html")
m.render(path='/home/aistudio/data/饼状图.html')

结果图:
在这里插入图片描述

Day02手势识别

属于图像分类任务,根据图像的语义信息将不同类别图像区分开,是计算机视觉中重要的基本问题。手势识别属于图像分类中的一个细分类问题。
主要步骤:

  1. 准备数据
  2. 配置网络
  3. 训练网络
  4. 模型评估
  5. 模型预测
    定义的DNN全连接神经网络:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#定义DNN网络
class MyDNN(fluid.dygraph.Layer):
def __init__(self):
super(MyDNN,self).__init__()
self.hidden1 = Linear(100,300,act="relu")
self.hidden2 = Linear(300,500,act="relu")
self.hidden3 = Linear(500,100,act="relu")
self.hidden4 = Linear(3*100*100, 10, act="softmax")
def forward(self,input):
x=self.hidden1(input)
#print(input.shape)
x=self.hidden2(x)
x=self.hidden3(x)
x=fluid.layers.reshape(x,shape=[-1,3*100*100])
#print(x.shape)
y=self.hidden4(x)
return y;

其中通过查看Paddle API,更改了几种不同的优化器和模型参数,最终accuracy还是达不到90%,还是不太会该如何选取参数。
识别结果:在这里插入图片描述

Day03-车牌识别

通过对经典的卷积网络模型比如LeNet的解析, 分为多个卷积层,激活层,池化层,然后是全连接层,最后通过Softmax函数将各分类标签通过概率表达出来。学会每一层的维度计算。
车牌识别中,需要事先将车牌中每个字符例如’沪’,’C’等切分出来,共形成65个分类,通过深度学习实际上最后预测的是车牌上的每个字符最大概率的预测字符,然后再拼接出来形成最终的识别结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#定义网络
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

Day04-口罩分类

检测在密集人流区域中戴口罩和未戴口罩的所有人脸,同时判断该人是否佩戴口罩。
vgg模型配置
在这里插入图片描述
vgg网络定义:

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
class VGGNet(fluid.dygraph.Layer):
'''
VGG网络
'''
def __init__(self):
super(VGGNet, self).__init__()
self.convpool01=ConvPool(3,64,3,2,2,2,act="relu")
self.convpool02=ConvPool(64,128,3,2,2,2,act="relu")
self.convpool03=ConvPool(128,256,3,2,2,3,act="relu")
self.convpool04=ConvPool(256,512,3,2,2,3,act="relu")
self.convpool05=ConvPool(512,512,3,2,2,3,act="relu")
self.pool_5_shape=512*7*7
self.fc01=fluid.dygraph.Linear(self.pool_5_shape,256,act="relu")
self.fc02=fluid.dygraph.Linear(256,256,act="relu")
self.fc03=fluid.dygraph.Linear(256,2,act="softmax")

def forward(self, inputs, label=None):
"""前向计算"""
#print(inputs.shape)
x=self.convpool01(inputs)
#print(x.shape)
x=self.convpool02(x)
#print(x.shape)
x=self.convpool03(x)
x=self.convpool04(x)
x=self.convpool05(x)
x=fluid.layers.reshape(x,shape=[-1,512*7*7])
x=self.fc01(x)
x=self.fc02(x)
x=self.fc03(x)
if label is not None:
acc=fluid.layers.accuracy(input=x,label=label)
return x, acc
else:
return x

人流密度检测问题

本竞赛所用训练和测试图片均来自一般监控场景,但包括多种视角(如低空、高空、鱼眼等),图中行人的相对尺寸也会有较大差异。部分训练数据参考了公开数据集(如ShanghaiTech [1], UCF-CC-50 [2], WorldExpo’10 [3],Mall [4] 等)。

本竞赛的数据标注均在对应json文件中,每张训练图片的标注为以下两种方式之一:

(1)部分数据对图中行人提供了方框标注(boundingbox),格式为[x, y, w, h][x,y,w,h];

(2)部分图对图中行人提供了头部的打点标注,坐标格式为[x, y][x,y]。

此外部分图片还提供了忽略区(ignore_region)标注,格式为[x_0, y_0, x_1, y_1, …, x_n, y_n]组成的多边形(注意一张图片可能有多个多边形忽略区),图片在忽略区内的部分不参与训练/测试。
人流密度检测网络训练使用的CNN模型网络配置如下:

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

class CNN(fluid.dygraph.Layer):
'''
网络
'''
def __init__(self):
super(CNN, self).__init__()


self.conv01_1 = fluid.dygraph.Conv2D(num_channels=3, num_filters=64,filter_size=3,padding=1,act="relu")
self.pool01=fluid.dygraph.Pool2D(pool_size=2,pool_type='max',pool_stride=2)

self.conv02_1 = fluid.dygraph.Conv2D(num_channels=64, num_filters=128,filter_size=3, padding=1,act="relu")
self.pool02=fluid.dygraph.Pool2D(pool_size=2,pool_type='max',pool_stride=2)

self.conv03_1 = fluid.dygraph.Conv2D(num_channels=128, num_filters=256,filter_size=3, padding=1,act="relu")
self.pool03=fluid.dygraph.Pool2D(pool_size=2,pool_type='max',pool_stride=2)

self.conv04_1 = fluid.dygraph.Conv2D(num_channels=256, num_filters=512,filter_size=3, padding=1,act="relu")

self.conv05_1 = fluid.dygraph.Conv2D(num_channels=512, num_filters=512,filter_size=3,padding=1, act="relu")


self.conv06 = fluid.dygraph.Conv2D(num_channels=512,num_filters=256,filter_size=3,padding=1,act='relu')
self.conv07 = fluid.dygraph.Conv2D(num_channels=256,num_filters=128,filter_size=3,padding=1,act='relu')
self.conv08 = fluid.dygraph.Conv2D(num_channels=128,num_filters=64,filter_size=3,padding=1,act='relu')
self.conv09 = fluid.dygraph.Conv2D(num_channels=64,num_filters=1,filter_size=1,padding=0,act=None)


def forward(self, inputs, label=None):
"""前向计算"""
out = self.conv01_1(inputs)

out = self.pool01(out)

out = self.conv02_1(out)

out = self.pool02(out)
out = fluid.layers.dropout(x=out,dropout_prob=0.25)
out = self.conv03_1(out)

out = self.pool03(out)
out = fluid.layers.dropout(x=out,dropout_prob=0.25)
out = self.conv04_1(out)
out = fluid.layers.dropout(x=out,dropout_prob=0.5)
out = self.conv05_1(out)
out = fluid.layers.dropout(x=out,dropout_prob=0.5)
out = self.conv06(out)
out = self.conv07(out)
out = self.conv08(out)
out = self.conv09(out)

return out

通过几天的实践学习,掌握了训练的一般步骤,按照数据处理,配置网络,训练网络,模型评估和模型预测这样的步骤,再就是本地没GPU加速,运用百度paddle提供免费的算力,进行参数调优,但是对如何调整参数获得更好的效果,还是不太会。