学习记录5

目录

Mnist学习

 激活函数的选择

Paddle学习流程

网络参数调整(更换或加深)

调整训练的超参数(Epoch,Batch Size)

总结


Mnist学习

##导入相关库
import paddle
import numpy as np ##矩阵运算库
import matplotlib.pyplot as plt ##画图工具
paddle.__version__
import paddle.vision.transforms as T ##图像预处理库,一个高层APIvision.transforms

# 数据的加载和预处理
transform = T.Normalize(mean=[127.5], std=[127.5]) ##图像归一化,0-255的像素值变成小区间-1到1
##搜索一下参数的设置

# 训练数据集
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)

# 评估数据集
eval_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)

print('训练集样本量: {},验证集样本量: {}'.format(len(train_dataset), len(eval_dataset)))
# 数据集查看
print('图片:')
print(type(train_dataset[0][0]))##显示数据预处理后的类型,矩阵类型
print(train_dataset[0][0])##显示数据
print('标签:')
print(type(train_dataset[0][1]))
print(train_dataset[0][1])##显示标签

# 可视化展示,三种展示方法
#plt.figure()
plt.imshow(train_dataset[0][0].reshape([28,28]), cmap=plt.cm.binary)
##plt.show()

# 模型网络结构搭建
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 512),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数,便于反向传播函数
    paddle.nn.Linear(512, 10)      # 输出层
)

# 模型封装
model = paddle.Model(network)  ##把网络变成模型

# 模型可视化,检测是否搭建成功
model.summary((1, 28, 28))

# 配置优化器、损失函数、评估指标,优化器,学习率
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),
              paddle.nn.CrossEntropyLoss(),##要小,交叉熵已经集成softmax(概率统计)
              paddle.metric.Accuracy())##评估集与结果的比较,看出模型过拟合(学过头了,训练太多了)或欠拟合
              
# 启动模型全流程训练
model.fit(train_dataset,  # 训练数据集
          eval_dataset,   # 评估数据集
          epochs=5,       # 训练的总轮次
          batch_size=64,  # 训练使用的批大小
          verbose=1)      # 日志展示形式,1为进度条形式

# 模型评估,根据prepare接口配置的loss和metric进行返回
result = model.evaluate(eval_dataset, verbose=1)

print(result)   

# 模型预测

# 进行批量预测操作
result = model.predict(eval_dataset)

# 定义画图方法
def show_img(img, predict):
    plt.figure()
    plt.title('predict: {}'.format(predict))
    plt.imshow(img.reshape([28, 28]), cmap=plt.cm.binary)
    plt.show()

# 抽样展示
indexs = [2, 15, 38, 211]
for idx in indexs:
    show_img(eval_dataset[idx][0], np.argmax(result[0][idx]))

# 读取单张图片
image = eval_dataset[501][0]

# 单张图片预测
result = model.predict_batch([image])##最大值对应的索引的标签即为预测结果

# 可视化结果
show_img(image, np.argmax(result))

# 保存用于后续继续调优训练的模型
model.save('finetuning/mnist')
# 继续调优训练
from paddle.static import InputSpec


# 模型封装,为了后面保存预测模型,这里传入了inputs参数
model_2 = paddle.Model(network, inputs=[InputSpec(shape=[-1, 28, 28], dtype='float32', name='image')])

# 加载之前保存的阶段训练模型
model_2.load('finetuning/mnist')##文件目录加模型名

# 模型配置
model_2.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),
                paddle.nn.CrossEntropyLoss(),##分类常用交叉熵
                paddle.metric.Accuracy())

# 模型全流程训练
model_2.fit(train_dataset, 
            eval_dataset,
            epochs=2,
            batch_size=64,
            verbose=1)

# 保存用于后续推理部署的模型
model_2.save('infer/mnist', training=False)

以上手写识别模型使用全连接矩阵网络结构,还可使用高层API模型,如下

network_2 = paddle.vision.models.LeNet(num_classes = 10)##10个结果

或者卷积网络模型

##卷积网络结构搭建
import paddle.nn as nn

network_3 = nn.Sequential(
        nn.Conv2D(in_channels=1,out_channels=6,kernel_size=3,stride=1,padding=1),
        nn.ReLU(),##激活函数
        nn.MaxPool2D(kernel_size=2,stride=2),
        nn.Conv2D(in_channels=6,out_channels=16,kernel_size=5,stride=1,padding=0),
        nn.ReLU(),
        nn.MaxPool2D(kernel_size=2,stride=2),
        nn.Flatten(),
        nn.Linear(in_features=400,out_features=120),
        nn.Linear(in_features=120,out_features=84),
        nn.Linear(in_features=84,out_features=10)
)

##模型可视化
paddle。summary(network_3,(1,1,28,28))

        

图像分类解决二分类,多分类,多标签。

LeNet是CNN卷积神经网络的鼻祖,定义了基本结构,卷积层,池化层,全连接层。

                平均池化,适用于传递背景信息,

                最大值池化,用于提取边缘或关键特征信息。

 激活函数的选择

        

        Tanh

        Relu函数

Paddle学习流程

1.数据加载和预处理,可以远程下载

2.模型的网络设计与开发

        sequential

        subclass更复杂一点的卷积网络

        内置网络

