基于Keras的手写数字识别(附源码)

news2025/3/19 3:25:38

目录

引言

为什么要创建虚拟环境,好处在哪里?

源码 

我修改的部分

调用本地数据

修改第二层卷积层


引言

本文是博主为了记录一个好的开源代码而写,下面是代码出处!强烈建议收藏!【深度学习实战—1】:基于Keras的手写数字识别(非常详细、代码开源)

写的非常好,但是复现这篇博客却让我吃了很多苦头, 大家要先下载Anaconda3然后创建一个虚拟环境,在虚拟环境里面主要下载以下三个东西版本号只要对应好,肯定能运行,其他的库少什么安装什么!如果用显卡跑模型,原博客有提及配置!

版本号
Python版本3.7.3
Keras版本2.4.3
tensorflow版本2.4.0

为什么要创建虚拟环境,好处在哪里?

在进行机器学习项目时,我们经常会遇到需要为不同的模型安装不同版本的Python或相关库的情况。这是因为每个模型可能依赖于特定版本的库,这些版本之间可能存在兼容性差异。如果不使用虚拟环境,而是在主环境中直接安装这些库,可能会遇到以下问题:

首先,当你为新的模型安装特定版本的库时,可能会覆盖掉主环境中已经存在的其他模型所需的库版本,导致之前的模型无法正常运行。

其次,不同的Python版本之间也可能存在兼容性问题。如果你直接在主环境中升级或降级Python版本,可能会影响到依赖于特定Python版本的其他项目。

为了避免这些问题,使用虚拟环境变得尤为重要。虚拟环境是一个隔离的Python环境,其中可以安装特定版本的Python和库,而不会影响到主环境或其他虚拟环境。这样,你可以为每个机器学习模型创建一个独立的虚拟环境,并在其中安装所需的Python版本和库版本,从而确保每个模型都能在其特定的环境中稳定运行。

通过这种方法,你可以轻松地管理多个项目,而无需担心库版本冲突或Python版本不兼容的问题。希望这样的解释能帮助大家更好地理解虚拟环境在机器学习项目中的重要性。

源码 

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from keras.datasets import mnist
from sklearn.metrics import confusion_matrix
import seaborn as sns
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import np_utils
import tensorflow as tf

config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.compat.v1.Session(config=config)

# 设定随机数种子,使得每个网络层的权重初始化一致
# np.random.seed(10)

# x_train_original和y_train_original代表训练集的图像与标签, x_test_original与y_test_original代表测试集的图像与标签
(x_train_original, y_train_original), (x_test_original, y_test_original) = mnist.load_data()
# 假设你已经知道mnist.npz文件的路径
# file_path = 'mnist.npz'  # 替换为你的mnist.npz文件的实际路径
#
# # 加载npz文件
# with np.load(file_path, allow_pickle=True) as f:
#     x_train_original = f['x_train']
#     y_train_original = f['y_train']
#     x_test_original = f['x_test']
#     y_test_original = f['y_test']

"""
数据可视化
"""


# 单张图像可视化
def mnist_visualize_single(mode, idx):
    if mode == 0:
        plt.imshow(x_train_original[idx], cmap=plt.get_cmap('gray'))
        title = 'label=' + str(y_train_original[idx])
        plt.title(title)
        plt.xticks([])  # 不显示x轴
        plt.yticks([])  # 不显示y轴
        plt.show()
    else:
        plt.imshow(x_test_original[idx], cmap=plt.get_cmap('gray'))
        title = 'label=' + str(y_test_original[idx])
        plt.title(title)
        plt.xticks([])  # 不显示x轴
        plt.yticks([])  # 不显示y轴
        plt.show()


# 多张图像可视化
def mnist_visualize_multiple(mode, start, end, length, width):
    if mode == 0:
        for i in range(start, end):
            plt.subplot(length, width, 1 + i)
            plt.imshow(x_train_original[i], cmap=plt.get_cmap('gray'))
            title = 'label=' + str(y_train_original[i])
            plt.title(title)
            plt.xticks([])
            plt.yticks([])
        plt.show()
    else:
        for i in range(start, end):
            plt.subplot(length, width, 1 + i)
            plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
            title = 'label=' + str(y_test_original[i])
            plt.title(title)
            plt.xticks([])
            plt.yticks([])
        plt.show()


mnist_visualize_multiple(mode=0, start=0, end=4, length=2, width=2)
# 原始数据量可视化
print('训练集图像的尺寸:', x_train_original.shape)
print('训练集标签的尺寸:', y_train_original.shape)
print('测试集图像的尺寸:', x_test_original.shape)
print('测试集标签的尺寸:', y_test_original.shape)

"""
数据预处理
"""
#
# 从训练集中分配验证集
x_val = x_train_original[50000:]
y_val = y_train_original[50000:]
x_train = x_train_original[:50000]
y_train = y_train_original[:50000]
print('======================')
# 打印验证集数据量
print('验证集图像的尺寸:', x_val.shape)
print('验证集标签的尺寸:', y_val.shape)
print('======================')
# 将图像转换为四维矩阵(nums,rows,cols,channels), 这里把数据从unint类型转化为float32类型, 提高训练精度。
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
x_val = x_val.reshape(x_val.shape[0], 28, 28, 1).astype('float32')
x_test = x_test_original.reshape(x_test_original.shape[0], 28, 28, 1).astype('float32')
#
# 原始图像的像素灰度值为0-255,为了提高模型的训练精度,通常将数值归一化映射到0-1。
x_train = x_train / 255
x_val = x_val / 255
x_test = x_test / 255
#
print('训练集传入网络的图像尺寸:', x_train.shape)
print('验证集传入网络的图像尺寸:', x_val.shape)
print('测试集传入网络的图像尺寸:', x_test.shape)
# #
# 图像标签一共有10个类别即0-9,这里将其转化为独热编码(One-hot)向量
y_train = np_utils.to_categorical(y_train)
print(y_train[0])

y_val = np_utils.to_categorical(y_val)
y_test = np_utils.to_categorical(y_test_original)


#
# """
# 定义网络模型
# """
#
#
def CNN_model():
    model = Sequential()
    model.add(Conv2D(filters=16, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))  # 卷积层
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))  # 池化层
    # model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))  # 卷积层
    model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))  # 卷积层
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))  # 池化层
    model.add(Flatten())  # 平铺层
    model.add(Dense(100, activation='relu'))  # 全连接层
    model.add(Dense(10, activation='softmax'))  # 全连接层

    print(model.summary())
    return model


#
#
# """
# 训练网络
# """
#
model = CNN_model()
# #
# 编译网络(定义损失函数、优化器、评估指标)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 开始网络训练(定义训练数据与验证数据、定义训练代数,定义训练批大小) 原来20
train_history = model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=20, batch_size=32, verbose=2)

# 模型保存
model.save('handwritten_numeral_recognition.h5')


#
#
# #
# #
# 定义训练过程可视化函数(训练集损失、验证集损失、训练集精度、验证集精度)
def show_train_history(train_history, train, validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train', 'validation'], loc='best')
    plt.show()


show_train_history(train_history, 'accuracy', 'val_accuracy')
show_train_history(train_history, 'loss', 'val_loss')

# 输出网络在测试集上的损失与精度
score = model.evaluate(x_test, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

# 测试集结果预测
predictions = model.predict(x_test)
predictions = np.argmax(predictions, axis=1)
print('前9张图片预测结果:', predictions[:9])


# 预测结果图像可视化
def mnist_visualize_multiple_predict(start, end, length, width):
    for i in range(start, end):
        plt.subplot(length, width, 1 + i)
        plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
        title_true = 'true=' + str(y_test_original[i])
        title_prediction = ',' + 'prediction' + str(model.predict_classes(np.expand_dims(x_test[i], axis=0)))
        title = title_true + title_prediction
        plt.title(title)
        plt.xticks([])
        plt.yticks([])
    plt.show()


mnist_visualize_multiple_predict(start=0, end=9, length=3, width=3)

# 混淆矩阵
cm = confusion_matrix(y_test_original, predictions)
cm = pd.DataFrame(cm)
class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']


def plot_confusion_matrix(cm):
    plt.figure(figsize=(10, 10))
    sns.heatmap(cm, cmap='Oranges', linecolor='black', linewidth=1, annot=True, fmt='', xticklabels=class_names,
                yticklabels=class_names)
    plt.xlabel("Predicted")
    plt.ylabel("Actual")
    plt.title("Confusion Matrix")
    plt.show()


plot_confusion_matrix(cm)

我修改的部分

调用本地数据

# x_train_original和y_train_original代表训练集的图像与标签, x_test_original与y_test_original代表测试集的图像与标签
# (x_train_original, y_train_original), (x_test_original, y_test_original) = mnist.load_data()
# 假设你已经知道mnist.npz文件的路径
file_path = 'mnist.npz'  # 替换为你的mnist.npz文件的实际路径

# 加载npz文件
with np.load(file_path, allow_pickle=True) as f:
    x_train_original = f['x_train']
    y_train_original = f['y_train']
    x_test_original = f['x_test']
    y_test_original = f['y_test']

因为原来的代码是每次运行都请求下载网上的在线数据,这是没必要的,当你运行了一次,可以把数据存在本地,然后以后本地调用

修改第二层卷积层

def CNN_model():
    model = Sequential()
    model.add(Conv2D(filters=16, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))  # 卷积层
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))  # 池化层
    # model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))  # 卷积层
    model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))  # 卷积层
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))  # 池化层
    model.add(Flatten())  # 平铺层
    model.add(Dense(100, activation='relu'))  # 全连接层
    model.add(Dense(10, activation='softmax'))  # 全连接层

    print(model.summary())
    return model

 原文中的第二层卷积层的输入是规定为(28,28,1),但是这是有问题的,应该是不设置参数,这样子的话,会自动将第一个池化层的输出当作输入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1694401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5、sqlmap注入post类型+os-shell

题目:青少年:Easy_SQLi 1、打开网页,是一个登入表单 2、判断注入类型,是一个字符注入,使用or直接绕过密码进去了 3、上bp抓取数据包,sqlmmap用post注入走一遍,找到数据库,账号密码&…

【Linux】TCP协议【中】{确认应答机制/超时重传机制/连接管理机制}

文章目录 1.确认应答机制2.超时重传机制:超时不一定是真超时了3.连接管理机制 1.确认应答机制 TCP协议中的确认应答机制是确保数据可靠传输的关键部分。以下是该机制的主要步骤和特点的详细解释: 数据分段与发送: 发送方将要发送的数据分成一…

Linux网络编程:HTTP协议

前言: 我们知道OSI模型上层分为应用层、会话层和表示层,我们接下来要讲的是主流的应用层协议HTTP,为什么需要这个协议呢,因为在应用层由于操作系统的不同、开发人员使用的语言类型不同,当我们在传输结构化数据时&…

JVM-调优之-如何使用arthas-观察jvm-cpu-内存-垃圾回收等信息

前言: 可以简单代替把dump文件下载下来后用visualvm分析了;跟visualvm类似的; docker中如何安装arthas看这个:docker中怎么使用arthas_arthas 集成到容器镜像-CSDN博客 curl -O https://arthas.aliyun.com/arthas-boot.jar wget …

闲话 .NET(5):.NET Core 有什么优势?

前言 .NET Core 并不是 .NET FrameWork 的升级版,它是一个为满足新一代的软件设计要求而从头重新开发的开发框架和平台,所以它没有 .NET FrameWork 的历史包袱,相对于 .NET FrameWork,它具备很多优势。 .NET Core 有哪些优势&am…

列主元消去法和矩阵三角分解法求解线性方程组

目录 列主元消去法矩阵三角分解法 列主元消去法 构建增广矩阵: 将线性方程组写成矩阵形式 𝐴𝑋𝐵,并将系数矩阵 𝐴与常数向量 𝐵组成增广矩阵 [𝐴∣𝐵]。选择主元&#…

ACW石子合并-XMUOJ元素共鸣:唤醒神之眼 -区间DP

题目 思路 话不多说&#xff0c;直接上代码 代码 /* ACW石子合并-XMUOJ元素共鸣&#xff1a;唤醒神之眼 JinlongW-2024/05/25 区间DP 当i<j时&#xff0c;f[i][j]min(f[i][k]f[k][j]s[j]-s[i-1]) 当ij时&#xff0c;f[i][j]0 最终答案&#xff1a;f[1][n] *//* 区间DP…

ESP32 接入点灯科技实现远程控制(物联网)

文章目录 ESP32-C3MQTT协议blinker App 源码blinker 开发者Arduino 支持文档导入 blinker 库注册点灯 APPblinker WiFi 示例blinker 蓝牙示例 本示例中开发板使用的是Seeed Studio (XIAO-ESP32-C3) ESP32-C3 ESP32-C3 是 Espressif Systems 公司开发的一款单核 Wi-Fi 和蓝牙双模…

mysql图形化界面及将mysql注册成后台程序

安装图形化界面版本 右键新建数据库 字符集使用utf8防止以后数据库中存在中文字符导致乱码 将mysql注册成后台程序 cmd进入命令行界面 切换路径到cd /mysql/bin 将mysql注册成后台程序 mysqld.exe --install mysql1 (失败&#xff0c;说明没有权限) 以管理员身份打开成功…

每日5题Day10 - LeetCode 46 - 50

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;46. 全排列 - 力扣&#xff08;LeetCode&#xff09; class Solution {//这道题就是一个dfs//把所有结果遍历&#xff0c;到叶子节点就可以添加结果了List<Int…

忘记“也是一门学问:机器如何忘记自己学到的知识?

在信息时代&#xff0c;我们常常希望人工智能能够学到更多的知识&#xff0c;变得更加智能。但你是否想过&#xff0c;有时候让机器"忘记"一些它学到的东西&#xff0c;也是一件很重要的事&#xff1f; 随着用户隐私保护意识的提高和相关法律法规的出台&#xff0c;…

云端智享——记移动云手写docker-demo

目录 前言什么是移动云&#xff1f;为何我会使用移动云&#xff1f;移动云“好”在哪里&#xff1f;资源大屏显示继续项目部署其他细节 移动云产品的评价未来展望 前言 在如今这个万物都上云的时代&#xff0c;我们需要选择合适的云产品&#xff0c;而移动云有着独特的优势和广…

链表-设计LRU缓存结构

题目描述&#xff1a; 代码实现&#xff1a;这里记录了根据LRU算法原理最直接理解的代码实现。 import java.util.*;//存储输入内容&#xff0c;记录访问权值 class CounterInfo {int key;int value;int times;//代表key对应的权值&#xff0c;值越小优先级越高public Counter…

Android 自定义图片进度条

用系统的Progressbar&#xff0c;设置图片drawable作为进度条会出现图片长度不好控制&#xff0c;容易被截断&#xff0c;或者变形的问题。而我有个需求&#xff0c;使用图片背景&#xff0c;和图片进度&#xff0c;而且在进度条头部有个闪光点效果。 如下图&#xff1a; 找了…

用于时间序列概率预测的蒙特卡洛模拟

大家好&#xff0c;蒙特卡洛模拟是一种广泛应用于各个领域的计算技术&#xff0c;它通过从概率分布中随机抽取大量样本&#xff0c;并对结果进行统计分析&#xff0c;从而模拟复杂系统的行为。这种技术具有很强的适用性&#xff0c;在金融建模、工程设计、物理模拟、运筹优化以…

基于springboot+vue的招聘信息管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

大模型的灵魂解读:Anthropic AI的Claude3 Sonnet可解释性研究

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提供了大模型领域最新技…

【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

HarmonyOS开发之DevEco Studio安装

HUAWEI DevEco Studio是基于IntelliJ IDEA Community开源版本打造&#xff0c;为运行在HarmonyOS和OpenHarmony系统上的应用和服务&#xff08;以下简称应用/服务&#xff09;提供一站式的开发平台。 作为一款开发工具&#xff0c;除了具有基本的代码开发、编译构建及调测等功能…

Python高级进阶--slice切片

slice切片⭐⭐ 在 Python 中&#xff0c;切片操作是一种常见且方便的方式&#xff0c;用于从字符串、列表或元组中获取部分元素。这种操作通过指定起始索引、结束索引和步长来实现。下面我们来看一些关于切片的简单介绍以及一些常见用法。 1. 切片简介 取一个str、list、tup…