输入 2 对测试集整体进行测试,得出准确率(10秒左右)
输入其他数字自动退出程序
回复其他数字会自动退出程序
输入图片要求是28*28像素
模型训练大概需要2分钟,请耐心等候!
本代码使用在线MNIST数据库,无需本地MNIST数据库!
文件会自动在同目录下面生成Model
文件夹,里面包含两个文件model.pdopt
、model.pdparams
如果需要可视化,可以将callbacks
行注释去除
如果需要下图格式,请将上面代码中 verbose=0
修改为verbose=1
def data_process():
transform = T.Normalize(mean=[127.5], std=[127.5])
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
print('训练样本量:{},测试样本量:{}'.format(len(train_dataset), len(test_dataset)))
return train_dataset, test_dataset
2.训练模型
def create_model(train_dataset, test_dataset):
print('查找是否存在模型.')
# 网络结构代码实现,调用paddle的网络
network = paddle.vision.models.LeNet(num_classes=10)
model = paddle.Model(network)
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()), # 优化器
paddle.nn.CrossEntropyLoss(), # 损失函数
paddle.metric.Accuracy()) # 评估指标
if not os.path.exists('Model/model.pdopt') or not os.path.exists('Model/model.pdparams'):
print('不存在模型,开始训练模型.')
# callback = paddle.callbacks.VisualDL(log_dir='visualdl_log_dir_LeNet学习率0.001')
# 启动全流程训练
model.fit(train_dataset, # 训练数据集
test_dataset, # 评估数据集
epochs=5, # 训练轮次
batch_size=64, # 单次计算数据样本量
verbose=0,
# callbacks=callback
) # 日志展示形式
print("模型训练结束")
# 进行预测操作
# result = model_1.predict(test_dataset)
model.save('Model/model')
else:
model.load('Model/model')
print("已经存在训练好的模型!!!")
return model
3.测试单张和多张
def Test_one(imgPath, modelPath):
model = modelPath
# image = preprocessing.StandardScaler().fit_transform(np.array(Image.open(imgPath).convert('L'), dtype='float32'))
im = Image.open(imgPath).convert('L')
# 为灰度图像,每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。 转换公式:L = R * 299/1000 + G * 587/1000+ B * 114/1000。
# im = im.resize((28, 28), Image.ANTIALIAS)
im = numpy.array(im).reshape(-1, 1, 28, 28).astype('float32')
im = im / 255.0 - 1.0
result = model.predict([im], verbose=True)
print('预测结果是:', result[0][0].argmax(), '\n') # argmax()得到最大值下标
# 测试准确率
def Test_all(modelPath):
model = modelPath
result = model.evaluate(test_dataset, verbose=1)
print('准确率为:', result['acc'])
4.主程序
if __name__ == '__main__':
print('训练数据自动使用paddle自带的MINST数据库')
print('回复数字1为测试一张图片,回复数字2为测试测试集准确率,回复其他数字自动退出程序!!!\n')
train_dataset, test_dataset = data_process()
model = create_model(train_dataset, test_dataset)
while 1:
ans = input('测试一张(1)还是测试集准确率(2):')
match (ans):
case '1':
modelPath = model # 模型文件会生成在本文件同目录下不需要选择,这里Path默认直接加载模型
root = tk.Tk()
root.withdraw()
print('请选择测试图片')
imgPath = filedialog.askopenfilename()
Test_one(imgPath, modelPath)
continue
case '2':
modelPath = model
Test_all(modelPath)
continue
case _:
print('测试结束!!!')
exit()
如果是完成大作业需求,请各位自己适配!!!! |
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName :CNN3.py
# @Time :2023/4/24 14:28
# @Author :YKW
import os
import paddle
import numpy
import tkinter as tk
from PIL import Image
from tkinter import filedialog
import paddle.vision.transforms as T
'protobuf版本建议使用3.20.0,否则会不兼容'
'训练数据自动使用paddle自带的MINST数据库'
# 数据预处理,从paddle库得到mnist数据
def data_process():
transform = T.Normalize(mean=[127.5], std=[127.5])
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
print('训练样本量:{},测试样本量:{}'.format(len(train_dataset), len(test_dataset)))
return train_dataset, test_dataset
# 训练模型
def create_model(train_dataset, test_dataset):
print('查找是否存在模型.')
# 网络结构代码实现,调用paddle的网络
network = paddle.vision.models.LeNet(num_classes=10)
model = paddle.Model(network)
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()), # 优化器
paddle.nn.CrossEntropyLoss(), # 损失函数
paddle.metric.Accuracy()) # 评估指标
if not os.path.exists('Model/model.pdopt') or not os.path.exists('Model/model.pdparams'):
print('不存在模型,开始训练模型.')
# callback = paddle.callbacks.VisualDL(log_dir='visualdl_log_dir_LeNet学习率0.001')
# 启动全流程训练
model.fit(train_dataset, # 训练数据集
test_dataset, # 评估数据集
epochs=5, # 训练轮次
batch_size=64, # 单次计算数据样本量
verbose=0,
# callbacks=callback
) # 日志展示形式
print("模型训练结束")
# 进行预测操作
# result = model_1.predict(test_dataset)
'''
indexs = [5, 20, 48, 210]
for idx in indexs:
show_img(test_dataset[idx][0], np.argmax(result[0][idx]))'''
model.save('Model/model')
else:
model.load('Model/model')
print("已经存在训练好的模型!!!")
return model
# 测试单张
def Test_one(imgPath, modelPath):
model = modelPath
# image = preprocessing.StandardScaler().fit_transform(np.array(Image.open(imgPath).convert('L'), dtype='float32'))
im = Image.open(imgPath).convert('L')
# 为灰度图像,每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。 转换公式:L = R * 299/1000 + G * 587/1000+ B * 114/1000。
# im = im.resize((28, 28), Image.ANTIALIAS)
im = numpy.array(im).reshape(-1, 1, 28, 28).astype('float32')
im = im / 255.0 - 1.0
result = model.predict([im], verbose=True)
print('预测结果是:', result[0][0].argmax(), '\n') # argmax()得到最大值下标
# 测试准确率
def Test_all(modelPath):
model = modelPath
result = model.evaluate(test_dataset, verbose=1)
print('准确率为:', result['acc'])
if __name__ == '__main__':
print('训练数据自动使用paddle自带的MINST数据库')
print('回复数字1为测试一张图片,回复数字2为测试测试集准确率,回复其他数字自动退出程序!!!\n')
train_dataset, test_dataset = data_process()
model = create_model(train_dataset, test_dataset)
while 1:
ans = input('测试一张(1)还是测试集准确率(2):')
match (ans):
case '1':
modelPath = model # 模型文件会生成在本文件同目录下不需要选择,这里Path默认直接加载模型
root = tk.Tk()
root.withdraw()
print('请选择测试图片')
imgPath = filedialog.askopenfilename()
Test_one(imgPath, modelPath)
continue
case '2':
modelPath = model
Test_all(modelPath)
continue
case _:
print('测试结束!!!')
exit()