综合案例:垃圾分类

数据处理

1、本地数据的读取,进行图片路径读取,标签读取,对标签进行平滑处理。
标签类别转换以及标签平滑

label
label=tf.keras.utils.to_categorical(label,num_classes=10)
label=smooth(label)
def smooth(y,smooth_factor=0.1):
	assert len(y.shape)==2
	y*=1-smooth_factory
	y+=smooth_factory/y.shape[1]

要求训练集和验证集的数据集都可以整除batch_size

i = -2
j = -2
while 1:
	if (len(train_img_paths) % batch_size == 0):
		break
	else:
		train_img_paths = train_img_paths[:i]
		train_labels = train_labels[:i]
		i -= 1
while 1:
	if (len(validation_img_paths) % batch_size == 0):
		break
	else:
		validation_img_paths = validation_img_paths[:j]
		validation_labels = validation_labels[:j]
		j -= 1

tf.keras.Sequence类封装,返回序列数据
对于很多任务来说我们需要做更多的有些自定义预处理,如标签平滑,随机擦除等。
随机擦除

def get_random_eraser(p=0.5, s_l=0.02, s_h=0.4, r_1=0.3, r_2=1/0.3, v_l=0, v_h=255, pixel_level=False):
    def eraser(input_img):
        img_h, img_w, img_c = input_img.shape
        p_1 = np.random.rand()

        if p_1 > p:
            return input_img

        while True:
            s = np.random.uniform(s_l, s_h) * img_h * img_w
            r = np.random.uniform(r_1, r_2)
            w = int(np.sqrt(s / r))
            h = int(np.sqrt(s * r))
            left = np.random.randint(0, img_w)
            top = np.random.randint(0, img_h)

            if left + w <= img_w and top + h <= img_h:
                break

        if pixel_level:
            c = np.random.uniform(v_l, v_h, (h, w, img_c))
        else:
            c = np.random.uniform(v_l, v_h)
		input_img[top:top + h, left:left + w, :] = c
		return input_img

    return eraser

改变图像尺寸到300*300,并且做填充使得图像处于中间

@staticmethod
 def center_img(img, size=None,fill_value=255):
     h, w = img.shape[:2]
     if size is None:
         size = max(h, w)
     shape = (size, size) + img.shape[2:]
     background = np.full(shape, fill_value, np.uint8)
     center_x = (size - w) // 2
     center_y = (size - h) // 2
     background[center_y:center_y + h, center_x:center_x + w] = img
     return background

完整代码

class datasequence(Sequence):
    def __init__(self,img_paths,labels,batch_size,img_size,use_aug):
        self.x_y=np.hstack((np.array(img_paths).reshape(len(img_paths),1),np.array(labels)))
        self.batch_size=batch_size
        self.img_size=img_size#(300,300)
        self.use_aug=use_aug
        self.alpha=0.2
        self.eraser=get_random_eraser(s_h=0.3,pixel_level=True)
    def __len__(self):
        return math.ceil(len(self.x_y)/self.batch_size)
    @staticmethod
    def center(img,size=None,fill_value=255):
        h,w=img.shape[:2]
        if size is None:
            size=max(h,w)
        shape=(size,size)+img.shape[2:]
        background=np.full(shape,fill_value,np.uint8)
        ceter_x=(size-w)//2
        ceter_y=(size-h)//2
        background[ceter_y:ceter_y+h,ceter_x:ceter_x+w]=img
        return background
    #处理每张图片,大小,数据增强
    def preprocess_img(self,img_path):
        img=Image.open(img_path)
        scale=self.img_size[0]/max(img.size[:2])
        img=img.resize((int(img.size[0]*scale),int(img.size[1]*scale)))
        img=img.convert('RGB')
        img=np.array(img)
        #如果是训练集则进行数据增强
        if self.use_aug:
            #随机擦除
            img=self.eraser(img)
            #反转
            datagen = ImageDataGenerator(
                width_shift_range=0.05,
                height_shift_range=0.05,
                horizontal_flip=True,
                vertical_flip=True,
            )
            img = datagen.random_transform(img)
        img = self.center_img(img, self.img_size[0])
        return img
    def __getitem__(self, idx):
        #获取当前批次的特征值和目标值
        batch_x = self.x_y[idx * self.batch_size: self.batch_size * (idx + 1), 0]
        batch_y = self.x_y[idx * self.batch_size: self.batch_size * (idx + 1), 1:]

        batch_x = np.array([self.preprocess_img(img_path) for img_path in batch_x])
        batch_y = np.array(batch_y).astype(np.float32)

        return batch_x, batch_y
    def on_epoch_end(self):
        np.random.shuffle(self.x_y)

模型训练

#建立读取数据
train_sequence,validation_sequence=data_from_sequence()
base_model=EfficientNet.EfficientNetB3(include_top=False, input_shape=(paclasses=param.num_classes)
x=base_model.output
x=GlobalAveragePooling2D(name='avg_pool')(x)
predictions = Dense(param.num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)

#回调函数
callback= tf.keras.callbacks.ModelCheckpoint()
model.fit_generator()

模型的导出

tf.save_model.save(model,'path')

model=tf.saved_model.load('path')
y_pred=model(x)
sparse_categorical_accuracy.update_state(y_true=test_label,
 y_pred=y_pred)

总结

数据决定模型的上限,因此数据对于模型的处理至关重要。总共学到了三种data和label的处理方式,第三种比较难sequence。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值