深度学习笔记2——Tranforms的使用

目录

1. transforms结构

2.Tensor的用法和以及其数据类型

        1.tensor的用法

        1.__call__()

           2.to_tensor()

 2.tensor类的数据类型


1. transforms结构

        transforms的底层并没有太过于复杂的代码和逻辑。他是由transforms.py里写的几个工具类来实现的功能和算法。图片通过transforms的工具处理,然后得出我们想得到的结果。

2.Tensor的用法和以及其数据类型

        对于tensor我们首先得有一个最简单的认识,那就是他是一种图片打开的类型,关于这种类型我们常用的有三种,一种是PIL他是由Image.open()打开的,第二章就是tensor他是用ToTensor()打开的图片类型,最后一种就是narrays是cv.imread()打开的,这里我们先讲Tensor的用法和数据结构

        1.tensor的用法
tensor_trans=transforms.ToTensor()
tensor_img=tensor_trans(img)
print(tensor_img)

        我们来看上面这三行代码,之前我们说过,transforms这个包是个工具类,所以他下面有许许多多的工具类,而ToTensor这个类的就是为了将图片转换成Tensor形式。所以我们先创建一个ToTensor类的对象,但第二行代码就有些让人摸不清头脑了,这个时候我们来看源码:

class ToTensor:
    """Convert a PIL Image or ndarray to tensor and scale the values accordingly.

    This transform does not support torchscript.

    Converts a PIL Image or numpy.ndarray (H x W x C) in the range
    [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0]
    if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)
    or if the numpy.ndarray has dtype = np.uint8

    In the other cases, tensors are returned without scaling.

    .. note::
        Because the input image is scaled to [0.0, 1.0], this transformation should not be used when
        transforming target image masks. See the `references`_ for implementing the transforms for image masks.

    .. _references: https://github.com/pytorch/vision/tree/main/references/segmentation
    """

    def __init__(self) -> None:
        _log_api_usage_once(self)

    def __call__(self, pic):
        """
        Args:
            pic (PIL Image or numpy.ndarray): Image to be converted to tensor.

        Returns:
            Tensor: Converted image.
        """
        return F.to_tensor(pic)

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}()"

        我们发现在这个类里只有三个函数,第一个是初始化函数,第三个是相当于java里面的toString方法,就是为了返回一个字符串,但造成上面的结果的第二个函数。就是__call__()

        1.__call__()

                讲到这个函数,我们就得讲到一个概念,就是就是可调用对象。我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,如果你想确定某个对象是否是课调用对象可以用到callable。很明显,我们平时的类对象是不可调用对象,因为我们平时除了初始化的时候可以类名(参数)这样写,但对于类对象我们基本是不会怎么写的,所以在这里__call__函数就是将实例对象转换成了可调用对象,这里我举了一个例子:

class Person:
    def __call__(self, name):
        print("__call__"+"hello"+name)
    def hello(self, name):
        print("hello"+name)

person = Person()
person(name="zhangsan")
person.hello("list")

        就像上面这样,我们定义了一个Person类,在person类里面写了两个函数,然后对其调用,结果如下:

        我们发现如果你直接调用实例对象并往里面传参,代码就会调用__call__()函数并调用他的函数块,而Tensor类这里也是一样,

tensor_img=tensor_trans(img)

        如果你直接往实例对象里面传参他就会,调用__call__()函数,但其实他和tensor_trans.__call__(img)这个函数是一样的,但把实例对象转化成可调用对象是这个函数的特性。然后就会调用对应的函数块,如下:

 def __call__(self, pic):
        """
        Args:
            pic (PIL Image or numpy.ndarray): Image to be converted to tensor.

        Returns:
            Tensor: Converted image.
        """
        return F.to_tensor(pic)
           2.to_tensor()

            对于F.to_tensor(pic)这个语句,pic这个参数可以是PIL或是numpy数据类型,但F这个似乎没有见过对应的库,因为在transforms库里面,用了这样一个语句:

from . import functional as F

        这段代码语句 from . import functional as F 在Python中是一种导入模块的方式。

  • from .: 这表示从当前目录中导入模块。
  • import functional as F: 这表示导入名为functional的模块,并将其重命名为F,以便在代码中更方便地引用。

        所以,这行代码的意思是从当前目录中导入名为functional的模块,并将其重命名为F,以后可以使用F来访问这个模块中的函数和变量。而to_tensor()这个函数就是把img转换成Tensor数据类型:

def to_tensor(pic) -> Tensor:
    """Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor.
    This function does not support torchscript.

    See :class:`~torchvision.transforms.ToTensor` for more details.

    Args:
        pic (PIL Image or numpy.ndarray): Image to be converted to tensor.

    Returns:
        Tensor: Converted image.
    """
    if not torch.jit.is_scripting() and not torch.jit.is_tracing():
        _log_api_usage_once(to_tensor)
    if not (F_pil._is_pil_image(pic) or _is_numpy(pic)):
        raise TypeError(f"pic should be PIL Image or ndarray. Got {type(pic)}")

    if _is_numpy(pic) and not _is_numpy_image(pic):
        raise ValueError(f"pic should be 2/3 dimensional. Got {pic.ndim} dimensions.")

    default_float_dtype = torch.get_default_dtype()

    if isinstance(pic, np.ndarray):
        # handle numpy array
        if pic.ndim == 2:
            pic = pic[:, :, None]

        img = torch.from_numpy(pic.transpose((2, 0, 1))).contiguous()
        # backward compatibility
        if isinstance(img, torch.ByteTensor):
            return img.to(dtype=default_float_dtype).div(255)
        else:
            return img

    if accimage is not None and isinstance(pic, accimage.Image):
        nppic = np.zeros([pic.channels, pic.height, pic.width], dtype=np.float32)
        pic.copyto(nppic)
        return torch.from_numpy(nppic).to(dtype=default_float_dtype)

    # handle PIL Image
    mode_to_nptype = {"I": np.int32, "I;16" if sys.byteorder == "little" else "I;16B": np.int16, "F": np.float32}
    img = torch.from_numpy(np.array(pic, mode_to_nptype.get(pic.mode, np.uint8), copy=True))

    if pic.mode == "1":
        img = 255 * img
    img = img.view(pic.size[1], pic.size[0], F_pil.get_image_num_channels(pic))
    # put it from HWC to CHW format
    img = img.permute((2, 0, 1)).contiguous()
    if isinstance(img, torch.ByteTensor):
        return img.to(dtype=default_float_dtype).div(255)
    else:
        return img

        从注释我们可以看出来,往这里面传的参数pic可以是PIL Image 或 numpy.ndarray,然后返回一个Tensor()类型,所以对于ToTensor()类的使用我们完整的代码应该是:

img_path="D:\\pythonData\\ten\\face_image1.jpg"
img=Image.open(img_path)
tensor_trans=transforms.ToTensor()
print(tensor_trans)
tensor_img=tensor_trans(img)
print(tensor_img)

        然后我们用前面讲过的SummaryWriter类的writer.add_image()方法把图片数据放入tensorboard如下:

 2.tensor类的数据类型

在上述代码里面我们用了print(tensor.img)我们打印出了tensor的数据,结果如下:

        我们单从打印结果来看,tensor似乎是一个三维数组,在深度学习的知识里面,tensor也叫张量。张量一般和向量和矩阵放在一起来理解。他们是不同维度的数据。例如,向量是一阶张量,矩阵是二阶张量,也就是说张量是多维数组,目的是把向量和矩阵推向更高的维度。因为张量其实是更高维度的向量,所以向量的一些数学性质他也是有的。在我们开始处理图象的时候,张量就更加重要,因为图像一般以n维数组的形式出现。

### 回答1: 这是 PyTorch 中的 Lambda 变换。和 TensorFlow 中的 Lambda 层类似,Lambda 变换也是一种可自定义的变换,允许使用者将任意的函数封装成一个变换,以便在数据预处理过程中使用。在 PyTorch 中,使用 Lambda 变换可以方便地添加自定义的数据预处理逻辑,比如自定义数据增强方法、自定义数据清洗方法等等。Lambda 变换的一个常见用法是将一个 Python 函数转换为 PyTorch 的张量计算,从而允许将这个函数作为一个 PyTorch 的变换来使用使用 Lambda 变换可以使得数据预处理的代码更加简洁和易读。 ### 回答2: `tranforms.lambda()`是一个在Python中用于创建匿名函数的函数。匿名函数是一种没有标识符的函数,通常用于在输入不方便定义具名函数的地方使用使用`tranforms.lambda()`可以更简洁地定义匿名函数。这个函数接受两个参数,第一个参数是函数的参数列表,第二个参数是函数的表达式或语句。 例如,我们可以用`tranforms.lambda()`来定义一个简单的加法匿名函数: ``` add = tranforms.lambda x, y: x + y ``` 上述代码定义了一个匿名函数,它接受两个参数`x`和`y`,并返回它们的和。 使用这个匿名函数时,我们可以直接调用它,并传入参数: ``` result = add(3, 5) # 返回8 ``` 这样我们可以更简洁地定义和使用匿名函数,而无需为它们定义具名函数的标识符。 需要注意的是,`tranforms.lambda()`函数并不是Python内置的函数,而是在某些特定的库或框架中提供的一个工具函数。在使用之前,需要确保已正确导入相关的库或模块。 ### 回答3: tranforms.lambda() 是 TensorFlow 的一个功能函数,用于创建一个 LambdaLayer 对象。LambdaLayer 是一个自定义层,可以在模型中插入一个任意的自定义函数作为层。该函数将作为模型的一部分,并参与前向传播和反向传播过程。 使用 tranforms.lambda() 函数创建 LambdaLayer 对象时,需要传入一个自定义函数作为参数。这个函数可以是任意的 Python 函数,也可以是 Lambda 表达式。然后,通过调用 LambdaLayer 对象的 __call__() 方法,将函数应用于输入数据,得到输出结果。 LambdaLayer 的典型应用场景是对输入数据进行一些简单的自定义操作,例如对数据进行格式转换、数据增强等。通过使用 LambdaLayer,可以把这些操作作为网络的一部分,无需额外创建一个独立的函数,从而使代码更加简洁和可读。 总的来说,tranforms.lambda() 是 TensorFlow 提供的一个功能函数,用于创建一个 LambdaLayer 对象,该对象可以将自定义函数应用于输入数据,并作为模型的一部分参与训练过程。它可以很好地用于简化代码并增加模型的灵活性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值