Herramientas de usuario

Herramientas del sitio


inteligencia_artificial:datasets

¡Esta es una revisión vieja del documento!


Datasets clásicos

Vamos a crear diferentes colecciones de datos, tomando como partida colecciones de datos en bruto, considerados clásicos en el aprendizaje de inteligencia artificial y aprendizaje automático: Irises, Breast Cancer, MNIST Digits, CIFAR-10.

Irises

Dataset de la flor de Iris, un dataset clásico desarrollado por R. A. Fisher en 1936 en su paper “The Use of Multiple Measurements in Taxonomic Problems”.

Es un dataset pequeño, con 3 clases, 50 muestras de datos por cada clase, y 4 atributos: anchura del sépalo, longitud del sépalo, anchura del pétalo y longitud del pétalo, simepre en centímetros. Las tres clases son la subespecie de la flor de Iris: I. setosa, I. versicolour, y I. virginica.

Se puede descargar del repositorio principal de UCI, o directamente desde su web.

Una vez descargado:

  1. Abrimos el documento descargado y vemos cómo están estructurados los datos.
  2. Dividimos el dataset en un array para los datos de entrada (x) y otro para los valores etiquetados (y).
  3. Ordenamos los datos de forma aleatoria.
  4. Guardamos los datos para poder usarlos cuando nos hagan falta.
  5. Como todos los atributos tienen el mismo rango de medidas, no es necesario normalizar, por lo que pueden representarse directamente en un gráfico de barras.

Podemos ver el código a continuación:

import numpy as np
 
with open("iris.data") as f:
lines = [i[:-1] for i in f.readlines()]
 
n = ["Iris-setosa","Iris-versicolor","Iris-virginica"]
x = [n.index(i.split(",")[-1]) for i in lines if i != ""]
x = np.array(x, dtype="uint8")
 
y = [[float(j) for j in i.split(",")[:-1]] for i in lines if i != ""]
y = np.array(y)
 
i = np.argsort(np.random.random(x.shape[0]))
x = x[i]
y = y[i]
 
np.save("iris_features.npy", y)
np.save("iris_labels.npy", x)

Puede comprobarse en el cuaderno de Google Colab correspondiente.

Breast Cancer

Estos datos se corresponden con el Wisconsin Diagnostic Breast Cancer dataset.
El dataset puede descargarse ya preparado para trabajar con él desde sklearn, pero descargaremos los dtos en bruto desde la página oficial para prepararlos, ya que la manipulación y preparación de datos es algo común en este campo.

Pueden descargarse de la misma web que el dataset Iris, pinchando en el enlace “Data Folder” y descargando el fichero “wdbc.data”.

Este dataset contiene 569 datos de biopsias mamarias. Están etiquetadas 2 clases: M (Maligno 212 muestras), o B (Benigno 357 muestras). El primer elemento es un código ID que podemos obviar, el segundo la etiqueta correspondiente a una de las 2 clases del dataset: M (Maligno), o B (Benigno), y a continuación hay 30 atributos consecutivos relacionados con las medidas de las células recogidas en la biopsia.

Para poder trabajar adecuadamente con los valores de los parámetros, es necesario normalizarlos. A continuación prepararemos el dataset con el siguiente código:

import numpy as np
import matplotlib.pyplot as plt
 
with open("wdbc.data") as f:
  lines = [i[:-1] for i in f.readlines() if i != ""]
 
n = ["B","M"]
x = np.array([n.index(i.split(",")[1]) for i in lines],dtype="uint8")
y = np.array([[float(j) for j in i.split(",")[2:]] for i in lines])
i = np.argsort(np.random.random(x.shape[0]))
x = x[i]
y = y[i]
z = (y - y.mean(axis=0)) / y.std(axis=0)
 
np.save("bc_features.npy", y)
np.save("bc_features_standard.npy", z)
np.save("bc_labels.npy", x)
plt.boxplot(z)
plt.show()

Este código está debidamente explicado en el cuaderno de Google Colab.

MNIST digits

Este dataset está compuesto por miles de pequeñas imágenes de dígitos (0 - 9) escritos a mano en escala de grises. Este dataset es el caballo de batalla del machine learning moderno, y uno de los primeros datasets que fueron usados para experimentar con deep learning. Se usa muchísimo y es muy sencillo trabajar con él.

