目录
写在前面:
主要学习内容:
遇到的问题:
Day1 数据可视化 :
Day2 手势识别:
Day3 车牌识别:
Day4 口罩分类:
Day5 人流密度检测:
Day6 模型压缩:
最后
第一次知道飞桨,是无意看见推送“PaddleHub口罩检测”,简简单单几行代码通过调用PaddleHub口罩检测的预训练模型,就可以预测出图片是否戴口罩的行为。觉得很有用也蛮有意思
下面附上链接(亲测效果还是很好的)
PaddleHub口罩检测
(乱入)记得刚入学的时候,就看了胡晓曼老师的视频,觉得讲得很清楚code也写得很棒。到后来无意中加入训练营,又在首页看到了胡老师的身影。(那种感觉真的很奇妙)
课程链接在下方:
深度学习7日入门-CV特辑(希望这个链接不变 一直在~)
Day1:pyecharts的使用,主要是对数据的可视化,用pe作出的图像交互性很好,美观,也可制作动态图(个人感觉用于网站上或竞赛比较好,但是不适用于学术论文)。
Day2-Day4:图像识别,分类模型的学习训练。Day2手势识别10分类,Day3车牌识别65分类,Day4口罩分类2分类。主要流程是对图像数据处理(划分训练集测试集、size大小统一、数据增强等)、定义训练集和测试集的reader、设置训练和测试的数据提供器、网络的定义(Day2-Day4由易到难)、模型训练、模型测试、个别图像单独测试查看结果是否准确。
当然以上只是一个简单流程,每一步下又含有多个细节。图像分类不同数据集大体流程一致(像直播课老师说得八股文?),但细节部分需要仔细斟酌。
Day5:比赛,人流密度检测。当时想着根据前几天学习的内容重造一个图像N分类模型,但是这个N不确定,最后未做出来。(参考了baseline真香,已经很努力去学习、去理解)
Day6:模型压缩,利用PaddleSlim进行量化模型,然后训练和测试量化后的模型。效果还是很不错的,PaddleSlim代码在这里:PaddleSlim
code均在notebook下运行:
train(train_program)
#train iter=0, top1=0.0859375, top5=0.4140625, loss=2.72890472412
#train iter=100, top1=0.921875, top5=0.984375, loss=0.284728884697
#train iter=200, top1=0.9375, top5=1.0, loss=0.170599237084
#train iter=300, top1=0.96875, top5=0.9921875, loss=0.154459327459
#train iter=400, top1=0.96875, top5=1.0, loss=0.137120470405
test(val_program)
#test iter=0, top1=0.9921875, top5=1.0, loss=0.0384954810143
#final test result top1=0.977463960648, top5=0.999298870564
以下是量化后模型训练测试:
train(quant_program)
#train iter=0, top1=0.96875, top5=1.0, loss=0.170183762908
#train iter=100, top1=0.9453125, top5=1.0, loss=0.0788282752037
#train iter=200, top1=0.9921875, top5=1.0, loss=0.0579609684646
#train iter=300, top1=0.984375, top5=0.9921875, loss=0.0774042457342
#train iter=400, top1=0.96875, top5=1.0, loss=0.0834123492241
test(val_quant_program)
#test iter=0, top1=0.9921875, top5=1.0, loss=0.0308529287577
#final test result top1=0.980568885803, top5=0.999699532986
有的已解决,有的尚未解决。
爬虫用到了re,通过正则表达式匹配爬取数据。xpath、beautifulsoup、CSS选择器我都做过,但是正则迟迟未学会。(据说正则匹配速度最快,看来以后得好好加强下,奥里给!!!)
定义DNN网络,老师讲解用了4个Linear层。
这里比较奇怪的是训练方式,像之前我见过的训练方式是先要定义一些占位符(x、y之类的),选优化器、设置学习率、设置batch_size、设置迭代次数等。
而老师讲解是封装类(可以理解),然后在def forward():下实现网路部分的代码(第一次见!未看到占位符等~)
#定义 DNN网络
class MyDNN(fluid.dygraph.Layer):
def __init__(self):
super(MyDNN,self).__init__()
self.hidden1 = Linear(100,100,act='leaky_relu')
self.hidden2 = Linear(100,100,act='leaky_relu')
self.hidden3 = Linear(100,100,act='leaky_relu')
self.hidden4 = Linear(3*100*100,10,act='softmax')
def forward(self,input):
# print(input.shape)
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
在训练的时候:动态图训练、模型实例化、训练模式、opt优化器设置迭代次数等,通过train_reader灌入数据、标签。交叉熵计算loss值取平均、计算精度取平均。经过多少个batch后打印日志,反向计算、minimize
方法进行参数更新、重置梯度,最后是模型保存。
#用动态图进行训练
with fluid.dygraph.guard():
model = MyDNN() #模型实例化
model.train() #训练模式
opt = fluid.optimizer.AdagradOptimizer(learning_rate = 0.005, parameter_list = model.parameters())#优化器选用SGD随机梯度下降,学习率为0.001.
#学习率考虑 0.005? , regularization=fluid.regularizer.L1Decay(regularization_coeff = 0.01)
epochs_num = 150 #迭代次数
for pass_num in range(epochs_num):
for batch_id,data in enumerate(train_reader()):
images = np.array([x[0].reshape(3,50,50) for x in data],np.float32) #真实数据 图像大小转 100 * 100,并转化为浮点型
labels = np.array([x[1] for x in data]).astype('int64') # 真实标签值 整型
labels = labels[:, np.newaxis]
# print(images.shape)
image = fluid.dygraph.to_variable(images) # ndarray转换为fluid.Variable
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) #优化器对象的minimize方法进行参数更新
model.clear_gradients() #将参数梯度清零以保证下一轮训练的正确性
fluid.save_dygraph(model.state_dict(),'MyDNN')#保存模型
测试时:动态图,加载模型(之前保存好的)、模型实例化、加载模型参数、评估模式、分批次对test_reader的数据进行预测
#模型校验
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,50,50) for x in data],np.float32) #100*100 改为 20*20
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)
详细内容见 动态图机制-DyGraph
学到了学到了,这种训练方式我个人感知训练比较快、准确度高~等等?
遇到了问题:如果我重新启动notebook,不训练,直接进入测试环节(注意之前的训练模型我已保存过),测试的时候精度非常低甚至是0.0???(此处我内心的小问号)助教老师说了:可能我模型过拟合了?
但是我在训练后同样保存模型直接测试精度很高(问题未解决!!)
老师还说了他们对DNN网络 尝试调参、加层(训练速度很慢,但是最后精度在95%左右)
我内心:???
简单CNN网络的实现(讲课前我已实现好)主要是卷积层那里参数与老师不一致,然后确实精度不如老师的版本??(这里不同层的参数设置 还要好好研究一番)
问题来了?我后来又对CNN网络进行了手势识别训练(10分类),精度不如车牌识别(65分类)?怎么肥事??!!
类别数越少10 < 65,训练精度测试不应该更高么?别给我说模型过拟合(不信!!!)
然后陷入模型层的调参过程中,无果……
以为是简简单单二分类,准确率随随便便90%+。可笑,我提前预习了内容,实现了我以为的VGG网络,参数不合适完蛋~精度0.7劝退!!
听了直播课,尝试了老师的版本,我加了自己的修改(参数、dropout层等),精度92%还不错
高潮来了:我又自己实现了一遍(未看老师的),全连接层那里没用Linear(),用了封装好的fc()精度0.9以下???!(生气!!!)
助教解答:参数不合适,模型过拟合?(我不服!!除了全连接层实现,所有的参数是一样的) 摊手.jpg
此题还是没解决(有点伤心)
baseline调参:batch_size 设置8一次处理8张图片,learning_rate 设置 5 * 1e-4,优化器AdamOptimizer(别的貌似效果不好,很疑惑,但是不知缘由?这是一个问题)
迭代次数设置高一些,能得到一个不错的分数(嘻嘻~)。但代价是训练时间比较长(可以理解~)
这一天知识比较偏学术,感觉学习深入可以解决很多问题,发好的paper~(可惜从来没研究过这一块内容,大哭!!!)
PaddleSlim文档
第一次接触cv感觉还不错?学到了PaddlePaddle框架下新的训练方式,自己动手写了好些code,总体收获还是不错的!
我何时也能成为像晓曼老师那样的大牛呢(大哭)