3.模型训练

4.模型评估和测试

5.模型保存和部署.save(model_path)继续调优

        .save(model_path,training = False)用于预测部署

网络参数调整(更换或加深)

更换网络结构,添加几层来看效果。训练参数不变。

##更改前的代码
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 512),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数,便于反向传播函数
    paddle.nn.Linear(512, 10)      # 输出层
)

# 配置优化器、损失函数、评估指标,优化器,学习率
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),
              paddle.nn.CrossEntropyLoss(),##要小,交叉熵已经集成softmax(概率统计)
              paddle.metric.Accuracy())##评估集与结果的比较,看出模型过拟合(学过头了,训练太多了)或欠拟合
              
# 启动模型全流程训练
model.fit(train_dataset,  # 训练数据集
          eval_dataset,   # 评估数据集
          epochs=5,       # 训练的总轮次
          batch_size=64,  # 训练使用的批大小
          verbose=1)      # 日志展示形式,1为进度条形式

结果为

{'loss': [0.0], 'acc': 0.9747}
# 将512更改为256
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 256),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数,便于反向传播函数
    paddle.nn.Linear(256, 10)      # 输出层
)

结果为

{'loss': [5.6028525e-06], 'acc': 0.9695},准确率下降

改为400,

{'loss': [0.0], 'acc': 0.9688},准确率又降了。

改为600,

{'loss': [2.503392e-06], 'acc': 0.9721},和512的准确率接近了

改为650,

{'loss': [2.3841855e-07], 'acc': 0.9724},准确率高了一点

改为700,

{'loss': [2.3841855e-07], 'acc': 0.9715}准确率低了。。

。。。确实玄学

# 网络多一层
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 650),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数,便于反向传播函数
    paddle.nn.Linear(650, 512),  
    paddle.nn.ReLU(), 
    paddle.nn.Linear(512, 10)

)

隐层多添加一层,效果也不如例子好。

{'loss': [1.9073468e-06], 'acc': 0.9693}
# 网络多添加几层
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 650),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数,便于反向传播函数
    paddle.nn.Linear(650, 512),  
    paddle.nn.ReLU(), 
    paddle.nn.Linear(512, 400),
    paddle.nn.ReLU(),
    paddle.nn.Linear(400, 300),
    paddle.nn.ReLU(),
    paddle.nn.Linear(300, 200),
    paddle.nn.ReLU(),
    paddle.nn.Linear(200, 10)
)

隐层多添几层,效果不如例子好,比多添加一层好。

{'loss': [0.0], 'acc': 0.9717}

调整训练的超参数(Epoch,Batch Size)

在网络模型使用最高准确率原例时,修改Epoch与Batch Size的值,观察结果。

# Epoch = 5 的结果

Epoch 5/5
step 938/938 [==============================] - loss: 0.1218 - acc: 0.9773 - 8ms/step         
Eval begin...
step 157/157 [==============================] - loss: 0.0010 - acc: 0.9774 - 6ms/step         
Eval samples: 10000
Eval begin...
step 10000/10000 [==============================] - loss: 3.5763e-07 - acc: 0.9774 - 2ms/step        
Eval samples: 10000
{'loss': [3.576278e-07], 'acc': 0.9774}

在例子中,epoch=5,此时第五轮训练准确率达到最高0.9773,测试准确率有0.9774,最终准确率0.9774. 

epoch = 3

将训练轮数降低,准确率降低。

{'loss': [4.9351427e-05], 'acc': 0.9693}
Epoch = 6

训练轮数增加,准确率没有5轮好,但比3轮好。

{'loss': [1.1920922e-06], 'acc': 0.9734}
Epoch = 8

 训练轮数增加为8,准确率没有5轮好,但比3轮好。

值得一提的是第8轮的训练结果准确率为0.9840,是测试各轮数结果最高的准确率,可是在测试集准确率又下降了,此时最好的Epoch仍然是5轮。

Epoch 8/8
step 938/938 [==============================] - loss: 0.0037 - acc: 0.9840 - 7ms/step         
Eval begin...
step 157/157 [==============================] - loss: 4.7354e-04 - acc: 0.9764 - 7ms/step     
Eval samples: 10000
Eval begin...
step 10000/10000 [==============================] - loss: 0.0000e+00 - acc: 0.9764 - 2ms/step         
Eval samples: 10000
{'loss': [0.0], 'acc': 0.9764}

最后尝试训练9次,结果也是测试的时候准确率降低了,无法解释。。。

Epoch 9/9
step 938/938 [==============================] - loss: 0.0043 - acc: 0.9856 - 8ms/step         
Eval begin...
step 157/157 [==============================] - loss: 2.2484e-05 - acc: 0.9723 - 6ms/step     
Eval samples: 10000
Eval begin...
step 10000/10000 [==============================] - loss: 0.0000e+00 - acc: 0.9723 - 2ms/step        
Eval samples: 10000
{'loss': [0.0], 'acc': 0.9723}

Batch Size改了几次数值,结果也是原本的64准确率最高。

总结

对模型,训练和预测有了实例化的理解,至于参数的选择,可能更多的是靠加减大小调试出更好的结果吧,最优解是不存在的!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值