百度AI Studio首頁https://aistudio.baidu.com/aistudio/index
一、課程評價
1、每日課程分為理論部分和實踐部分,課程內(nèi)容由淺至深,循序漸進。每次課后都有作業(yè),用以鞏固課上所學(xué)的知識,親自上手搭建網(wǎng)絡(luò),調(diào)整參數(shù),不斷提高準(zhǔn)確率,滿滿的成就感。
2、課程微信群學(xué)習(xí)氛圍濃郁,班班和助教們都很專業(yè),幾乎所有的問題發(fā)到群里后,很快就能得到班班,助教和同學(xué)們的幫助。
3、免費,完全免費,paddlepaddle為每位同學(xué)承擔(dān)1699元/人學(xué)費,每天運行AI Studio項目就能獲得12小時免費GPU資源(Tesla V100),連續(xù)5天還能額外獲得48小時,完全就是白嫖啊。
4、獎勵多多,完成作業(yè)+打比賽就可以獲得結(jié)業(yè)證書,還有小度音響、小度在家、深度學(xué)習(xí)書籍等各種獎勵。
二、課程內(nèi)容
Day 1:新冠疫情可視化
1、本地安裝PaddlePaddle:https://www.paddlepaddle.org.cn/documentation/docs/zh/install/index_cn.html
2、使用Pyecharts進行全國疫情實時數(shù)據(jù)
#安裝pyecharts
#pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyecharts
import json
import datetime
from pyecharts.charts import Map
from pyecharts import options as opts
from pyecharts.charts import Pie
# 讀原始數(shù)據(jù)文件
today = datetime.date.today().strftime('%Y%m%d') #20200315
datafile = 'work/'+ today + '.json'
with open(datafile, 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())
# 分析全國實時確診數(shù)據(jù):'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]
data_pair = [list(z) for z in zip(labels, counts)]
pie = Pie(init_opts=opts.InitOpts(width='900px',height='500px'))
pie.add(
series_name="新冠病例統(tǒng)計",
data_pair=data_pair,
radius="55%",
center=["30%", "70%"],
label_opts=opts.LabelOpts(is_show=False,position="center")).set_global_opts(
title_opts=opts.TitleOpts(title='全國實時確診數(shù)據(jù)',subtitle='數(shù)據(jù)來源:丁香園 '),
legend_opts=opts.LegendOpts(is_show=False),).set_series_opts(
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>: {c} (u0z1t8os%)"),
label_opts=opts.LabelOpts(formatter=": {c}",
)
)
pie.render(path='/home/aistudio/work/pie.html')

