kaggle 手写数字识别

本文介绍了一种使用深度学习进行手写数字识别的方法,通过Kannada-MNIST数据集进行训练,详细展示了数据预处理、模型搭建、训练及评估的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习最好的办法就是实践。

深度学习有很多入门的数据集,手写数字数据集是其中一个代表。

以Kannada-MNIST为例:我们做一个手写数字识别的程序。

引入pandas,做数据预处理用的。

import pandas as pd

加载训练数据

train_data = pd.read_csv("/kaggle/input/Kannada-MNIST/train.csv")

加载测试数据
test_data = pd.read_csv("/kaggle/input/Kannada-MNIST/test.csv")

取出训练数据的标签

train_y = train_data["label"]

取出训练数据的样本
train_x = train_data.drop(labels = ["label"], axis = 1)

把数据reshape成28*28的图像

train_x = np.array(train_x).reshape(-1,28,28,1)

把数据做一个归一化,成0~1之间的数
train_x = train_x/255

引入图像绘制库

import matplotlib.pyplot as plt

显示第一张训练数据的图像
g = plt.imshow(train_x[0][:,:,0])

引入一堆keras的API

模型容器

from keras.models import Sequential

全连接,卷积,若干优化算法
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, BatchNormalization

梯度算法优化器
from keras.optimizers import Adam

数据增强
from keras.preprocessing.image import ImageDataGenerator

动态调整学习率
from keras.callbacks import ReduceLROnPlateau

算法模型

容器

model = Sequential()

卷积
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu',input_shape = (28,28,1)))

归一化
model.add(BatchNormalization())
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())

池化层
model.add(MaxPool2D(pool_size=(2,2)))

丢弃部分参数
model.add(Dropout(0.36))
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.36))
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())

拉直
model.add(Flatten())

全连接
model.add(Dense(512,activation='relu'))
model.add(Dense(64,activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.25))

多分类

model.add(Dense(10, activation = "softmax"))

打印出模型
from keras.utils import plot_model
plot_model(model, to_file='model.png', show_shapes=True, show_layer_names=True)
from IPython.display import Image
Image("model.png")

from keras.optimizers import Adam
# 定义Optimizer
optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
# 编译model
model.compile(optimizer = optimizer , loss = "categorical_crossentropy", metrics=["accuracy"])
# 设置学习率的动态调整
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.5, 
                                            min_lr=0.00001)
epochs = 50
batch_size = 128
# 通过数据增强来防止过度拟合
datagen = ImageDataGenerator(
        featurewise_center=False, # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.1, # Randomly zoom image 
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=False,  # randomly flip images
        vertical_flip=False)  # randomly flip images
datagen.fit(train_x)

# 训练模型
history = model.fit_generator(datagen.flow(train_x,train_y, batch_size=batch_size),
                              epochs = epochs, validation_data = (val_x,val_y),
                              verbose = 2, steps_per_epoch=train_x.shape[0] // batch_size
                              , callbacks=[learning_rate_reduction])

# 画训练集和验证集的loss和accuracy曲线。可以判断是否欠拟合或过拟合
fig, ax = plt.subplots(2,1)
ax[0].plot(history.history['loss'], color='b', label="Training loss")
ax[0].plot(history.history['val_loss'], color='r', label="validation loss",axes =ax[0])
legend = ax[0].legend(loc='best', shadow=True)

ax[1].plot(history.history['acc'], color='b', label="Training accuracy")
ax[1].plot(history.history['val_acc'], color='r',label="Validation accuracy")
legend = ax[1].legend(loc='best', shadow=True)

from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import itertools
# 画出混淆矩阵,可以用来观察误判比较高的情况

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
    
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

# Predict the values from the validation dataset
Y_pred = model.predict(val_x)
# Convert predictions classes to one hot vectors 
Y_pred_classes = np.argmax(Y_pred,axis = 1) 
# Convert validation observations to one hot vectors
Y_true = np.argmax(val_y,axis = 1) 
# compute the confusion matrix
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes) 
# plot the confusion matrix
plot_confusion_matrix(confusion_mtx, classes = range(10)) 

# 显示一些错误结果,及预测标签和真实标签之间的不同
errors = (Y_pred_classes - Y_true != 0)

Y_pred_classes_errors = Y_pred_classes[errors]
Y_pred_errors = Y_pred[errors]
Y_true_errors = Y_true[errors]
X_val_errors = val_x[errors]

def display_errors(errors_index,img_errors,pred_errors, obs_errors):
    """ This function shows 6 images with their predicted and real labels"""
    n = 0
    nrows = 2
    ncols = 3
    fig, ax = plt.subplots(nrows,ncols,sharex=True,sharey=True)
    for row in range(nrows):
        for col in range(ncols):
            error = errors_index[n]
            ax[row,col].imshow((img_errors[error]).reshape((28,28)))
            ax[row,col].set_title("Predicted label :{}\nTrue label :{}".format(pred_errors[error],obs_errors[error]))
            n += 1
            # Probabilities of the wrong predicted numbers
Y_pred_errors_prob = np.max(Y_pred_errors,axis = 1)

# Predicted probabilities of the true values in the error set
true_prob_errors = np.diagonal(np.take(Y_pred_errors, Y_true_errors, axis=1))

# Difference between the probability of the predicted label and the true label
delta_pred_true_errors = Y_pred_errors_prob - true_prob_errors

# Sorted list of the delta prob errors
sorted_dela_errors = np.argsort(delta_pred_true_errors)

# Top 6 errors 
most_important_errors = sorted_dela_errors[-6:]

# Show the top 6 errors
display_errors(most_important_errors, X_val_errors, Y_pred_classes_errors, Y_true_errors)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值