paddle第一周学习心得
Paddle第一周学习心得
深度学习案例(一)
这是我参加百度课程《百度架构师手把手带你零基础实践深度学习
》的第二个案例。
案例介绍
本案例为构建一个简单的手写数字识别模型。即构建模型用于识别数据集mnist中的手写数字(0、1、2、3…9),并通过调节模型中的学习率、优化器、隐藏层数等来改变模型对手写数字识别的准确率。
在本文案例中很多地方会让你觉得雨里雾里的,这是非常正常的,在参加这门课程时,我在学习中反反复复看了老师们提供的文案和视频教程,在结合百度搜索,反复练习课程中提供的案例,一点一点的吸收课程中的知识。
案例中的数据集:链接: mnist数据集. 密码:lhf8
环境配置
python环境 python3任意版本,反正我是用最高版本的
我使用的pycharm编写代码,代码中的第三方库在pycharm中均可安装,本次案例用到的第三方库有:numpy、matplotlib、paddle这三个,其它的在调试过程中根据需要进行安装,安装这一块网上有不少教程,这一部分就不进行过多的展开,通过搜素引擎检索知识是作为程序员的必备经验,大家加油吧。
模型构建
基本结构:导入模块——数据加载——训练配置——训练过程——保存模型
导入模块
import random # python中的随机数模块 import paddle # paddle深度学习框架包,可以不导入 import paddle.fluid as fluid # paddle深度学习框架包中的一个模块 from paddle.fluid.dygraph.nn import Conv2D,Pool2D,Linear # paddle框架中的卷积层、池化层、线性变化 import numpy as np # 强大的第三方运算库 import matplotlib.pyplot as plt # 绘图工具,可以不导入 import gzip # 解压工具 import json # 文件读取
数据加载
# 传入参数为train、valid、test,分别用于加载训练集、验证集和测试集 def load_data(mode = 'train'): # 数据集路径,与.py文件放在同一文件夹下 datafile = 'mnist.json.gz' # 解压数据集并加载数据 data = json.load(gzip.open(datafile)) # 数据集中含有70000张图片,训练集50000张、验证集10000张、测试集10000张 train_data,val_data,test_data = data if mode == 'train': # 当传入参数为“train”时, images_data,images_label = train_data[0],train_data[1] elif mode == 'valid': # 当传入参数为“valid”时 images_data,images_label = val_data[0],val_data[1] elif mode == 'test': # 当传入参数为“test”时 images_data,images_label = test_data[0],test_data[1] # 获取图片的数量,数据集信息可用np.array().shape获取 image_len = len(images_data) # 图片由(-1,1)之间的数字组成,因此图片又被称为数字图像 # 图片行数 IMAGE_ROW = 28 # 图片列数 IMAGE_COL = 28 # 模型每次读取数据集个数 BATCH_NUM = 100 # 图片编号,构建(0,1,2....image_len-1)相对于为每张图片进行编号,从0开始 index_list = list(range(image_len)) # 数据读取 def data_generator(): if mode == 'train': # 乱序,打乱图片顺序 random.shuffle(index_list) # 建立一个用来存储图片的空list image_list = [] # 建立一个用来存储标签的空list label_list = [] # 遍历数据集 for i in index_list: # 加载第i个数据集中的图片,并对其重新排列 image = np.reshape(images_data[i],[1,IMAGE_ROW,IMAGE_COL]).astype('float32') # 加载第i个数据集中的标签,并对其重新排列 label = np.reshape(images_label[i],[1]).astype('int64') # 将加载进来的图片存入list中 image_list.append(image) # 将加载进来的标签存入list中 label_list.append(label) # 当list中的个数为100个时,将数据集进行返回 if len(image_list) == BATCH_NUM: # yield用于分批读取数据用于减少计算机负担 yield np.array(image_list),np.array(label_list) # 清空图片list和标签list image_list = [] label_list = [] # 将剩余不足100个的数据集进行返回 if len(image_list) > 0: yield np.array(image_list),np.array(label_list) return data_generator
构建模型结构
下面来构建模型的内部结构,该模型有输入层——隐藏层——输出层组成,其中隐藏层结构为卷积层(Conv2D)——池化层(Pool2D)——(Conv2D)——池化层(Pool2D)——全连接层(Linear)
class MNIST(fluid.dygraph.Layer): def __init__(self): super(MNIST,self).__init__() # 第一层卷积神经网络,num_channel输入通道(深度)为1,num_filters输出通道(深度)为20,filter_size卷积核大小5*5,stride步长(卷积核每次移动格子数),padding边界补充2(图片周围补两圈0),激活函数relu self.conv1 = Conv2D(num_channels=1,num_filters=20,filter_size=5,stride=1,padding=2,act='relu') # 第一层池化层,pool_size池化核(类似于卷积核)大小2,pool_stride步长2,pool_type类型max,每次获取池化后最大数据 self.pool1 = Pool2D(pool_size=2,pool_stride=2,pool_type='max') # 第二层卷积神经网络,num_channel输入通道(深度)为1,num_filters输出通道(深度)为20,filter_size卷积核大小5*5,stride步长(卷积核每次移动格子数),padding边界补充2(图片周围补两圈0),激活函数relu self.conv2 = Conv2D(num_channels=20,num_filters=20,filter_size=5,stride=1,padding=2,act='relu') # 第二层池化层,pool_size池化核(类似于卷积核)大小2,pool_stride步长2, self.pool2 = Pool2D(pool_size=2,pool_stride=2,pool_type='max') # 全连接层,input_dim输入维度980,输出维度10,激活函数softmax self.fc = Linear(input_dim=980,output_dim=10,act='softmax') def forward(self,data_image,data_label,check_data=False,check_content=False): # 输入数据data_image维度(100,1,28,28) # 输出conv1维度(100,20,28,28) conv1 = self.conv1(data_image) # 输入数据conv1维度(100,20,28,28) # 输出pool1维度(100,20,14,14) pool1 = self.pool1(conv1) # 输入数据pool1维度(100,20,14,14) # 输出conv2维度(100,20,14,14) conv2 = self.conv2(pool1) # 输入数据conv2维度(100,20,14,14) # 输出pool2维度(100,20,7,7) pool2 = self.pool2(conv2) # 重新排列pool # 输入数据pool2维度(100,20,7,7) # 输出_pool2维度(100,20*7*7)=(100,980) _pool2 = fluid.layers.reshape(pool2,[pool2.shape[0],-1]) # 输入数据_pool2维度(100,980) # 输出output维度(100,10) output = self.fc(_pool2) # 对应识别数据和真实数据,计算识别数据的准确率 if data_label is not None: acc = fluid.layers.accuracy(input=output,label=data_label) return output,acc else: return output
训练配置
# 获取训练集数据 train_loader = load_data('train') use_gpu = False # 模型运行时使用cpu或gpu进行计算 place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace() # paddle框架的起点 with fluid.dygraph.guard(place): # 调用模型构建部分写的MNIST类 model = MNIST() # 训练模型 model.train() # 常见优化器,任选其一,通过使用不同的优化器,调整不同优化器的学习率,使得模型识别时有不同的效果。 optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.01, parameter_list=model.parameters()) #optimizer = fluid.optimizer.MomentumOptimizer(learning_rate=0.01, momentum=0.9, parameter_list=model.parameters()) #optimizer = fluid.optimizer.AdagradOptimizer(learning_rate=0.01, parameter_list=model.parameters()) #optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.01, parameter_list=model.parameters())
训练过程
EPOCH_NUM = 1 for epoch_id in range(EPOCH_NUM): for batch_id, data in enumerate(train_loader()): # 获取数据集中图片和标签, images_data,labels_data = data # 将数据集中图片和标签类型转换成paddle框架中数据对应类型 images = fluid.dygraph.to_variable(images_data) labels = fluid.dygraph.to_variable(labels_data) # 训练模型,并返回预测结果和预测准确率 predict,acc = model(images,labels) # 计算交叉熵损失函数 loss = fluid.layers.cross_entropy(predict,labels) # 损失函数求平均 avg_loss = fluid.layers.mean(loss) if batch_id % 200 == 0: print("epoch: {}, batch: {}, loss is: {}, acc is {}".format(epoch_id, batch_id, avg_loss.numpy(), acc.numpy())) # 梯度下降(反向传递) avg_loss.backward() # 优化 optimizer.minimize(avg_loss) # 梯度归零 model.clear_gradients()
保存模型
fluid.save_dygraph(model.state_dict(),'mnist_acc')
完成代码
import random import paddle.fluid as fluid from paddle.fluid.dygraph.nn import Conv2D,Pool2D,Linear import numpy as np import gzip import json def load_data(mode = 'train'): datafile = 'mnist.json.gz' data = json.load(gzip.open(datafile)) train_data,val_data,test_data = data if mode == 'train': images_data,images_label = train_data[0],train_data[1] elif mode == 'valid': images_data,images_label = val_data[0],val_data[1] elif mode == 'test': images_data,images_label = test_data[0],test_data[1] image_len = len(images_data) IMAGE_ROW = 28 IMAGE_COL = 28 BATCH_NUM = 100 index_list = list(range(image_len)) def data_generator(): if mode == 'train': random.shuffle(index_list) image_list = [] label_list = [] for i in index_list: image = np.reshape(images_data[i],[1,IMAGE_ROW,IMAGE_COL]).astype('float32') label = np.reshape(images_label[i],[1]).astype('int64') image_list.append(image) label_list.append(label) if len(image_list) == BATCH_NUM: yield np.array(image_list),np.array(label_list) image_list = [] label_list = [] if len(image_list) > 0: yield np.array(image_list),np.array(label_list) return data_generator class MNIST(fluid.dygraph.Layer): def __init__(self): super(MNIST,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=980,output_dim=10,act='softmax') def forward(self,inputs,label,check_shape=False,check_context=False): output1 = self.conv1(inputs) output2 = self.pool1(output1) output3 = self.conv2(output2) output4 = self.pool2(output3) _outputs4 = fluid.layers.reshape(output4,[output4.shape[0],-1]) output5 = self.fc(_outputs4) if check_shape: print("\n########### print network layer's superparams #####") print('conv1--kernel_size:{}, padding:{}, stride:{}'.format(self.conv1.weight.shape,self.conv1._padding,self.conv1._stride)) print('conv2--kernel_size:{}, padding:{}, stride:{}'.format(self.conv2.weight.shape,self.conv2._padding,self.conv2._stride)) print('pool1--pool_type:{}, pool_size:{}, pool_stride:{}'.format(self.pool1._pool_type,self.pool1._pool_size,self.pool1._pool_stride)) print('pool2--pool_type:{}, pool_size:{}, pool_stride:{}'.format(self.pool2._pool_type,self.pool2._pool_size,self.pool2._pool_stride)) print('fc--weight_size:{}, bias_size:{}, activation:{}'.format(self.fc.weight.shape,self.fc.bias.shape,self.fc._act)) print("\n####### print shape of feature of every layer #######") print("input_shape:{}".format(inputs)) print("output1_shape:{}".format(output1)) print("output2_shape:{}".format(output2)) print("output3_shape:{}".format(output3)) print("output4_shape:{}".format(output4)) print("output5_shape:{}".format(output5)) if check_context: print("\n##### print convolution layer's kernel #######") print("conv1 params -- kernel weights:",self.conv1.weight[0][0]) print("conv2 params -- kernel weights:",self.conv2.weight[0][0]) if label is not None: acc = fluid.layers.accuracy(input=output5,label=label) return output5,acc else: return output5 use_gpu = False place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace() def main(): train_loader = load_data('train') with fluid.dygraph.guard(place): model = MNIST() model.train() optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.01,parameter_list=model.parameters()) EPOCH_NUM = 1 for epoch_id in range(EPOCH_NUM): for batch_id, data in enumerate(train_loader()): images_data,labels_data = data images = fluid.dygraph.to_variable(images_data) labels = fluid.dygraph.to_variable(labels_data) if batch_id == 0 and epoch_id == 0: predict,acc = model(images,labels,check_shape=True,check_context=False) elif batch_id == 401: predict,acc = model(images,labels,check_shape=False,check_context=True) else: predict,acc = model(images,labels) loss = fluid.layers.cross_entropy(predict,labels) avg_loss = fluid.layers.mean(loss) if batch_id % 200 == 0: print("epoch: {}, batch: {}, loss is: {}, acc is {}".format(epoch_id, batch_id, avg_loss.numpy(), acc.numpy())) avg_loss.backward() optimizer.minimize(avg_loss) model.clear_gradients() fluid.save_dygraph(model.state_dict(),'mnist_acc')print("Model has been saved") if __name__ == '__main__': main()
总结:
这里用案例的形式和大家进行讲解,讲解方式对新人非常不友好,若你是新人,你需要有大量的前置知识,如神经网络,python基础等。但我个人在学习过程中发现,我比较适合以案例的形式进行学习,早期我学习大量的python基础知识,但让我制作一样东西时,我却无从下手,实战经验果然还是要通过实战获取,我在学习这个案例时,除了标题中的5个步骤以外的内容基本看不懂,都是通过背代码、print打各个参数信息、百度等途径一点一点的磨出来的,相信你也可以做到。
由于是第一次写博客,写的多烂我心理也有数,欢迎大家的批评
- PaddlePaddle第一周学习心得
- 飞桨PaddlePaddle百度架构师手把手带你零基础实践深度学习 第一周心得
- 记录一下paddlepaddle深度学习心得
- PaddlePaddle论文复现课程-BigGan学习心得
- 2020.8.11-2020.8.16paddle学习心得②
- 百度PaddlePaddle深度学习七日打卡技术心得及笔记
- 第一周:PageRank学习心得--JAVA编程实现
- 2020.8.11-2020.8.16paddle学习心得体会③
- JAVA第一周学习心得
- paddlepaddle框架学习心得
- PaddlePaddle/飞桨 第一周学习心得
- 百度飞桨PaddlePaddle深度学习心得分享
- 百度飞桨PaddlePaddle7日打卡营学习心得
- 飞桨paddlepaddle深度学习七日学习心得
- 飞桨PaddlePaddle论文复现营论文学习心得
- 第一周学习心得
- 《软件工程》学习心得体会——项目第一周
- PaddlePaddle深度学习心得
- PaddlePaddle之学习心得[AIStudio]
- java第一周培训学习心得