卷积神经网络(CNN)实现图像分类——Python

卷积神经网络(CNN)实现图像分类——Python

文章目录

    • 1.代码运行
    • 2.注意事项
    • 3.代码分析
    • 4.源代码

1.代码运行

  1. 输入 1 测试一张图片并预测结果

  1. 输入 2 对测试集整体进行测试,得出准确率(10秒左右)

  2. 输入其他数字自动退出程序

2.注意事项

  1. 本程序包含python库较多,请自行配置(pip),如有需求,请评论或私信
    卷积神经网络(CNN)实现图像分类——Python_第1张图片

  2. 回复其他数字会自动退出程序

  3. 输入图片要求是28*28像素

  4. 模型训练大概需要2分钟,请耐心等候!

  5. 本代码使用在线MNIST数据库,无需本地MNIST数据库!

  6. 文件会自动在同目录下面生成Model文件夹,里面包含两个文件model.pdoptmodel.pdparams

  7. 如果需要可视化,可以将callbacks行注释去除

  8. 如果需要下图格式,请将上面代码中 verbose=0修改为verbose=1

3.代码分析

  1. 数据预处理,从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

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()

4.源代码

如果是完成大作业需求,请各位自己适配!!!!
#!/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()



你可能感兴趣的:(python基础,python,cnn,分类,开发语言,深度学习)