Python Case|Uso de redes convolucionales para clasificar imágenes de galaxias

imagen

 Galaxy Zoo (Galaxy Zoo) es un proyecto científico voluntario organizado por instituciones de investigación como la Universidad de Oxford y que invita al público a asistir, con el propósito de catalogar más de 1 millón de imágenes de galaxias. Este es un estudio público a gran escala del cielo estrellado en astronomía. El entusiasmo del público es alto. Con la participación activa de casi 100.000 voluntarios, la primera fase del proyecto del zoológico de galaxias se completó en solo 175 días: 950.000 Las galaxias fueron clasificados, y cada galaxia fue clasificada 38 veces en promedio.

Según los resultados de la investigación del Galaxy Zoo, las imágenes de galaxias se pueden dividir en cuatro categorías: galaxias circulares, galaxias intermedias, galaxias laterales y galaxias espirales. La Figura 1 muestra imágenes de 4 clases de galaxias seleccionadas al azar. La primera fila es una galaxia circular, es decir, la forma de la galaxia es un círculo con bordes suaves. La segunda fila es la galaxia intermedia, es decir, la forma de la galaxia es una elipse, la razón por la que se llama galaxia intermedia significa que su forma está entre la galaxia circular en la primera fila y la galaxia lateral en la tercera fila. . La galaxia de borde que se muestra en la fila 3 es una galaxia de disco lateral con una protuberancia central. La cuarta fila es una galaxia espiral. Como sugiere el nombre, este tipo de galaxia tiene forma de espiral, con una protuberancia nuclear en el medio y brazos espirales alrededor. La Vía Láctea es una galaxia espiral típica.

imagen

■ Figura 1 Ejemplo de una imagen de galaxia

Debido a que el conjunto de datos original del zoológico de galaxias es relativamente grande, este capítulo solo usa parte de los datos: se seleccionan 500 imágenes en cada uno de los cuatro tipos de muestras de galaxias, por lo que la muestra de datos en este capítulo es 4 × 500 = 2000 imágenes . Cada imagen es una imagen RGB con una etiqueta de clasificación y el tamaño de la imagen es de 424×424×3 píxeles. Las etiquetas de clase son 0, 1, 2, 3, que representan galaxias circulares, intermedias, de canto y espirales, respectivamente.

La tarea de este caso es utilizar la red neuronal convolucional para clasificar 2000 imágenes de galaxias y evaluar el efecto de clasificación del modelo de red.

 

01. Realización de casos

Esta sección usa el modelo ResNet50 en la biblioteca Keras para implementar el caso anterior, es decir, usa el modelo ResNet50 para clasificar imágenes de galaxias. El proceso de implementación es el siguiente.

1. Descripción del conjunto de datos

En este caso, el conjunto de datos se almacena en la carpeta image_anli. Hay cuatro tipos de galaxias: galaxias circulares, galaxias intermedias, galaxias laterales y galaxias espirales. Cada tipo de galaxia tiene 500 imágenes, y el tamaño de la imagen es 424 × 424 ×3 . Según la categoría de imágenes de galaxias, las imágenes de galaxias se colocan en 4 carpetas y las etiquetas de categoría son 0, 1, 2 y 3, que representan galaxias circulares, galaxias intermedias, galaxias laterales y galaxias espirales, respectivamente. El nombre de la carpeta es la etiqueta de categoría de esa galaxia. El diagrama de estructura de directorios donde se encuentra el conjunto de datos se muestra en la Figura 2.

imagen

■Figura 2 Diagrama de la estructura del directorio donde se encuentra el conjunto de datos

2. División del conjunto de datos

Antes de entrenar y probar las imágenes de galaxias, primero es necesario dividir el conjunto de datos: divida 2000 imágenes de galaxias en un conjunto de entrenamiento (entrenamiento), un conjunto de verificación (validación) y un conjunto de prueba (prueba) según la proporción de 7: 2:1, respectivamente para entrenamiento, validación y prueba de modelos. La idea de realización es: primero divida la carpeta image_anli en una carpeta temporal y una carpeta de prueba de acuerdo con la proporción de 9: 1, y la carpeta de prueba es un conjunto de prueba, que almacena 4 subcarpetas, incluido un total de 4 × 50 = 200 imágenes de galaxias; hay 4 subcarpetas almacenadas en la carpeta temporal, incluido un total de 4 × 450 = 1800 imágenes de galaxias, y luego la carpeta temporal se divide en un conjunto de entrenamiento y un conjunto de verificación de acuerdo con una proporción de 7:2.

Cree un nuevo programa .py denominado split_dataset.py, que se utiliza para completar la tarea de división del conjunto de datos. El proceso de implementación específico es el siguiente.

(1) Biblioteca de importación. Importe la biblioteca os y la biblioteca shutil para realizar operaciones relacionadas en carpetas y archivos, y la biblioteca aleatoria realiza una división aleatoria de datos. el código se muestra a continuación.

import os
import random
import shutil

 (2) Defina la función split() para dividir el conjunto de datos original en dos conjuntos de datos según la proporción especificada y copie la imagen en la carpeta correspondiente. el código se muestra a continuación.

def split(initial path, save dir, split rate):
'''
划分数据集
:param initial path:字符串类型,未划分数据之前的文件路径
:param save dir:列表类型,划分数据之后的文件路径
:param split rate:浮点数,划分比例
'''
# 获取数据集数量及类别
file number list=os.listdir(initial path)
total num classes=len(file number list)
#置入随机种子,使每次划分的数据集相同
random.seed(1)
for i in range(total num classes):
class name=file number list [i]
image dir=os.path.join(initial path,class name)
# 调用函数将图像从一个文件夹复制到另一个文件夹
file copy(image dir,save list dir,class name, split rate)
print(' s 已成功划分 class name)

 Entre ellos, la función file_copy() copia la imagen de file_dir a save_dir en proporción. el código se muestra a continuación.

def file copy(file dir, save dir,class name,split rate):
'''
将图像从源文件夹复制到目标文件夹
:param file dir:字符串类型,未划分数据之前的文件路径
:param save dir:列表类型,划分数据之后的文件路径
:param class name:字符串类型,星系类别的名称
:param split rate:浮点数,划分比例
'''
image list=os.listdir(file dir)      #获取图片的原始路径
image number=len(image list)       
train number=int(image number * split rate)
#从 image list 中随机选取图像
train_sample=random.sample(image_list,train_number)
test_sample=list(set(image_list) - set(train_sample))
data_sample=[train_sample,test_sample]
# 复制图像到目标文件夹
for i in range(len(save dir)) :
if os.path.isdir(save dir i  + class name) :
for data in data sample [i] :
shutil.copy(os.path.join(file dir,data),os.path.join(save)
dir [i]  + class_name+'/',data))
else:
os.makedirs(save dir[i]  + class_name)
for data in data sample [i] :
shutil.copy(os.path.join(file_dir,data), os.path.join(save)
dir [i]  + class_name+'/', data))

 (3) Función principal. En la función principal, la función split() se llama por primera vez, y el conjunto de datos original se divide en una carpeta temporal y una carpeta de prueba de acuerdo con la proporción de 9:1, y la función split() se llama por segunda vez. tiempo, y la carpeta temporal se divide en 7:2 La proporción se divide en conjunto de entrenamiento y conjunto de validación. el código se muestra a continuación.

if_name_== ' _main_'
# 原始数据集路径
initial path=r'./image anli'
#保存路径
save_list dir=[r'./temp/',r'./test/]
# 原始数据集按 9:1被划分为 temp 文件夹和 test 文件夹
split rate=0.9
split(initial path, save list dir, split rate)
# 继续将 temp 划分成训练集和验证集
initial path=r'./temp
#保存路径
save list dir=[r'./train/',r'./val/!]
# temp 数据集按 7:2 被划分成训练集和验证集
split rate=7/9
split(initial path,save list dir,split rate)

    

3. Clasificar imágenes usando el modelo ResNet50

Después de dividir el conjunto de datos, cree un programa classify_resnet50.py para realizar funciones como lectura y procesamiento de imágenes, capacitación y evaluación de modelos. El proceso de implementación específico es el siguiente.

(1) Biblioteca de importación. Importe el modelo ResNet50 empaquetado de Keras, clasifique la imagen e importe los métodos relacionados del módulo sklearn.metrics para evaluar la precisión de la clasificación, la tasa de recuperación, la tasa de precisión y la medida F1 del modelo. el código se muestra a continuación.

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from sklearn.metrics import accuracy score
from sklearn.metrics import precision score
from sklearn.metricsimport recall score
from sklearn.metrics import f score

 (2) Lea la imagen del conjunto de datos. Lea las imágenes del conjunto de entrenamiento, el conjunto de verificación y el conjunto de prueba del local, y póngalos en los objetos tren, val y prueba respectivamente. el código se muestra a continuación.

# 从训练集、验证集和测试集所在文件夹里读取图像
train dir=r'. train'
test dir=r'. test!
val dir=r'. val
height=224width=224
# resnet 50 的处理的图像大小
# resnet 50 的处理的图像大小
batch size=24
train=tf.keras.preprocessing.image dataset from directory(
train dir
seed=123
image size=(height, width),
batch size=batch size)
test=tf.keras.preprocessing.image dataset from directory(test dir,
shuffle=False
image size=(height,width)batch size=batch size)
val=tf.keras.preprocessing.image dataset from directory(val dir,
seed=123
image size=(height, width)
batch size=batch size)

Al leer las imágenes del conjunto de prueba, establezca el valor del parámetro shuffle en Falso. El propósito de esto es no alterar el orden de lectura de las imágenes del conjunto de prueba, lo cual es conveniente para la evaluación posterior del efecto de clasificación del modelo.

(3) Mejora de la imagen. Los grandes conjuntos de datos son un requisito previo para el éxito de las redes neuronales profundas. Si el conjunto de datos de entrenamiento es pequeño, se puede usar el aumento de imágenes para aumentar la diversidad del conjunto de entrenamiento. La mejora de imágenes se refiere a la generación de muestras de entrenamiento similares pero diferentes después de una serie de cambios aleatorios en las imágenes de entrenamiento. Las imágenes utilizadas por la red neuronal en cada ronda de entrenamiento iterativo no son exactamente las mismas para mejorar la solidez del modelo. Además, cambiar aleatoriamente las muestras de entrenamiento puede reducir la dependencia del modelo de ciertas propiedades, mejorando así la capacidad de generalización del modelo. Por ejemplo, haga zoom o mueva la imagen aleatoriamente para que el objeto de destino aparezca en diferentes posiciones, reduciendo la dependencia del modelo en la posición del objeto. En este caso, la cantidad de imágenes de galaxias en el conjunto de entrenamiento es limitada, así que use la capa de preprocesamiento de tensorflow.keras para realizar las siguientes operaciones de mejora de imágenes en el conjunto de entrenamiento.

① Voltear aleatoriamente tf.keras.layers.experimental.preprocessing.RandomFlip (modo): voltear aleatoriamente la imagen de entrada. Generalmente, mode="horizontal" significa voltear horizontalmente, y mode="vertical" significa voltear hacia arriba y hacia abajo.

② Rotación aleatoria tf.keras.layers.experimental.preprocessing.RandomRotation (factor): rota aleatoriamente la imagen de entrada según el ángulo de rotación (factor×2π). El factor del parámetro puede ser una tupla de 2 elementos o un solo número de coma flotante: un valor positivo indica una rotación en sentido contrario a las agujas del reloj y un valor negativo indica una rotación en el sentido de las agujas del reloj. Por ejemplo, factor=(-0.2, 0.3) significa que el rango de rotación es una cantidad aleatoria en [-20%×2π, 30%×2π]. factor=0.1 significa que el rango de rotación es una cantidad aleatoria dentro de [-10%×2π, 10%×2π]. Debido a la invariancia de rotación de las imágenes de galaxias, la categoría de las imágenes de galaxias no cambiará después de la rotación, lo que puede aumentar la cantidad de datos hasta cierto punto.

③ Escalado aleatorio de capas.experimental.preprocesamiento.RandomZoom(factor): reducir o ampliar aleatoriamente la imagen de la galaxia. El parámetro factor representa el factor de escala y el valor puede ser una tupla de 2 elementos o un solo número de punto flotante. factor=(0.2, 0.3) indica que el rango de reducción de salida es [+20%, +30%] cantidad aleatoria, factor=(-0.3, -0.2) indica que el rango de amplificación de salida es [+20%, +30% ] cantidad aleatoria.

④ Capas de altura aleatoria.experimental.preprocesamiento.RandomHeight (factor): cambia aleatoriamente la altura de la imagen. El parámetro factor representa la relación y su valor es similar al parámetro factor de escalado aleatorio.

⑤ Capas de ancho aleatorio.experimental.preprocesamiento.RandomWidth (factor): Mueva la imagen al azar para un cierto ancho.

⑥ Capas normalizadas.preprocesamiento.experimental.Reescalado (escala): normalizar los datos. scale=1./255 indica que la entrada cuyo rango de valores es [0, 255] está normalizada al rango [0, 1].

El código específico para la mejora de la imagen en este caso es el siguiente.

# 图像增强,包括随机水平翻转,随机旋转,随机缩放
data augmentation=keras.Seguential(
[
layers.experimental.preprocessing.RandomFlip("horizontal",
input shape=(height, width,3)),
layers.experimental.preprocessing.RandomRotation(0.1),
layers.experimental.preprocessing.RandomZoom(0.1),
layers.experimental.preprocessing.Randomwidth(0.1),
layers.experimental.preprocessing.RandomHeight(0.1),
layers.experimental.preprocessing.Rescaling(1./255)
]
)

 Para mostrar el efecto de la mejora de la imagen, una imagen seleccionada al azar en el conjunto de datos se voltea horizontalmente y se rota al azar, el efecto se muestra en la Figura 3.

imagen

 

■ Figura 3 Ejemplo de mejora de imagen

(4) Construcción de modelos y entrenamiento. El modelo de red seleccionado en este caso es el modelo ResNet50 que viene con Keras. El optimizador (optimizer) usado es Adam, la pérdida seleccionada es sparse_categorical_crossentropy, y el estándar de medición (metrics) usa precision. El valor de las épocas establecidas es 100, y el valor de batch_size es El valor es 32. Por supuesto, la elección de los hiperparámetros no es única. Puede probar otros hiperparámetros usted mismo y observar sus efectos de entrenamiento. el código se muestra a continuación.

#构建模型
model=Sequential(Ldata augmentation,
ResNet50(weights=None,classes= 4)])
#配置模型参数
model.compile(optimizer="Adam"loss='sparse categorical crossentropy'rmetrics='accuracy' )
#训练模型
epochs=100
history=model.fit(train,epochs=epochs,batch size=32
validation data=val)
# 保存模型
model.save("resnet img.h5")

Después de que se ejecuta el programa, se genera un archivo llamado resnet_img.h5 en el directorio donde se encuentra el programa, que es el modelo entrenado.

(5) Modelo de prueba. Una vez completada la capacitación del modelo, use el conjunto de prueba para probar el modelo y verificar el efecto de clasificación del modelo. Al evaluar el modelo, utilice la tasa de precisión, la tasa de recuperación, la tasa de precisión y los indicadores de evaluación de medición F1 en la biblioteca Scikit-learn. En este caso, los indicadores anteriores se escriben en una función personalizada test_score(), y luego la categoría predicha por el modelo y el valor real de la etiqueta se envían a la función, y la eficiencia de clasificación del modelo supera el 85%. el código se muestra a continuación.

deftest score(x,y):
'''
自定义函数对分类效果进行评估
:param x:预测类别
:param y:真实标签
'''
print("准确率:.4f" accuracy score(x,y))
print("精确率:4f" precision score(x,Y,average='macro'))
print("召回率:.4f"号recall score(x,y,average='macro'))
print("F1度量:.4f" fl score(x,y,average='macro'))
#加载模型
model=tf.keras .models.load model("resnet img.h5")
# 使用模型对测试集进行预测
predict y=model.predict(test)
predict class=np.argmax(predict y, axis=1)    #选出最大概率对应的下标#生成标签值
labels=[07 * 50+[1  * 50+27 * 50+/3 * 50      # 评估预测结果
test score(predict class,labels)

 La salida es:

准确率:0.8550
精确率:0.8550
召回率:0.8791
E1度量:0.8571

De lo anterior se puede ver que la prueba del conjunto de prueba contiene 200 imágenes de galaxias, que se dividen en 4 categorías, y cada categoría tiene 50 imágenes. El conjunto de prueba es predicho por model.predict (prueba), y los valores en los datos devueltos son matrices de matriz de 200. Cada matriz de matriz almacena 4 valores de probabilidad, y la imagen de galaxia correspondiente se divide en 0, 1, los valores de probabilidad de 2 y 3 categorías. Luego, el subíndice correspondiente al valor máximo en cada matriz se obtiene a través de np.argmax(), y el valor del subíndice es la categoría de esta imagen.

Al leer las imágenes del conjunto de prueba, el orden de las imágenes del conjunto de prueba no se alteró, por lo que las etiquetas del conjunto de prueba no se alteraron. El orden de etiquetas correspondiente a las 200 imágenes de galaxias en el conjunto de prueba es 50 valores de etiqueta 0, 50 valores de etiqueta 1, 50 valores de etiqueta 2, 50 valores de etiqueta 3, y la variable de etiquetas es una variable que contiene 50 0 , una lista de 50 1, 50 2 y 50 3, así que use la variable etiquetas para representar la verdadera categoría de las 200 imágenes del conjunto de prueba.

Supongo que te gusta

Origin blog.csdn.net/qq_41640218/article/details/131800594
Recomendado
Clasificación