ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kaggle之Digit Recognizer

2019-09-11 10:00:52  阅读:216  来源: 互联网

标签:Digit errors val pred kaggle train Recognizer model size


文章目录


 
  没有数据的预先处理,也没有没有数据增强,直接上神经网络训练然后测试,虽然准确率大致为0.97,但是排名为两千多名。之后在评论区找到一个评价较好且预测准确率较高的笔记参考下,还是有很多不足。一是了解率keras环境下的一些函数操作,二是了解到数据的预先处理查看以及增强同样也很重要,三是对训练测试完的模型需要一些图像和混淆矩阵判断模型的表现。

model的建立

先说说模型,这里keras的模型搭建在熟悉率相关函数后较为简单,这里给出了代码和相关解释

model = Sequential()

# 没有标明步长默认为1
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                 activation ='relu', input_shape = (28,28,1)))
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                 activation ='relu'))
# keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid')
model.add(MaxPool2D(pool_size=(2,2)))
# 需要丢弃的输入比例,将一些置为0
model.add(Dropout(0.25))


model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                 activation ='relu'))
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                 activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))


model.add(Flatten())
model.add(Dense(256, activation = "relu"))
model.add(Dropout(0.5))
model.add(Dense(10, activation = "softmax"))

# 建议使用优化器的默认参数,除了学习率 lr
optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
# 编译创建好的模型,网络模型搭建完后,需要对网络的学习过程进行配置,否则在调用 fit 或 evaluate 时会抛出异常
model.compile(optimizer = optimizer , loss = "categorical_crossentropy", metrics=["accuracy"])
# Set a learning rate annealer 标准评估停止提升时,降低学习速率
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.5, 
                                            min_lr=0.00001)

数据的预处理以及数据增强

其实越来越感觉模型的建立因为都大同小异,除非你能新提出一个新的网络结构,最重要的影响最终结果的就是数据的相关处理。数据的预处理在keras中主要利用pandas.read_csv函数对csv文件进行读取,读取后的数据格式是dataframe


# pd 读取为dataframe格式
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")

# 查找一列的'label'值,X是训练集,Y是标签
Y_train = train["label"]
# Drop 'label' column,drop函数默认删除行,列需要加axis = 1
X_train = train.drop(labels = ["label"],axis = 1) 
# free some space,是个好习惯
del train 

# 图像可视化,观察已有数据的整体分布情况,合理分块进行训练
# sns.set(style='white', context='notebook', palette='deep')
# 以'label'列的不同数据为类别(作为x轴)分类画图
# g = sns.countplot(Y_train)
# 各个数据的个数
# Y_train.value_counts()

# Check the data
# df.isnull().any()会判断哪些列包含缺失值,该列存在缺失值则返回True,反之False
# isnull().sum()就更加直观了,它直接告诉了我们每列缺失值的数量
X_train.isnull().any().describe()
test.isnull().any().describe()

# Normalize the data (0~1)
X_train = X_train / 255.0
test = test / 255.0

# 在这里调整数据的输入和输出格式
# Reshape image in 3 dimensions (height = 28px, width = 28px , canal = 1),这里加上-1后是4维
X_train = X_train.values.reshape(-1,28,28,1)
test = test.values.reshape(-1,28,28,1)
# Encode labels to one hot vectors( train number *10) (ex : 2 -> [0,0,1,0,0,0,0,0,0,0]),列为0~9,每个为其对应数的概率
Y_train = to_categorical(Y_train, num_classes = 10)

# 在这里加上这个是为了保证数据的随机划分也和笔者保持一致
random_seed = 2
# rain_test_split函数用于将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签 
# X_train,Y_train是0.9的训练数据和标签,X_val,Y_val是0.1的测试数据和标签
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.1, random_state=random_seed)

在这里插入图片描述
上述代码g = sns.countplot(Y_train)展示的图可以很直观的显示训练数据的平均分配,可以让训练比较可靠
数据增强后的训练:这里ImageDataGenerator是用于数据增强的函数


# Turn epochs to 30 to get 0.9967 accuracy
epochs = 1 
batch_size = 86

# Without data augmentation i obtained an accuracy of 0.98114
#history = model.fit(X_train, Y_train, batch_size = batch_size, epochs = epochs, 
#          validation_data = (X_val, Y_val), verbose = 2)
# With data augmentation to prevent overfitting (accuracy 0.99286)

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
# x: 样本数据。秩应该为 4。对于灰度数据,通道轴的值应该为 1;对于 RGB 数据,值应该为 3。
# datagen.fit(train_data)正是用于计算train_data数据的均值,标准差等会更mean,std,principal_compoments
datagen.fit(X_train)



# Fit the model
# batch的size设置的不能太大也不能太小,因此实际工程中最常用的就是mini-batch,一般size设置为几十或者几百
# fit_generator函数返回History对象,其记录了运行输出
# steps_per_epoch:整数,当生成器返回steps_per_epoch次数据时计一个epoch结束,执行下一个epoch
# verbose: 日志显示模式。0,1 或 2。0 = 安静模式,1 = 进度条,2 = 每轮一行
history = model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),
                              epochs = epochs, validation_data = (X_val,Y_val),
                              verbose = 2, steps_per_epoch=X_train.shape[0] // batch_size,  
                              callbacks=[learning_rate_reduction])                            

训练完后模型的评测

在这里其实算是最终的已经训练好模型的评测,对训练次数的决定以及相关干扰图像的摘选等都很有意义

# 训练与测试的准确率和错误率图像
fig, ax = plt.subplots(2,1)
# History类对象包含两个属性,分别为epoch和history,epoch为训练轮数,history字典含val_loss,val_acc,loss,acc四个key值
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)



# 建立误差矩阵用于估计判断整个模型的好坏
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:
    	# astype:转换数组的数据类型
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    thresh = cm.max() / 2.
    # product(A, B)函数,返回A、B中的元素的笛卡尔积的元组
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        # 这里i,j为何反转不清楚
        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 1*10
Y_pred = model.predict(X_val)
# 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(Y_val,axis = 1) 
# compute the confusion matrix
# sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
# y_true: 是样本真实分类结果,y_pred: 是样本预测分类结果
# labels:是所给出的类别,通过这个可对类别进行选择
# sample_weight : 样本权重
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes) 
# plot the confusion matrix
plot_confusion_matrix(confusion_mtx, classes = range(10)) 


# 找出那些预测错误且和真实标签概率相差较大的图像
# Errors are difference between predicted labels and true labels
# error=[ True False  True……]
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 = X_val[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
# take(a,b,)从a中取出b位置对应的数,这里take会得到矩阵sizi:num(error)* num(error)
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_dela_errors = np.argsort(delta_pred_true_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)

在这里插入图片描述
可以看到随着训练损失度逐渐下降,而准确度在提升
在这里插入图片描述
这里混淆矩阵显示率整体的预测与真实的对照关系

总结

  按照上述方法排名提升至三百七十多,对于最开始的提交是没有在keras,tensorflow这类平台上撰写的代码,只能针对一些较为简单的项目,还是需要了解这些平台下的函数以及相关使用方法

标签:Digit,errors,val,pred,kaggle,train,Recognizer,model,size
来源: https://blog.csdn.net/csdnczx/article/details/100677375

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有