Day04- interpretación de la red neuronal clásico de convolución

Day04- interpretación de la red neuronal clásico de convolución

Descripción del empleo

artículos reales de hoy en día se basa en la categoría de "máscara" red neuronal clásico convolución de VGG.

reconocimiento de máscaras, es uno que puede detectar y realizar el propietario no usar una máscara que lleva una densa multitud en el área de la cara con eficacia, mientras que el juez si se debe usar una máscara. Por lo general, se compone de dos unidades funcionales, la clasificación se puede hacer para detectar mascarillas y máscaras faciales, respectivamente.

La práctica de la producción en comparación con el medio ambiente máscaras problemas identificados, reducir la dificultad para lograr cara solamente máscaras modelo juicio, para determinación de si usar máscaras faciales . Esta práctica está diseñada para identificar la columna de texto a través de una máscara, por lo que entendemos y sabemos cómo utilizar el diagrama dinámico para construir una red neuronal clásico convolución volar hélice.

Nota especial: Esta práctica conjuntos de datos de Internet, no para fines comerciales con.

Requisitos de trabajo:

  • 1, de acuerdo con los contenidos aprendidos en clase, y se ejecutan en una red construida VGGNet. Sobre esta base, intente otra configuración de la red.
  • 2, el pensamiento y la práctica parámetro de ajuste, optimización, mejorar la precisión de la prueba.

Cursos y conjunto de datos del enlace está disponible para prefacio buscando introducción antes de que el aprendizaje formal

Todo lo que necesitamos son los datos contenidos en la carpeta Día 04. characterData.zip es un conjunto de datos que hay que usar, CarID.png se utiliza para probar el efecto de la imagen final.

Ejemplo de código

En primer lugar, la configuración del entorno

# 导入需要的包

import os
import zipfile
import random
import json
import paddle
import sys
import numpy as np
from PIL import Image
from PIL import ImageEnhance
import paddle.fluid as fluid
from multiprocessing import cpu_count
import matplotlib.pyplot as plt
# 参数配置

train_parameters = {
    "input_size": [3, 224, 224],                              #输入图片的shape
    "class_dim": -1,                                          #分类数
    "src_path":"/home/aistudio/work/maskDetect.zip",#原始数据集路径
    "target_path":"/home/aistudio/data/",                     #要解压的路径
    "train_list_path": "/home/aistudio/data/train.txt",       #train.txt路径
    "eval_list_path": "/home/aistudio/data/eval.txt",         #eval.txt路径
    "readme_path": "/home/aistudio/data/readme.json",         #readme.json路径
    "label_dict":{},                                          #标签字典
    "num_epochs": 1,                                         #训练轮数
    "train_batch_size": 8,                                    #训练时每个批次的大小
    "learning_strategy": {                                    #优化函数相关的配置
        "lr": 0.001                                           #超参数学习率
    } 
}

En segundo lugar, la preparación de datos

  1. Descomprimir el conjunto de datos original
  2. Dividido en proporción al conjunto de entrenamiento y el conjunto de validación
  3. Revueltos, generando una lista de datos
  4. Configurado para proporcionar entrenamiento conjunto de datos y un proveedor de conjunto de datos de validación
def unzip_data(src_path,target_path):
    '''
    解压原始数据集,将src_path路径下的zip包解压至data目录下
    '''
    if(not os.path.isdir(target_path + "maskDetect")):     
        z = zipfile.ZipFile(src_path, 'r')
        z.extractall(path=target_path)
        z.close()
