社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

非算法工程师也能玩转深度学习--(一)--数据集处理篇

嘉平廿二 • 3 年前 • 116 次点击  
阅读 47

非算法工程师也能玩转深度学习--(一)--数据集处理篇

前言

当下,人工智能多次被提到国家战略,其发展势头可称得上是互联网行业之最,在各个大厂都疯狂招揽AI相关人才的同时,人工智能行业的入门门槛也越来越高。但是,人工智能真正要落地,离不开各行各业的工程师。传统意义上讲,将人工智能引入到工程中大概是这样的过程:收集数据集->处理数据集->定义模型->训练模型->模型调参->开发模型服务->模型部署->加入工程链路。

首先声明,本篇文章仅适用于图片分类数据集的处理,大家如果已经拥有了自己的图片数据集,例如传统的mnist,猫狗数据集这种,以文件夹名称为图片的标签,可以直接跳过“VOC”数据集处理这一步,直接进入数据增强和数据集划分,数据增强是本篇文章的重点所在,下面会重点介绍。

作为阿里巴巴-淘系技术部-频道与D2C智能团队的一员,我们的使命就是:前端智能让业务创新更⾼效。整个的过程有一定的上手难度,不过不用担心,小编会从实际项目入手,一步步为你揭开AI的神秘面纱。

VOC数据集处理(已经拥有图片数据集的小伙伴可以直接进入第二步)

拥有一个高质量的数据集是做好机器学习的关键,模型结构千千万,数据集可千万不能拖后腿。小编假设你已经拥有了一个图片分类数据集,小编是做前端UI组件识别的,所以使用的是一个VOC格式的数据集,格式如下

voc数据集格式

具体处理VOC数据集的代码小编也为亲准备好啦 不同的数据集更改一下cats里的标签即可

# 提取一些组件保存为图片 裁剪出特定分类保存
import os
import sys
import shutil
import random
import cv2
import xml.etree.ElementTree as ET

cats = [
    'cat', 'dog'
    ]
def do_start(input_dir, output_dir):
    # 输入文件路径
    input_xml_dir = os.path.join(input_dir, 'Annotations')
    input_img_dir = os.path.join(input_dir, 'JPEGImages')
    # 输出图片路径
    output_img_dir = os.path.join(output_dir, 'Components')
    # 如果路径不存在
    if not os.path.exists(output_img_dir):
        os.makedirs(output_img_dir)
    all_xmls = os.listdir(input_xml_dir)
    count = 0
    for index, xml_name in enumerate(all_xmls):
        count = count + 1 
        # print(xml_name)
        xml_path = os.path.join(input_xml_dir, xml_name)
        xml_data = open(xml_path,'r')
        tree = ET.parse(xml_data)
        root = tree.getroot()
        
        img_name = root.find('filename').text
        img = cv2.imread(os.path.join(input_img_dir, img_name))
        size = root.find('size')
        width = int(size.find('width').text)
        height = int(size.find('height').text)
        
        objs = root.findall('object')
        for index, obj in enumerate(objs):
            r_name = obj.find('name').text
            if r_name in cats:
                print(img_name, r_name)
                r_xmlbox = obj.find('bndbox')
                r_xmin = int(float(r_xmlbox.find('xmin').text))
                r_xmax = int(float(r_xmlbox.find('xmax').text))
                r_ymin = int(float(r_xmlbox.find('ymin').text))
                r_ymax = int(float(r_xmlbox.find('ymax').text))
                cropped_img = img[
                    int(r_ymin) : int(r_ymax), 
                    int(r_xmin) : int(r_xmax)
                ] 
                cut_img_name = '{}-{}'.format(r_name, img_name)
                print(cut_img_name)
                try:
                    cv2.imwrite(os.path.join(output_img_dir, cut_img_name), cropped_img)
                except:
                    print('error: ', img_name) 
if __name__ == '__main__':
    args = sys.argv
    input_dir = args[1]
    output_dir = args[2]
    do_start(input_dir, output_dir)
复制代码

数据增强

数据增强可以说是极其关键的一步,一套更加丰富的数据集对模型能力的提升是非常大的,小编将传统的各种图片数据增强的方法都集成到一起并且随机化,包括图片的裁剪,翻转,局部遮挡,像素模糊等等。

无论是使用TensorFlow还是PyTorch,都有自带的一些数据增强方法,在这里小编为亲准备了一套更专业,随机化程度更高的数据增强方法,主要使用imgaug,有兴趣的小伙伴可以去官网浏览哦 imgaug官网 可见一张图片就能有许多种变换方式,通过数据增强可以使得数据集更加丰富。

在方法中小编定义了很多种数据增强的方法,对于每个数据文件夹,随机选取2-5种方法对数据进行增强,很大程度上保证了数据的不重复性。话不多说,直接上代码

import cv2
from imgaug import augmenters as iaa
import os