Se puede descargar el dataset canónico desde su web, pero nosotros la importaremos desde Keras, por facilidad. Keras devuelve los datos del dataset como un array de 3 dimensiones: la primera hace referencia a cada una de las imágenes (60.000 para entrenar y 10.000 de test), y la segunda y tercera los píxeles de cada imagen.

Cada imagen está definida por una cuadrícula de 28 x 28 píxeles, que en los datos que nos devuelve keras están estructurados de la siguiente forma: array de 28 elementos que representa cada fila de la cuadrícula del dígito, cada uno a su vez con otros 28 elementos que representan los valores de cada píxel de esa fila. Cada píxel está definido por un entero de 8 bits sin signo [0,255].

Para trabajar con este dataset en modelos clásicos, tendremos que pasarlo a vectores de atributos. Para ello:

  1. Pasaremos las imágenes (3 dimensiones: dígito - fila de píxeles - píxel) a vector de atributos (2 dimensiones: dígito - valor de píxeles).
  2. Cambiaremos el orden de las imágenes y de los píxeles que las forman, de forma determinista, a todas de la misma manera.
  3. Crearemos un dataset con las nuevas imágenes (de nuevo pasamos a una estructura de 3 dimensiones), que se podrá usar más adelante para comprobar las diferencias entre los modelos de redes neuronales clásicas y los modelos de redes neuronales convolucionales.

El código necesario es:

import numpy as np
import keras
from keras.datasets import mnist
 
(xtrn, ytrn), (xtst, ytst) = mnist.load_data()
idx = np.argsort(np.random.random(ytrn.shape[0]))
xtrn = xtrn[idx]
ytrn = ytrn[idx]
idx = np.argsort(np.random.random(ytst.shape[0]))
xtst = xtst[idx]
ytst = ytst[idx]
 
np.save("mnist_train_images.npy", xtrn)
np.save("mnist_train_labels.npy", ytrn)
np.save("mnist_test_images.npy", xtst)
np.save("mnist_test_labels.npy", ytst)
 
xtrnv = xtrn.reshape((60000,28*28))
xtstv = xtst.reshape((10000,28*28))
np.save("mnist_train_vectors.npy", xtrnv)
np.save("mnist_test_vectors.npy", xtstv)
 
idx = np.argsort(np.random.random(28*28))
for i in range(60000):
  xtrnv[i,:] = xtrnv[i,idx]
for i in range(10000):
  xtstv[i,:] = xtstv[i,idx]
np.save("mnist_train_scrambled_vectors.npy", xtrnv)
np.save("mnist_test_scrambled_vectors.npy", xtstv)
 
t = np.zeros((60000,28,28))
for i in range(60000):
  t[i,:,:] = xtrnv[i,:].reshape((28,28))
np.save("mnist_train_scrambled_images.npy", t)
t = np.zeros((10000,28,28))
for i in range(10000):
  t[i,:,:] = xtstv[i,:].reshape((28,28))
np.save("mnist_test_scrambled_images.npy", t)

Este se encuentra debidamente explicado y comentado en el cuaderno de Google Colab correspondiente.

En principio, no es necesario normalizar los datos, ya que todos son imágenes del mismo número de bits, y la frecuencia con la que aparece cada dígito es similar (el dataset está “equilibrado”).

CIFAR-10

CIFAR-10 es otro dataset clásico para modelos de aprendizaje profundo, lo suficientemente pequeño como para no necesitar una gran cantidad de tiempo de entrenamiento con CPU, o una GPU.

Al igual que con MNIST, lo descargaremos desde Keras, aunque puede encontrarse en su web oficial.

El dataset está formado por 60.000 imágenes RGB de 32 x 32 píxeles, divididas en 10 clases, con 6.000 imágenes por cada una, etiquetadas de la siguiente manera:

Etiqueta Clase
0 Airplane
1 Automobile
2 Bird
3 Cat
4 Deer
5 Dog
6 Frog
7 Horse
8 Ship
9 Truck

50.000 imágenes forman el conjunto de datos de entrenamiento, y 10.000 el conjunto de imágenes de test.

