Vahid Mirjalili

Python Machine Learning


Скачать книгу

      Esta ilustración muestra que el algoritmo Adaline compara las etiquetas de clase verdaderas con la salida de valores continuos de la función de activación lineal para calcular el error del modelo y actualizar los pesos. Por el contrario, el perceptrón compara las etiquetas de clase verdaderas con las etiquetas de clase predichas.

      Uno de los ingredientes clave de los algoritmos de aprendizaje automático supervisado es una función objetivo definida que debe ser optimizada durante el proceso de aprendizaje. Esta función objetivo suele ser una función de coste que queremos minimizar. En el caso de Adaline, podemos definir la función de coste para aprender los pesos como la Suma de Errores Cuadráticos (SSE, del inglés Sum of Squared Errors) entre la salida calculada y la etiqueta de clase verdadera:

      Hemos añadido el término simplemente para facilidad nuestra, porque nos permitirá derivar el gradiente de un modo más fácil, como veremos en los siguientes párrafos. La principal ventaja de esta función de activación lineal continua, en comparación con la función escalón unitario, es que la función de coste pasa a ser diferenciable. Otra propiedad a tener en cuenta de esta función de coste es que es convexa; esto significa que podemos utilizar un simple pero potente algoritmo de optimización, denominado descenso de gradiente, para encontrar los pesos que minimicen nuestra función de coste y clasificar así las muestras del conjunto de datos Iris.

      Como se muestra en la imagen siguiente, podemos describir la idea principal que hay detrás del descenso de gradiente como bajar una colina hasta obtener un mínimo de coste global o local. En cada iteración, realizamos un paso en la dirección opuesta del gradiente donde el tamaño del paso está determinado por el valor del rango de aprendizaje, así como por la pendiente del gradiente:

      Con el descenso de gradiente, podemos actualizar los pesos haciendo un paso en la dirección opuesta del gradiente de nuestra función de coste :

      donde el cambio de peso se define como el gradiente negativo multiplicado por el rango de aprendizaje :

      Para calcular el gradiente de la función de coste, necesitamos calcular la derivación parcial de la función de coste con respecto a cada peso :

      Por lo que podemos escribir la actualización del peso como:

      Como actualizamos todos los pesos a la vez, nuestra regla de aprendizaje Adaline es:

Para los que están familiarizados con el cálculo, la derivación parcial de la función de coste SSE con respecto al peso j se puede obtener así:

      Aunque la regla de aprendizaje Adaline puede parecer idéntica a la regla del perceptrón, podemos observar que el con [no image in epub file] es un número real y una etiqueta de clase completa. Además, la actualización del peso se calcula en base a todas las muestras del conjunto de entrenamiento (en lugar de actualizar los pesos de forma incremental después de cada muestra), razón por la cual este enfoque también se conoce como descenso de gradiente en lotes.

      Como la regla del perceptrón y Adaline son muy parecidos, tomaremos la implementación del perceptrón que definimos anteriormente y cambiaremos el método fit de manera que los pesos se actualicen minimizando la función de coste mediante el descenso de gradiente:

      class AdalineGD(object):

       """ADAptive LInear NEuron classifier.

       Parameters

       ------------

       eta : float

       Learning rate (between 0.0 and 1.0)

       n_iter : int

       Passes over the training dataset.

       random_state : int

       Random number generator seed for random weight

       initialization.

       Attributes

       -----------

       w_ : 1d-array

       Weights after fitting.

       cost_ : list

       Sum-of-squares cost function value in each epoch.

       """

       def __init__(self, eta=0.01, n_iter=50, random_state=1):

       self.eta = eta

       self.n_iter = n_iter

       self.random_state = random_state

       def fit(self, X, y):

       """ Fit training data.

       Parameters

       ----------

       X : {array-like}, shape = [n_samples, n_features]

       Training vectors, where n_samples is the number of

       samples and

       n_features is the number of features.

       y : array-like, shape = [n_samples]

       Target values.

       Returns

       -------

       self : object

       """

       rgen = np.random.RandomState(self.random_state)

       self.w_ = rgen.normal(loc=0.0, scale=0.01,

       size=1 + X.shape[1])