Saltar al contenido

Cómo calcular el tamaño de lote óptimo

Solución:

Del reciente libro Deep Learning de Goodfellow et al., Capítulo 8:

Los tamaños de minibatch generalmente dependen de los siguientes factores:

  • Los lotes más grandes proporcionan una estimación más precisa del gradiente, pero con rendimientos menos que lineales.
  • Las arquitecturas multinúcleo suelen estar infrautilizadas por lotes extremadamente pequeños. Esto motiva el uso de un tamaño de lote mínimo absoluto, por debajo del cual no hay reducción en el tiempo para procesar un minibatch.
  • Si todos los ejemplos del lote se van a procesar en paralelo (como suele ser el caso), la cantidad de memoria se escala con el tamaño del lote. Para muchas configuraciones de hardware, este es el factor limitante en el tamaño del lote.
  • Algunos tipos de hardware logran un mejor tiempo de ejecución con tamaños específicos de arreglos. Especialmente cuando se utilizan GPU, es común que la potencia de 2 tamaños de lote ofrezca un mejor tiempo de ejecución. La potencia típica de 2 tamaños de lote varía de 32 a 256, y a veces se intenta 16 para modelos grandes.
  • Los lotes pequeños pueden ofrecer un efecto regularizador (Wilson y Martinez, 2003), quizás debido al ruido que agregan al proceso de aprendizaje. El error de generalización suele ser mejor para un tamaño de lote de 1. El entrenamiento con un tamaño de lote tan pequeño puede requerir una tasa de aprendizaje pequeña para mantener la estabilidad debido a la gran variación en la estimación del gradiente. El tiempo de ejecución total puede ser muy alto como resultado de la necesidad de realizar más pasos, tanto por la tasa de aprendizaje reducida como porque se requieren más pasos para observar todo el conjunto de entrenamiento.

Lo que en la práctica suele significar “en potencias de 2 y cuanto mayor sea, mejor, siempre que el lote se ajuste a su memoria (GPU)“.

Es posible que también desee consultar varias publicaciones buenas aquí en Stack Exchange:

  • Compensación del tamaño del lote frente al número de iteraciones para entrenar una red neuronal
  • Selección del tamaño de mini lotes para la regresión de redes neuronales
  • ¿Qué tamaño debe tener el lote para el descenso de gradiente estocástico?

Solo tenga en cuenta que el artículo de Keskar et al. ‘On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima’, citado por varias de las publicaciones anteriores, ha recibido algunas objeciones de otros investigadores respetables de la comunidad de aprendizaje profundo.

Espero que esto ayude…

ACTUALIZAR (Diciembre de 2017): Hay un nuevo artículo de Yoshua Bengio y su equipo, Tres factores que influyen en los mínimos en SGD (noviembre de 2017); Vale la pena leerlo en el sentido de que informa sobre nuevos resultados teóricos y experimentales sobre la interacción entre la tasa de aprendizaje y el tamaño del lote.

Puede estimar el tamaño de lote más grande usando:

Tamaño máximo de lote = bytes de memoria GPU disponibles / 4 / (tamaño de tensores + parámetros entrenables)

para definir la función para encontrar el tamaño del lote para entrenar el modelo

def FindBatchSize(model):
    """#model: model architecture, that is yet to be trained"""
    import os, sys, psutil, gc, tensorflow, keras
    import numpy as np
    from keras import backend as K
    BatchFound= 16

    try:
        total_params= int(model.count_params());    GCPU= "CPU"
        #find whether gpu is available
        try:
            if K.tensorflow_backend._get_available_gpus()== []:
                GCPU= "CPU";    #CPU and Cuda9GPU
            else:
                GCPU= "GPU"
        except:
            from tensorflow.python.client import device_lib;    #Cuda8GPU
            def get_available_gpus():
                local_device_protos= device_lib.list_local_devices()
                return [x.name for x in local_device_protos if x.device_type == 'GPU']
            if "gpu" not in str(get_available_gpus()).lower():
                GCPU= "CPU"
            else:
                GCPU= "GPU"

        #decide batch size on the basis of GPU availability and model complexity
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <1000000):
            BatchFound= 64    
        if (os.cpu_count() <16) and (total_params <500000):
            BatchFound= 64  
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <2000000) and (total_params >=1000000):
            BatchFound= 32      
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=2000000) and (total_params <10000000):
            BatchFound= 16  
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=10000000):
            BatchFound= 8       
        if (os.cpu_count() <16) and (total_params >5000000):
            BatchFound= 8    
        if total_params >100000000:
            BatchFound= 1

    except:
        pass
    try:

        #find percentage of memory used
        memoryused= psutil.virtual_memory()
        memoryused= float(str(memoryused).replace(" ", "").split("percent=")[1].split(",")[0])
        if memoryused >75.0:
            BatchFound= 8
        if memoryused >85.0:
            BatchFound= 4
        if memoryused >90.0:
            BatchFound= 2
        if total_params >100000000:
            BatchFound= 1
        print("Batch Size:  "+ str(BatchFound));    gc.collect()
    except:
        pass

    memoryused= [];    total_params= [];    GCPU= "";
    del memoryused, total_params, GCPU;    gc.collect()
    return BatchFound



#####################################################################################################
#####################################################################################################
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *