Pytorch对两张图片进行相同的数据增广操作

参考资料

  1. 个人博客 - Pytorch同时对输入输出使用transform
  2. 知乎 - 4个例子让你的pytorch数据增强过程不随机
  3. CSDN - Tensorflow如何对两幅图像做同样的数据增广操作
  4. Pytorch官方文档 - torchvision.transforms.functional

问题描述

原始的人脸表情识别训练过程中,对于每张输入的图片,都有一个表情标签与之对应(这里只考虑单标签)。可以直接使用torchvision.transform中的transforms.RandomCroptransforms.RandomHorizontalFliptransforms.RandomRotation等对图片进行随机操作,从而实现对数据的增广操作,提高模型的泛化能力。

但在人脸表情识别中引入Attention机制后,对于每张输入图片,则对应一个脸部分割的概率图。在对原始图片进行transform的变换时,与之对应的脸部分割图mask应与之进行相同的变化。但是上面提到的所有操作都是随机操作,涉及一个随机值。所以,无法做到输入与mask进行相同的transform。所以,决定放弃使用数据增广的操作,而是直接使用的是原图,训练过程中出现train的准确率不断上升,最后达到100%,而test的准确率则开始是上升,中间出现波动。最后开始下降。很显然,模型过拟化。为了解决这个问题,相当于解决如何用Pytorch对两张图片进行相同的数据增广操作的问题?

解决方法

在pytorch文档上可以看到,除了torchvision.transform 还有torchvision.transforms.functional。
相比transform ,transforms.functional 更加灵活,该方法只提供了图像的增强变换功能,而并没有随机部分

引用自资料1

实际上是用torchvision.transforms.functional中提供的函数(都没有引入随机性),来自定义transform函数。

示例

原图及脸部分割mask如图所求

然后对图片同时进行随机旋转和翻转,代码如下

import random
import cv2
from torchvision import transforms
import torchvision.transforms.functional as tf
from PIL import Image

def my_transform1(image, mask):

        # 拿到角度的随机数。angle是一个-180到180之间的一个数
        angle = transforms.RandomRotation.get_params([-180, 180])
        # 对image和mask做相同的旋转操作,保证他们都旋转angle角度
        image = image.rotate(angle)
        mask = mask.rotate(angle)
        
        image = tf.to_tensor(image)
        mask = tf.to_tensor(mask)
        return image, mask

def my_transform2(image, mask):
    # 50%的概率应用垂直,水平翻转。
    if random.random() > 0.5:
        image = tf.hflip(image)
        mask = tf.hflip(mask)
    if random.random() > 0.5:
        image = tf.vflip(image)
        mask = tf.vflip(mask)
    image = tf.to_tensor(image)
    mask = tf.to_tensor(mask)
    return image, mask


# transform处理对象一般都是 PIL Image

image = Image.open('./0.jpg') # 原图
mask = Image.open('./0_seg_face.jpg') # mask

image_tensor, mask_tensor = my_transform1(image, mask)

#此时image, mask为tensor,需转成PIL Image
image_rotate = transforms.ToPILImage()(image_tensor).convert('L').save('0_rotate.jpg')
mask_rotate = transforms.ToPILImage()(mask_tensor).convert('L').save('0_seg_face_rotate.jpg')

image_tensor, mask_tensor = my_transform2(image, mask)

#此时image, mask为tensor,需转成PIL Image
image_flip = transforms.ToPILImage()(image_tensor).convert('L').save('0_flip.jpg')
mask_flip = transforms.ToPILImage()(mask_tensor).convert('L').save('0_seg_face_flip.jpg')

旋转后图片为(每次旋转结果可能都不一样,角度随机)

翻转后图片为

发布了169 篇原创文章 · 获赞 35 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/happyeveryday62/article/details/104350332
今日推荐