0% encontró este documento útil (0 votos)
359 vistas40 páginas

Clasificación de Imágenes en MATLAB

Este documento presenta un ejemplo de cómo utilizar una red neuronal profunda preentrenada llamada AlexNet para clasificar imágenes. Muestra cómo importar imágenes a MATLAB, cargar AlexNet, hacer predicciones sobre el contenido de las imágenes y examinar las capas y puntuaciones de predicción de la red para obtener más información sobre las clasificaciones.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
359 vistas40 páginas

Clasificación de Imágenes en MATLAB

Este documento presenta un ejemplo de cómo utilizar una red neuronal profunda preentrenada llamada AlexNet para clasificar imágenes. Muestra cómo importar imágenes a MATLAB, cargar AlexNet, hacer predicciones sobre el contenido de las imágenes y examinar las capas y puntuaciones de predicción de la red para obtener más información sobre las clasificaciones.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Deep Learning MATLAB

Ejemplo de clasificación de fotos

En esta sección del curso aprenderá a utilizar una red neuronal profunda prefabricada para
clasificar el contenido de las siguientes 12 imágenes. Idealmente, las clasificaciones serían del
tipo "playa", "gato", "magdalenas", "lago", "pescado", etc.

En esta interacción, importará algunos de estos archivos de imagen a MATLAB y los visualizará.

View image files


Instructions are in the task pane to the left. Complete and submit each task one at a time.

Puede utilizar la función imread para importar imágenes almacenadas con la mayoría de
formatos de archivo estándar (GIF, JPEG, PNG, etc.)

I = imread('filename.png');

El comando anterior lee la imagen del archivo especificado a una variable de MATLAB
llamada I.
ACTIVIDAD
Importe la imagen del archivo file01.jpg al espacio de trabajo de MATLAB. Almacénela en
una variable llamada img1.
img1 = imread('file01.jpg');
Puede utilizar la función imshow para mostrar una imagen almacenada en una variable de
MATLAB

imshow(I)
ACTIVIDAD
Muestre la imagen importada en la variable img1.

imshow(img1)

Las dos primeras tareas importan y muestran la imagen de file01.jpg. Añada comandos al
script de manera que también importe y muestre las imágenes de los
archivos file02.jpg y file03.jpg. Almacene las imágenes en variables
llamadas img2 e img3, respectivamente.

img2 = imread('file02.jpg');
imshow(img2)

img3 = imread('file03.jpg');
imshow(img3)

Classify images
Instructions are in the task pane to the left. Complete and submit each task one at a time.

Puede utilizar la función alexnet para crear una copia de la red profunda predefinida
“AlexNet” en el espacio de trabajo de MATLAB.

net = alexnet
ACTIVIDAD
Utilice la función alexnet para cargar una red previamente entrenada. Guarde el resultado
en una variable llamada deepnet.

deepnet = alexnet;

Do not edit. This code imports and displays the image in file01.jpg.
img1 = imread('file01.jpg');
imshow(img1)
Puede utilizar la función classify para hacer una predicción sobre una imagen.

pred = classify(net,img)
ACTIVIDAD
Utilice la función classify con la red previamente entrenada AlexNet para predecir el tema
de la imagen almacenada en la variable img1. Almacene la predicción de la red en una variable
llamada pred1.

Puede quitar los signos de punto y coma para ver el resultado.


pred1 = classify(deepnet,img1);

This code imports and displays the images in file02.jpg and file03.jpg.
img2 = imread('file02.jpg');
imshow(img2)
img3 = imread('file03.jpg');
imshow(img3)

ACTIVIDAD
Añada comandos al script de manera que haga predicciones sobre el contenido de las
imágenes almacenadas en las variables img2 e img3. Almacene las clases predichas en
variables llamadas pred2 y pred3, respectivamente.

Puede quitar los signos de punto y coma para ver los resultados.

pred2 = classify(deepnet,img2)
pred3 = classify(deepnet,img3)
Examen de las capas de AlexNet

Como cualquier otra CNN, AlexNet se representa en MATLAB como un arreglo de capas. De
especial interés son el primer y el último elemento de este arreglo, que representan las capas de
entrada y de salida, respectivamente.

Examine Network Layers


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code imports AlexNet.


deepnet = alexnet;

En esta interacción, examinará las propiedades de estas capas para determinar qué forma de
imagen toma AlexNet como entrada y qué clases devuelve como salida.

La variable deepnet representa una red convolucional profunda. Puede inspeccionar las
capas de la red haciendo referencia a la propiedad Layers de la variable, utilizando la
indexación variable.Property:

deepnet.Layers
ACTIVIDAD
Extraiga la propiedad Layers de deepnet a una variable llamada ly.
ly = deepnet.Layers

La variable ly es un arreglo de capas de red. Puede inspeccionar una capa individual


indexándola a ly con la indexación de arreglos normal de MATLAB:

layer3 = ly(3)
ACTIVIDAD
Extraiga la primera capa (entrada) de la red a una variable llamada inlayer.
inlayer = ly(1)
Cada capa de la red tiene propiedades relevantes para ese tipo de capa. Una propiedad
importante para una capa de entrada es InputSize, que es el tamaño (dimensiones) de las
imágenes que la red espera como entrada.
ACTIVIDAD
Extraiga la propiedad InputSize de la primera capa de la red (almacenada en la
variable inlayer). Almacene el resultado en una variable llamada insz.

