基于MNIST数据集的手写数字识别项目1

资源文件

csv格式的MNIST数据集


一、MNIST数据集介绍

(1)数据集有60000张
(2)每张图片大小28*28
(3)颜色通道:1(灰度)
(4)像素取值范围[0,255],0代表黑色,255代表白色
(5)每张图片有一个标签:0-9

二、开发步骤

1.引入库

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
from keras.layers import Conv2D,Input,LeakyReLU,Dense,Activation,Flatten,Dropout,MaxPool2D
from keras import models
from keras.optimizers import Adam,RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ReduceLROnPlateau

2.加载数据集

np.random.seed(666) #随机种子,确保每次运行结果一致
train_data = pd.read_csv('/BASICCNN/MnistCsv/train.csv') #读取数据集
train_data = train_data.iloc[np.random.permutation(len(train_data))] #打乱数据集
train_data.head(3) #显示前3行 #默认显示5print(train_data.shape)

在这里插入图片描述

3.将训练集分解为训练集和验证集

train_size = train_data.shape[0] #训练集大小
print(train_size)
val_size = int(train_size*0.2) #验证集大小,占比20%
print(val_size)
#验证集数据和标签
X_val = np.asarray(train_data.iloc[:val_size,1:]).reshape([val_size,28,28,1]) #验证集
Y_val = np.asarray(train_data.iloc[:val_size,0]).reshape([val_size,1]) #标签
#训练集数据和标签
X_Train = np.asarray(train_data.iloc[val_size:,1:]).reshape([train_size-val_size,28,28,1])
Y_Train = np.asarray(train_data.iloc[val_size:,0]).reshape([train_size-val_size,1])
print(X_val.shape,X_Train.shape)

在这里插入图片描述

4.加载测试集test.csv

test_data = pd.read_csv('/BASICCNN/MnistCsv/test.csv')
X_test = np.asarray(test_data.iloc[:,:]).reshape([-1,28,28,1])
print(X_test.shape)

在这里插入图片描述

5.正则化数据集

X_Train =X_Train/255.
X_val = X_val/255.
X_test = X_test/255.

6.可视化训练集和验证集中不同数字出现的频率

#统计训练集中每个数字出现的频率
counts = train_data.iloc[val_size:,:].groupby('label')['label'].count() #groupby分组
print(counts)
#显示训练集
fig = plt.figure(figsize=(10,6)) #画布大小
fig.add_subplot(111) #11列,位置1
plt.bar(counts.index,counts.values,width=0.8,color='blue') #柱状图参数设置
for i in counts.index:
    plt.text(i,counts.values[i]+20,str(counts.values[i]),horizontalalignment='center',fontsize=14)
plt.tick_params(labelsize=14)
plt.xticks(counts.index)
plt.xlabel('Digits',fontsize=16)
plt.ylabel('Frequency',fontsize=16)
plt.title('Frequency in Train Data',fontsize=20)
plt.savefig('/BASICCNN/TrainImage/Csvmnist_Train.png')
plt.show()

在这里插入图片描述

#显示验证集
fig = plt.figure(figsize=(10,6)) #画布大小
fig.add_subplot(111) #11列,位置1
counts2 = train_data.iloc[:val_size,:].groupby('label')['label'].count()
plt.bar(counts2.index,counts2.values,width=0.8,color='green') #柱状图参数设置
for i in counts2.index:
    plt.text(i,counts2.values[i]+20,str(counts2.values[i]),horizontalalignment='center',fontsize=14)
plt.tick_params(labelsize=14)
plt.xticks(counts2.index)
plt.xlabel('Digits',fontsize=16)
plt.ylabel('Frequency',fontsize=16)
plt.title('Frequency in Val Data',fontsize=20)
plt.savefig('/BASICCNN/TrainImage/Csvmnist_Val.png')
plt.show()

在这里插入图片描述

7.显示部分数据集中的数字图片

rows = 5
cols = 6
fig = plt.figure(figsize=(2*cols,2*rows))
for i in range(rows*cols):
    fig.add_subplot(rows,cols,i+1)  #图片添加到相应的位置
    plt.imshow(X_Train[i].reshape([28,28]),cmap='PuOr')
    plt.axis('off')
    plt.title(str(Y_Train[i]),y=-0.15,color='blue') #显示对应标签
plt.savefig('/BASICCNN/TrainImage/Csvmnist_Show.png')
plt.show()

在这里插入图片描述

8.构建网络模型

model = models.Sequential()
model.add(Conv2D(32,3,padding='same',input_shape=(28,28,1)))
model.add(LeakyReLU())
model.add(Conv2D(32,3,padding='same'))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2)))

model.add(Conv2D(64,3,padding='same',input_shape=(28,28,1)))
model.add(LeakyReLU())
model.add(Conv2D(64,3,padding='same'))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten()) #维度拉平
model.add(Dense(256,activation='relu'))
model.add(Dense(64,activation='relu'))
model.add(Dense(10,activation='sigmoid'))  #sigmoid归一[0,1]

9.编译模型

lr = 0.001 #学习率
loss = 'sparse_categorical_crossentropy' #损失函数
model.compile(Adam(lr=lr),loss=loss,metrics=['accuracy'])
model.summary()

在这里插入图片描述

10.训练模型

epochs = 2
batch_size = 32
history1 = model.fit(X_Train,Y_Train,batch_size=batch_size,epochs=epochs,validation_data=(X_val,Y_val))
model.save('/BASICCNN/TrainModel_h5/CsvmnistTrain.h5')


在这里插入图片描述

11.绘制训练和验证结果

fig = plt.figure(figsize=(20,7))
#121代表12列第一张
fig.add_subplot(121)
plt.plot(history1.epoch,history1.history['accuracy'],label='Train Accuracy')
plt.plot(history1.epoch,history1.history['val_accuracy'],label='Val Accuracy')
plt.title('Accuracy Curve',fontsize=18)
plt.xlabel('Epochs',fontsize=15)
plt.ylabel('Accuracy',fontsize=15)
plt.legend()
plt.savefig('/BASICCNN/TrainImage/CsvmnistTrain_accuracy.png')
plt.show()

plt.plot(history1.epoch,history1.history['loss'],label='Train Loss')
plt.plot(history1.epoch,history1.history['val_loss'],label='Val Loss')
plt.title('Loss Curve',fontsize=18)
plt.xlabel('Epochs',fontsize=15)
plt.ylabel('Loss',fontsize=15)
plt.legend()
plt.savefig('/BASICCNN/TrainImage/CsvmnistVal_loss.png')
plt.show()

在这里插入图片描述
在这里插入图片描述

12.数据增强

datagen = ImageDataGenerator(
    rotation_range=10,
    zoom_range=0.1,
)
datagen.fit(X_Train)

13.学习率重置

new_lr = ReduceLROnPlateau(monitor='val_accuracy',patience=2,verbose=1,
                           factor=0.5,min_lr=0.00001)

14.重新训练

epochs = 2
history2 = model.fit_generator(datagen.flow(X_Train,Y_Train,batch_size=batch_size),
                               steps_per_epoch=int(X_Train.shape[0]/batch_size)+1,
                               epochs=epochs,validation_data=(X_val,Y_val),callbacks=[new_lr])

15.保存模型

model.save('/BASICCNN/TrainModel_h5/CsvmnistTrain2.h5')

在这里插入图片描述

16.绘制训练和验证过程

fig = plt.figure(figsize=(20,7))
#121代表12列第一张
fig.add_subplot(121)
plt.plot(history2.epoch,history2.history['accuracy'],label='Train Accuracy')
plt.plot(history2.epoch,history2.history['val_accuracy'],label='Val Accuracy')
plt.title('Accuracy Curve',fontsize=18)
plt.xlabel('Epochs',fontsize=15)
plt.ylabel('Accuracy',fontsize=15)
plt.legend()
plt.savefig('/BASICCNN/TrainImage/CsvmnistTrain2_accuracy.png')
plt.show()

plt.plot(history2.epoch,history2.history['loss'],label='Train Loss')
plt.plot(history2.epoch,history2.history['val_loss'],label='Val Loss')
plt.title('Loss Curve',fontsize=18)
plt.xlabel('Epochs',fontsize=15)
plt.ylabel('Loss',fontsize=15)
plt.legend()
plt.savefig('/BASICCNN/TrainImage/CsvmnistVal2_loss.png')
plt.show()

在这里插入图片描述
在这里插入图片描述

17.显示被预测错误的图片

predict_val = np.argmax(model.predict(X_val),axis=1) #对验证集预测,输出每行预测概率最高的索引
rows = 10
cols = 10
fig = plt.figure(figsize=(cols,rows))
for i in range(rows*cols):
    if Y_val[i] != predict_val[i]:
        fig.add_subplot(rows,cols,1+i)  #图片添加到相应的位置
        plt.imshow(X_val[i].reshape([28,28]),cmap='BrBG')
        plt.axis('off')
        plt.title('T:'+str(Y_val[i])+'P:'+str(predict_val[i]),y=-0.15,color='blue') #显示对应标签
plt.savefig('/BASICCNN/TrainImage/Csvmnist_ShowError.png')
plt.show()

在这里插入图片描述

18.在测试上预测

Y_Test = np.argmax(model.predict(X_test),axis=1)
rows = 4
cols = 9
fig = plt.figure(figsize=(2*cols,2*rows))
for i in range(rows*cols):
    fig.add_subplot(rows,cols,i+1)  #图片添加到相应的位置
    plt.imshow(X_test[i].reshape([28,28]),cmap='PuOr')
    plt.axis('off')
    plt.title(str(Y_Test[i]),y=-0.15,color='blue') #显示对应标签
plt.savefig('/BASICCNN/TrainImage/Csvmnist_Test.png')
plt.show()

在这里插入图片描述

19.可视化模型中间层

#1 抽取模型所有层,除了Flatten和Dense层
output_layers = [layer.output for layer in model.layers[:-4]]
#2 创建新的模型,一个输入,多个输出
new_model = models.Model(inputs=model.input,outputs=output_layers)
#3 预测每一层的输出
pred_2 = new_model.predict(X_val[2].reshape([1,28,28,1]))
pred_6 = new_model.predict(X_val[6].reshape([1,28,28,1]))
#4 抽取预测结果的第一层
first_layer = pred_2[0]
first_layer.shape  #32 通道数
#5 显示以上两张图片,第一层的4个通道的图片
rows = 4
cols = 2
fig = plt.figure(figsize=(2*cols,2*rows))
for i in range(4):
    fig.add_subplot(rows,cols,2*i+1)
    plt.imshow(pred_2[0][0,:,:,i].reshape([28,28]),cmap='PuOr')
    plt.axis('off')
    fig.add_subplot(rows, cols, 2 * i + 2)
    plt.imshow(pred_6[0][0, :, :, i].reshape([28, 28]), cmap='PuOr')
    plt.axis('off')
    plt.savefig('/BASICCNN/TrainImage/Csvmnistlayer_compare'+str(i)+'.png')

first_layer.shape[2]
#7 定义可视化函数
def plot_layer(layer,i,layer_name=None):
    rows = layer.shape[-1]/16 #层的通道数
    cols = 16
    fig = plt.figure(figsize=(cols,rows))
    for i in range(layer.shape[-1]):
        fig.add_subplot(rows,cols,i+1)
        plt.imshow(layer[0,:,:,i].reshape(layer.shape[2],layer.shape[2]),cmap='Blues')
        plt.axis('off')
    fig.suptitle(layer_name,fontsize=14)
    fig.savefig('/BASICCNN/TrainImage/Csvmnistintlayer'+str(i)+'.png')
    plt.show()
#6 可视化所有中间层
for i ,layer in enumerate(new_model.predict(X_val[6].reshape([1,28,28,1]))):
    plot_layer(layer,i,output_layers[i].name)

在这里插入图片描述
在这里插入图片描述

20.将test的预测结果存入csv文件中

df_submit = pd.DataFrame([test_data.index+1,Y_Test],['Image ID','Label']).transpose()
df_submit.to_csv('/BASICCNN/MnistCsv/submit.csv',index=False)
dt = pd.read_csv('/BASICCNN/MnistCsv/submit.csv')
dt.head()

在这里插入图片描述

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个使用 PyTorch 框架实现的 MNIST 数字识别代码: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.transforms as transforms from torchvision.datasets import MNIST from torch.utils.data import DataLoader # 定义模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, 3, padding=1) self.conv2 = nn.Conv2d(32, 64, 3, padding=1) self.pool = nn.MaxPool2d(2) self.fc1 = nn.Linear(64 * 7 * 7, 128) self.fc2 = nn.Linear(128, 10) self.relu = nn.ReLU() def forward(self, x): x = self.relu(self.conv1(x)) x = self.pool(x) x = self.relu(self.conv2(x)) x = self.pool(x) x = x.view(-1, 64 * 7 * 7) x = self.relu(self.fc1(x)) x = self.fc2(x) return x # 定义超参数 batch_size = 64 learning_rate = 0.01 num_epochs = 5 # 加载数据集 train_dataset = MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) test_dataset = MNIST(root='./data', train=False, transform=transforms.ToTensor(), download=True) train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) # 实例化模型和损失函数以及优化器 model = Net() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=learning_rate) # 训练模型 for epoch in range(num_epochs): train_loss = 0.0 train_acc = 0.0 for i, (images, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() train_loss += loss.item() * images.size(0) _, preds = torch.max(outputs, 1) train_acc += torch.sum(preds == labels.data) train_loss = train_loss / len(train_loader.dataset) train_acc = train_acc / len(train_loader.dataset) print('Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.2f}%'.format(epoch+1, num_epochs, train_loss, train_acc*100)) # 测试模型 with torch.no_grad(): test_loss = 0.0 test_acc = 0.0 for i, (images, labels) in enumerate(test_loader): outputs = model(images) loss = criterion(outputs, labels) test_loss += loss.item() * images.size(0) _, preds = torch.max(outputs, 1) test_acc += torch.sum(preds == labels.data) test_loss = test_loss / len(test_loader.dataset) test_acc = test_acc / len(test_loader.dataset) print('Test Loss: {:.4f}, Test Accuracy: {:.2f}%'.format(test_loss, test_acc*100)) ``` 这个代码中定义了一个卷积神经网络模型,使用 SGD 优化器进行训练,最后在测试集上进行测试并输出结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值