pytorch 小土堆学习笔记
文章目录
P6 P7 加载数据与实战
1. Dataset
Dataset:提供一种方式去获取数据及其label
实现功能:
1.如何获取每一个数据及其label
2.告诉我们总共有多少个数据
2. Dataloader
Dataloader:为后面的网络提供不同的数据形式
对Dataset数据进行打包/压缩(batchsize)后,将数据送进网络
# use of class Dataset
from torch.utils.data import Dataset
help(Dataset)
help(Dataset) 能看到Dataset的用法解释:
Help on class Dataset in module torch.utils.data.dataset:
class Dataset(typing.Generic)
| Dataset(*args, **kwds)
|
| An abstract class representing a :class:`Dataset`.
|
| All datasets that represent a map from keys to data samples should subclass
| it. All subclasses should overwrite :meth:`__getitem__`, supporting fetching a
| data sample for a given key. Subclasses could also optionally overwrite
| :meth:`__len__`, which is expected to return the `在这里插入代码片`size of the dataset by many
| :class:`~torch.utils.data.Sampler` implementations and the default options
| of :class:`~torch.utils.data.DataLoader`.
|
| .. note::
| :class:`~torch.utils.data.DataLoader` by default constructs a index
| sampler that yields integral indices. To make it work with a map-style
| dataset with non-integral indices/keys, a custom sampler must be provided.
|
| Method resolution order:
| Dataset
| typing.Generic
| builtins.object
|
| Methods defined here:
|
| __add__(self, other: 'Dataset[T_co]') -> 'ConcatDataset[T_co]'
|
| __getattr__(self, attribute_name)
|
| __getitem__(self, index) -> +T_co
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| register_datapipe_as_function(function_name, cls_to_register, enable_df_api_tracing=False) from builtins.type
|
| register_function(function_name, function) from builtins.type
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'functions': typing.Dict[str, typing.Callable]}
|
| __orig_bases__ = (typing.Generic[+T_co],)
|
| __parameters__ = (+T_co,)
|
| functions = {'concat': functools.partial(<function Dataset.register_da...
|
| ----------------------------------------------------------------------
| Class methods inherited from typing.Generic:
|
| __class_getitem__(params) from builtins.type
|
| __init_subclass__(*args, **kwargs) from builtins.type
| This method is called when a class is subclassed.
|
| The default implementation does nothing. It may be
| overridden to extend subclasses.
|
| ----------------------------------------------------------------------
| Static methods inherited from typing.Generic:
|
| __new__(cls, *args, **kwds)
| Create and return a new object. See help(type) for accurate signature.
Process finished with exit code 0
实战:
from torch.utils.data import Dataset
from PIL import Image
import os
# help(Dataset)
class MyData(Dataset):
def __init__(self, root_dir, label_dir): # 初始化类。根据该类创建一个特例/实例时,需要运行的一个函数,为整个class提供一个**全局变量**,为后面的函数提供变量
self.root_dir = root_dir # global
self.label_dir = label_dir
self.path = os.path.join(self.root_dir, self.label_dir)
self.img_path = os.listdir(self.path)
def __getitem__(self, idx):
img_name = self.img_path[idx]
img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)
img = Image.open(img_item_path)
label = self.label_dir
return label, img
def __len__(self):
return len(self.img_path)
root_dir = 'dataset/train'
box_label_dir = 'box'
box2_label_dir = 'box2'
box_dataset = MyData(root_dir, box_label_dir)
box2_dataset = MyData(root_dir, box2_label_dir)
train_dataset = box_dataset + box2_dataset # concat dataset
也可以再pycharm下方中的Python Console进行调试:
本节主要函数总结:
# concat path 路径拼接
os.path.join(path_a, path_b)
# path list 遍历路径下文件(名),并将该路径下所有文件暂存到一个列表path_1
path_1 = os.listdir(path)
# concat dataset 数据集拼接
train_dataset = box_dataset + box2_dataset # dataset 可直接 + 来实现拼接
# 读取img
img = Image.open(img_path) # 所得到的img变量里面有多个img相关的参数,里面的参数可以使用img.xx实现调用
P8 TensorBoard 的使用(一)
在pycharm中,以y=x为例,打开tensorboard:
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
# writer.add_image()
# y = x
for i in range(100):
# scalar 标量
writer.add_scalar("y=x", i, i) # tag, scalar_value: y轴数据:i,global_step:x轴数据,训练步距数
writer.close()
打开可视化tensorboard命令:
在pycharm的terminal中输入:
tensorboard --logdir=logs
返回:
TensorFlow installation not found - running with reduced feature set.
NOTE: Using experimental fast data loading logic. To disable, pass
"--load_fast=false" and report issues on GitHub. More details:
https://github.com/tensorflow/tensorboard/issues/4784
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.11.0 at http://localhost:6006/ (Press CTRL+C to quit)
如果默认端口6006遇到冲突,可指定端口避免冲突,输入命令改为:
tensorboard --logdir=logs --port=6007
P9 TensorBoard 的使用(二)
1. add_image 的使用
PIL 方式打开图片:
from PIL import Image
image_path = "data/bgpic7.jpg"
img = Image.open(image_path)
可见:图片格式为PIL格式,不满足add_image方法的要求(add_image图片格式要求,可按住Ctrl点击该方法进入说明文档查看)
image_path = "data/bgpic7.jpg"
from PIL import Image
img = Image.open(image_path)
print(type(img))
# <class 'PIL.JpegImagePlugin.JpegImageFile'>
2. 利用opencv读取图片,获得numpy型图片数据
image_path = "data/bgpic7.jpg"
from PIL import Image
img = Image.open(image_path)
print(type(img))
<class 'PIL.JpegImagePlugin.JpegImageFile'>
import numpy as np
img_array = np.array(img)
可见 img_array = np.array(img) 将PIL的图片格式转换为array的数据格式:
3. 使用np.array将PIL图片格式转换为array图片格式
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np
writer = SummaryWriter("logs")
# add_image 的使用
# writer.add_image()
image_path = '/media/lyt/00F68E2CF68E2250/21研究生/learn_pytorch/data/2.png'
image_PIL = Image.open(image_path) # read image
image_array = np.array(image_PIL) # change image type from PIL to array
print(type(image_array))
print(image_array.shape)
# writer.add_image("test", image_array, 1, dataformats='HWC')
writer.add_image("test", image_array, 2, dataformats='HWC') # 可拖动现实两个步骤的图片
# y = 2x
for i in range(100):
# scalar 标量
writer.add_scalar("y=2x", 2*i, i) # tag, scalar_value: y轴数据:i,global_step:x轴数据,训练步距数
writer.close()
在termial中,输入:
tensorboard --logdir=logs
点击端口链接,查看tensorboard界面结果,通过设置step=2,可拖动橙色进度条查看dataset每个步骤的操作可视化读图效果:
P10 Transforms的使用(一)
torchvision 中的 transforms:主要对图片做变换
transforms 的结构及用法:
transforms主要是transforms.py工具包,该工具包内含有多种对图片进行变换的工具(多个class,包括:Totensor, resize等)。
输入图片——》transforms.py工具箱——》结果
from PIL import Image
from torchvision import transforms
# python 的用法 ——》tensor数据类型
# 通过 transforms: TOTensor去看两个问题
# 1. transforms该如何使用(python中)
# 2. 为什么我们需要Tensor数据类型
image_path = r'/media/lyt/00F68E2CF68E2250/21研究生/learn_pytorch/data/2.png'
img = Image.open(image_path)
# print(img) # <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=802x198 at 0x7FA6A735A090>
# 1. transforms该如何使用(python中)
# tensor_img = transforms.ToTensor(img) # TypeError: ToTensor() takes no arguments
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
# print(tensor_img)
初始化实例之后,再传入参数调用函数(init和call的用法区别),transforms的用法使用过程步骤图解:
P11 Transforms的使用(二)
debug上述代码可以看到:
在Protected Attributes中可以看到,
backward_hooks: 反向传播的钩子,反向传播方法
_grad: 梯度
_grad_fn:梯度方法
…
因此,tensor_img 中,包含了神经网络理论基础的一些参数。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
import cv2
# python 的用法 ——》tensor数据类型
# 通过 transforms: TOTensor去看两个问题
# 1. transforms该如何使用(python中)
# 2. 为什么我们需要Tensor数据类型
image_path = r'/media/lyt/00F68E2CF68E2250/21研究生/learn_pytorch/data/2.png'
img = Image.open(image_path)
# print(img) # <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=802x198 at 0x7FA6A735A090>
writer = SummaryWriter('logs') # 光标点在括号中,ctrl+p 可查看方法参数
# 1. transforms该如何使用(python中)
# tensor_img = transforms.ToTensor(img) # TypeError: ToTensor() takes no arguments
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
# print(tensor_img)
cv_img = cv2.imread(image_path) # 直接读取array图片类型,通过opencv读取。前面是通过PIL读取PIL的图片格式,然后用numnpy将PIL格式转换为array格式
writer.add_image("tensor_img", tensor_img)
writer.close()
运行后去tensorboard刷新一下,可以看到:
P12 常见的Transforms(一)
主要是使用transforms.py中常用的方法
可以Ctrl+点击 from torchvision import transforms 中的transforms,进入transforms.py查看方法类,也可通过pycharm左下角的structure查看:
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms # hold Ctrl and click it(transforms) to read usage
img_path = r'/media/scau/21B1CA0D9A1CBC09/DL/learn_pytorch/data/1.png'
writer = SummaryWriter('logs')
img = Image.open(img_path)
print(img)
# Totensor
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("img_totensor", img_tensor)
# Normalize
print(img_tensor[0][0][0]) # 0层0行0列
trans_norm = transforms.Normalize([0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5])
# trans_norm = transforms.Normalize([0.5, 2, 5, 6], [2, 1, 4, 8])
# trans_norm = transforms.Normalize([3, 8, 1, 9], [4, 7, 1, 1])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image('img_norm', img_norm, 2)
writer.close()
在tensorboard中刷新,可以看到三个步骤的图片normalize的可视化效果(step0~step2):
P13 常见的Transforms(二)
Tips:Pycharm 忽略大小写设置
正常情况下,输入T才能提示Tensor方法,设置之后,即使输入小写t,也能提示Tensor方法:
取消勾选首字母匹配 Match case
** Compose() 用法**
transforms的一些用法实例:
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms # hold Ctrl and click it(transforms) to read usage
img_path = r'/media/scau/21B1CA0D9A1CBC09/DL/learn_pytorch/data/2.png'
writer = SummaryWriter('logs')
img = Image.open(img_path)
print(img)
# Totensor
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("img_totensor", img_tensor)
# Normalize
print(img_tensor[0][0][0]) # 0层0行0列
trans_norm = transforms.Normalize([0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5])
# trans_norm = transforms.Normalize([0.5, 2, 5, 6], [2, 1, 4, 8])
# trans_norm = transforms.Normalize([3, 8, 1, 9], [4, 7, 1, 1])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image('img_norm', img_norm, 2)
# Rize
print(img.size)
trans_resize = transforms.Resize((512, 512))
img_resize = trans_resize(img_tensor)
writer.add_image('resize', img_resize, 0)
print(img_resize.shape)
# Compose - resize - 2 . Compose函数级联
trans_resize_2 = transforms.Resize(512) # 等比例缩放
trans_compose = transforms.Compose([trans_resize_2, trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image('resize', img_resize_2, 1)
# RandomCrop 随机裁剪
# trans_randomCrop = transforms.RandomCrop((120, 250))
trans_randomCrop = transforms.RandomCrop(50)
img_randomCrop = trans_randomCrop(img_tensor)
writer.add_image('random_crop', img_randomCrop)
for i in range(10):
img_random = img_randomCrop
writer.add_image('img_random_crop', img_random, i)
writer.close()
transforms的一些用法总结
1. 多看官方文档、多关注输入输出(类型)、关注方法需要什么参数
2. 不知道输出内容或类型情况下: print()、print(type())、debug