Actuamos igual que con el dataset MNIST, pasamos las imágenes a vectores de atributos y las guardamos para su uso posterior (en este caso no las vamos a manipular).
En este caso hay que tener en cuenta que las imágenes tienen una dimensión más, ya que las imágenes en lugar de tener formato de escala de grises, son en color RGB (Red, Green, Blue), tres valores de color por cada píxel: (60.000; 32; 32; 3).

Para esto tenemos el siguiente código:

import numpy as np
import keras
from keras.datasets import cifar10
 
(xtrn, ytrn), (xtst, ytst) = cifar10.load_data()
idx = np.argsort(np.random.random(ytrn.shape[0]))
xtrn = xtrn[idx]
ytrn = ytrn[idx]
idx = np.argsort(np.random.random(ytst.shape[0]))
xtst = xtst[idx]
ytst = ytst[idx]
 
np.save("cifar10_train_images.npy", xtrn)
np.save("cifar10_train_labels.npy", ytrn)
np.save("cifar10_test_images.npy", xtst)
np.save("cifar10_test_labels.npy", ytst)
 
xtrnv = xtrn.reshape((50000,32*32*3))
xtstv = xtst.reshape((10000,32*32*3))
np.save("cifar10_train_vectors.npy", xtrnv)
np.save("cifar10_test_vectors.npy", xtstv)

Este código está explicado en el cuaderno de Google Colab dedicado.

Aumento de datos

En ocasiones tenemos pocos datos de entrada, de modo que necesitamos disponer de más datos para entrenar al modelo adecuadamente. Para ello es posible conseguir más datos modificando los existentes, de manera que pudieran haber sido extraídos del parent distribution.

Siempre que fuera posible, deberíamos realizar un aumento de datos, ya que suele dar buenos resultados al entrenar los modelos.

En modelos clásicos, el aumento de datos puede ayudar a que el modelo sea más preciso, consiguiendo muestras que podrían extraerse de la distribución principal. En modelos de aprendizaje profundo modernos, pueden ayudar en el proceso de regulación. Este proceso es el que hace que el modelo aprenda las características importantes de los datos de entrada como nosotros deseemos (ejemplo: aprender a diferenciar lobos de perros Husky, sin que el modelo aprenda por ejemplo a diferenciar los fondos de los animales, en lugar de los animales en sí).

Otro beneficio del aumento de datos es disminuir la probabilidad de que ocurra overfitting. El overfitting o sobreajuste, es la capacidad de un modelo por el que recuerda muy bien los datos de entrenamiento, pero es incapaz de generalizar cuando se le introducen otros datos, como si sólo se aprendiese de memoria los datos de entrenamiento.

Una cosa muy importante a tener en cuenta, es que los datos aumentados a partir de un dato de uno de los tres tipos de dataset (entrenamiento, test y validación), deben pertenecer a ese mismo dataset. NUNCA los datos aumentados pueden pertenecer a datasets diferentes, o a uno distinto del dato original. La forma correcta de aumentar los datos para evitar que se de este problema de forma accidental, es hacerlo después de haber creado los datasets de entrenamiento, test y validación.

Los datos que se aumentan normalmente son los de entrenamiento, aunque teóricamente no debería haber problema en aumentar los de test y validación, especialmente si hay pocos.

Cómo aumentar los datos de entrenamiento

Cuando los datos son imágenes, es bastante directo. Podemos rotar la imagen, voltearla horizontal o verticalmente, cambiar los colores, tal vez incluso intercambiando los canales RGB, etc.

La única consideración que hay que tener a la hora de aumentar datos a partir de uno en concreto, es que los nuevos tengan sentido. En el caso de imágenes, por ejemplo, no tiene sentido dar la vuelta a una imagen de un mono colgado del árbol, ya que todos los árboles se mostrarían del revés y podría generar algún problema. En una vista aérea no habría, en principio, problema en rotar la imagen, pero añadir una imagen frontal si el resto son aéreas, tampoco tiene razón de ser.

En el caso de vectores de atributos, el cambio es más sutil, pero también se basa en la misma premisa: que tenga sentido. Los nuevos datos creados deben poder pertenecer a la “distribución padre”.

Se ha creado en Google colab un ejemplo de aumento de datos del dataset irises, y otro ejemplo de aumento de datos del dataset CIFAR-10, bien razonados que se pueden consultar.

inteligencia_artificial/datasets.1686234657.txt.gz · Última modificación: por alberto

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki