▲conda命令: conda命令详解
1.创建环境
例子:
#创建python3.6版本的环境test:
conda create -n test python=3.6
#激活该环境test:
conda activate test
#展示该环境的包:
pip list
2.确定cuda和gpu
▲电脑查询GPU型号:
任务管理器-性能
or
设备管理器-显示适配器
▲电脑查询GPU型号对应的cuda:
命令行输入:
nvidia-smi
or
NVIDIA控制面板-系统信息-组件-3D设置-NVCUDA64.DLL 产品名称(相关链接)
(有时候有错误,可以去更新一下驱动,具体可见土堆视频的p3)
3.在pytorch官网安装pytorch
Stable:稳定版
cuda的型号需要查看自己的gpu确定
复制命令行进行安装
安装很慢的话可以下载本地包,具体可见土堆视频的p3
4.检查是否安装成功
命令行
#命令行,进入python环境
python
#进入Python环境后,import torch,没有报错即为成功
import torch
#判断是否可以用gpu
torch.cuda.is_available() #返回True,即可以用gpu
5.pycharm中创建一个项目
6.配置jupyter nootbook
下载anaconda之后默认安装jupyter,但默认的环境为base
要切换环境
命令行:
# 激活test环境
conda activate test
# 在当前环境安装jupyter需要的包(还是库?)
conda install nb_conda
# 打开jupyter
jupyter notebook
创建一个新的文件
7.两个函数 dir() / help()
在pycharm的console中,
演示一下如何探索torch.cuda.is_available()函数
命令行输入
8.Dataset
from torch.utils.data import Dataset
▲Dataset文档:
查看文档两种方法:
(1)在pycharm中按住ctrl键,点击相应的类或包
(2)在jupyter中输入Dataset??
,得到Dataset的文档
读一下,文档说要重写两个函数__getitem__
和 __len__
Init signature: Dataset(*args, **kwds)
Source:
class Dataset(Generic[T_co]):
r"""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.
"""
functions: Dict[str, Callable] = {}
def __getitem__(self, index) -> T_co:
raise NotImplementedError
def __add__(self, other: 'Dataset[T_co]') -> 'ConcatDataset[T_co]':
return ConcatDataset([self, other])
# No `def __len__(self)` default?
# See NOTE [ Lack of Default `__len__` in Python Abstract Base Classes ]
# in pytorch/torch/utils/data/sampler.py
def __getattr__(self, attribute_name):
if attribute_name in Dataset.functions:
function = functools.partial(Dataset.functions[attribute_name], self)
return function
else:
raise AttributeError
@classmethod
def register_function(cls, function_name, function):
cls.functions[function_name] = function
@classmethod
def register_datapipe_as_function(cls, function_name, cls_to_register, enable_df_api_tracing=False):
if function_name in cls.functions:
raise Exception("Unable to add DataPipe function name {} as it is already taken".format(function_name))
def class_function(cls, enable_df_api_tracing, source_dp, *args, **kwargs):
result_pipe = cls(source_dp, *args, **kwargs)
if isinstance(result_pipe, Dataset):
if enable_df_api_tracing or isinstance(source_dp, DFIterDataPipe):
if function_name not in UNTRACABLE_DATAFRAME_PIPES:
result_pipe = result_pipe.trace_as_dataframe()
return result_pipe
function = functools.partial(class_function, cls_to_register, enable_df_api_tracing)
cls.functions[function_name] = function
File: c:\anaconda3\envs\test\lib\site-packages\torch\utils\data\dataset.py
Type: GenericMeta
▲在控制台可以进行测试
这里学到一个技巧,在写代码的过程中,可以通过控制台来不断调试!!!直接复制过来就行。▲DataSet加载数据
视频讲解见土堆视频p7
from torch.utils.data import Dataset
from PIL import Image
import os
class MyData(Dataset): # 创建MyData类继承Dataset
def __init__(self, root_dir, label_dir): # 创建初始化
self.root_dir = root_dir # 'dataset/train'
self.label_dir = label_dir # 'ants'
self.path = os.path.join(self.root_dir, self.label_dir) # 'dataset/train\\ants'
self.img_path = os.listdir(self.path)
def __getitem__(self, idx): # idx作为一个编号
img_name = self.img_path[idx] # '0013035.jpg'
img_item_path = os.path.join(self.root_dir, self.label_dir, img_name) # 'dataset/train\\ants\\0013035.jpg'
img = Image.open(img_item_path) # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x231AA844B00>
label = self.label_dir # 'ants'
return img, label
def __len__(self):
return len(self.img_path)
root_dir = "dataset/train"
ants_label_dir = "ants"
bees_label_dir = "bees"
ants_dataset = MyData(root_dir,ants_label_dir)
bees_dataset = MyData(root_dir,bees_label_dir)
train_dataset = ants_dataset + bees_dataset
9.TensorBoard
▲导包错误
from torch.utils.tensorboard import SummaryWriter #导入SummaryWriter 报错
解决方法 改成:from tensorboardX import SummaryWriter (需要pip install tensorboardX )
pip install -i https://mirrors.aliyun.com/pypi/simple/ tensorboardX
▲y=x实例测试add_scalar
from tensorboardX import SummaryWriter
writer = SummaryWriter("logs") #通过ctrl可看文档,logs是名字
# y = x
for i in range(100):
writer.add_scalar("y=x", i, i)
writer.close()
运行后,生成logs文件
打开该logs
命令行输入:
tensorboard --logdir=logs #logdir=事件文件所在文件夹名
或者
tensorboard --logdir=logs --port=6007 #port指定端口打开
▲测试add_image
按住ctrl查看文档,可以看到需要的图片是numpy_compatible
类型的
在console里测试,
from PIL import Image
image_path = "data/train/ants_image/0013035.jpg"
img = Image.open(image_path)
print(type(img)) #查看这个img的类型
# 输出<class 'PIL.JpegImagePlugin.JpegImageFile'> 是JpegImageFile类型,不符合要求
#所以将图片转换成numpy类型
import numpy as np
img_array = np.array(img)
print(type(img_array))
#<class 'numpy.ndarray'>
在pycharm中进行运行
from tensorboardX import SummaryWriter
import numpy as np
from PIL import Image
writer = SummaryWriter("logs")
# 测试add_image
img_path = "data/train/ants_image/0013035.jpg"
img_PIL = Image.open(img_path) # type:<class 'PIL.JpegImagePlugin.JpegImageFile'>,即转换成JpegImageFile类型
img_array = np.array(img_PIL) # type:<class 'numpy.ndarray'>,即转换成numpy类型
print(img_array.shape) # 判断一下img_array的shape,输出(512, 768, 3) #或者将这段在console中运行,可以直接看到img_array的各种信息
# writer.add_image("test", img_array, 1) 这样运行是会报错的,从add_image的官方文档可以看出来,shape的默认是(3, H, W),而此处img_array的shape是(H,W,3)。而官方文档也给出了解决方法,即确定dataformats。
writer.add_image("test", img_array, 1, dataformats='HWC') # 在官方文档的Examples里有 1是步数,dataformats是shape
writer.close()
同样在命令行中输入
tensorboard --logdir=logs --port=6007 #port指定端口打开
即可在打开的网址的Image中看到每一步的图片
alt+回车:进行错误提醒
10.transforms
from torchvision import transforms
▲文档:
▲transforms的用法:
transforms是有个py文件,里面有各种各样的类。我们要用里面的类作为工具。
from PIL import Image
from torchvision import transforms
# 用PIL读取图片
img_path = "data/train/ants_image/0013035.jpg"
img_PIL = Image.open(img_path) # img:<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x15AFF9D68D0>
# 这两句是transforms的精髓(注意:如果直接img_tensor = transforms.ToTensor(img_PIL)就是错误的)请思考一下。
# 用transforms将PIL图片类型转换为tensor类型
tensor_trans = transforms.ToTensor() # 从transforms中选择一个class进行创建: tool = transforms.ToTensor()
img_tensor = tensor_trans(img_PIL) # 看这个class需要什么东西,进行传参: result = tool(input)
# print(img_tensor)
▲tensor的数据类型:
transforms的运用:
from PIL import Image
from torchvision import transforms
import cv2
from tensorboardX import SummaryWriter
# python的用法 ——tensor数据类型
# 通过transforms.ToTensor去看两个问题
# 1.transforms 该如何使用(python)
# 2.为什么需要Tensor数据类型
# 用PIL读取图片
img_path = "data/train/ants_image/0013035.jpg"
img_PIL = Image.open(img_path) # img:<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x15AFF9D68D0>
# 用opencv读取图片成numpy类型
img_cv = cv2.imread(img_path) # 用print(type(cv_img))或者console查看类型: <class 'numpy.ndarray'>
print(img_cv.shape) # 注意图片的shape
# 用transforms将PIL图片类型转换为tensor类型
tensor_trans = transforms.ToTensor() # 从transforms中选择一个class进行创建: tool = transforms.ToTensor()
img_tensor = tensor_trans(img_PIL) # 看这个class需要什么东西,进行传参: result = tool(input)
# print(img_tensor)
# 用transforms将numpy类型转换为tensor类型
tensor_trans = transforms.ToTensor()
img_tensor_cv = tensor_trans(img_cv)
writer = SummaryWriter("logs")
writer.add_image("numpy_img", img_cv, dataformats='HWC') # 注意shape
writer.add_image("Tensor_img", img_tensor)
writer.add_image("Tensor_img_cv", img_tensor_cv)
writer.close()
▲常见的transforms:
transforms的各个函数中点开有一些属性,常见的有__init__ 以及__call__
__call__的用法:
class Person:
def __call__(self, name):
print("__call__ " + "hello " + name)
def hello(self, name):
print("hello " + name)
p = Person()
p("小明") # 调用方法的不同,可以直接在对象后面打括号。输出: __call__ hello 小明
p.hello("小红") # hello 小红
▇ 常见的transforms——Compose:
把多个transforms联合在一起。文档里有用法示例
▇ 常见的transforms——ToTensor:
Convert a PIL Image
or numpy.ndarray
to tensor.
(在函数的括号里按住ctrl+p可以进行参数提醒)
# 常用的transforms
from PIL import Image
from tensorboardX import SummaryWriter
from torchvision import transforms
img_PIL = Image.open("data/train/ants_image/0013035.jpg")
print(img_PIL) # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1A684D48978>
# ToTensor的使用
trans_toTenser = transforms.ToTensor()
img_tensor = trans_toTenser(img_PIL)
writer = SummaryWriter("logs")
writer.add_image("ToTensor", img_tensor)
writer.close()
▇ 常见的transforms——Normalize:
output[channel] = (input[channel] - mean[channel]) / std[channel]
例如:trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
若输入的像素是[0,1],则输出的像素则为[-1,1]
注意:此处图片有三个维度,所以每个维度的均值和标准差都要写
# 常用的transforms
from PIL import Image
from tensorboardX import SummaryWriter
from torchvision import transforms
img_PIL = Image.open("data/train/ants_image/0013035.jpg")
print(img_PIL) # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1A684D48978>
writer = SummaryWriter("logs")
# ToTensor的使用
trans_toTenser = transforms.ToTensor()
img_tensor = trans_toTenser(img_PIL)
writer.add_image("ToTensor", img_tensor)
# Normalize的使用
print(img_tensor[0][0][0]) # 第一层 第一行 第一列
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]) # mean:均值 std:标准差,注意看文档。此处图片有三个维度,所以每个维度的均值和标准差都要写
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0]) # 第一层 第一行 第一列
writer.add_image("Normalize的使用", img_norm)
writer.close()
输出:
tensor(0.3137)
tensor(-0.3725)
图片:
▇ 常见的transforms——Resize:
看文档
# 常用的transforms
from PIL import Image
from tensorboardX import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img_PIL = Image.open("data/train/ants_image/0013035.jpg") # img_PIL: <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1A684D48978>
# ToTensor的使用
trans_toTenser = transforms.ToTensor()
img_tensor = trans_toTenser(img_PIL)
writer.add_image("ToTensor", img_tensor)
# Resize的使用
trans_resize = transforms.Resize((512, 512))
img_resize = trans_resize(img_PIL) # img_resize: <PIL.Image.Image image mode=RGB size=512x512 at 0x2AD8FE676D8>
img_resize = trans_toTenser(img_resize) # img_resize: tensor
writer.add_image("Resize", img_resize)
writer.close()
最终效果:
▇ 常见的transforms——Compose:
Composes several transforms together.
注:Compose的用法要注意输入输出。例如trans_resize_2是PIL->PIL, trans_toTenser是将PIL—>tensor,前面的输出必须是后面的输入类型
# 常用的transforms
from PIL import Image
from tensorboardX import SummaryWriter
from torchvision import transforms
img_PIL = Image.open("data/train/ants_image/0013035.jpg")
print(img_PIL) # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1A684D48978>
writer = SummaryWriter("logs")
# ToTensor的使用
trans_toTenser = transforms.ToTensor()
img_tensor = trans_toTenser(img_PIL)
writer.add_image("ToTensor", img_tensor)
# Resize的使用
# img_PIL: <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x2AD8F8E8518>
trans_resize = transforms.Resize((800, 400))
img_resize = trans_resize(img_PIL) # img_resize: <PIL.Image.Image image mode=RGB size=512x512 at 0x2AD8FE676D8>
img_resize = trans_toTenser(img_resize) # img_resize: tensor
writer.add_image("Resize", img_resize, 1)
# Compose的使用
trans_resize_2 = transforms.Resize(400)
# Compose的用法要注意输入输出。例如trans_resize_2是PIL->PIL, trans_toTenser是将PIL—>tensor,前面的输出必须是后面的输入类型
trans_compose = transforms.Compose([trans_resize_2, trans_toTenser])
img_resize_compose = trans_compose(img_PIL)
writer.add_image("Resize_2", img_resize_compose, 0)
writer.close()
▇ 常见的transforms——RandomCrop:
随机裁剪,随机裁剪图片上的某个部位
# 常用的transforms
from PIL import Image
from tensorboardX import SummaryWriter
from torchvision import transforms
img_PIL = Image.open("data/train/ants_image/0013035.jpg")
print(img_PIL) # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1A684D48978>
writer = SummaryWriter("logs")
# ToTensor的使用
trans_toTenser = transforms.ToTensor()
img_tensor = trans_toTenser(img_PIL)
writer.add_image("ToTensor", img_tensor)
# RandomCrop
trans_random = transforms.RandomCrop((500, 100)) # 随机裁剪
trans_random_compose = transforms.Compose([trans_random, trans_toTenser]) # 转化为tensor类型
for i in range(10):
img_crop = trans_random_compose(img_PIL) # 随机裁剪10个
writer.add_image("RandomCropHW", img_crop, i)
writer.close()
总结:官方文档里都有参数args,返回值returns以及类型
如果不知道类型,可以通过
print()
print(type())
debug