insz = inlayer.InputSize

Dimensiones de las imágenes

Las imágenes en escala de grises se representan en MATLAB como un arreglo m por n, donde
el valor de cada elemento representa la intensidad del píxel de imagen correspondiente. Las
imágenes en color se representan como un arreglo m por n por 3, donde los tres
planos m por n representan las intensidades de rojo, verde y azul, respectivamente.

En AlexNet es obligatorio que la imagen de entrada tenga un tamaño de 227 por 227 por 3; es
decir, una imagen en color de 227 píxeles de alto y 227 píxeles de ancho.
ACTIVIDAD
Extraiga la última capa (salida) de la red a una variable llamada outlayer.

outlayer = ly(25)
La propiedad Classes de una capa de salida asigna los nombres de las categorías que la red
está entrenada para predecir.
ACTIVIDAD
Extraiga la propiedad Classes de la última capa de la red (almacenada en la
variable outlayer). Almacene el resultado en una variable llamada categorynames.

categorynames = outlayer.Classes

Puntuaciones de predicción

La función classify devuelve la clase predicha de la imagen de entrada, pero ¿hay una forma
de conocer el grado de “fiabilidad” de la red acerca de dicha clasificación? Puede ser importante
tener en cuenta esa fiabilidad a la hora de decidir qué hacer con la salida.

Para clasificar una entrada en una clase de n clases, la red neuronal tiene una capa de salida
de n neuronas, una por cada clase. Al pasar la entrada por la red se obtiene el cálculo de un
valor numérico para cada una de esas neuronas. Estos valores numéricos representan la
predicción de la red sobre cuál es la probabilidad de que esa entrada pertenezca a cada clase.
Examinar estos valores le dará información sobre la predicción de la red.

Investigate Predictions
Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code loads in an image and imports AlexNet.


img = imread('file01.jpg');
imshow(img)
net = alexnet;
categorynames = net.Layers(end).ClassNames;

La función classify ofrece la clase a la que la red asigna la puntuación más alta. Puede
obtener las puntuaciones predichas para todas clases; para ello solicite una segunda salida
a classify.

[pred,scrs] = classify(net,img)
ACTIVIDAD
Utilice la función classify con la red previamente entrenada AlexNet net para predecir el
tema de la imagen almacenada en la variable img. Almacene la predicción de la red en una
variable llamada pred y todas las puntuaciones de predicción en una variable llamada scores.
[pred,scores] = classify(net,img);

Puede utilizar el vector de las puntuaciones de predicción para investigar la clasificación de la


red.
ACTIVIDAD
Cree un gráfico de barras de las puntuaciones de predicción.

Tenga en cuenta que este gráfico de barras será difícil de leer, dado que incluye 1000
puntuaciones de predicción. Creará un gráfico de barras más centrado tras realizar esta tarea.
bar(scores)
Extracción solo de las puntuaciones significativas

El diagrama que acaba de crear muestra la puntuación predicha (en el eje y) para cada una de
las 1000 clases (en el eje x). Como puede ver, la mayoría de las puntuaciones están muy
próximas a 0. Puede resultar informativo centrarse solo en las clases que tengan puntuaciones
significativas.

ACTIVIDAD
Cree un arreglo lógico highscores que tenga el valor 1 (true), siempre que scores sea mayor
que 0.01.

highscores = scores > 0.01;


Utilice la indexación lógica para crear un gráfico de barras de los valores de predicción superiores
al valor del umbral 0.01.

bar(scores(highscores))
ACTIVIDAD
Utilice la indexación lógica y la función xticklabels para etiquetar el gráfico de barras con los
nombres de clases predichas adecuados. La lista completa de nombres de clases se almacena
en la variable categorynames.

xticklabels(categorynames(highscores))

¡Listo! Hasta ahora, ha usado un valor de codificación fija para el umbral (0.01) para observar
las clases con puntuaciones significativas. Puede experimentar con diferentes criterios de
umbral. La forma más sencilla de hacerlo es probar con distintos valores para el umbral.

También podría utilizar un criterio más dinámico, como calcular un umbral basado en la
distribución de puntuaciones. Intente crear un umbral a partir de una desviación estándar sobre
la puntuación mediana.

thresh = median(scores) + std(scores);


highscores = scores > thresh;

Una vez que tenga las puntuaciones, puede utilizar MATLAB para realizar cualquier análisis
que necesite. Consulte la documentación, donde encontrará otro ejemplo de utilización de las
puntuaciones para proporcionar información más detallada.
Intente también modificar la primera línea de código del script para investigar las puntuaciones
de predicción para las imágenes de file02.jpg y file03.jpg. De manera predeterminada,
las etiquetas de marca del gráfico de barras no mostrarán las etiquetas de todas las barras.
Utilice este código en la sección de la Tarea 5 del script para mostrar las etiquetas
correctamente:

xticks(1:length(scores(highscores)))
xticklabels(categorynames(highscores))
xtickangle(60)

¿Le da esta visualización alguna información sobre la clasificación (incorrecta) por parte de la
red de la imagen de file02.jpg?

Cuando haya terminado, puede pasar a la siguiente sección.

Create a Datastore
Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code displays the images in the current folder and imports AlexNet.
ls *.jpg
net = alexnet;

Puede utilizar la función imageDatastore para crear un almacén de datos en MATLAB,


especificando como entrada los nombres de carpetas o archivos. Puede utilizar caracteres
comodín tales como * para especificar varios archivos.

ds = imageDatastore('foo*.png')

Con esto se creará un almacén de datos de todos los archivos PNG de la carpeta actual cuyos
nombres empiecen por foo.
ACTIVIDAD
Cree un almacén de datos llamado imds que haga referencia a los archivos de imagen de la
carpeta actual con nombres numerados comprendidos entre file01.jpg y file12.jpg.
(Observe que estos son los únicos archivos de imagen de esta carpeta cuyos nombres tienen
la forma filenn.jpg).

imds = imageDatastore('file*.jpg')
Las propiedades del almacén de datos contienen la metainformación sobre los archivos de
datos
ACTIVIDAD
Utilice la propiedad Files del almacén de datos imds para extraer los nombres de archivo de
las imágenes. Almacene el resultado en una variable llamada fname.
fname = imds.Files
Puede importar datos manualmente desde un almacén de datos mediante las
funciones read, readimage y readall: read importa las imágenes de una en una, por
orden; readimage importa una única imagen específica; readall importa todas las
imágenes a una única celda de una matriz (cada imagen en una celda independiente).

I = readimage(ds,n)

Con esto se importará la n-ésima imagen del almacén de datos ds a una serie llamada I.
ACTIVIDAD
Utilice la función readimage para importar la imagen de file07.jpg (el 7.o archivo del
almacén de datos). Almacene la imagen importada en una variable llamada img.
img = readimage(imds,7);
Puede utilizar un almacén de datos de imágenes en lugar de una imagen individual en
funciones de CNN tales como classify.

preds = classify(net,ds)

El resultado será una serie de clases predichas, una por cada imagen del almacén de datos.
ACTIVIDAD
Utilice AlexNet (cargada como la variable net) para clasificar los contenidos de todas las
imágenes del conjunto de datos. Almacene los resultados en una variable llamada preds.

preds = classify(net,imds)

Tenga en cuenta que la función classify pasará 12 imágenes por AlexNet. Es posible que
tarde varios segundos en ejecutarse.

¡Listo!

Recuerde que puede obtener las puntuaciones de predicción para todas las 1000 categorías
como segunda salida de la función classify. En este caso, las puntuaciones serán una
matriz de 12 por 1000. Cada fila representa las puntuaciones de predicción para cada imagen.
Intente obtener las puntuaciones y utilizarlas para investigar con más detalle las clasificaciones.

Por ejemplo, ¿qué predicciones han sido las más “fiables”? Localice el elemento máximo de
cada fila para ver el grado de fiabilidad de la clasificación para cada imagen:

max(scores,[],2)

También puede crear un gráfico de barras para cada fila de las puntuaciones de predicción; para
ello, recurra a las técnicas de la actividad anterior. Cuando haya terminado, puede pasar a la
siguiente sección.

Preprocesar fotos
Hasta ahora, ha estado utilizando fotos preprocesadas para luego clasificarlas. Estas imágenes
se redimensionaron para que pudieran clasificarse con AlexNet. Originalmente, estas imágenes
tenían diferentes tamaños.

En esta interacción, redimensionará una imagen para que pueda clasificarse con una red
previamente entrenada.

Process Images for Classification


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code imports and displays the image from the file file01.jpg.
img = imread('file01.jpg');
imshow(img)
ACTIVIDAD
Utilice la función size para ver el tamaño de la imagen img. Guarde el resultado en una
variable sz.
sz = size(img)

La capa de entrada de una red especifica el tamaño de imagen que requiere la red.

expectedSize = inputlayer.InputSize
ACTIVIDAD
Importe AlexNet. Extraiga la propiedad InputSize de la primera capa de la red. Almacene el
resultado en una variable llamada insz.

net = alexnet;
inlayer = net.Layers(1)
insz = inlayer.InputSize

Puede utilizar la función imresize para redimensionar una imagen de manera que coincida
con el tamaño de entrada exigido.

imgresz = imresize(img,[numrows numcols]);

Así redimensionará img para que sea numrows por numcols. Es decir, imgresz tiene un ancho
de numcols píxeles y una altura de numrows píxeles.
ACTIVIDAD
Utilice la función imresize para redimensionar la imagen almacenada en la variable img de
manera que mida 227 por 227. Almacene de nuevo el resultado en la variable img.

A continuación, muestre la imagen redimensionada con imshow.


img = imresize(img,[227 227]);
imshow(img)

Preprocesamiento de imágenes con un almacén de datos


Para clasificar imágenes mediante una red neuronal convolucional, cada imagen debe tener el
tamaño especificado por la capa de entrada de la red.

Por lo general es preciso preprocesar las imágenes antes de que se puedan clasificar. Puede
preprocesar las imágenes individualmente, pero lo más habitual es realizar los mismos pasos
de preprocesamiento en todo el conjunto de datos. Es más eficiente aplicar estos pasos a todo
el conjunto de datos.
Preprocesamiento a mano

Puede llevar mucho tiempo procesar cada imagen individualmente. Si quiere utilizar un
almacén de datos de imágenes, también necesitará guardar las imágenes procesadas en una
carpeta. Para grandes conjuntos de datos, guardar un duplicado de sus archivos puede ocupar
mucho espacio.

Puede realizar un preprocesamiento con la función augmentedImageDatastore, que toma como


entrada un almacén de datos de imágenes y un tamaño de imagen. El almacén de datos puede
pasarse a la función classify.
Resize Images in a Datastore
Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code displays the images in the current folder and imports AlexNet.
ls *.jpg
net = alexnet
Recuerde que puede utilizar la función imageDatastore para crear un almacén de datos.
Puede utilizar caracteres comodín tales como * para especificar varios archivos.

ds = imageDatastore('*.jpg')
ACTIVIDAD
Cree un almacén de datos de imágenes llamado imds que haga referencia a los archivos de
imagen de la carpeta actual cuya extensión sea .jpg.
imds = imageDatastore('file*.jpg')
Los almacenes de datos de imágenes aumentadas pueden realizar preprocesamientos simples
de una colección completa de imágenes. Para crear este almacén de datos, utilice la
función augmentedImageDatastore tomando como entrada el tamaño de entrada de
imagen de su red.

auds = augmentedImageDatastore([r c],imds)


ACTIVIDAD
Cree un almacén de datos de imágenes aumentadas a partir de imds que redimensione las
imágenes a 227 por 227. Asigne al nuevo almacén de datos el nombre auds.
auds = augmentedImageDatastore([227 227],imds)

Puede utilizar el almacén de datos de imágenes aumentadas como entrada para la


función classify. Antes de clasificar cada imagen, se preprocesará mediante los métodos que
haya especificado al crear el almacén de datos.
ACTIVIDAD
Clasifique las imágenes de auds mediante la función classify, utilizando la red almacenada
en la variable net. Almacene las predicciones en una variable preds.
preds = classify(net,auds)

¡Listo!
El redimensionamiento es uno de los pasos de preprocesamiento más habituales a la hora de
clasificar imágenes.

Los almacenes de datos de imágenes aumentadas pueden realizar muchos otros métodos de
preprocesamiento. En la siguiente sección utilizará la función augmentedImageDatastore para
convertir imágenes en escala de grises a imágenes RGB.
Conversión a imágenes RGB
Una imagen en escala de grises tiene un tamaño de n por m por 1. En muchas redes previamente
entrenadas, como AlexNet, es obligatorio que el tamaño de la imagen sea p por p por 3. Si sus
imágenes están en escala de grises, es posible que tenga que convertirlas a arreglos
tridimensionales.

Preprocess Color Using a Datastore


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code displays the images in the current folder and imports AlexNet.
ls *.jpg
net = alexnet

This code creates an image datastore of these images.


imds = imageDatastore('file*.jpg')

Las imágenes que utilizará en esta interacción están en escala de grises. Puede utilizar la
función montage para mostrar todas las imágenes.

montage(imds)

ACTIVIDAD
Utilice la función montage para mostrar las imágenes del almacén de datos imds.

montage(imds)
Puede convertir estas imágenes a un arreglo tridimensional si establece la
opción ColorPreprocessing al crear un almacén de datos de imágenes aumentadas.

auds = augmentedImageDatastore([n m],...


imds,'ColorPreprocessing','gray2rgb')

Con esto replicará tres veces la imagen en escala de grises, para crear un arreglo
tridimensional. Si imgray es una matriz que representa una imagen en escala de grises, la
imagen procesada será un arreglo tridimensional que representa una imagen en color (RGB).
ACTIVIDAD
Cree un almacén de datos de imágenes aumentadas a partir del almacén de datos de
imágenes imds. Preprocese las imágenes para que su tamaño sea 227 por 227 por 3.

Asigne al almacén de datos de imágenes aumentadas el nombre auds.

auds = augmentedImageDatastore([227 227],imds,'ColorPreprocessing','gray2rgb')

Clasifique las imágenes de auds mediante la función classify. AlexNet se almacena en la


variable net. Almacene las predicciones en una variable preds.

Create a Datastore Using Subfolders


Instructions are in the task pane to the left. Complete and submit each task one at a time.
De manera predeterminada, imageDatastore busca los archivos de imagen dentro de la
carpeta especificada. Puede utilizar la opción 'IncludeSubfolders' para buscar
imágenes dentro de las subcarpetas de la carpeta especificada.

ds = imageDatastore('folder',...
'IncludeSubfolders',true)
ACTIVIDAD
Cree un almacén de datos flwrds para todas las imágenes de las subcarpetas de la
carpeta Flowers.
flwrds = imageDatastore('Flowers','IncludeSubfolders',true)
ACTIVIDAD
Utilice AlexNet (cargada como la variable net) para clasificar los contenidos de todas las
imágenes del conjunto de datos. Almacene los resultados en una variable llamada preds.

Tenga en cuenta que la función classify pasará 15 imágenes por AlexNet. Es posible que
tarde varios segundos en ejecutarse.

preds = classify(net,flwrds)
Ventajas de la transferencia del aprendizaje

Iniciarse en el uso de una red previamente entrenada como AlexNet es muy sencillo. Pero
carece de flexibilidad en cuanto a la forma en que funciona la red, y esta probablemente no
solucionará el problema en concreto que usted esté intentando resolver.

Puede crear y entrenar una red usted mismo, empezando solo con la arquitectura de la red y
pesos aleatorios. Pero lograr unos resultados razonables requiere mucho esfuerzo: (1)
conocimiento y experiencia en arquitectura de redes (2) una ingente cantidad de datos de
entrenamiento y (3) mucho tiempo de computación.
La transferencia del aprendizaje es una solución eficiente para muchos problemas. El
entrenamiento requiere algunos datos y tiempo de computación, pero mucho menos que hacerlo
desde cero, y el resultado es una red adaptada específicamente a su problema.

Flujo de trabajo típico para la transferencia del aprendizaje

Para realizar la transferencia del aprendizaje necesita crear tres componentes:


1. Un arreglo de capas que representan la arquitectura de red. Para la transferencia del
aprendizaje, este arreglo de capas se crea mediante la modificación de una red preexistente
como AlexNet.
2. Imágenes con etiquetas conocidas, para utilizarlas como datos de entrenamiento. Por lo
general se proporcionan como almacén de datos.
3. Una variable que contenga las opciones que controlan el comportamiento del algoritmo de
entrenamiento.
Estos tres componentes se proporcionan como entradas a la función trainNetwork, que
devuelve como salida la red entrenada.
Debería probar el rendimiento de la red entrenada que acaba de crear. Si no es el adecuado,
debería intentar ajustar alguna de las opciones de entrenamiento y volver a realizar el
entrenamiento.

Etiquetado de imágenes de entrenamiento

Al entrenar una red, necesita proporcionar etiquetas conocidas para las imágenes de
entrenamiento. La carpeta Flowers contiene 12 subcarpetas, cada una de las cuales contiene
a su vez 80 imágenes de un tipo de flor. Por tanto, el nombre de la carpeta puede utilizarse para
proporcionar las etiquetas necesarias para el entrenamiento.

Label Images in a Datastore


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code creates a datastore of 960 flower images.


load pathToImages
flwrds = imageDatastore(pathToImages,'IncludeSubfolders',true);
flowernames = flwrds.Labels
Las etiquetas necesarias para el entrenamiento pueden almacenarse en la
propiedad Labels del almacén de datos de imágenes. De manera predeterminada, la
propiedad Labels está vacía.

Puede hacer que el almacén de datos determine automáticamente las etiquetas a partir de los
nombres de las carpetas; para ello, especifique la opción 'LabelSource'.

ds = imageDatastore(folder,...
'IncludeSubfolders',true,...
'LabelSource','foldernames')
ACTIVIDAD
Recree el almacén de datos flwrds con todas las imágenes de las subcarpetas incluidas en la
ruta de carpeta almacenada en la variable pathToImages, en esta ocasión utilizando los
nombres de carpetas como etiquetas de las imágenes. La variable pathToImages ya existe en
el espacio de trabajo.

flwrds = imageDatastore(pathToImages,'IncludeSubfolders',true,'LabelSource','foldernames')
ACTIVIDAD
Extraiga la propiedad Labels de flwrds a una variable llamada flowernames.

flowernames = flwrds.Labels

Split Data for Training and Testing


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code creates a datastore of 960 flower images.


load pathToImages
flwrds =
imageDatastore(pathToImages,'IncludeSubfolders',true,'LabelSource','folde
rnames')

Puede utilizar la función splitEachLabel para dividir las imágenes de un almacén de datos
en dos almacenes de datos independientes.

[ds1,ds2] = splitEachLabel(imds,p)

La proporción p (un valor de 0 a 1) indica la proporción de imágenes con cada etiqueta


de imds que debería estar contenida en ds1. El resto de archivos se asignan a ds2.
ACTIVIDAD
Divida el almacén de datos flwrds en dos almacenes de datos, flwrTrain y flwrTest,
de manera que el 60% de los archivos de cada categoría esté en flwrTrain.
De manera predeterminada, splitEachLabel mantiene los archivos ordenados. Puede
mezclar de forma aleatoria los archivos, para lo cual deberá añadir el
indicador 'randomized'.

[ds1,ds2] = splitEachLabel(imds,p,'randomized')
ACTIVIDAD
Divida el almacén de datos flwrds en dos almacenes de datos, flwrTrain y flwrTest, de
manera que el 80% de los archivos de cada categoría esté en flwrTrain.
[flwrTrain,flwrTest] = splitEachLabel(flwrds,0.8,'randomized')

Datos de entrenamiento no compensados

En algunas aplicaciones es habitual tener muchas más imágenes de una clase que de otras. Por
ejemplo, al intentar detectar defectos, por lo general es fácil obtener muchas imágenes sin
defectos, pero más difícil obtenerlas con defectos.

En este caso, dividir los datos proporcionalmente por clase dará como resultado que la red
recibirá entrenamiento fundamentalmente con imágenes sin defectos. Esto puede sesgar el
entrenamiento y dar como resultado una red que “cumple con los porcentajes” en lugar de
aprender realmente a identificar características que indiquen la presencia de defectos.
Para evitarlo, puede resultar útil dividir los datos de manera que las imágenes de entrenamiento
tengan el mismo número de cada clase.

Cuando p es un valor de 0 a 1, se interpreta como una proporción. Las imágenes entonces se


dividen de manera que cada etiqueta se divida proporcionalmente. También puede especificar
un número exacto de archivos que tomar de cada etiqueta para asignarlos a ds1.

[ds1,ds2] = splitEachLabel(imds,n)

Así se asegura que todas las etiquetas de ds1 tienen n imágenes, incluso aunque no todas las
categorías contengan el mismo número de imágenes.
ACTIVIDAD
Divida el almacén de datos flwrds en dos almacenes de datos, flwrTrain y flwrTest,
de manera que 50 archivos de cada categoría estén en flwrTrain.

[flwrTrain,flwrTest] = splitEachLabel(flwrds,50)

¡Listo! Dividir las imágenes en dos conjuntos facilita la utilización de un conjunto para entrenar
su red y el otro para probar el rendimiento del resultado.

También puede utilizar un conjunto de “validación” para supervisar el rendimiento de la red


durante el entrenamiento. En ese caso, puede dividir los datos en tres conjuntos: uno para el
entrenamiento, otro para la validación durante el entrenamiento y otro más para una prueba
independiente del resultado final. Pruebe a utilizar splitEachLabel para dividir las imágenes
de Flowers en varios conjuntos. Asigne varios valores a p o n como entradas y pida el número
adecuado de almacenes de datos como salidas.
Recuerde que las redes de tipo feed-forward se representan en MATLAB como un arreglo de
capas. De esta forma es sencillo realizar la indexación de las capas de una red y cambiarlas.

Para modificar una red preexistente, cree una nueva capa...

...luego realice la indexación del arreglo de capas que representa la red y sobrescriba la capa
elegida con la recién creada.
Como con cualquier otra asignación indexada de MATLAB, puede combinar estos pasos en una
única línea.

Modify Network Layers


Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code imports AlexNet and extracts its layers.


anet = alexnet;
layers = anet.Layers

La función fullyConnectedLayer crea una nueva capa totalmente conectada, con un


número determinado de neuronas.

fclayer = fullyConnectedLayer(n)
ACTIVIDAD
Cree una nueva capa completamente conectada llamada fc con 12 neuronas (para los 12
tipos de flores).
fc = fullyConnectedLayer(12)
Puede utilizar la indexación de arreglos estándar para modificar elementos individuales de un
arreglo de capas.

mylayers(n) = mynewlayer
ACTIVIDAD
Sustituya la última capa totalmente conectada (la capa 23. a) de la red representada por el
arreglo layers con la nueva capa recién creada, fc.
layers(23) = fc
Correspondencia de la capa de salida con las capas anteriores

Actualmente la capa de salida sigue usando las 1000 etiquetas para las clases de AlexNet. Esto
supondrá un problema cuando se pase la información desde la nueva capa completamente
conectada (de 12 clases) recién creada. Para corregirlo, debe sustituir la capa de salida con una
nueva capa de salida, vacía. Las 12 clases se determinarán durante el entrenamiento, a partir
de las etiquetas de los datos de entrenamiento.

Puede utilizar la función classificationLayer para crear una nueva capa de salida para
una red de clasificación de imágenes.

cl = classificationLayer

Con un único comando puede crear nuevas capas y sobrescribir una capa existente con una
capa nueva:

mylayers(n) = classificationLayer

ACTIVIDAD
Sustituya la capa final (salida) de la red representada por el arreglo layers con una nueva
capa de clasificación.

layers(end) = classificationLayer

Net Training Options


Instructions are in the task pane to the left. Complete and submit each task one at a time.
¿Cuáles son las opciones que se pueden establecer para controlar el entrenamiento de la red?
Puede ver las opciones disponibles para un algoritmo de entrenamiento específico mediante la
función trainingOptions.

opts = trainingOptions('sgdm')

Con esto se crea una variable opts que contiene las opciones predeterminadas para el
algoritmo de entrenamiento “descenso de gradiente estocástico con ímpetu” (SGDM).
ACTIVIDAD
Cree una variable llamada opts con las opciones predeterminadas del algoritmo de
entrenamiento para el optimizador SGDM. Quite el signo de punto y coma del final de la línea
para mostrar el resultado.
opts = trainingOptions('sgdm')
Cambio del ritmo de aprendizaje

Con frecuencia, querrá primero intentar el entrenamiento conservando los valores


predeterminados de la mayoría de las opciones. Sin embargo, al realizar la transferencia del
aprendizaje, lo habitual es querer empezar con un valor de InitialLearnRate menor que
el predeterminado (0.01).

El ritmo de aprendizaje controla el grado de agresividad con el que el algoritmo cambia los pesos
de la red. El objetivo de la transferencia del aprendizaje es afinar una red existente, así que por
lo general querrá cambiar los pesos con menos agresividad que cuando el entrenamiento se
realiza desde cero.

Puede especificar cualquier número de ajustes como pares opcionales nombre-valor en la


función trainingOptions.

opts = trainingOptions('sgdm','Name',value)
ACTIVIDAD
Cree una variable llamada opts con las opciones predeterminadas del algoritmo de
entrenamiento para el optimizador SGDM, excepto para la opción InitialLearnRate, que
debe establecerse como 0.001.

opts = trainingOptions('sgdm','InitialLearnRate',0.001)
¡Listo! Ha creado una variable que contiene los ajustes predeterminados del algoritmo de
entrenamiento, excepto para el ritmo de aprendizaje inicial, que se ha establecido como 0.001
en lugar de como 0.01.

Hay otros algoritmos de entrenamiento disponibles. Intente crear opciones de entrenamiento


para el optimizador Adam.
¿Qué es un "minilote"?
En cada iteración, se utiliza un subconjunto de las imágenes de entrenamiento, llamado minilote,
para actualizar los pesos. Cada iteración utiliza un minilote diferente. Una vez que todo el
conjunto de entrenamiento se ha utilizado se completa una época.

El número máximo de épocas (MaxEpochs) y el tamaño de los minilotes (MiniBatchSize)


son parámetros que puede establecer en las opciones del algoritmo de entrenamiento.

Tenga en cuenta que la pérdida y la precisión indicadas durante el entrenamiento se refieren al


minilote que se está usando en la iteración actual.

De manera predeterminada, las imágenes se mezclan una vez antes de dividirse en minilotes.
Puede controlar este proceso con la opción Shuffle.

Utilización de GPU
Una GPU (unidad de procesamiento de gráficos) puede acelerar significativamente los muchos
cálculos necesarios para el deep learning. Si el ordenador no dispone de una GPU soportada, el
entrenamiento puede realizarse con la CPU, pero llevará más tiempo. Si va a dedicarse en serio
al deep learning, es preferible que entrene su red en un ordenador con una GPU que sea capaz
de gestionar el procesamiento necesario.
• Si dispone de una GPU adecuada y ha instalado Parallel Computing Toolbox, la
función trainNetwork realizará automáticamente el entrenamiento en la GPU, sin
necesidad de ningún código especial.
• En caso contrario, el entrenamiento se realizará en la CPU de su ordenador. Así tendrá la
opción de experimentar un poco antes de decidirse a comprar el hardware y el software
necesarios.

Script de ejemplo de transferencia del aprendizaje


El siguiente código implementa la transferencia del aprendizaje para el ejemplo de las especies
de flores de este mismo capítulo. Está disponible como el script trainflowers.mlx en los
archivos de ejemplo del curso. Puede descargar los archivos de ejemplo del curso desde el menú
de ayuda de la esquina superior derecha. Encontrará más información sobre este conjunto de
datos en la página 17 Category Flower Dataset de la Universidad de Oxford.

Tenga en cuenta que este ejemplo puede tardar algún tiempo en ejecutarse si lo ejecuta en un
ordenador que no tenga una GPU soportada.

Obtener imágenes de entrenamiento

%% el bueno está al final de script 3

flower_ds =
imageDatastore('Flowers','IncludeSubfolders',true,'LabelSource','foldernames'
);
[trainImgs,testImgs] = splitEachLabel(flower_ds,0.6);
numClasses = numel(categories(flower_ds.Labels));
Crear una red mediante la modificación de AlexNet

net = alexnet;
layers = net.Layers;
layers(end-2) = fullyConnectedLayer(numClasses);
layers(end) = classificationLayer;

Establecer las opciones del algoritmo de entrenamiento

options = trainingOptions('sgdm','InitialLearnRate', 0.001);

Realizar el entrenamiento

[flowernet,info] = trainNetwork(trainImgs, layers, options);

Utilizar la red entrenada para clasificar imágenes de prueba

testpreds = classify(flowernet,testImgs);
Evaluación de una red tras el entrenamiento

La variable flowernet contiene la red obtenida mediante la transferencia del aprendizaje en


AlexNet con los datos de las especies de flores. La variable info es una estructura que contiene
información sobre el entrenamiento.

¿Cómo de buena es esta red? En las siguientes dos interacciones, evaluará flowernet.
Evaluate Performance
Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code loads the training information of flowernet.


load pathToImages
load trainedFlowerNetwork flowernet info
La variable info es una estructura que contiene información sobre el entrenamiento. Los
campos TrainingLoss y TrainingAccuracy contienen un registro del rendimiento de la red
con los datos de entrenamiento en cada iteración.

ACTIVIDAD
Represente la pérdida de entrenamiento, almacenada en el campo TrainingLoss de info.

plot(info.TrainingLoss)

This code creates a datastore of the flower images.


dsflowers =
imageDatastore(pathToImages,'IncludeSubfolders',true,'LabelSource','folde
rnames');
[trainImgs,testImgs] = splitEachLabel(dsflowers,0.98);

Parece que la red tiene un buen rendimiento con los datos de entrenamiento, pero la verdadera
prueba es el rendimiento que ofrezca con los datos de prueba.
ACTIVIDAD
Utilice la función classify para obtener las clasificaciones que flowernet predice para las
imágenes del almacén de datos testImgs. Almacene el resultado en una variable
llamada flwrPreds.

Tenga en cuenta que la función classify pasará 24 imágenes por flowernet. Es posible que
tarde varios segundos en ejecutarse.
flwrPreds = classify(flowernet,testImgs)
Investigate test performance
Instructions are in the task pane to the left. Complete and submit each task one at a time.

This code sets up the Workspace for this activity.


load pathToImages.mat
pathToImages
flwrds =
imageDatastore(pathToImages,'IncludeSubfolders',true,'LabelSource','folde
rnames');
[trainImgs,testImgs] = splitEachLabel(flwrds,0.98);
load trainedFlowerNetwork flwrPreds
Puede determinar cuántas de las imágenes de prueba ha clasificado correctamente la red; para
ello, compare la clasificación predicha con la clasificación conocida. Las clasificaciones
conocidas se almacenan en la propiedad Labels del almacén de datos.
ACTIVIDAD
Almacene las clasificaciones conocidas de las imágenes de prueba en una variable
llamada flwrActual; para ello, extraiga la propiedad Labels del almacén de datos testImgs.
flwrActual = testImgs.Labels;

Puede utilizar la comparación lógica y la función nnz para determinar el número de elementos
de dos arreglos que coincidan:

numequal = nnz(a == b)
ACTIVIDAD
Utilice la función nnz y el operador de igualdad (==) para contar cuántas de las clasificaciones
predichas (flwrPreds) coinciden con la clasificación correcta (flwrActual). Almacene el
resultado en una variable llamada numCorrect.

numCorrect = nnz(flwrPreds == flwrActual)


ACTIVIDAD
Calcule la fracción de imágenes de prueba correctamente clasificadas; para ello,
divida numCorrect entre el número de imágenes de prueba. Almacene el resultado en una
variable llamada fracCorrect.

fracCorrect = numCorrect/numel(flwrPreds)
Rendimiento por clases

La pérdida y la precisión ofrecen medidas generales del rendimiento de la red. Pero puede
resultar informativo investigar cuál es el rendimiento de la red para las diferentes clases de
imágenes. ¿Están las clasificaciones erróneas distribuidas de forma aleatoria o hay
determinadas clases que le resultan más difíciles a la red? ¿Hay clases que la red confunde de
una manera desproporcionada?

La función confusionchart calcula y muestra la matriz de confusión para las


clasificaciones predichas.

confusionchart(knownclass,predictedclass)

El elemento (j,k) de la matriz de confusión es un recuento de cuántas imágenes de la


clase j predijo la red que estarían en la clase k. Por tanto, los elementos diagonales
representan clasificaciones correctas, en tanto que los no diagonales representan
clasificaciones erróneas.
ACTIVIDAD
Muestre la matriz de confusión para los datos de prueba de flores. Las clasificaciones
predichas se almacenan en el arreglo categórico flwrPreds. Las clasificaciones conocidas
se almacenan en la propiedad Labels del almacén de datos testImgs.
confusionchart(testImgs.Labels,flwrPreds)

¡Listo! Ha determinado que la red flowernet tiene una precisión del 92% (22/24) con los datos
de prueba. Puede comprobar visualmente que en las dos clasificaciones erróneas se ha predicho
que las imágenes eran campanillas, cuando en realidad eran una flor de azafrán y un lirio. Puede
utilizar técnicas de análisis de datos estándar de MATLAB para investigar con más detalle estas
imágenes clasificadas erróneamente. Un enfoque típico sería localizar los archivos que contienen
las imágenes clasificadas erróneamente y luego importar y visualizar esas imágenes (o un
subconjunto de ellas) para comprobar si hay alguna característica que le esté creando problemas
a la red.

Tenga en cuenta que en este ejemplo la relación imágenes de entrenamiento/imágenes de


prueba es muy superior a la que normalmente se utilizaría en la práctica. La razón es que así se
reduce el tiempo necesario para clasificar las imágenes de prueba en estas interacciones. A ser
posible, en la práctica debería reservar suficientes imágenes de prueba como para que los
resultados de la prueba sean representativos del comportamiento de la red en el uso general.
Resumen de funciones de transferencia del aprendizaje
Crear una red
Función Descripción

alexnet Cargar la red previamente entrenada “AlexNet”

supported networks Ver una lista de las redes previamente entrenadas disponibles

fullyConnectedLayer Crear una capa de red completamente conectada

classificationLayer Crear una nueva capa de salida para una red de clasificación

Obtener imágenes de entrenamiento


Función Descripción

imageDatastore Crear una referencia de almacén de datos a los archivos de


imágenes

augmentedImageDatastore Preprocesar una colección de archivos de imágenes

splitEachLabel Dividir el almacén de datos en varios almacenes de datos

Establecer las opciones del algoritmo de entrenamiento


Función Descripción

trainingOptions Crear una variable que contenga las opciones del algoritmo de entrenamiento

Realizar el entrenamiento
Función Descripción

trainNetwork Realizar el entrenamiento

Utilizar la red entrenada para realizar clasificaciones


Función Descripción

classify Obtener de la red entrenada las clasificaciones de las imágenes de entrada


Evaluar la red entrenada
Función Descripción

nnz Contar los elementos de una serie cuyo valor no sea cero

confusionchart Calcular la matriz de confusión

heatmap Visualizar la matriz de confusión como mapa de calor

Proyecto: Vitalidad de lombriz intestinal


Visión general

En este proyecto clasificará las lombrices intestinales como vivas o muertas utilizando una red
neuronal convolucional previamente entrenada.

Trabajará con diapositivas de microscopio.

Las lombrices vivas son curvilíneas.


Las lombrices muertas son rectilíneas.

Algunas diapositivas de microscopio contienen tanto lombrices curvilíneas como rectilíneas.


Esta tipo de diapositivas se etiquetaron con el tipo de lombrices que más aparecía en cada
diapositiva. Puede ver el archivo WormData.csv para comprobar la etiqueta asignada a cada
diapositiva.
Conjunto de datos y scripts

Los archivos del proyecto incluyen las imágenes, las etiquetas y un script con la solución.

WormImages contiene 93 imágenes microscópicas. Escale las imágenes para que se


muestren correctamente. La app Image Browser escalará automáticamente las imágenes.
WormData.csv contiene las etiquetas para cada imagen. Puede utilizarlas como la
propiedad Labels de un almacén de datos de imágenes.

El script roundworms.mlx proporciona una solución que permite la transferencia del aprendizaje
desde AlexNet.
Tiempo de entrenamiento

Si dispone de una GPU soportada, podrá entrenar su red en menos de un minuto. También
puede entrenar su red en una CPU, pero el proceso de entrenamiento puede llevar hasta diez
minutos.

¿Listo para empezar?


Descargue los archivos del curso para empezar. Puede volver a acceder a cualquiera de los
capítulos anteriores si necesita repasar los conceptos utilizados en el proyecto.

También podría gustarte