Day 2:手勢識別
DNN網(wǎng)絡(luò)結(jié)構(gòu)(經(jīng)過N次訓(xùn)練后,測試集準(zhǔn)確率為0.982)
數(shù)據(jù)集地址:
https://aistudio.baidu.com/aistudio/datasetdetail/2182
#定義DNN網(wǎng)絡(luò)
class MyDNN(fluid.dygraph.Layer):
def __init__(self):
super(MyDNN,self).__init__()
self.conv1 = Conv2D(num_channels=3,num_filters=6,filter_size=2,stride=2,act='relu')
self.pool1 = Pool2D(pool_size=2,pool_type='max',pool_stride=2)
self.conv2 = Conv2D(num_channels=6,num_filters=16,filter_size=3,stride=2,act='relu')
self.pool2 = Pool2D(pool_size=2,pool_type='max',pool_stride=2)
self.linear1 = Linear(16*6*6,256,act='relu')
self.linear2 = Linear(256,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.reshape(x,shape=[-1,16*6*6])
x = self.linear1(x)
x = fluid.layers.dropout(x,dropout_prob=0.7)
y = self.linear2(x)
return y

Day 3:車牌識別
CNN網(wǎng)絡(luò)結(jié)構(gòu)(經(jīng)過N次訓(xùn)練后,測試集準(zhǔn)確率為0.978)
數(shù)據(jù)集地址:
https://aistudio.baidu.com/aistudio/datasetdetail/23617
#定義網(wǎng)絡(luò)
class MyLeNet(fluid.dygraph.Layer):
def __init__(self):
super(MyLeNet,self).__init__()
self.hidden1_1 = Conv2D(num_channels=1,num_filters=28,filter_size=5,stride=1,act='relu')
self.hidden1_2 = Pool2D(2,pool_type='max',pool_stride=1)
self.hidden2_1 = Conv2D(num_channels=28,num_filters=32,filter_size=3,stride=1,act='relu')
self.hidden2_2 = Pool2D(2,pool_type='max',pool_stride=1)
self.hidden3 = Conv2D(num_channels=32,num_filters=32,filter_size=3,stride=1,act='relu')
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

Day 4:口罩分類
VGG16網(wǎng)絡(luò)結(jié)構(gòu)(準(zhǔn)確率為1.0)
數(shù)據(jù)集地址:
https://aistudio.baidu.com/aistudio/datasetdetail/22392
https://aistudio.baidu.com/aistudio/datasetdetail/23615
class ConvPool(fluid.dygraph.Layer):
'''卷積+池化'''
def __init__(self,
num_channels,
num_filters,
filter_size,
pool_size,
pool_stride,
groups,
pool_padding=0,
pool_type='max',
conv_stride=1,
conv_padding=0,
act=None):
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[i], #通道數(shù)
num_filters=num_filters, #卷積核個數(shù)
filter_size=filter_size, #卷積核大小
stride=conv_stride, #步長
padding=conv_padding, #padding大小,默認為0
act=act)
)
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網(wǎng)絡(luò)
'''
def __init__(self):
super(VGGNet, self).__init__()
self.c2p1_64 = ConvPool(num_channels=[3,64],num_filters=64,filter_size=3,pool_size=2,pool_stride=2,groups=2,conv_stride=1,conv_padding=1,act='relu')
self.c2p2_128 = ConvPool(num_channels=[64,128],num_filters=128,filter_size=3,pool_size=2,pool_stride=2,groups=2,conv_stride=1,conv_padding=1,act='relu')
self.c3p3_256 = ConvPool(num_channels=[128,256,256],num_filters=256,filter_size=3,pool_size=2,pool_stride=2,groups=3,conv_stride=1,conv_padding=1,act='relu')
self.c3p4_512 = ConvPool(num_channels=[256,512,512],num_filters=512,filter_size=3,pool_size=2,pool_stride=2,groups=3,conv_stride=1,conv_padding=1,act='relu')
self.c3p5_512 = ConvPool(num_channels=[512,512,512],num_filters=512,filter_size=3,pool_size=2,pool_stride=2,groups=3,conv_stride=1,conv_padding=1,act='relu')
self.linear1 = fluid.dygraph.Linear(512*7*7,4096,act='relu')
self.linear2 = fluid.dygraph.Linear(4096,4096,act='relu')
self.linear3 = fluid.dygraph.Linear(4096,2,act='softmax')
def forward(self, inputs):
"""前向計算"""
x = self.c2p1_64(inputs)
x = self.c2p2_128(x)
x = self.c3p3_256(x)
x = self.c3p4_512(x)
x = self.c3p5_512(x)
x = fluid.layers.reshape(x,shape=[-1,512*7*7])
x = self.linear1(x)
x = fluid.layers.dropout(x,dropout_prob=0.5)
x = self.linear2(x)
x = fluid.layers.dropout(x,dropout_prob=0.5)
y = self.linear3(x)
return y

Day 5:PaddleHub體驗
【比賽】人流密度檢測
數(shù)據(jù)集地址:https://aistudio.baidu.com/aistudio/datasetdetail/1917
Day 6:PaddleSlim模型壓縮
PaddleSlim代碼地址: https://github.com/PaddlePaddle/PaddleSlim
文檔地址:https://paddlepaddle.github.io/PaddleSlim/
#安裝paddleslim
#pip install paddleslim
#1. 導(dǎo)入依賴
import paddle
import paddle.fluid as fluid
import paddleslim as slim
import numpy as np
#2. 構(gòu)建模型
#該章節(jié)構(gòu)造一個用于對MNIST數(shù)據(jù)進行分類的分類模型,選用MobileNetV1,并將輸入大小設(shè)置為[1, 28, 28],輸出類別數(shù)為10。 為了方便展示示例,我們在paddleslim.models下預(yù)定義了用于構(gòu)建分類模型的方法,執(zhí)行以下代碼構(gòu)建分類模型:
use_gpu = fluid.is_compiled_with_cuda()
exe, train_program, val_program, inputs, outputs = slim.models.image_classification("MobileNet", [1, 28, 28], 10, use_gpu=use_gpu)
place = fluid.CUDAPlace(0) if fluid.is_compiled_with_cuda() else fluid.CPUPlace()
#3 定義輸入數(shù)據(jù)
#為了快速執(zhí)行該示例,我們選取簡單的MNIST數(shù)據(jù),Paddle框架的paddle.dataset.mnist包定義了MNIST數(shù)據(jù)的下載和讀取。 代碼如下:
import paddle.dataset.mnist as reader
train_reader = paddle.batch(
reader.train(), batch_size=128, drop_last=True)
test_reader = paddle.batch(
reader.test(), batch_size=128, drop_last=True)
data_feeder = fluid.DataFeeder(inputs, place)
#4. 訓(xùn)練和測試
#先定義訓(xùn)練和測試函數(shù),正常訓(xùn)練和量化訓(xùn)練時只需要調(diào)用函數(shù)即可。在訓(xùn)練函數(shù)中執(zhí)行了一個epoch的訓(xùn)練,因為MNIST數(shù)據(jù)集數(shù)據(jù)較少,一個epoch就可將top1精度訓(xùn)練到95%以上。
def train(prog):
iter = 0
for data in train_reader():
acc1, acc5, loss = exe.run(prog, feed=data_feeder.feed(data), fetch_list=outputs)
if iter % 100 == 0:
print('train iter={}, top1={}, top5={}, loss={}'.format(iter, acc1.mean(), acc5.mean(), loss.mean()))
iter += 1
def test(prog):
iter = 0
res = [[], []]
for data in test_reader():
acc1, acc5, loss = exe.run(prog, feed=data_feeder.feed(data), fetch_list=outputs)
if iter % 100 == 0:
print('test iter={}, top1={}, top5={}, loss={}'.format(iter, acc1.mean(), acc5.mean(), loss.mean()))
res[0].append(acc1.mean())
res[1].append(acc5.mean())
iter += 1
print('final test result top1={}, top5={}'.format(np.array(res[0]).mean(), np.array(res[1]).mean()))
#調(diào)用train函數(shù)訓(xùn)練分類網(wǎng)絡(luò),train_program是在第2步:構(gòu)建網(wǎng)絡(luò)中定義的
train(train_program)
train iter=0, top1=0.0390625, top5=0.46875, loss=2.89760327339
train iter=100, top1=0.9296875, top5=0.9921875, loss=0.196367427707
train iter=200, top1=0.96875, top5=1.0, loss=0.125141501427
train iter=300, top1=0.9609375, top5=0.9921875, loss=0.158306568861
train iter=400, top1=0.9375, top5=1.0, loss=0.178206339478
#調(diào)用test函數(shù)測試分類網(wǎng)絡(luò),val_program是在第2步:構(gòu)建網(wǎng)絡(luò)中定義的。
test(val_program)
test iter=0, top1=0.9765625, top5=1.0, loss=0.0672305747867
final test result top1=0.962439894676, top5=0.998597741127
#5. 量化模型
#按照配置在train_program和val_program中加入量化和反量化op.
place = exe.place
# quant_program = #請在次數(shù)添加你的代碼
# val_quant_program = #請在次數(shù)添加你的代碼
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)
2020-04-05 21:52:28,981-INFO: quant_aware config {'moving_rate': 0.9, 'weight_quantize_type': 'channel_wise_abs_max', 'is_full_quantize': False, 'dtype': 'int8', 'weight_bits': 8, 'window_size': 10000, 'activation_bits': 8, 'quantize_op_types': ['conv2d', 'depthwise_conv2d', 'mul'], 'not_quant_pattern': ['skip_quant'], 'activation_quantize_type': 'moving_average_abs_max', 'for_tensorrt': False}
2020-04-05 21:52:30,032-INFO: quant_aware config {'moving_rate': 0.9, 'weight_quantize_type': 'channel_wise_abs_max', 'is_full_quantize': False, 'dtype': 'int8', 'weight_bits': 8, 'window_size': 10000, 'activation_bits': 8, 'quantize_op_types': ['conv2d', 'depthwise_conv2d', 'mul'], 'not_quant_pattern': ['skip_quant'], 'activation_quantize_type': 'moving_average_abs_max', 'for_tensorrt': False}
#6 訓(xùn)練和測試量化后的模型?
#微調(diào)量化后的模型,訓(xùn)練一個epoch后測試。
train(quant_program)
train iter=0, top1=0.96875, top5=1.0, loss=0.0995958149433
train iter=100, top1=0.96875, top5=1.0, loss=0.0631555095315
train iter=200, top1=0.96875, top5=1.0, loss=0.100415810943
train iter=300, top1=0.9921875, top5=0.9921875, loss=0.0579719617963
train iter=400, top1=0.953125, top5=1.0, loss=0.122109659016
#測試量化后的模型,和3.2 訓(xùn)練和測試中得到的測試結(jié)果相比,精度相近,達到了無損量化。
test(val_quant_program)
test iter=0, top1=0.984375, top5=1.0, loss=0.0304987411946
final test result top1=0.973056912422, top5=0.99919873476
三、心得體會
課程難度適中,作業(yè)提供baseline,降低了學(xué)習(xí)的難度。在作業(yè)中手寫了DNN,LeNet,VGG16等網(wǎng)絡(luò),并且通過修改網(wǎng)絡(luò)結(jié)構(gòu)和參數(shù)得到了較高的準(zhǔn)確率,是一次很好的實踐經(jīng)歷。在課程的學(xué)習(xí)中,對深度學(xué)習(xí)的一些概念有了更深的理解,實踐的經(jīng)驗對畢業(yè)設(shè)計也有很大幫助。例如可以通過dropout和正則化等方法解決過擬合問題;模型的準(zhǔn)確率不僅僅與網(wǎng)絡(luò)結(jié)構(gòu)有關(guān),還和batch_size,learning_rate等參數(shù)密不可分
四、PaddlePaddle打卡營預(yù)告
1、下一期打卡營
課程時間:4月22日
課程內(nèi)容:python和AI打卡營,適合無人工智能背景,無編程基礎(chǔ)、無學(xué)習(xí)氛圍、無計算資源又想好好學(xué)習(xí)、天天向上的純小白
課程簡介:基礎(chǔ)語法、進階運用、深度學(xué)習(xí)工具和paddlehub 創(chuàng)意賽
課程報名:關(guān)注飛槳PaddlePaddle公眾號
2、籌備中打卡營
1、論文復(fù)現(xiàn)營:以CV領(lǐng)域檢測任務(wù)、GAN、視頻分類等經(jīng)典方向的最新頂會論文(如,CVPR)為案例,介紹論文研讀、框架搭建、模型優(yōu)化等方面內(nèi)容,帶你進入科研大軍
2、競賽輔導(dǎo)營:以CV領(lǐng)域研究最應(yīng)用最廣的目標(biāo)檢測為題,講解目標(biāo)檢測兩階段(R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN、FPN、Mask-RCNN)和一階段方法(YOLO、SSD),介紹大賽的塞梯解讀、數(shù)據(jù)分析、模型選取、模型優(yōu)化、后處理調(diào)優(yōu)的方面經(jīng)驗知識