1 前言
?? 優(yōu)質(zhì)競賽項目系列,今天要分享的是
基于深度學(xué)習(xí)的手勢識別實現(xiàn)
該項目較為新穎,適合作為競賽課題方向,學(xué)長非常推薦!
?? 更多資料, 項目分享:文章來源:http://www.zghlxwxcb.cn/news/detail-726987.html
https://gitee.com/dancheng-senior/postgraduate文章來源地址http://www.zghlxwxcb.cn/news/detail-726987.html
2 項目背景
手勢識別在深度學(xué)習(xí)項目是算是比較簡單的。這里為了給大家會更好的訓(xùn)練。其中的數(shù)據(jù)集如下:
3 任務(wù)描述
圖像分類是根據(jù)圖像的語義信息將不同類別圖像區(qū)分開來,是計算機(jī)視覺中重要的基本問題。手勢識別屬于圖像分類中的一個細(xì)分類問題。雖然與NLP的內(nèi)容其實沒有多大的關(guān)系,但是作為深度學(xué)習(xí),DNN是一個最為簡單的深度學(xué)習(xí)的算法,它是學(xué)習(xí)后序CNN、RNN、Lstm以及其他算法深度學(xué)習(xí)算法的基礎(chǔ)。
實踐環(huán)境:Python3.7,PaddlePaddle1.7.0。
用的仍然是前面多次提到的jupyter notebook,當(dāng)然我們也可以用本地的pycharm。不過這里需要提醒大家,如果用的是jupyter
notebook作為試驗訓(xùn)練,在實驗中會占用很大的內(nèi)存,jupyter
notebook默認(rèn)路徑在c盤,時間久了,我們的c盤會內(nèi)存爆滿,希望我們將其默認(rèn)路徑修改為其他的路徑,網(wǎng)上有很多的修改方式,這里限于篇幅就不做說明了。這里需要給大家簡要說明:paddlepaddle是百度
AI Studio的一個開源框架,類似于我們以前接觸到的tensorflow、keras、caffe、pytorch等深度學(xué)習(xí)的框架。
4 環(huán)境搭配
首先在百度搜索paddle,選擇你對應(yīng)的系統(tǒng)(Windows、macOs、Ubuntu、Centos),然后選擇你的安裝方式(pip、conda、docker、源碼編譯),最后選擇python的版本(Python2、python3),但是一般選擇python3。
左后先則版本(GPU、CPU),但是后期我們用到大量的數(shù)據(jù)集,因此,我們需要下載GPU版本。,然后將該命令復(fù)制到cmd終端,點擊安裝,這里用到了百度的鏡像,可以加快下載安裝的速度。
?
python -m pip install paddlepaddle-gpu==1.8.3.post107 -i https://mirror.baidu.com/pypi/simple
學(xué)長電腦是window10系統(tǒng),用的是pip安裝方式,安裝的版本是python3,本人的CUDA版本是CUDA10,因此選擇的示意圖以及安裝命令如圖所示。這里前提是我們把GPU安裝需要的環(huán)境配好,網(wǎng)上有很多相關(guān)的
環(huán)境配好了,接下來就該項目實現(xiàn)。
5 項目實現(xiàn)
5.1 準(zhǔn)備數(shù)據(jù)
首先我們導(dǎo)入必要的第三方庫。
?
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
該數(shù)據(jù)集是學(xué)長自己收集標(biāo)注的數(shù)據(jù)集(目前較小):包含0-9共就種數(shù)字手勢,共2073張手勢圖片。
圖片一共有3100100張,格式均為RGB格式文件。在本次實驗中,我們選擇其中的10%作為測試集,90%作為訓(xùn)練集。通過遍歷圖片,根據(jù)文件夾名稱,生成label。
我按照1:9比例劃分測試集和訓(xùn)練集,生成train_list 和 test_list,具體實現(xiàn)如下:
?
data_path = '/home/aistudio/data/data23668/Dataset' # 這里填寫自己的數(shù)據(jù)集的路徑,windows的默認(rèn)路徑是\,要將其路徑改為/。
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('列表已生成')
其效果圖如圖所示:
這里需要簡單的處理圖片。需要說明一些函數(shù):
- data_mapper(): 讀取圖片,對圖片進(jìn)行歸一化處理,返回圖片和 標(biāo)簽。
- data_reader(): 按照train_list和test_list批量化讀取圖片。
- train_reader(): 用于訓(xùn)練的數(shù)據(jù)提供器,亂序、按批次提供數(shù)據(jù)
- test_reader():用于測試的數(shù)據(jù)提供器
具體的實現(xiàn)如下:
?
def data_mapper(sample):
img, label = sample
img = Image.open(img)
img = img.resize((32, 32), Image.ANTIALIAS)
img = np.array(img).astype('float32')
img = img.transpose((2, 0, 1))
img = img / 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(), 512)
5.2 構(gòu)建網(wǎng)絡(luò)
在深度學(xué)習(xí)中有一個關(guān)鍵的環(huán)節(jié)就是參數(shù)的配置,這些參數(shù)設(shè)置的恰當(dāng)程度直接影響這我們的模型訓(xùn)練的效果。
因此,也有特別的一個崗位就叫調(diào)參崗,專門用來調(diào)參的,這里是通過自己積累的經(jīng)驗來調(diào)參數(shù),沒有一定的理論支撐,因此,這一塊是最耗時間的,當(dāng)然也是深度學(xué)習(xí)的瓶頸。
接下來進(jìn)行參數(shù)的設(shè)置。
?
train_parameters = {
"epoch": 1, #訓(xùn)練輪數(shù)
"batch_size": 16, #批次大小
"lr":0.002, #學(xué)習(xí)率
"skip_steps":10, #每10個批次輸出一次結(jié)果
"save_steps": 30, #每10個批次保存一次結(jié)果
"checkpoints":"data/"
}
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)
前面也提到深度神經(jīng)網(wǎng)絡(luò)(Deep Neural Networks, 簡稱DNN)是深度學(xué)習(xí)的基礎(chǔ)。DNN網(wǎng)絡(luò)圖如圖所示:
首先定義一個神經(jīng)網(wǎng)絡(luò),具體如下
?
class MyLeNet(fluid.dygraph.Layer):
def __init__(self):
super(MyLeNet, self).__init__()
self.c1 = Conv2D(3, 6, 5, 1)
self.s2 = Pool2D(pool_size=2, pool_type='max', pool_stride=2)
self.c3 = Conv2D(6, 16, 5, 1)
self.s4 = Pool2D(pool_size=2, pool_type='max', pool_stride=2)
self.c5 = Conv2D(16, 120, 5, 1)
self.f6 = Linear(120, 84, act='relu')
self.f7 = Linear(84, 10, act='softmax')
def forward(self, input):
# print(input.shape)
x = self.c1(input)
# print(x.shape)
x = self.s2(x)
# print(x.shape)
x = self.c3(x)
# print(x.shape)
x = self.s4(x)
# print(x.shape)
x = self.c5(x)
# print(x.shape)
x = fluid.layers.reshape(x, shape=[-1, 120])
# print(x.shape)
x = self.f6(x)
y = self.f7(x)
return y
這里需要說明的是,在forward方法中,我們在每一步都給出了打印的print()函數(shù),就是為了方便大家如果不理解其中的步驟,可以在實驗中進(jìn)行打印,通過結(jié)果來幫助我們進(jìn)一步理解DNN的每一步網(wǎng)絡(luò)構(gòu)成。
5.3 開始訓(xùn)練
接下來就是訓(xùn)練網(wǎng)絡(luò)。
為了方便我觀察實驗中訓(xùn)練的結(jié)果,學(xué)長引入了matplotlib第三方庫,直觀的通過圖來觀察我們的訓(xùn)練結(jié)果,具體訓(xùn)練網(wǎng)絡(luò)代碼實現(xiàn)如下:
?
import matplotlib.pyplot as plt
Iter=0
Iters=[]
all_train_loss=[]
all_train_accs=[]
def draw_train_process(iters,train_loss,train_accs):
title='training loss/training accs'
plt.title(title,fontsize=24)
plt.xlabel('iter',fontsize=14)
plt.ylabel('loss/acc',fontsize=14)
plt.plot(iters,train_loss,color='red',label='training loss')
plt.plot(iters,train_accs,color='green',label='training accs')
plt.legend()
plt.grid()
plt.show()
with fluid.dygraph.guard():
model = MyLeNet() # 模型實例化
model.train() # 訓(xùn)練模式
opt = fluid.optimizer.SGDOptimizer(learning_rate=0.01,
parameter_list=model.parameters()) # 優(yōu)化器選用SGD隨機(jī)梯度下降,學(xué)習(xí)率為0.001.
epochs_num = 250 # 迭代次數(shù)
for pass_num in range(epochs_num):
for batch_id, data in enumerate(train_reader()):
images = np.array([x[0].reshape(3, 32, 32) 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) # 預(yù)測
# print(predict)
loss = fluid.layers.cross_entropy(predict, label)
avg_loss = fluid.layers.mean(loss) # 獲取loss值
acc = fluid.layers.accuracy(predict, label) # 計算精度
Iter += 32
Iters.append(Iter)
all_train_loss.append(loss.numpy()[0])
all_train_accs.append(acc.numpy()[0])
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') # 保存模型
draw_train_process(Iters, all_train_loss, all_train_accs)
訓(xùn)練過程以及結(jié)果如下:
前面提到強(qiáng)烈建議大家安裝gpu版的paddle框架,因為就是在訓(xùn)練過程中,paddle框架會利用英偉達(dá)的GP加速,訓(xùn)練的速度會很快的,而CPU則特別的慢。因此,CPU的paddle框架只是在學(xué)習(xí)的時候還可以,一旦進(jìn)行訓(xùn)練,根本不行。
可能GPU需要幾秒的訓(xùn)練在CPU可能需要十幾分鐘甚至高達(dá)半個小時。其實不只是paddlepaddle框架建議大家安裝GPU版本,其他的類似tensorflow、keras、caffe等框架也是建議大家按安裝GPU版本。不過安裝起來比較麻煩,還需要大家認(rèn)真安裝。
?
with fluid.dygraph.guard():
accs = []
model_dict, _ = fluid.load_dygraph('MyLeNet')
model = MyLeNet()
model.load_dict(model_dict) # 加載模型參數(shù)
model.eval() # 訓(xùn)練模式
for batch_id, data in enumerate(test_reader()): # 測試集
images = np.array([x[0].reshape(3, 32, 32) 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)
5.4 模型評估
配置好了網(wǎng)絡(luò),并且進(jìn)行了一定的訓(xùn)練,接下來就是對我們訓(xùn)練的模型進(jìn)行評估,具體實現(xiàn)如下:
結(jié)果還可以,這里說明的是,剛開始我們的模型訓(xùn)練評估不可能這么好,可能存在過擬合或者欠擬合的問題,不過更常見的是過擬合,這就需要我們調(diào)整我們的epoch、batchsize、激活函數(shù)的選擇以及優(yōu)化器、學(xué)習(xí)率等各種參數(shù),通過不斷的調(diào)試、訓(xùn)練最好可以得到不錯的結(jié)果,但是,如果還要更好的模型效果,其實可以將DNN換為更為合適的CNN神經(jīng)網(wǎng)絡(luò)模型,效果就會好很多,關(guān)于CNN的相關(guān)知識以及實驗,我們下篇文章在為大家介紹。最后就是我們的模型的預(yù)測。
6 識別效果
7 最后
?? 更多資料, 項目分享:
https://gitee.com/dancheng-senior/postgraduate
到了這里,關(guān)于計算機(jī)競賽 題目:基于深度學(xué)習(xí)的手勢識別實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!