def get_data_list(target_path,train_list_path,eval_list_path):
    '''
    生成数据列表
    '''
    #存放所有类别的信息
    class_detail = []
    #获取所有类别保存的文件夹名称
    data_list_path=target_path+"maskDetect/"
    class_dirs = os.listdir(data_list_path)  
    #总的图像数量
    all_class_images = 0
    #存放类别标签
    class_label=0
    #存放类别数目
    class_dim = 0
    #存储要写进eval.txt和train.txt中的内容
    trainer_list=[]
    eval_list=[]
    #读取每个类别,['maskimages', 'nomaskimages']
    for class_dir in class_dirs:
        if class_dir != ".DS_Store":
            class_dim += 1
            #每个类别的信息
            class_detail_list = {}
            eval_sum = 0
            trainer_sum = 0
            #统计每个类别有多少张图片
            class_sum = 0
            #获取类别路径 
            path = data_list_path  + class_dir
            # 获取所有图片
            img_paths = os.listdir(path)
            for img_path in img_paths:                                  # 遍历文件夹下的每个图片
                name_path = path + '/' + img_path                       # 每张图片的路径
                if class_sum % 10 == 0:                                 # 每10张图片取一个做验证数据
                    eval_sum += 1                                       # test_sum为测试数据的数目
                    eval_list.append(name_path + "\t%d" % class_label + "\n")
                else:
                    trainer_sum += 1 
                    trainer_list.append(name_path + "\t%d" % class_label + "\n")#trainer_sum测试数据的数目
                class_sum += 1                                          #每类图片的数目
                all_class_images += 1                                   #所有类图片的数目
             
            # 说明的json文件的class_detail数据
            class_detail_list['class_name'] = class_dir             #类别名称,如jiangwen
            class_detail_list['class_label'] = class_label          #类别标签
            class_detail_list['class_eval_images'] = eval_sum       #该类数据的测试集数目
            class_detail_list['class_trainer_images'] = trainer_sum #该类数据的训练集数目
            class_detail.append(class_detail_list)  
            #初始化标签列表
            train_parameters['label_dict'][str(class_label)] = class_dir
            class_label += 1 
            
    #初始化分类数
    train_parameters['class_dim'] = class_dim

   
    
    #乱序  
    random.shuffle(eval_list)
    with open(eval_list_path, 'a') as f:
        for eval_image in eval_list:
            f.write(eval_image) 
            
    random.shuffle(trainer_list)
    with open(train_list_path, 'a') as f2:
        for train_image in trainer_list:
            f2.write(train_image) 

    # 说明的json文件信息
    readjson = {}
    readjson['all_class_name'] = data_list_path                  #文件父目录
    readjson['all_class_images'] = all_class_images
    readjson['class_detail'] = class_detail
    jsons = json.dumps(readjson, sort_keys=True, indent=4, separators=(',', ': '))
    with open(train_parameters['readme_path'],'w') as f:
        f.write(jsons)
    print ('生成数据列表完成!')
def custom_reader(file_list):
    '''
    自定义reader
    '''
    def reader():
        with open(file_list, 'r') as f:
            lines = [line.strip() for line in f]
            for line in lines:
                img_path, lab = line.strip().split('\t')
                img = Image.open(img_path) 
                if img.mode != 'RGB': 
                    img = img.convert('RGB') 
                img = img.resize((224, 224), Image.BILINEAR)
                img = np.array(img).astype('float32') 
                img = img.transpose((2, 0, 1))  # HWC to CHW 
                img = img/255                # 像素值归一化 
                yield img, int(lab) 
    return reader
# 参数初始化

src_path=train_parameters['src_path']
target_path=train_parameters['target_path']
train_list_path=train_parameters['train_list_path']
eval_list_path=train_parameters['eval_list_path']
batch_size=train_parameters['train_batch_size']

'''
解压原始数据到指定路径
'''
unzip_data(src_path,target_path)

'''
划分训练集与验证集,乱序,生成数据列表
'''#每次生成数据列表前,首先清空train.txt和eval.txtwith open(train_list_path, 'w') as f: 
    f.seek(0)
    f.truncate() 
with open(eval_list_path, 'w') as f: 
    f.seek(0)
    f.truncate() 
#生成数据列表   
get_data_list(target_path,train_list_path,eval_list_path)

'''
构造数据提供器
'''
train_reader = paddle.batch(custom_reader(train_list_path),
                            batch_size=batch_size,
                            drop_last=True)
