首页 > 技术知识 > 正文

文章目录 1 概述 2 批量生成训练数据 2.1 如何实现 2.2 实验验证 2.3 图片标注并生成训练所需文件 3 数据增强 4 目标检测中的图像增强 1 概述

这几年深度学习领域的新进展就是以这个想法为基础产生的。我们可以使用更复杂的深度学习网络,在图片中挖出数以百万计的特征。

这时问题也就来了。机器学习过程中是需要一个输入文件的。这个输入文件的行、列分别指代样本名称以及特征名称。如果是进行百万张图片的分类,每个图片都有数以百万计的特征,我们将拿到一个百万样本百万特征的巨型矩阵。传统的机器学习方法拿到这个矩阵时,受限于计算机内存大小的限制,通常是无从下手的。也就是说,传统的机器学习方法,除了在多数情况下不会自动产生这么多的特征以外,模型的训练也会是一个大问题。

深度学习算法为了实现对这个量级数据的计算,做了以下算法以及工程方面的创新

将全部所有数据按照样本拆分成若千批次,每个批次大小通常在十几个到 100 多个样本之间(接下来要讲的内容)。

将产生的批次逐一参与训练,更新参数,使用 GPU 等并行计算卡代替 CPU,加速并行计算速度。

2 批量生成训练数据

1、在做深度学习时候,数据量往往非常大,如果一次性加载到内存中,往往会出现OOM问题,为了解决这个问题,我们就不用model.fit()来训练,而用model.fit_generator()来训练。这样来数据就用生成器(lazy calculate)的方式加载数据,减少内存压力。

2、keras的官方文档里并没有实现batch_size的功能

3、同时,看了几篇中文文档,写的data_generator函数都存在batch size > 数据量时候,或者读到文件末尾但是没有达到batch_size的时候,导致生成的数据不正确。

2.1 如何实现

假设有如下数据:

[ { “sentence”: “奖励就是亲”, “judge”: “positive” }, { “sentence”: “不许这样”, “judge”: “negative” }, { “sentence”: “他女朋友旁边所以不方便跟说话”, “judge”: “negative” }, { “sentence”: “真的那好心疼”, “judge”: “negative” } ]

data_generator 函数如下

def data_generator(self, file_name, batch_size): “”” :return: “”” # !!一定要将这几行写到while 循环外面 train_data_indi = [] train_data_seg = [] train_data_label = [] cnt = 0 while 1: label_tags = [negative, positive] with open(file_name) as f: json_items = ijson.items(f, item) for json_data in json_items: cnt += 1 train_data_label.append([label_tags.index(json_data[judge])]) if cnt == batch_size: print(train_data_label) train_data_label = pad_sequences(train_data_label) train_data_label = to_categorical(train_data_label, 2) yield (train_data_label) #返回数据 train_data_indi = [] train_data_seg = [] train_data_label = [] cnt = 0
<

2.2 实验验证

if __name__ == “__main__”: test = DataPreprocessor() cnt = 0 for i in test.data_generator(./data/test.json, 5): #for i in test_gen(./data/test.json): cnt += 1 if cnt > 5: break

结果:

Using TensorFlow backend. [[1], [0], [0], [0], [1]] [[0], [0], [0], [1], [0]] [[0], [0], [1], [0], [0]] [[0], [1], [0], [0], [0]] [[1], [0], [0], [0], [1]] [[0], [0], [0], [1], [0]]

2.3 图片标注并生成训练所需文件

准备标注工具lableme 在anaconda中下载labelme软件,在此过程中如安装速度过慢可以根据上一篇文章的做法换成豆瓣或阿里源能够加快安装速度

(tensorflow_gpu) C:\User$ pip install labelme

安装完后打开labelme软件并打开所需标注图片所在的文件夹

(tensorflow_gpu) C:\User$ labelme

根据所需的class标注图片

如图中所示,class分为box与bottle,标注完成后会在文件夹中生成对应的json文件 此处需要注意: 标注的同一个class的不通物体,需要通过后缀区分,如box1,box2 由于labelme标注的区域为中间实体区域,标注图片中的每一个物体的region不要出现重叠或包含关系,否则标注的区域只能属于大的region,会出现错误

【深度学习】深度神经网络框架的INPUT PROCESS 【可以批量转换】转换为训练文件 标注完成所有图片后,需要将json文件转换为训练所需的文件,转换后会生成一个与”xxx_json”文件夹,其中包含所需训练的info.yaml和label.png文件

此处需要注意: 新版的lablme不能直接生成info.yaml文件,需要修改lableme的代码,以支持此功能 ## 转换单张图片的json文件 (tensorflow_gpu) C:\User$ labelme_json_to_dataset xxx\Image0.json ## 批量转换所有的json文件 (tensorflow_gpu) C:\User> $json = Get-ChildItem -Filter *.json (tensorflow_gpu) C:\User> $json | ForEach-Object { labelme_json_to_dataset $_.Name}

【深度学习】深度神经网络框架的INPUT PROCESS1

3 数据增强

之前详细介绍过,这里不再详细说明。 数据增强是非常重要的提高目标检测算法鲁棒性的手段,学习一下对身体有好处! 【深度学习】深度神经网络框架的INPUT PROCESS2 数据增强做了什么 数据增强其实就是让图片变得更加多样。比如说原图是一个电脑

放大缩小 旋转 水平翻转