sometimes = lambda aug: iaa.Sometimes(0.5, aug)
# 定义一组变换方法.
seq = iaa.Sequential([

    # 选择2到5种方法做变换
    iaa.SomeOf((2, 5),
        [
                iaa.Fliplr(0.5), # 对50%的图片进行水平镜像翻转
                iaa.Flipud(0.5), # 对50%的图片进行垂直镜像翻转	

                sometimes(
                    iaa.Superpixels(
                        p_replace=(0, 1.0),
                        n_segments=(20, 200)
                    )
                ),
                iaa.OneOf([
                    iaa.GaussianBlur((0, 3.0)),
                    iaa.AverageBlur(k=(2, 7)),
                    iaa.MedianBlur(k=(3, 11)),
                ]),
                iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),
                iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)),
                iaa.AdditiveGaussianNoise(
                    loc=0, scale=(0.0, 0.05*255)
                ),
                iaa.Invert(0.05, per_channel=True), 
                iaa.Add((


    
-10, 10), per_channel=0.5),
                iaa.AddElementwise((-40, 40)),
                iaa.Multiply((0.5, 1.5)),
                iaa.MultiplyElementwise((0.5, 1.5)),
                iaa.ContrastNormalization((0.5, 2.0)),
        ],
        random_order=True
    )
 
],random_order=True) #apply augmenters in random order
 
# 图片文件相关路径
path = 'cat'
savedpath = 'cat-aug'
 
imglist=[]
filelist = os.listdir(path)
 
# 遍历要增强的文件夹,把所有的图片保存在imglist中
for item in filelist:
    if(item == '.DS_Store'):
        continue
    img = cv2.imread(path +'/'+ item)
    imglist.append(img)
print('all the picture have been appent to imglist')
print(len(imglist))
 
#对文件夹中的图片进行增强操作,循环n次,n为数据集扩充的倍数,可以自己设置哦
for count in range(4):
	images_aug = seq.augment_images(imglist)
	for index in range(len(images_aug)-1):
		filename = str(count) + str(index) +'.jpg'
		#保存图片
		cv2.imwrite(savedpath +'/'+ filename,images_aug[index])
		print('image of count%s index%s has been writen'%(count,index))
复制代码

亲们可以定义自己的数据增强方法,建议尽量增大样本扩充的随机性,以上方法即使在普通的电脑上速度也非常快,但是考虑到深度学习的图片数据集比较大,所以脚本的输入是一个图片文件夹,亲们可以先准备少量的数据实验一下~

数据集划分

在进行模型训练之前,最好能够将数据集切分为训练集,测试集和验证集,训练集用于模型拟合的数据样本;验证集是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估;测试集用来评估模最终模型的泛化能力,但不能作为调参、选择特征等算法相关的选择的依据。

数据集 作用 比喻
训练集 用于模型的训练 学生的课本
验证集 用于调超参数,监控模型是否发生过拟合(以决定是否停止训练) 课后作业
测试集 为了评估最终模型泛化能力(仅最后一次使用) 期末考试

当然啦,小编也为亲们准备了划分数据集的脚本,直接上代码

# 将一个文件夹下图片按比例分在三个文件夹下
import os
import random
import shutil
from shutil import copy2
datadir_normal = "./cat-aug"

all_data = os.listdir(datadir_normal)#(图片文件夹)
num_all_data = len(all_data)
print( "num_all_data: " + str(num_all_data) )
index_list = list(range(num_all_data))
random.shuffle(index_list)
num = 0

trainDir = "./train/cat"#(将训练集放在这个文件夹下)
if not os.path.exists(trainDir):
    os.mkdir(trainDir)
        
validDir = './validation/cat'#(将验证集放在这个文件夹下)
if not os.path.exists(validDir):
    os.mkdir(validDir)
        
testDir = './test/cat'#(将测试集放在这个文件夹下)        
if not os.path.exists(testDir):
    os.mkdir(testDir)
        
for i in index_list:
    fileName = os.path.join(datadir_normal, all_data[i])
    if num < num_all_data*0.8:
        copy2(fileName, trainDir)
    elif num>num_all_data*0.8 and num < num_all_data*0.9:
        copy2(fileName, validDir)
    else:
        copy2(fileName, testDir)
    num += 1
num_train = len(os.listdir(trainDir))
print('num_train:' + str(num_train))

num_test = len(os.listdir(testDir))
print('num_test:' + str(num_test))

num_val = len(os.listdir(validDir))
print('num_val:' + str(num_val))
复制代码

以上代码是按照3:1:1来划分数据集的,比较经典,大家也可以自己去调整划分的比例。

写在最后

以上三步就是处理数据集的整个流程,也是做深度学习的第一步,之后小编会出一系列的文章,和大家一起了解最新的AI技术。希望大家点个关注,点个赞呀~

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/70959
 
116 次点击