eval_reader = paddle.batch(custom_reader(eval_list_path),
                            batch_size=batch_size,
                            drop_last=True)

En tercer lugar, la configuración del modelo

Day4l

VGG grupo central de cinco operación de convolución entre cada uno de los dos grupos hacer reducción de la dimensión espacio Max-Pooling. El número de veces utilizando el mismo grupo de sucesivas convolución 3x3, la convolución kernel aumentar entre 64 y 512 grupo de poca profundidad, el número de granos de convolución en el mismo grupo es el mismo que el grupo más profundo. Después de dos capas completa conexión de contacto de convolución, seguida de una capa de clasificación. Puesto que las diferentes capas dentro de cada circunvolución con estos tipos de capas 11,13,16,19 modelo, en la Fig. 16 muestra una capa de estructura de red.

class ConvPool(fluid.dygraph.Layer):
    '''卷积+池化'''
    def __init__(self,
                 num_channels,
                 num_filters,
                 filter_size,
                 pool_size,
                 pool_stride,
                 groups,
                 pool_padding=1,
                 pool_type='max',
                 conv_stride=1,
                 conv_padding=0,
                 act=None):
        super(ConvPool, self).__init__()  

        self._conv2d_list = []

        for i in range(groups):
            conv2d = self.add_sublayer(   #返回一个由所有子层组成的列表。
                'bb_%d' % i,
                fluid.dygraph.Conv2D(
                num_channels=num_channels, #通道数
                num_filters=num_filters,   #卷积核个数
                filter_size=filter_size,   #卷积核大小
                stride=conv_stride,        #步长
                padding=conv_padding,      #padding大小,默认为0
                act=act)
            )
        self._conv2d_list.append(conv2d)   

        self._pool2d = fluid.dygraph.Pool2D(
            pool_size=pool_size,           #池化核大小
            pool_type=pool_type,           #池化类型,默认是最大池化
            pool_stride=pool_stride,       #池化步长
            pool_padding=pool_padding      #填充大小
            )

    def forward(self, inputs):
        x = inputs
        for conv in self._conv2d_list:
            x = conv(x)
        x = self._pool2d(x)
        return x

Por favor completar la definición de red de VGG :


class VGGNet(fluid.dygraph.Layer):
    '''
    VGG网络
    '''
    def __init__(self):
        super(VGGNet, self).__init__()
       
        

    def forward(self, inputs, label=None):
        """前向计算"""
        
        

En cuarto lugar, el modelo de formación

all_train_iter=0
all_train_iters=[]
all_train_costs=[]
all_train_accs=[]

def draw_train_process(title,iters,costs,accs,label_cost,lable_acc):
    plt.title(title, fontsize=24)
    plt.xlabel("iter", fontsize=20)
    plt.ylabel("cost/acc", fontsize=20)
    plt.plot(iters, costs,color='red',label=label_cost) 
    plt.plot(iters, accs,color='green',label=lable_acc) 
    plt.legend()
    plt.grid()
    plt.show()


def draw_process(title,color,iters,data,label):
    plt.title(title, fontsize=24)
    plt.xlabel("iter", fontsize=20)
    plt.ylabel(label, fontsize=20)
    plt.plot(iters, data,color=color,label=label) 
    plt.legend()
    plt.grid()
    plt.show()
