交叉采样或如何从数据集中挤出千分之几

本文是关于图片和分类的。对属性进行细微的研究,例如触摸MNIST的肖像(好吧,这是解决其他类似问题的暗示)。



网络上有许多关于特定神经网络的解释以及某些观点对学习的意义和贡献的出版物。寻找晶须,尾巴和其他零件及其重要性和意义的工作很多。现在,我不会取代图书馆员并列出清单。我只说说我的实验。



一切都始于精彩的视频报告“机器人的思想。 ML模型的解释”,是在一个聪明人的建议下进行回顾的,并且像任何明智的企业一样,提出了许多问题。例如:-数据集的关键点有多独特?



或另一个问题:-网络上有很多文章介绍如何更改图片的一个点会严重扭曲网络预测。让我提醒您,在本文中,我们将仅考虑分类问题。这个阴险点有多独特?在MNIST的自然序列中是否存在这样的点,如果发现并抛出这些点,神经网络的训练精度会更高吗?



作者遵循摆脱所有不必要方法的传统方法,决定不干扰其他问题,并选择了一种简单,可靠和有效的方法来研究所提出的问题:



作为实验问题,作为准备的示例,请选择熟悉的MNIST(yann.lecun.com/exdb/mnist)及其分类。



作为实验网络,我选择了适合初学者使用的经典网络,即KERAS团队的一个示例网络

github.com/keras-team/keras/blob/master/examples/mnist_cnn.py



。我决定自己进行这项研究。



让我们以一种停止标准来训练KERAS的网络,例如在测试序列上准确性没有增加的情况下。教导网络,直到test_accuracy变得大大大于validation_accuracy,并且validation_accuracy在15个时期内没有改善。换句话说,网络停止了学习,开始了再培训。



从MNIST数据集中,我们将通过丢弃点组来创建324个新数据集,并且将由相同网络在完全相同的条件下以相同的初始权重进行授课。



让我们开始吧,我认为布局从第一行到最后一行的所有代码是正确的。即使读者看过他,显然很多次。



我们加载库并加载mnist数据集(如果尚未加载)。



然后,将其转换为'float32'格式,并将其规格化为0。-1。



准备工作已经结束。



'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
from keras.optimizers import *
from keras.callbacks import EarlyStopping

import numpy as np
import os

num_classes = 10

# input image dimensions
img_rows, img_cols = 28, 28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= np.max(x_train)
x_test /= np.max(x_test)

XX_test = np.copy(x_test)
XX_train = np.copy(x_train)
YY_test = np.copy(y_test)
YY_train = np.copy(y_train)


print('x_train shape:', XX_train.shape)
print('x_test shape:', XX_test.shape)




让我们在变量中记住模型文件和权重的名称,以及网络的准确性和损失。这不在源代码中,但是对于实验来说是必需的。



f_model = "./data/mnist_cnn_model.h5"
f_weights = "./data/mnist_cnn_weights.h5"
accu_f = 'accuracy'
loss_f = 'binary_crossentropy'


网络本身与

github.com/keras-team/keras/blob/master/examples/mnist_cnn.py上的完全相同



保存网络并扩展到磁盘。我们将以相同的初始权重进行所有训练尝试:



y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=[loss_f], optimizer=Adam(lr=1e-4), metrics=[accu_f])
model.summary()

model.save_weights(f_weights)
model.save(f_model)


Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 12, 12, 64)        0         
_________________________________________________________________
dropout (Dropout)            (None, 12, 12, 64)        0         
_________________________________________________________________
flatten (Flatten)            (None, 9216)              0         
_________________________________________________________________
dense (Dense)                (None, 128)               1179776   
_________________________________________________________________
dropout_1 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 1,199,882
Trainable params: 1,199,882
Non-trainable params: 0
_________________________________________________________________


让我们开始对初始mnist进行训练,以获得基准,基本效率。



x_test = np.copy(XX_test)
x_train = np.copy(XX_train)
s0 = 0

