una redes recurrente neuronales neuronal libreria implementacion ejemplos ejemplo crear convolucionales como python scikit-learn neural-network

python - recurrente - ¿Qué hay de malo en mi implementación de redes neuronales?



redes neuronales ejemplos (3)

Además de las respuestas anteriores, también debe tener en cuenta que es posible que tenga que ajustar la learning rate (estableciendo el valor de learning_rate = value en el inicializador) de la red. Si elige la tasa a grande, saltará de un mínimo local a otro o rodeará estos puntos, pero en realidad no convergerá (vea la imagen a continuación, tomada desde here ).

Además, también trace la loss y no solo la precisión de su red. Esto le dará una mejor idea al respecto.

Además, tenga en cuenta que debe utilizar una gran cantidad de datos de entrenamiento y pruebas para obtener una curva más o menos "suave", o incluso una curva representativa; Si está utilizando solo unos pocos (quizás unos pocos cientos) puntos de datos, las métricas resultantes no serán muy precisas, ya que contienen muchas cosas estocásticas. Para resolver este error, no debe capacitar a la red con los mismos ejemplos cada vez, sino que debe cambiar las órdenes de sus datos de capacitación y tal vez dividirla en diferentes mini lotes . Tengo mucha confianza en que puede resolver o incluso reducir su problema intentando recordar estos aspectos e implementarlos.

Dependiendo de su tipo de problema, debe cambiar la función de activación a algo diferente a la función tanh . Al realizar una clasificación, un OneHotEncoder también puede ser útil (si sus datos aún no están codificados en caliente); sklearn framework sklearn ofrece una implementation de esto.

Quiero trazar la curva de error de aprendizaje de una red neuronal con respecto al número de ejemplos de entrenamiento. Aquí está el código:

import sklearn import numpy as np from sklearn.model_selection import learning_curve import matplotlib.pyplot as plt from sklearn import neural_network from sklearn import cross_validation myList=[] myList2=[] w=[] dataset=np.loadtxt("data", delimiter=",") X=dataset[:, 0:6] Y=dataset[:,6] clf=sklearn.neural_network.MLPClassifier(hidden_layer_sizes=(2,3),activation=''tanh'') # split the data between training and testing X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(X, Y, test_size=0.25, random_state=33) # begin with few training datas X_eff=X_train[0:int(len(X_train)/150), : ] Y_eff=Y_train[0:int(len(Y_train)/150)] k=int(len(X_train)/150)-1 for m in range (140) : print (m) w.append(k) # train the model and store the training error A=clf.fit(X_eff,Y_eff) myList.append(1-A.score(X_eff,Y_eff)) # compute the testing error myList2.append(1-A.score(X_test,Y_test)) # add some more training datas X_eff=np.vstack((X_eff,X_train[k+1:k+101,:])) Y_eff=np.hstack((Y_eff,Y_train[k+1:k+101])) k=k+100 plt.figure(figsize=(8, 8)) plt.subplots_adjust() plt.title("Erreur d''entrainement et de test") plt.plot(w,myList,label="training error") plt.plot(w,myList2,label="test error") plt.legend() plt.show()

Sin embargo, obtengo un resultado muy extraño, con curvas fluctuantes, el error de entrenamiento está muy cerca del error de prueba que no parece ser normal. ¿Dónde está el error? No puedo entender por qué hay tantos altibajos y por qué el error de entrenamiento no aumenta, como se esperaría. ¡Cualquier ayuda sería apreciada!

EDITAR: el conjunto de datos que estoy usando es https://archive.ics.uci.edu/ml/datasets/Chess+%28King-Rook+vs.+King%29 donde me deshice de las clases que tienen menos de 1000 instancias. Recodifiqué manualmente los datos literales.


Creo que la razón por la que está viendo este tipo de curva es que la métrica de rendimiento que está midiendo es diferente de la métrica de rendimiento que está optimizando .

Métrica de optimización

La red neuronal minimiza una función de pérdida, y en el caso de las activaciones de Tanh, asumo que está utilizando una versión modificada de la pérdida de entropía cruzada. Si tuviera que graficar la pérdida a lo largo del tiempo, vería una función de error más monótonamente decreciente como espera. (En realidad no es monótono porque las redes neuronales no son convexas, pero eso no viene al caso).