'''
模型训练
'''
# with fluid.dygraph.guard(place = fluid.CUDAPlace(0)):
with fluid.dygraph.guard():
    print(train_parameters['class_dim'])
    print(train_parameters['label_dict'])
    vgg = VGGNet()
    optimizer=fluid.optimizer.AdamOptimizer(learning_rate=train_parameters['learning_strategy']['lr'],parameter_list=vgg.parameters()) 
    for epoch_num in range(train_parameters['num_epochs']):
        for batch_id, data in enumerate(train_reader()):
            dy_x_data = np.array([x[0] for x in data]).astype('float32')           
            y_data = np.array([x[1] for x in data]).astype('int64')      
            y_data = y_data[:, np.newaxis]

            #将Numpy转换为DyGraph接收的输入
            img = fluid.dygraph.to_variable(dy_x_data)
            label = fluid.dygraph.to_variable(y_data)

            out,acc = vgg(img,label)
            loss = fluid.layers.cross_entropy(out, label)
            avg_loss = fluid.layers.mean(loss)

            #使用backward()方法可以执行反向网络
            avg_loss.backward()
            optimizer.minimize(avg_loss)
             
            #将参数梯度清零以保证下一轮训练的正确性
            vgg.clear_gradients()
            

            all_train_iter=all_train_iter+train_parameters['train_batch_size']
            all_train_iters.append(all_train_iter)
            all_train_costs.append(loss.numpy()[0])
            all_train_accs.append(acc.numpy()[0])
                
            if batch_id % 1 == 0:
                print("Loss at epoch {} step {}: {}, acc: {}".format(epoch_num, batch_id, avg_loss.numpy(), acc.numpy()))

    draw_train_process("training",all_train_iters,all_train_costs,all_train_accs,"trainning cost","trainning acc")  
    draw_process("trainning loss","red",all_train_iters,all_train_costs,"trainning loss")
    draw_process("trainning acc","green",all_train_iters,all_train_accs,"trainning acc")  
    
    #保存模型参数
    fluid.save_dygraph(vgg.state_dict(), "vgg")   
    print("Final loss: {}".format(avg_loss.numpy()))

En quinto lugar, la validación del modelo

'''
模型校验
'''
with fluid.dygraph.guard():
    model, _ = fluid.load_dygraph("vgg")
    vgg = VGGNet()
    vgg.load_dict(model)
    vgg.eval()
    accs = []
    for batch_id, data in enumerate(eval_reader()):
        dy_x_data = np.array([x[0] for x in data]).astype('float32')
        y_data = np.array([x[1] for x in data]).astype('int')
        y_data = y_data[:, np.newaxis]
        
        img = fluid.dygraph.to_variable(dy_x_data)
        label = fluid.dygraph.to_variable(y_data)

        out, acc = vgg(img, label)
        lab = np.argsort(out.numpy())
        accs.append(acc.numpy()[0])
print(np.mean(accs))

En sexto lugar, las predicciones del modelo

def load_image(img_path):
    '''
    预测图片预处理
    '''
    img = Image.open(img_path) 
    if img.mode != 'RGB': 
        img = img.convert('RGB') 
    img = img.resize((224, 224), Image.BILINEAR)
    img = np.array(img).astype('float32') 
    img = img.transpose((2, 0, 1))  # HWC to CHW 
    img = img/255                # 像素值归一化 
    return img

label_dic = train_parameters['label_dict']

'''
模型预测
'''with fluid.dygraph.guard():
    model, _ = fluid.dygraph.load_dygraph("vgg")
    vgg = VGGNet()
    vgg.load_dict(model)
    vgg.eval()
    
    #展示预测图片
    infer_path='/home/aistudio/data/data23615/infer_mask01.jpg'
    img = Image.open(infer_path)
    plt.imshow(img)          #根据数组绘制图像
    plt.show()               #显示图像

    #对预测图片进行预处理
    infer_imgs = []
    infer_imgs.append(load_image(infer_path))
    infer_imgs = np.array(infer_imgs)
   
    for  i in range(len(infer_imgs)):
        data = infer_imgs[i]
        dy_x_data = np.array(data).astype('float32')
        dy_x_data=dy_x_data[np.newaxis,:, : ,:]
        img = fluid.dygraph.to_variable(dy_x_data)
        out = vgg(img)
        lab = np.argmax(out.numpy())  #argmax():返回最大数的索引
        print("第{}个样本,被预测为:{}".format(i+1,label_dic[str(lab)]))
        
print("结束")

Terminar el trabajo

VGG red definida:

Hace unos días, y el código es similar, pero hoy en día muchos de los ejemplos de código a través de los parámetros del modelo se unificaron acuerdo global, y ha añadido una clase ConvPool, los compuestos de convolución y piscina juntos, que sería más conveniente, también es que el uso.

class VGGNet(fluid.dygraph.Layer):
    '''
    VGG网络
    '''
    def __init__(self):
        super(VGGNet, self).__init__()
        # 通道数、卷积核个数、卷积核大小、池化核大小、池化步长、连续卷积个数
        self.convpool01 = ConvPool(3, 64, 3, 2, 2, 2, act='relu')
        self.convpool02 = ConvPool(64, 128, 3, 2, 2, 2, act='relu')
        self.convpool03 = ConvPool(128, 256, 3, 2, 2, 3, act='relu')
        self.convpool04 = ConvPool(256, 512, 3, 2, 2, 3, act='relu')
        self.convpool05 = ConvPool(512, 512, 3, 2, 2, 3, act='relu')

        self.pool_5_shape = 512*7*7
        self.fc01 = fluid.dygraph.Linear(self.pool_5_shape, 4096, act='relu')
        self.fc02 = fluid.dygraph.Linear(4096, 4096, act='relu')
        self.fc03 = fluid.dygraph.Linear(4096, 2, act='softmax')

    def forward(self, inputs, label=None):
        """前向计算"""
        out = self.convpool01(inputs)
        out = self.convpool02(out)
        out = self.convpool03(out)
        out = self.convpool04(out)
        out = self.convpool05(out)
        
        out = fluid.layers.reshape(out, shape=[-1, 512*7*7])
        out = self.fc01(out)
        out = self.fc02(out)
        out = self.fc03(out)

        if label is not None:
        	acc = fluid.layers.accuracy(input=out, label=label)
        	return out, acc
        else:
        	return out

Número de ruedas de entrenamiento de nuestra toma inicial es 10, se puede ver la exactitud del modelo de tren es de los altibajos.
day42

Dibujado fuera de la imagen, también, la exactitud del modelo ha sido entrenado en estado de shock.
day43

La precisión del conjunto de ensayo a aproximadamente 0,6.
Day44

reconocimiento de las máscaras es una clasificación binaria, los resultados sólo se usan máscaras y no el uso de máscaras de dos tipos. Predecimos máscaras Shihai imaginan apenas capaz de predecir el éxito.
day45

tasa de precisión es de sólo 0,6 pensar que sin duda todavía tenemos que ir parámetros optimizados fueron transferidos de los tres aspectos siguientes.

  • Varias rondas de formación, es decir, el número de iteraciones (num_epochs)
  • tasa de aprendizaje (learningrate)
  • Cada tamaño de lote de entrenamiento (batch_size)

Hemos aumentado el número de rondas de entrenamiento, el aumento de 20 veces, cortamos la tasa de aprendizaje, cayó a 0,0001, lo que aumenta el tamaño de cada lote de la formación, aumentó a 16. Estos parámetros pueden ser modificados configuración del entorno de la primera etapa.

Destacar aquí que un ligero aumento en el tamaño del lote puede ser entrenado para mejorar la precisión, pero batch_size no sólo el tamaño de la transferencia, generalmente un múltiplo de 8, la más alta eficiencia de dicha operación en paralelo dentro de la GPU .

Después del entrenamiento se puede ver, la precisión del conjunto de entrenamiento converge gradualmente a 1,0.
Day46

La precisión del equipo de prueba también llegó a 1,0, muy agradable.
day47

Dado que los datos es relativamente pequeño estudio, la capacidad de generalización no es fuerte, el grupo de retroalimentación peces gordos que se puede utilizar adecuadamente mejora de los datos (Data) Aumento de métodos para mejorar la predicción de una tasa de éxito escena real.

Publicado 61 artículos originales · ganado elogios 25 · vistas 7170

Supongo que te gusta

Origin blog.csdn.net/qq_42582489/article/details/105366036
Recomendado
Clasificación