用简单卷积神经网络实现手写体数字识别

环境:python,anaconda ,tensorflow

数据来源:kaggle网站:https://www.kaggle.com/c/digit-recognizer/data

import numpy as np
import pandas as pd
#获取数据
train_data = pd.read_csv('./dataset/digit-recognizer/train.csv')
test_data = pd.read_csv('./dataset/digit-recognizer/test.csv')

#查看数据样式
train_data.head()
#查看数据中有没有缺失值
##(看样子没有缺失值)
Col_with_missing = [col for col in train_data.columns if train_data[col].isnull().any()]
print(Col_with_missing)
#输出:[]

Col_with_missing = [col for col in test_data.columns if test_data[col].isnull().any()]
print(Col_with_missing)
#输出:[]

#查看训练数据中各个类别的分布情况
Y_train.value_counts()

#输出如下:(看上去还算均匀,如果各类别数据明显不均衡会影响训练结果)
#1    4684
#7    4401
#3    4351
#9    4188
#2    4177
#6    4137
#0    4132
#4    4072
#8    4063
#5    3795


#再用如下柱状图看一下个数据分布情况
import seaborn as sns
%matplotlib inline
sns.countplot(Y_train)

#我们数据集中的图像是28*28
img_row = 28
img_col = 28
#对图像数据归一化方法
def data_prep_X(X):
    num_img=len(X)
    x_as_array = X.values.reshape(num_img,img_row,img_col,1)
    X_out = x_as_array / 255
    return X_out


from keras.utils.np_utils import to_categorical
num_classes = 10
#将标签数据转为one_hot格式
def data_prep_Y(Y):
    out_y = to_categorical(Y,num_classes)
    return out_y

#对数据进行归一化处理
X_train = data_prep_X(X_train)
test_data = data_prep_X(test_data)
#标签数据转为one-hot
Y_train = data_prep_Y(Y_train)

#看看归一化后的图像样式
import matplotlib.pyplot as plt
plt.imshow(X_train[0][:,:,0])

from tensorflow.python import keras
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense,Flatten,Conv2D
from tensorflow.keras.callbacks import EarlyStopping

#EarlyStopping早停法,防止过拟合,此处我们不用
#early_stop = EarlyStopping(monitor='val_loss',patience=1)

#如下模型有3层卷积层
#Flatten,卷积层之后是无法直接连接Dense全连接层的,
#需要把卷积层的数据压平(Flatten),然后就可以直接加Dense层了

#Conv2D(20,kernel_size=(3,3)
# 20表示卷积核的个数,也可以自己设定,但是要考虑计算速度和防止过拟合
# (3,3)表示卷积核大小,也可以自己设定

#模型的结构可以自己设定,比如加入池化以及droupout等,模型的变化会对计算速度和准确度有影响

model = Sequential()

model.add(Conv2D(20,kernel_size=(3,3),
                activation='relu',
                input_shape=(img_row,img_col,1)))
model.add(Conv2D(20,kernel_size=(3,3),
                activation='relu'))
model.add(Flatten())
model.add(Dense(128,activation='relu'))
model.add(Dense(num_classes,activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
             optimizer='adam',
             metrics=['accuracy'])

#开始训练validation_split 表示将数据分割为训练数据和验证数据的比例
model.fit(X_train,Y_train,
         batch_size=128,
         epochs=20,
         validation_split=0.2,
          #callbacks=[early_stop]
         )
#训练过程中的损失和准确度
losses_acc = pd.DataFrame(model.history.history)
losses_acc

 

#损失图像如下
losses_acc[['loss','val_loss']].plot()

# 预测
results = model.predict(test_data)

results = np.argmax(results,axis = 1)

results = pd.Series(results,name="Label")

print(results)
#如下可以看到预测结果第一个图像预测为2,第二个预测为0,第三那个预测为9

#我们画图看一下预测预测结果为2的第一个图像是什么样子
plt.imshow(test_data[0][:,:,0])

#第27998个图像(预测为9)
plt.imshow(test_data[27998][:,:,0])

 

 

#我们将预测结果保存为mySubmission.csv
submission = pd.concat([pd.Series(range(1,28001),name = "ImageId"),results],axis = 1)

submission.to_csv("mySubmission.csv",index=False)

至此我们一个简单的通过CNN训练的手写体数字识别就完成了!

首次发帖不喜勿喷,欢迎指正

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值