百度深度学习CV7日-Day02-手势识别

若该文为原创文章,未经允许不得转载
QQ: 627833006
Email: [email protected]
微信:Abner程
CSDN博客地址:https://blog.csdn.net/weixin_46718879
Gitee代码存储:https://gitee.com/abnerwork/python.git

目录

  • 1.概述
  • 2.DNN结构
  • 3.代码分析
  • 3.后续

1.概述

本文主要使用DNN网络,来进行手势识别。
本文使用百度提供的动态图方法来对训练集进行训练。

2.DNN结构

百度深度学习CV7日-Day02-手势识别_第1张图片
每层输入输出的计算过程:
百度深度学习CV7日-Day02-手势识别_第2张图片

3.代码分析

从已有的数据集中,先打散图片,随机训练。
代码中定义DNN网络结构,实际训练参数需要调整!!!!!
从最终来看该网络训练评分并不高,但是代码能很好的说明第二章中提到的输入->隐藏层->输出的流程。

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


# 生成图像列表
data_path = 'C:/chengyang/workspace/python/Day02/data/Dataset'
character_folders = os.listdir(data_path)
# print(character_folders)
if(os.path.exists('C:/chengyang/workspace/python/Day02/data//train_data.list')):
    os.remove('C:/chengyang/workspace/python/Day02/data/train_data.list')
if(os.path.exists('C:/chengyang/workspace/python/Day02/data/test_data.list')):
    os.remove('C:/chengyang/workspace/python/Day02/data/test_data.list')


for character_folder in character_folders:


    with open('C:/chengyang/workspace/python/Day02/data/train_data.list', 'a') as f_train:
        with open('C:/chengyang/workspace/python/Day02/data/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('列表已生成')


# 定义训练集和测试集的reader
def data_mapper(sample):
    img, label = sample
    img = Image.open(img)
    img = img.resize((100, 100), 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)


# 用于训练的数据提供器
train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=data_reader('C:/chengyang/workspace/python/Day02/data/train_data.list'), buf_size=256), batch_size=32)
# 用于测试的数据提供器
test_reader = paddle.batch(reader=data_reader('C:/chengyang/workspace/python/Day02/data/test_data.list'), batch_size=32)


#定义DNN网络  核心部分, 该代码只是实例 DNN网络结构,实际训练参数需要调整!!!!!
class MyDNN(fluid.dygraph.Layer):
    def __init__(self):
        super(MyDNN,self).__init__()
        ## 疑问:
        # 第一层的输入是100, 输出是100, 但是实际图像是3*100*100,这中间具体是怎么运算的?
        self.hidden1 = Linear(input_dim = 100, output_dim = 100, act='relu')
        self.hidden2 = Linear(input_dim = 100, output_dim = 100, act='relu')
        self.hidden3 = Linear(input_dim = 100, output_dim = 100, act='relu')
        self.hidden4 = Linear(input_dim = 3*100*100, output_dim = 4096, act='relu')
        self.hidden5 = Linear(input_dim = 4096, output_dim = 10, act='softmax')
    def forward(self,input):
        # print('input = ', format(input.shape))
        y1 = self.hidden1(input)
        # print('y1 = ', format(y1.shape))
        y2 = self.hidden2(y1)
        # print('y2 = ', format(y2.shape))
        y3 = self.hidden3(y2)
        # print('y3 = ', format(y3.shape))
        y4 = fluid.layers.reshape(y3, [-1, 3*100*100])
        # print('y4 = ', format(y4.shape))
        y5 = self.hidden4(y4)
        # print('y = ', format(y.shape))
        y = self.hidden5(y5)
        return y


#用动态图进行训练
with fluid.dygraph.guard():
    model=MyDNN() #模型实例化
    model.train() #训练模式
    opt=fluid.optimizer.SGDOptimizer(learning_rate=0.01, parameter_list=model.parameters())#优化器选用SGD随机梯度下降,学习率为0.001.


    epochs_num=50 #迭代次数


    for pass_num in range(epochs_num):


        for batch_id,data in enumerate(train_reader()):


            images=np.array([x[0].reshape(3,100,100) for x in data],np.float32)
            # print('images = ', format(images.shape))


            labels = np.array([x[1] for x in data]).astype('int64')
            labels = labels[:, np.newaxis]
            # print('labels = ', format(labels.shape))
            # print(images.shape)
            # 注意:该API仅支持【动态图】模式
            # 该函数实现从numpy.ndarray对象或者Variable对象创建一个 Variable 类型的对象。
            # https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/dygraph_cn/to_variable_cn.html
            image=fluid.dygraph.to_variable(images)
            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)
            model.clear_gradients()


    fluid.save_dygraph(model.state_dict(),'MyDNN')#保存模型


#模型校验
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,100,100) 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)


#读取预测图像,进行预测


def load_image(path):
    img = Image.open(path)
    img = img.resize((100, 100), Image.ANTIALIAS)
    img = np.array(img).astype('float32')
    img = img.transpose((2, 0, 1))
    img = img/255.0
    print(img.shape)
    return img


#构建预测动态图过程
with fluid.dygraph.guard():
    infer_path = 'C:/chengyang/workspace/python/Day02/手势.JPG'
    model=MyDNN()#模型实例化
    model_dict,_=fluid.load_dygraph('MyDNN')
    model.load_dict(model_dict)#加载模型参数
    model.eval()#评估模式
    infer_img = load_image(infer_path)
    infer_img=np.array(infer_img).astype('float32')
    infer_img=infer_img[np.newaxis,:, : ,:]
    infer_img = fluid.dygraph.to_variable(infer_img)
    result=model(infer_img)
    # display(Image.open('手势.JPG'))
    print(np.argmax(result.numpy()))

3.后续

该实验,只是为了了解DNN,为后续的CNN学习做铺垫。
DNN的学习过程中,留下了很多疑问!!!!!!!
比如:DNN的网络结构调整方法。
比如:DNN的训练流程如果调整参数,优化器的选择等等!!!!
道路艰险,还需努力学习!!!
但是通过学习DNN,也是第一次完整的把训练加测试的流程走完一遍。

你可能感兴趣的:(百度深度学习7日CV课程,paddlepaddle)