if os.path.isfile(f_model):
    model = load_model(f_model)
    model.load_weights(f_weights, by_name=False)

    step = 0
    while True:
        
        fit = model.fit(x_train, y_train,
                  batch_size=batch_size,
                  epochs=1,
                  verbose=0,
                  validation_data=(x_test, y_test)
                )
        
        current_accu = fit.history[accu_f][0]
        current_loss = fit.history['loss'][0]
        val_accu = fit.history['val_'+accu_f][0]
        val_loss = fit.history['val_loss'][0]
        print("\x1b[2K","accuracy {0:12.10f} loss {1:12.10f} step {2:5d} val_accu {3:12.10f} val_loss {4:12.10f}  ".\
                          format(current_accu, current_loss, step, val_accu, val_loss), end="\r")
    
        step += 1
        if val_accu > max_accu:
            s0 = 0
            max_accu = val_accu
        else:
            s0 += 1
        if current_accu * 0.995 > val_accu and s0 > 15:
            break
else:
    print("model not found ")

accuracy 0.9967333078 loss 0.0019656278 step   405 val_accu 0.9916999936 val_loss 0.0054226643  


现在让我们开始主要实验。我们从原始序列中训练了所有60,000张标记好的图片,并在其中重置了9x9正方形以外的所有内容。让我们获得324个实验序列,并将对它们进行网络训练的结果与对原始序列进行训练的结果进行比较。我们用相同的初始权重训练相同的网络。



batch_size = 5000
s0 = 0
max_accu = 0.

for i in range(28 - 9):
    for j in range(28 - 9):
        print("\ni= ", i, "  j= ",j)
        x_test = np.copy(XX_test)
        x_train = np.copy(XX_train)

        x_train[:,:i,:j,:] = 0.
        x_test [:,:i,:j,:] = 0.

        x_train[:,i+9:,j+9:,:] = 0.
        x_test [:,i+9:,j+9:,:] = 0.

        if os.path.isfile(f_model):
            model = load_model(f_model)
            model.load_weights(f_weights, by_name=False)
        else:
            print("model not found ")
            break

        step = 0
        while True:
            
            fit = model.fit(x_train, y_train,
                      batch_size=batch_size,
                      epochs=1,
                      verbose=0,
                      validation_data=(x_test, y_test)
                    )
            
            current_accu = fit.history[accu_f][0]
            current_loss = fit.history['loss'][0]
            val_accu = fit.history['val_'+accu_f][0]
            val_loss = fit.history['val_loss'][0]
            print("\x1b[2K","accuracy {0:12.10f} loss {1:12.10f} step {2:5d} val_accu {3:12.10f} val_loss {4:12.10f}  ".\
   format(current_accu, current_loss, step, val_accu, val_loss), end="\r")
        
            step += 1
            if val_accu > max_accu:
                s0 = 0
                max_accu = val_accu
            else:
                s0 += 1
            if current_accu * 0.995 > val_accu and s0 > 15:
                break


在这里发布所有324个结果没有任何意义,如果有人感兴趣,我可以亲自发送。如果有人要重复计算,则需要几天的时间。



事实证明,在9x9剪辑上的网络可以学习得更糟,这很明显,但也可以学得更好,这一点都不明显。



例如:



I = 0 J = 14

准确性0.9972333312损失0.0017946947步骤450 val_accu 0.9922000170 val_loss 0.0054322388



I = 18,J = 1和

准确性0.9973166585损失0.0019487827步骤415 val_accu 0.9922000170 val_loss 0.0053000450



我们扔掉从图片手写号码之外的所有方9x9的与学习的质量和知名度与我们一起提高



同样很明显,有一个以上的特殊领域可以提高网络质量。不是两个,而是以这两个为例。



实验结果和初步结论。



  • 我认为LeCune不会故意扭曲任何自然数据集,它不仅包含学习必不可少的点,而且还包含干扰学习的点。即使它们不可见,找到“有害”点的任务也变得迫在眉睫。
  • 您不仅可以沿数据集堆叠和融合,成组选择图像,还可以跨和堆叠,选择要分割的图像区域,然后照常进行叠加和混合。在这种情况下,这种方法可以提高培训质量,并且希望在类似的任务中,这种堆叠使用可以提高质量。在同一个kaggle.com上,有时(几乎总是)十分之几可以极大地提高您的权威和评价。


感谢您的关注。



All Articles