Métrica de rendimiento

La métrica de rendimiento que está midiendo es el porcentaje de precisión, que es diferente de la pérdida. ¿Por qué son diferentes? La función de pérdida nos dice cuánto error tenemos de manera diferenciable (lo cual es importante para los métodos de optimización rápidos). La métrica de precisión nos dice qué tan bien predecimos, lo que es útil para la aplicación de la red neuronal.

Poniendo todo junto

Debido a que está trazando el rendimiento de una métrica relacionada, puede esperar que la gráfica se vea similar a la de su métrica optimizada. Sin embargo, debido a que no son lo mismo, puede que esté introduciendo una variación no contabilizada en su gráfica (como lo demuestra la gráfica que publicó).

Hay un par de maneras de arreglar esto.

  1. Trazar la pérdida en lugar de la precisión. Esto realmente no soluciona su problema si realmente necesita la gráfica de precisión, pero le dará curvas mucho más suaves.
  2. Trazar un promedio en varias carreras. Guarde los trazados de precisión en más de 20 ejecuciones independientes de su algoritmo (como en el entrenamiento de la red 20 veces), luego promuévalos juntos y trace esto. Eso reducirá enormemente la varianza.

TL; DR

No espere que la gráfica de precisión siempre sea suave y disminuya monótonamente, no lo será.

Después de editar la pregunta:

Ahora que ha agregado su conjunto de datos, veo algunas otras cosas que pueden estar causando los problemas que está viendo.

Información en magnitud

El conjunto de datos define el rango y el archivo (fila y columna) de varias piezas de ajedrez. Estos se ingresan como un número entero de 1 a 6. Sin embargo, ¿2 es realmente 1 mejor que 1? ¿Es 6 realmente 4 mejor que 2? No creo que este sea el caso en términos de posición de ajedrez.

Imagina que estoy construyendo un clasificador que toma dinero como entrada. ¿Hay alguna cantidad de información representada por la magnitud de mis valores? Sí, $ 1 es bastante diferente de $ 100; y podemos decir que existe una relación basada en la magnitud.

Para un juego de ajedrez, ¿la fila 1 significa algo diferente a la fila 8? En absoluto, de hecho estas dimensiones son simétricas! El uso de una unidad de polarización en su red puede ayudar a explicar la simetría al "reescala" para que sus entradas sean efectivamente de [-3, 4] que ahora están centradas (ish) alrededor de 0.

Soluciones

Sin embargo, creo que obtendría la mayor cantidad de millas de codificación de teselas o de codificación en caliente de cada una de sus funciones. No permita que la red se base en la información contenida en la magnitud de cada función, ya que eso puede hacer que la red se convierta en malos óptimos locales.


Aleatorizar el conjunto de entrenamiento y repetir.

Si desea una comparación justa del efecto del número de muestras de entrenamiento en la precisión, le sugiero que elija n_samples de su conjunto de entrenamiento en lugar de agregar 100 muestras al lote anterior. También repetiría los tiempos N_repeat ajustados para cada valor de n_samples .

Esto daría algo como esto (no probado):

n_samples_array = np.arange(100,len(X_train),100) N_repeat = 10 for n_samples in n_samples_array: print(n_samples) # repeat the fit several times and take the mean myList_tmp, myList2_tmp = [],[] for repeat in range(0,N_repeat): # Randomly pick samples selection = np.random.choice(range(0,len(X_train)),n_samples,repeat=False) # train the model and store the training error A=clf.fit(X_train[selection],Y_train[selection]) myList_tmp.append(1-A.score(X_train[selection],Y_train[selection])) # compute the testing error myList2_tmp.append(1-A.score(X_test,Y_test)) myList.append(np.mean(myList_tmp)) myList2.append(np.mean(myList2_tmp))

Arranque en caliente

Cuando utiliza la función de fit , reinicia la optimización desde cero. Si desea ver la mejora en su optimización al agregar algunas muestras a la misma red entrenada anteriormente, puede usar la opción warm_start=True

Según la documentation :

warm_start: bool, opcional, predeterminado False

Cuando se establece en Verdadero, reutilice la solución de la llamada anterior para que se ajuste como inicialización; de lo contrario, simplemente borre la solución anterior.