第一天的作业主要是pyechart的使用,在给出的示例代码中已经给出了爬取疫情数据的代码。在作业中只需要补全pyecharts绘制饼状图的代码,查询pyecharts中关于饼状图绘制相关示例,很容易给出代码,这里需要注意的点在于数据过于密集,按照默认设置图片上半部分显示不出来,需要将图片下移。
import json
import datetime
from pyecharts import options as opts
from pyecharts.charts import Pie
# 读原始数据文件
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]
c = (
Pie()
.add(
"",
[list(z) for z in zip(labels, counts)],
center=["35%", "60%"],
radius=["0%", "40%"],
)
.set_global_opts(title_opts=opts.TitleOpts(title='全国实时确诊数据',
subtitle='数据来源:丁香园'),
legend_opts=opts.LegendOpts(is_show=False))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"),
is_show=False)
.render(path='/home/aistudio/data/全国实时确诊数据饼图.html')
)
这个作业是一个图像分类问题,需要手动设计一个网络来实现分类。这次的作业我尝试了LeNet、AlexNet以及仿照VGGNet尝试小卷积核多层卷积的架构,最终的效果都不是很高,在测试集上最高的准确率是92%,最后提交了一个简单点的网络,最终评分87分。这次作业中有一些同学达到99+%的准确率,采用的是如AlexNet这样的网络,所以可能在调优技巧上有一些技巧我没有get到。。。
#定义DNN网络
class MyDNN(fluid.dygraph.Layer):
def __init__(self):
super(MyDNN,self).__init__()
self.conv1 = Conv2D(num_channels=3, num_filters=64, filter_size=5,stride=2,padding=2, act='relu')
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=64, num_filters=64, filter_size=4,padding=1,act='relu')
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
# 创建第3个卷积层
#self.conv3 = Conv2D(num_channels=64, num_filters=64, filter_size=4, act='relu')
# 创建全连接层,第一个全连接层的输出神经元个数为64, 第二个全连接层输出神经元个数为分裂标签的类别数
self.fc1 = Linear(input_dim=12*12*64, output_dim=64, act='relu')
self.fc2 = Linear(input_dim=64, output_dim=10,act='softmax')
def forward(self,input):
x = self.conv1(input)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = fluid.layers.dropout(x, dropout_prob=0.5)
#x = self.conv3(x)
#batch_norm = fluid.BatchNorm(64)
#x = batch_norm(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = self.fc1(x)
x = self.fc2(x)
return x
opt=fluid.optimizer.AdamOptimizer(learning_rate=0.001,parameter_list=model.parameters())
epochs_num=80 #迭代次数
车牌识别这个任务事实上比Day 2的手势识别简单,因为图像较为简单,采用可以完成手写数字辨识的LeNet便可以完成这个任务。最终准确率98%。
#定义网络
class MyLeNet(fluid.dygraph.Layer):
def __init__(self):
super(MyLeNet,self).__init__()
self.conv1 = Conv2D(num_channels=1, num_filters=20, filter_size=5, stride=1, padding=2, act='relu')
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=20, num_filters=20, filter_size=5, stride=1, padding=2, act='relu')
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.fc = Linear(input_dim=20*5*5, output_dim=65, act='softmax')
def forward(self,input):
y = self.conv1(input)
y = self.pool1(y)
y = self.conv2(y)
y = self.pool2(y)
y = fluid.layers.reshape(y, [y.shape[0], -1])
y = self.fc(y)
return y
opt=fluid.optimizer.AdamOptimizer(learning_rate=0.001,parameter_list=model.parameters())
epochs_num= 30
同样是分类问题,使用VGG16网络即可,这里网络的实现使用sublayers,可以使代码更加简洁。这次我发现对于这个任务,momentum优化器的效果较好,Adam不太行,可能使因为这是个二分类问题,所以使用Adam算法容易陷入局部最优。撞了大运,最终的准确率100%。
class ConvPool(fluid.dygraph.Layer):
'''卷积+池化'''
def __init__(self,
num_channels,
num_filters,
groups,
filter_size=3,
pool_size=2,
pool_stride=2,
pool_padding=0,
pool_type='max',
conv_stride=1,
conv_padding=1,
acti='relu'):
super(ConvPool, self).__init__()
self._conv2d_list = []
for i in range(groups):
conv2d = self.add_sublayer( #返回一个由所有子层组成的列表。
'bb_%d' % i,
fluid.dygraph.Conv2D(
num_channels=num_channels, #通道数
num_filters=num_filters, #卷积核个数
filter_size=filter_size, #卷积核大小
stride=conv_stride, #步长
padding=conv_padding, #padding大小,默认为0
act=acti)
)
num_channels=num_filters
self._conv2d_list.append(conv2d)
self._pool2d = fluid.dygraph.Pool2D(
pool_size=pool_size, #池化核大小
pool_type=pool_type, #池化类型,默认是最大池化
pool_stride=pool_stride, #池化步长
pool_padding=pool_padding #填充大小
)
def forward(self, inputs):
x = inputs
for conv in self._conv2d_list:
x = conv(x)
x = self._pool2d(x)
return x
class VGGNet(fluid.dygraph.Layer):
'''
VGG网络
'''
def __init__(self):
super(VGGNet, self).__init__()
conv_arch=((2, 64), (2, 128), (3, 256), (3, 512), (3, 512))
self.vgg_blocks=[]
iter_id = 0
in_channels = [3, 64, 128, 256, 512, 512]
for (num_convs, num_channels) in conv_arch:
block = self.add_sublayer('block_'+str(iter_id),ConvPool(in_channels[iter_id],num_channels,num_convs))
#block = self.add_sublayer('block_' + str(iter_id),
# vgg_block(num_convs, in_channels=in_channels[iter_id],
# out_channels=num_channels))
self.vgg_blocks.append(block)
iter_id += 1
self.fc1 = Linear(input_dim=512*7*7, output_dim=4096,
act='relu')
self.drop1_ratio = 0.5
self.fc2= Linear(input_dim=4096, output_dim=4096,
act='relu')
self.drop2_ratio = 0.5
self.fc3 = Linear(input_dim=4096, output_dim=2,act='softmax')
def forward(self, inputs,label=None):
"""前向计算"""
x = inputs
for item in self.vgg_blocks:
x = item(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = fluid.layers.dropout(self.fc1(x), self.drop1_ratio)
x = fluid.layers.dropout(self.fc2(x), self.drop2_ratio)
x = self.fc3(x)
if (label is None):
return x
else:
acc=fluid.layers.accuracy(x,label)
return x,acc
optimizer = fluid.optimizer.Momentum(learning_rate=train_parameters['learning_strategy']['lr'],
momentum=train_parameters['learning_strategy']['momentum'],parameter_list=vgg.parameters())
再次陷入调优调不出来的困境,运行了提供的CSRNet的范本,但是发现最终给处的结果基本会停在一个稳定的输出,比如输入一张图像,输出基本是8个人,说明训练没有收敛。估计需要在VGG16预训练模型的基础上fintune效果会好一点,但是paddlehub的用法和torchvision不太一样,所以还需要学习一下怎么加载预训练模型,容后尝试。。。。。
看了比赛的结果说明,发现大佬们的思路开阔的多,基于回归以及目标检测的方法也有使用,后悔吊死在密度图这条路上。。。。
paddleslim实现模型压缩确实非常简便,作业的代码在看完官方文档后很容易写出。
quant_program = slim.quant.quant_aware(train_program, exe.place, for_test=False) #请在次数添加你的代码
val_quant_program = slim.quant.quant_aware(val_program, exe.place, for_test=True) #请在次数添加你的代码
这次一星期的学习,总的来说paddlepaddle算是入了门,作业里关于数据读取,网络构建,模型训练,准确率评估的代码有很多可以复制来使用。同时超参数调节确实需要一定的经验,需要多尝试,找经验。