una tutorial redes recurrente paso neuronales neuronal libreria implementacion hacer ejemplo como algoritmo python-3.x numpy neural-network deep-learning gradient-descent

python 3.x - tutorial - La red neuronal siempre predice la misma clase.



redes neuronales python pdf (3)

Estoy tratando de implementar una red neuronal que clasifique las imágenes en una de las dos categorías discretas. Sin embargo, el problema es que actualmente siempre predice 0 para cualquier entrada y no estoy realmente seguro de por qué.

Aquí está mi método de extracción de características:

def extract(file): # Resize and subtract mean pixel img = cv2.resize(cv2.imread(file), (224, 224)).astype(np.float32) img[:, :, 0] -= 103.939 img[:, :, 1] -= 116.779 img[:, :, 2] -= 123.68 # Normalize features img = (img.flatten() - np.mean(img)) / np.std(img) return np.array([img])

Aquí está mi rutina de descenso de gradiente:

def fit(x, y, t1, t2): """Training routine""" ils = x.shape[1] if len(x.shape) > 1 else 1 labels = len(set(y)) if t1 is None or t2 is None: t1 = randweights(ils, 10) t2 = randweights(10, labels) params = np.concatenate([t1.reshape(-1), t2.reshape(-1)]) res = grad(params, ils, 10, labels, x, y) params -= 0.1 * res return unpack(params, ils, 10, labels)

Aquí están mis propagaciones hacia adelante y hacia atrás (gradiente):

def forward(x, theta1, theta2): """Forward propagation""" m = x.shape[0] # Forward prop a1 = np.vstack((np.ones([1, m]), x.T)) z2 = np.dot(theta1, a1) a2 = np.vstack((np.ones([1, m]), sigmoid(z2))) a3 = sigmoid(np.dot(theta2, a2)) return (a1, a2, a3, z2, m) def grad(params, ils, hls, labels, x, Y, lmbda=0.01): """Compute gradient for hypothesis Theta""" theta1, theta2 = unpack(params, ils, hls, labels) a1, a2, a3, z2, m = forward(x, theta1, theta2) d3 = a3 - Y.T print(''Current error: {}''.format(np.mean(np.abs(d3)))) d2 = np.dot(theta2.T, d3) * (np.vstack([np.ones([1, m]), sigmoid_prime(z2)])) d3 = d3.T d2 = d2[1:, :].T t1_grad = np.dot(d2.T, a1.T) t2_grad = np.dot(d3.T, a2.T) theta1[0] = np.zeros([1, theta1.shape[1]]) theta2[0] = np.zeros([1, theta2.shape[1]]) t1_grad = t1_grad + (lmbda / m) * theta1 t2_grad = t2_grad + (lmbda / m) * theta2 return np.concatenate([t1_grad.reshape(-1), t2_grad.reshape(-1)])

Y aquí está mi función de predicción:

def predict(theta1, theta2, x): """Predict output using learned weights""" m = x.shape[0] h1 = sigmoid(np.hstack((np.ones([m, 1]), x)).dot(theta1.T)) h2 = sigmoid(np.hstack((np.ones([m, 1]), h1)).dot(theta2.T)) return h2.argmax(axis=1)

Puedo ver que la tasa de error está disminuyendo gradualmente con cada iteración, generalmente convergiendo en algún lugar alrededor de 1.26e-05.

Lo que he probado hasta ahora:

  1. PCA
  2. Diferentes conjuntos de datos (Iris de sklearn y números escritos a mano del curso Coursera ML, logrando aproximadamente un 95% de precisión en ambos). Sin embargo, ambos se procesaron en un lote, por lo que puedo suponer que mi implementación general es correcta, pero hay algo mal con la forma en que extraigo las características o cómo entreno al clasificador.
  3. Probé el SGDClassifier de sklearn y no funcionó mucho mejor, dándome una precisión de ~ 50%. Entonces, ¿algo está mal con las características?

Editar : Un resultado promedio de h2 se parece a lo siguiente:

[0.5004899 0.45264441] [0.50048522 0.47439413] [0.50049019 0.46557124] [0.50049261 0.45297816]

Entonces, salidas sigmoides muy similares para todos los ejemplos de validación.


Mi red siempre predice la misma clase. ¿Cuál es el problema?

Tuve esto un par de veces. Aunque actualmente soy demasiado vago para revisar su código, creo que puedo dar algunas sugerencias generales que también podrían ayudar a otros que tienen el mismo síntoma pero probablemente diferentes problemas subyacentes.

Depuración de redes neuronales

Ajustar conjuntos de datos de un elemento

Para cada clase i la red debería poder predecir, intente lo siguiente:

  1. Cree un conjunto de datos de solo un punto de datos de la clase i.
  2. Ajuste la red a este conjunto de datos.
  3. ¿La red aprende a predecir "clase i"?

Si esto no funciona, hay cuatro posibles fuentes de error:

  1. Algoritmo de entrenamiento con errores : pruebe con un modelo más pequeño, imprima muchos valores que se calculan entre ellos y vea si coinciden con sus expectativas.
    1. Dividiendo por 0: agregue un pequeño número al denominador
    2. Logaritmo de 0 / número negativo: como dividir por 0
  2. Datos : es posible que sus datos tengan el tipo incorrecto. Por ejemplo, podría ser necesario que sus datos sean del tipo float32 pero en realidad sean enteros.
  3. Modelo : También es posible que haya creado un modelo que no puede predecir lo que quiere. Esto debería revelarse cuando intente modelos más simples.
  4. Inicialización / Optimización : Dependiendo del modelo, su inicialización y su algoritmo de optimización pueden jugar un papel crucial. Para los principiantes que usan el descenso de gradiente estocástico estándar, diría que es importante inicializar los pesos al azar (cada peso tiene un valor diferente). - ver también: esta pregunta / respuesta

Curva de aprendizaje

Ver sklearn para más detalles.

La idea es comenzar con un pequeño conjunto de datos de entrenamiento (probablemente solo un elemento). Entonces el modelo debería poder ajustarse perfectamente a los datos. Si esto funciona, crea un conjunto de datos un poco más grande. Su error de entrenamiento debería aumentar ligeramente en algún momento. Esto revela la capacidad de sus modelos para modelar los datos.

Análisis de los datos

Verifique con qué frecuencia aparecen las otras clases. Si una clase domina a las otras (por ejemplo, una clase es el 99.9% de los datos), esto es un problema. Busque técnicas de "detección de valores atípicos".

Más

  • Tasa de aprendizaje : si su red no mejora y obtiene solo un poco mejor que la probabilidad aleatoria, intente reducir la tasa de aprendizaje. Para la visión por computadora, a menudo se usa / funciona una tasa de aprendizaje de 0.001 . Esto también es relevante si usa Adam como optimizador.
  • Preprocesamiento : asegúrese de utilizar el mismo preprocesamiento para la capacitación y las pruebas. Es posible que vea diferencias en la matriz de confusión (vea esta pregunta )

Errores comunes

Esto está inspirado en reddit :

  • Olvidó aplicar el preprocesamiento
  • Morir ReLU
  • Tasa de aprendizaje demasiado pequeña / demasiado grande
  • Función de activación incorrecta en la capa final:
    • ¿Tus objetivos no son la suma uno? -> No use softmax
    • Los elementos individuales de sus objetivos son negativos -> No use Softmax, ReLU, Sigmoid. Tanh podría ser una opción
  • Red demasiado profunda: no puedes entrenar. Pruebe primero una red neuronal más simple.
  • Datos muy desequilibrados: es posible que desee examinar imbalanced-learn

Después de una semana y media de investigación, creo que entiendo cuál es el problema. No hay nada malo con el código en sí. Los únicos dos problemas que impiden que mi implementación se clasifique con éxito son el tiempo dedicado al aprendizaje y la selección adecuada de los parámetros de velocidad de aprendizaje / regularización.

He tenido la rutina de aprendizaje funcionando por algún tiempo ahora, y ya está impulsando el 75% de precisión, aunque todavía hay mucho espacio para mejorar.


Solo en caso de que alguien más se encuentre con este problema. La mía tenía una deeplearning4j Lenet (CNN). Seguía dando el resultado final de la última carpeta de entrenamiento para cada prueba. Pude resolverlo increasing my batchsize lote y shuffling the training data para que cada lote contuviera al menos una muestra de más de una carpeta. Mi clase de datos tenía un lote de 1 que era realmente dangerous .

Editar: aunque otra cosa que observé recientemente es tener conjuntos limitados de muestras de entrenamiento por clase a pesar de tener un gran dataset . por ejemplo, entrenar una neural-network para reconocer human faces pero tener solo un máximo de, por ejemplo, 2 caras diferentes para 1 person mientras que el conjunto de datos consta de, digamos, 10.000 persons , es decir, un dataset de dataset de 20.000 faces en total. Un dataset mejor sería 1000 faces diferentes para 10,000 persons tanto, un dataset de dataset de 10,000,000 faces en total. Esto es relativamente necesario si desea evitar sobreajustar los datos a una clase para que su network pueda generalizar fácilmente y producir mejores predicciones.