¿Qué pasos de procesamiento previo recomendaría para un aprendizaje automático exitoso en un conjunto de datos MNIST?

Contrariamente a mi intuición, la introducción de ruido aleatorio y distorsiones en mi conjunto de entrenamiento en realidad mejoró mi clasificación correcta dramáticamente.

Primero, normalicé cada dígito con respecto al tamaño y la escala. Luego hice copias distorsionadas de cada dígito de entrenamiento. La distorsión incluía agregar ruido, estirar y rotar los dígitos.

La idea se presenta aquí:
http://arxiv.org/pdf/1003.0358.pdf

Opencv en python hace que todo esto sea bastante fácil. Aquí hay un código de Python (probablemente malo) que puede usar para normalizar los dígitos, que sería el enfoque tradicional, y luego distorsionarlos.

### IMPORTACIONES ############################################## ######################

importar os
importar cv2
importar csv
importar numpy
matemáticas de importación

### ARGS OPERACIONALES ############################################# ##############

### MODO DEPURACIÓN: IMPRIME EL NÚMERO DE IMÁGENES ESPECIFICADAS POR BEDUG_CUTOFF
DEPURACIÓN = Falso
DEBUG_CUTOFF = 10

### MODO DE TREN
TREN = Verdadero # AGREGA ETIQUETAS A LA PRIMERA COLUMNA
NORMALIZE_ONLY = False # NO AGREGA REGISTROS DISTORTADOS

### IO LOCATION – FILE_IN AND FILE_OUT DEBE ESTAR EN DIR
DIR = ‘C: / Ruta / a / digitsData’
FILE_IN = ‘train.csv’
FILE_OUT = ‘train_augmented.csv’

### NÚMEROS MÁGICOS GLOBALES PARA IMÁGENES … LO SÉ, OK … #########################

INPUT_SIZE = (28, 28) # TAMAÑO DE LA IMAGEN DE ENTRADA, 2-TUPLE
OUT_SIZE = (27, 27) # TAMAÑO DE LA IMAGEN DE SALIDA, 2-TUPLE

NORM_SIZE = (21, 21) # TAMAÑO FINAL DE LA CAJA DE LÍMITES PARA IMÁGENES NORMALIZADAS, 2-TUPLE, <OUT_SIZE
NORM_EXPAND_SIZE = int ((27-NORM_SIZE [0]) / 2)

LARGE_SIZE = (25,25) # TAMAÑO FINAL DE LA CAJA DE LÍMITES PARA IMÁGENES AMPLIADAS, 2-TUPLE, <OUT_SIZE
LARGE_EXPAND_SIZE = int ((27-LARGE_SIZE [0]) / 2)

RAND_PERCENT = .15 # INYECCIÓN DE RUIDO, <1.0
RAND_THRESHOLD = int (OUT_SIZE [0] * OUT_SIZE [0] * RAND_PERCENT)

GRADO = 15 # GRADO DE ROTACIÓN

### MÁS COMPLICADO …

# CONVERTIR UN NÚMERO 1, 7 U OTRO SKINNY EN UN CUADRADO DURANTE LA NORMALIZACIÓN ES DUMB
# EVITE HACERLO, NO VUELVA A AJUSTAR LOS NÚMEROS CUYA DEJÓ MÁS PÍXELES SE ENCUENTRA
# EN UN ÍNDICE> = A SKINNY_THRESHOLD
SKINNY_THRESHOLD = 10

# DIFÍCIL DE VER (Y POR LO TANTO PRUEBA) LA CAJA DE LÍMITES SIN ESTO, 0-255
TO_BLACK_THRESHOLD = 50

### ESCRIBIR IMAGEN PARA GRABAR ########################################### ###########

def write_image_to_record (src, out_csv, row_label = Ninguno):
out = numpy.array (src) .flatten ()
if (row_label! = None): out = numpy.insert (out, 0, row_label)
out_csv.writerow (fuera)

### NORMALIZAR ESCALA ############################################## ###############

def normalize_scale (src, out_size = OUT_SIZE, norm_size = NORM_SIZE, \
norm_expand_size = NORM_EXPAND_SIZE, skinny_threshold = SKINNY_THRESHOLD, \
to_black_threshold = TO_BLACK_THRESHOLD):

src [src <to_black_threshold] = 0
bottom, top = numpy.min (numpy.nonzero (src) [0]), numpy.max (numpy.nonzero (src) [0])
izquierda, derecha = numpy.min (numpy.nonzero (src.T) [0]), numpy.max (numpy.nonzero (src.T) [0])
bounding_box = src [abajo: arriba + 1, izquierda: derecha + 1]
if (left> = skinny_threshold): skinny = True
más: flaco = Falso
si es delgado: devuelve cv2.resize (src, (out_size))
más:
norma = cv2.resize (bounding_box, (norm_size))
return cv2.copyMakeBorder (norm, norm_expand_size, norm_expand_size, norm_expand_size, norm_expand_size, 0)

### RUIDO DE INYECCIÓN ############################################# ##################

def inject_noise (src, out_size = OUT_SIZE, rand_threshold = RAND_THRESHOLD):

ruido = numpy.copy (src) # COPIA PROFUNDA NECESARIA
ruido [numpy.random.randint (out_size [0] -1, tamaño = rand_threshold), numpy.random.randint (out_size [0] -1, tamaño = rand_threshold)] = 0
ruido de retorno

### AMPLIAR ############################################## ######################

def enlarge (src, skinny_threshold = SKINNY_THRESHOLD, input_size = INPUT_SIZE, \
out_size = OUT_SIZE, large_size = LARGE_SIZE, large_expand_size = LARGE_EXPAND_SIZE):

bottom, top = numpy.min (numpy.nonzero (src) [0]), numpy.max (numpy.nonzero (src) [0])
izquierda, derecha = numpy.min (numpy.nonzero (src.T) [0]), numpy.max (numpy.nonzero (src.T) [0])
bounding_box = src [abajo: arriba + 1, izquierda: derecha + 1]
if (left> = skinny_threshold): skinny = True
más: flaco = Falso
si (flaco):
tall_bounding_box = src [bottom-1: top + 2, 0: input_size [0] -1]
return cv2.resize (tall_bounding_box, (out_size))
más:
large = cv2.resize (bounding_box, large_size)
return cv2.copyMakeBorder (large, large_expand_size, large_expand_size, large_expand_size, large_expand_size, 0)

### ROTAR (Y TRADUCIR) ########################################## ###########

def rotate_about_center (src, angle, scale = 1.):

w = src.shape [1]
h = src.shape [0]
rangle = numpy.deg2rad (ángulo) # ANGLE IN RADS
# CALCULAR NUEVAS DIMENSIONES DE IMAGEN
nw = (abs (numpy.sin (rangle) * h) + abs (numpy.cos (rangle) * w)) * scale
nh = (abs (numpy.cos (rangle) * h) + abs (numpy.sin (rangle) * w)) * escala
# OBTENER MATRIZ DE ROTACIÓN
rot_mat = cv2.getRotationMatrix2D ((nw * 0.5, nh * 0.5), ángulo, escala)
# CENTROS ANTIGUOS Y NUEVOS COMBINADOS CON ROTACIÓN
rot_move = numpy.dot (rot_mat, numpy.array ([(nw-w) * 0.5, (nh-h) * 0.5,0]))
# ACTUALIZAR TRADUCCIÓN
rot_mat [0,2] + = rot_move [0]
rot_mat [1,2] + = rot_move [1]
return cv2.warpAffine (src, rot_mat, (int (math.ceil (nw)), int (math.ceil (nh))), flags = cv2.INTER_LANCZOS4)

def main ():

### IO
file_in = open (DIR + ‘/’ + FILE_IN, ‘rb’)
im_in_csv = csv.reader (file_in, dialect = ‘excel’)
file_out = open (DIR + ‘/’ + FILE_OUT, ‘wb’)
im_out_csv = csv.writer (file_out, dialect = ‘excel’)

para i, fila en enumerate (im_in_csv):
si i> 0: # ROW 0 ES SOLO ETIQUETAS

imprimir ‘Procesando imagen’ + str (i) + ‘…’

### GUARDAR ETIQUETA Y LEER LA FILA EN LA IMAGEN
row_array = numpy.asarray (fila)
row_array = row_array.astype (numpy.float32)
row_label = Ninguno
si (TREN):
row_label = row_array [0]
img = numpy.reshape (row_array [1:], (INPUT_SIZE))
más:
img = numpy.reshape (row_array, (INPUT_SIZE))
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘raw’ + str (i) + ‘.jpg’, img)

### NORMALIZAR ESCALA
norma = normalizar_escala (img)
write_image_to_record (norma, im_out_csv, row_label)
if (DEPURACIÓN): cv2.imwrite (DIR + ‘/’ + ‘norm’ + str (i) + ‘.jpg’, norm)
if (NORMALIZE_ONLY): continuar

si (TREN):

ruido = ruido_inyectar (norma)
write_image_to_record (noise, im_out_csv, row_label)
if (DEPURACIÓN): cv2.imwrite (DIR + ‘/’ + ‘noise’ + str (i) + ‘.jpg’, noise)

grande = agrandar (norma)
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘large’ + str (i) + ‘.jpg’, large)
ruido_grande = agrandar (ruido)
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘large_noise’ + str (i) + ‘.jpg’, large_noise)

# rotar + grados
plus = cv2.resize (rotate_about_center (grande, GRADO), OUT_SIZE)
write_image_to_record (plus, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_p’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, más)
plus_noise = cv2.resize (rotate_about_center (large_noise, DEGREE), OUT_SIZE)
write_image_to_record (plus_noise, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_noise_p’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, plus_noise)

# rotar – grados
menos = cv2.resize (rotate_about_center (grande, -DEGREE), (OUT_SIZE))
write_image_to_record (minus, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_m’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, menos)
menos ruido = cv2.resize (rotate_about_center (large_noise, -DEGREE), (OUT_SIZE))
write_image_to_record (minus_noise, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_noise_m’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, minus_noise)

si (DEPURACIÓN):
if (i> = DEBUG_CUTOFF):
descanso

más: im_out_csv.writerow (fila [0: OUT_SIZE [0] * OUT_SIZE [0] +1]) # ESCRIBE ETIQUETAS DE LA FILA

file_in.close ()
file_out.close ()

imprimir ‘Listo’

if __name__ == “__main__”:
principal()

More Interesting

¿Los modelos de aprendizaje automático en automóviles sin conductor utilizan aprendizaje supervisado, no supervisado o de refuerzo?

¿Cuál es más importante de los tres, es decir, informática ubicua, informática distribuida y procesamiento de lenguaje natural, en el mundo de hoy?

¿Qué significa realmente el valor semilla en el algoritmo de aprendizaje automático?

¿Qué significa el término difusión en bibliotecas numéricas con matrices como MATLAB, Numpy o TensorFlow?

¿Debo comenzar a aprender Python y el aprendizaje automático al mismo tiempo?

Cómo construir y ejecutar mi primera red de aprendizaje profundo

¿Cuál es la diferencia entre Empirical Bayes e inferencia bayesiana?

Quiero escribir un trabajo de investigación sobre análisis de sentimientos, pero no sé nada sobre el análisis de sentimientos. ¿Cómo debo proceder?

Dadas las variables / parámetros continuos, ¿cuál es la diferencia entre el aprendizaje automático y la interpolación?

¿Es posible que, en el futuro, los países sean manejados por una súper computadora que calcule el mejor resultado de una decisión política?

¿Alguna forma de dormir será esencial en la IA (inteligencia artificial)?

Cómo obtener la etiqueta del tema que modela la salida LDA

¿Qué tan grande es el mercado de consultoría de aprendizaje automático para nuevas empresas?

¿Cuál es la posibilidad de que un humano gane el juego de entropía?

Cómo planear mover mi carrera hacia el aprendizaje automático en India