伪代码:(不能直接用哦!!!!!!!!)

装载数据 1 imagepath=[./dataset/vehicles/KITTI extracted/4374. Png) for imagepath in l imagepath 1mg = get ath) img. Append (img 设置并初始化生成器 train datagen =Imagedatagenerator rescale=l 0/255 shear range=0. 2 zoom range=0. 2 horizontal flip=True train_generator = train datagen flow (np array (1 img)) ig lt figure (figsize= (7, 7) ax = fig. Add subplot (3, 3, 1) ax. Imshow (1 img [0]) aXset_ axis off () ax set _title (“Raw Image” for i in ra imgs next (train generator) fig. Add subplot (3, 3, i+2) ax. Imshow (imgs [0]) ax. Set title (” Augmentation용d”용 (i+1))
<
4 目标检测中的图像增强

在目标检测中如果要增强数据,并不是直接增强图片就好了,还要考虑到图片扭曲后框的位置。

也就是框的位置要跟着图片的位置进行改变。

from PIL import Image, ImageDraw import numpy as np from matplotlib.colors import rgb_to_hsv, hsv_to_rgb def rand(a=0, b=1): return np.random.rand()*(b-a) + a def get_random_data(annotation_line, input_shape, random=True, max_boxes=20, jitter=.5, hue=.1, sat=1.5, val=1.5, proc_img=True): random preprocessing for real-time data augmentation line = annotation_line.split() image = Image.open(line[0]) iw, ih = image.size h, w = input_shape box = np.array([np.array(list(map(int,box.split(,)))) for box in line[1:]]) # 对图像进行缩放并且进行长和宽的扭曲 new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) scale = rand(.25,2) if new_ar < 1: nh = int(scale*h) nw = int(nh*new_ar) else: nw = int(scale*w) nh = int(nw/new_ar) image = image.resize((nw,nh), Image.BICUBIC) # 将图像多余的部分加上灰条 dx = int(rand(0, w-nw)) dy = int(rand(0, h-nh)) new_image = Image.new(RGB, (w,h), (128,128,128)) new_image.paste(image, (dx, dy)) image = new_image # 翻转图像 flip = rand()<.5 if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT) # 色域扭曲 hue = rand(-hue, hue) sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat) val = rand(1, val) if rand()<.5 else 1/rand(1, val) x = rgb_to_hsv(np.array(image)/255.) x[…, 0] += hue x[…, 0][x[…, 0]>1] -= 1 x[…, 0][x[…, 0]<0] += 1 x[…, 1] *= sat x[…, 2] *= val x[x>1] = 1 x[x<0] = 0 image_data = hsv_to_rgb(x) # numpy array, 0 to 1 # 将box进行调整 box_data = np.zeros((max_boxes,5)) if len(box)>0: np.random.shuffle(box) box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy if flip: box[:, [0,2]] = w – box[:, [2,0]] box[:, 0:2][box[:, 0:2]<0] = 0 box[:, 2][box[:, 2]>w] = w box[:, 3][box[:, 3]>h] = h box_w = box[:, 2] – box[:, 0] box_h = box[:, 3] – box[:, 1] box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box if len(box)>max_boxes: box = box[:max_boxes] box_data[:len(box)] = box return image_data, box_data def normal_(annotation_line, input_shape): random preprocessing for real-time data augmentation line = annotation_line.split() image = Image.open(line[0]) box = np.array([np.array(list(map(int,box.split(,)))) for box in line[1:]]) return image, box if __name__ == “__main__”: with open(“2007_train.txt”) as f: lines = f.readlines() a = np.random.randint(0,len(lines)) line = lines[a] image_data, box_data = normal_(line,[416,416]) img = image_data for j in range(len(box_data)): thickness = 3 left, top, right, bottom = box_data[j][0:4] draw = ImageDraw.Draw(img) for i in range(thickness): draw.rectangle([left + i, top + i, right – i, bottom – i],outline=(255,255,255)) img.show() image_data, box_data = get_random_data(line,[416,416]) print(box_data) img = Image.fromarray((image_data*255).astype(np.uint8)) for j in range(len(box_data)): thickness = 3 left, top, right, bottom = box_data[j][0:4] draw = ImageDraw.Draw(img) for i in range(thickness): draw.rectangle([left + i, top + i, right – i, bottom – i],outline=(255,255,255)) img.show() # img = Image.open(r”F:\Collection\yolo_Collection\keras-yolo3-master\Mobile-yolo3-master/VOCdevkit/VOC2007/JPEGImages/00000.jpg”) # left, top, right, bottom = 527,377,555,404 # draw = ImageDraw.Draw(img) # draw.rectangle([left, top, right, bottom]) # img.show()
<

里面有一些比较重要的参数如: scale = rand(.25, 2) jitter=.5; hue=.1; sat=1.5; val=1.5;

其中: 1、scale代表原图片的缩放比率,rand(.25, 2)表示在0.25到2之间缩放。 2、jitter代表原图片的宽高的扭曲比率,jitter=.5表示在0.5到1.5之间扭曲。 3、hue=.1,sat=1.5,val=1.5;分别代表hsv色域中三个通道的扭曲,分别是:色调(H),饱和度(S),明度(V)。

实际效果如下: 原图: 【深度学习】深度神经网络框架的INPUT PROCESS3 【深度学习】深度神经网络框架的INPUT PROCESS4

猜你喜欢