微博:https://weibo.com/wangxiaocaoai/profile?rightmod=1&wvr=6&mod=personinfo
微信公众号:搜索"AI躁动街"
本节要点:
1 张量
2 创建张量的方式
3 张量的索引,切片,连接,换位等操作
4 随机抽样的操作
5 序列化(保存与加载)
6 并行化
torch.is_tensor(obj) 如果obj 是一个pytorch张量,则返回True
import torch
# 创建一个普通数值
a = 1
print(torch.is_tensor(a))
# 创建一个float类型的tensor
b = torch.FloatTensor(a)
print(torch.is_tensor(b))
False
True
torch.Storage是单个数据类型的连续的一维数组,每个torch.Tensor都具有相同数据类型的相应存储。他是torch.tensor底层数据结构,他除了像Tensor一样定义数值,还可以直接把文件映射到内存中进行操作
torch.is_storage(obj),如何obj 是一个pytorch storage对象,则返回True
# 创建torch.storage,共有以下8中类型
torch.FloatStorage([1,2,3,4,5])
torch.ByteStorage([1,2,3,4,5])
torch.ShortStorage([1,2,3,4,5])
torch.IntStorage([1,2,3,4,5])
torch.LongStorage([1,2,3,4,5])
torch.FloatStorage([1,2,3,4,5])
torch.DoubleStorage([1,2,3,4,5])
torch.ShortStorage([1,2,3,4,5])
# 判断是否为torch.storage
# 随机创建长度为5的一维数组
a = torch.FloatStorage(5)
print(a)
# 判断
print(torch.is_storage(a))
0.0
-0.0
821.166015625
4.657746965897047e-10
5.000000953674316
[torch.FloatStorage of size 5]
True
torch.set_default_tensor_type(torch.FloatTensor)
torch.get_default_dtype()
torch.float32
# 随机创建1*2*3维的tensor
a = torch.randn(1,2,3)
print(a)
# 输出元素个数
print(torch.numel(a))
tensor([[[-1.9520, -1.2041, -0.8372],
[-0.8017, -0.5982, 0.5224]]])
6
完全参考numpy
参数:
precision – 浮点数输出的精度位数 (默认为8 )
threshold – 阈值,触发汇总显示而不是完全显示(repr)的数组元素的总数 (默认为1000)
edgeitems – 汇总显示中,每维(轴)两端显示的项数(默认值为3)
linewidth – 用于插入行间隔的每行字符数(默认为80)。Thresholded matricies will ignore this parameter.
profile – pretty打印的完全默认值。 可以覆盖上述所有选项 (默认为short, full)
torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None)
torch.eye(n, m=None, out=None)
参数:
n (int ) – 行数
m (int, optional) – 列数.如果为None,则默认为n
out (Tensor, optinal) - Output tensor
a = torch.eye(4, 4)
print(a)
tensor([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
返回的张量tensor和numpy的ndarray共享同一内存空间。修改一个会导致另外一个也被修改。返回的张量不能改变大小。
import numpy as np
# 互换
a = np.array([1,2,3,4])
print('a:',a)
t = torch.from_numpy(a)
print('t:', t)
# 共享内存,修改一个,另一个改变
t[0] = -10
print('a:',a)
# tensor转numpy
t_a = t.numpy()
a: [1 2 3 4]
t: tensor([ 1, 2, 3, 4])
a: [-10 2 3 4]
包含在区间start 和 end 上均匀间隔的steps个点。 输出1维张量的长度为steps。
参数:
start (float) – 序列的起始点
end (float) – 序列的最终值
steps (int) – 在start 和 end间生成的样本数
out (Tensor, optional) – 结果张量
a = torch.linspace(start=1, end=20, steps=10)
print(a)
tensor([ 1.0000, 3.1111, 5.2222, 7.3333, 9.4444, 11.5556,
13.6667, 15.7778, 17.8889, 20.0000])
返回一个1维张量,包含在区间 10start 和 10end上以对数刻度均匀间隔的steps个点。 输出1维张量的长度为steps。
参数:
start (float) – 序列的起始点
end (float) – 序列的最终值
steps (int) – 在start 和 end间生成的样本数
out (Tensor, optional) – 结果张量
a = torch.logspace(start=-10, end=10, steps=5)
print(a)
tensor([ 1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10])
torch.ones(*sizes, out=None) → Tensor
参数:
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optional) – 结果张量
a = torch.ones(3, 4)
print(a)
tensor([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
回一个张量,包含了从区间[0,1)的均匀分布中抽取的一组随机数,形状由可变参数sizes 定义。
参数:
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optinal) - 结果张量 例子:
a = torch.rand(3, 4)
print(a)
tensor([[ 0.4617, 0.3783, 0.5476, 0.6975],
[ 0.9122, 0.4346, 0.7784, 0.4307],
[ 0.6557, 0.1655, 0.3513, 0.8785]])
返回一个张量,包含了从标准正态分布(均值为0,方差为 1,即高斯白噪声)中抽取一组随机数,形状由可变参数sizes定义。
参数:
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optinal) - 结果张量
a = torch.randn(3, 4)
print(a)
tensor([[ 0.4216, 0.0764, 0.5121, -0.6687],
[-0.2173, 1.3139, -1.9322, -0.9506],
[-0.1711, -0.4935, -0.0649, -0.0772]])
给定参数n,返回一个从0 到n -1 的随机整数排列。
参数:
n (int) – 上边界(不包含)
a = torch.randperm(10)
print(a)
tensor([ 6, 0, 7, 3, 2, 1, 8, 5, 4, 9])
torch.arange(start, end, step=1, out=None) → Tensor
返回一个1维张量,长度为 floor((end−start)/step)。包含从start到end,以step为步长的一组序列值(默认步长为1)。
参数:
start (float) – 序列的起始点
end (float) – 序列的终止点
step (float) – 相邻点的间隔大小
out (Tensor, optional) – 结果张量
a = torch.arange(10, 20, 2)
print(a)
tensor([ 10., 12., 14., 16., 18.])
警告:建议使用函数 torch.arange()
a = torch.range(10, 20, 2)
print(a)
tensor([ 10., 12., 14., 16., 18., 20.])
返回一个全为标量 0 的张量,形状由可变参数sizes 定义。
参数:
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optional) – 结果张量
a = torch.zeros(3, 4)
print(a)
tensor([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
torch.cat(inputs, dimension=0) → Tensor
参数:
inputs (sequence of Tensors) – 可以是任意相同Tensor 类型的python 序列
dimension (int, optional) – 沿着此维连接张量序列。
a = torch.randn(2, 4)
b = torch.randn(2, 4)
a_b_0 = torch.cat((a, b), 0)
a_b_1 = torch.cat((a, b), 1)
print(a)
print(b)
print(a_b_0)
print(a_b_1)
tensor([[ 0.6137, 0.1970, -0.2391, -0.9429],
[ 1.8466, 1.6018, 1.4970, 0.2305]])
tensor([[ 0.7776, 0.1084, -0.8127, -1.3126],
[ 1.1053, 0.3898, 0.1087, -0.4667]])
tensor([[ 0.6137, 0.1970, -0.2391, -0.9429],
[ 1.8466, 1.6018, 1.4970, 0.2305],
[ 0.7776, 0.1084, -0.8127, -1.3126],
[ 1.1053, 0.3898, 0.1087, -0.4667]])
tensor([[ 0.6137, 0.1970, -0.2391, -0.9429, 0.7776, 0.1084, -0.8127,
-1.3126],
[ 1.8466, 1.6018, 1.4970, 0.2305, 1.1053, 0.3898, 0.1087,
-0.4667]])
torch.chunk(tensor, chunks, dim=0)
在给定维度(轴)上将输入张量进行分块儿。
参数:
tensor (Tensor) – 待分块的输入张量
chunks (int) – 分块的个数
dim (int) – 沿着此维度进行分块
a = torch.randn(4, 6)
a_chunk = torch.chunk(a, 2, 0)
print('a_chunk:', a_chunk)
print('type:', type(a_chunk)) # 返回的是一个tuple
a_chunk: (tensor([[-0.9597, -0.6585, -1.1580, 0.2790, -0.5184, 1.8365],
[ 0.5250, 1.1513, -0.8885, 0.1913, 1.2182, -0.0828]]), tensor([[ 2.3396, -0.6564, 0.2860, -1.0066, -0.1558, 0.4544],
[-1.4732, 0.6251, -1.3311, 2.0909, -0.5014, 1.0714]]))
type:
a_chunk = torch.chunk(a, 2, 1) # 在维度=1上进行分块
print('a_chunk:', a_chunk)
a_chunk: (tensor([[-0.9597, -0.6585, -1.1580],
[ 0.5250, 1.1513, -0.8885],
[ 2.3396, -0.6564, 0.2860],
[-1.4732, 0.6251, -1.3311]]), tensor([[ 0.2790, -0.5184, 1.8365],
[ 0.1913, 1.2182, -0.0828],
[-1.0066, -0.1558, 0.4544],
[ 2.0909, -0.5014, 1.0714]]))
torch.gather(input, dim, index, out=None) → Tensor
其实是根据dim和index去取出input中的元素
参数:
input (Tensor) – 源张量
dim (int) – 索引的轴
index (LongTensor) – 聚合元素的下标
out (Tensor, optional) – 目标张量
a = torch.Tensor([[1, 2, 3],[4, 5, 6]])
print(a)
tensor([[ 1., 2., 3.],
[ 4., 5., 6.]])
# 其实就是在维度1上取出下标为[[0, 1], [2, 0]]的a中的元素
a_gather = torch.gather(a, 1, torch.LongTensor([[0, 1], [2, 0]]))
print(a_gather)
tensor([[ 1., 3., 2.],
[ 5., 6., 4.]])
# 换成0维度感受一下
a_gather = torch.gather(a, 0, torch.LongTensor([[1, 0, 1], [0, 1, 1]]))
print(a_gather)
tensor([[ 4., 2., 6.],
[ 1., 5., 6.]])
沿着指定维度对输入进行切片,取index中指定的相应项(index为一个LongTensor),然后返回到一个新的张量, 返回的张量与原始张量_Tensor_有相同的维度(在指定轴上)。
注意: 返回的张量不与原始张量共享内存空间。
torch.index_select(input, dim, index, out=None) → Tensor
参数:
input (Tensor) – 输入张量
dim (int) – 索引的轴
index (LongTensor) – 包含索引下标的一维张量
out (Tensor, optional) – 目标张量
a = torch.rand(4, 6)
print(a)
tensor([[ 0.6482, 0.9216, 0.7734, 0.5927, 0.9646, 0.5529],
[ 0.9330, 0.5138, 0.4323, 0.5836, 0.2940, 0.8188],
[ 0.8988, 0.1239, 0.6988, 0.0342, 0.3798, 0.8176],
[ 0.4482, 0.5771, 0.9904, 0.6088, 0.9014, 0.6419]])
# 在维度1上切割
a_select = torch.index_select(a, 1, torch.LongTensor([0, 3]))
print(a_select)
tensor([[ 0.6482, 0.5927],
[ 0.9330, 0.5836],
[ 0.8988, 0.0342],
[ 0.4482, 0.6088]])
# 在维度0上切割
a_select = torch.index_select(a, 0, torch.LongTensor([0,2]))
print(a_select)
tensor([[ 0.6482, 0.9216, 0.7734, 0.5927, 0.9646, 0.5529],
[ 0.8988, 0.1239, 0.6988, 0.0342, 0.3798, 0.8176]])
根据掩码张量mask中的二元值,取输入张量中的指定项( mask为一个 ByteTensor),将取值返回到一个新的1D张量,
张量 mask须跟input张量有相同数量的元素数目,但形状或维度不需要相同。 注意: 返回的张量不与原始张量共享内存空间。
torch.masked_select(input, mask, out=None) → Tensor
参数:
input (Tensor) – 输入张量
mask (ByteTensor) – 掩码张量,包含了二元索引值
out (Tensor, optional) – 目标张量
a = torch.rand(2, 4)
print(a)
tensor([[ 0.6390, 0.5035, 0.6042, 0.8629],
[ 0.3294, 0.6633, 0.3334, 0.5081]])
mask = torch.ByteTensor([[0, 0, 1, 0], [1, 1, 0, 1]])
a_mask_select = torch.masked_select(a, mask)
print(a_mask_select) # 注意,返回的是一个一维的张量, 该张量里的元素是a中mask里1对应位置的元素
tensor([ 0.6042, 0.3294, 0.6633, 0.5081])
返回一个包含输入input中非零元素索引的张量。输出张量中的每行包含输入中非零元素的索引。
如果输入input有n维,则输出的索引张量output的形状为 z x n, 这里 z 是输入张量input中所有非零元素的个数。
torch.nonzero(input, out=None) → LongTensor
参数:
input (Tensor) – 源张量
out (LongTensor, optional) – 包含索引值的结果张量
a = torch.Tensor([[1, 2, 3, 0, 5], [6, 7, 0, 7, 9]])
print(a)
tensor([[ 1., 2., 3., 0., 5.],
[ 6., 7., 0., 7., 9.]])
a_nonzero = torch.nonzero(a)
print(a_nonzero) # 注意,输出的是非零元素的索引哦
tensor([[ 0, 0],
[ 0, 1],
[ 0, 2],
[ 0, 4],
[ 1, 0],
[ 1, 1],
[ 1, 3],
[ 1, 4]])
将输入张量分割成相等形状的chunks(如果可分)。 如果沿指定维的张量形状大小不能被split_size 整分, 则最后一个分块会小于其它分块。
torch.split(tensor, split_size, dim=0)
参数:
tensor (Tensor) – 待分割张量
split_size (int) – 单个分块的形状大小
dim (int) – 沿着此维进行分割
a = torch.randn(4, 7)
print(a)
tensor([[ 1.9670, 1.0551, 0.1469, -0.2239, -1.7594, -1.2708, -0.4926],
[-0.8019, -0.4658, 0.4625, 1.3451, 0.3857, -0.8660, -1.1791],
[ 1.4074, -0.8085, -1.2970, -0.7953, 0.2780, 0.9627, -1.0428],
[ 1.2674, -1.3966, -0.7654, 1.2177, 0.9083, -0.1382, -0.3038]])
a_split = torch.split(a, 2, dim=1)
print(a_split) # 注意当不能整分的时候,最后一个分块是小于其他分块的
(tensor([[ 1.9670, 1.0551],
[-0.8019, -0.4658],
[ 1.4074, -0.8085],
[ 1.2674, -1.3966]]), tensor([[ 0.1469, -0.2239],
[ 0.4625, 1.3451],
[-1.2970, -0.7953],
[-0.7654, 1.2177]]), tensor([[-1.7594, -1.2708],
[ 0.3857, -0.8660],
[ 0.2780, 0.9627],
[ 0.9083, -0.1382]]), tensor([[-0.4926],
[-1.1791],
[-1.0428],
[-0.3038]]))
torch_chunk与torch_split区别:
torch_chunk传入的参数是要分多少块,torch_split传入的参数是每块多少大。
将输入张量形状中的1 去除并返回。 如果输入是形如(A×1×B×1×C×1×D),那么输出形状就为: (A×B×C×D)
当给定dim时,那么挤压操作只在给定维度上。例如,输入形状为: (A×1×B), squeeze(input, 0) 将会保持张量不变,只有用 squeeze(input, 1),形状会变成 (A×B)。
注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
torch.squeeze(input, dim=None, out=None)
参数:
input (Tensor) – 输入张量
dim (int, optional) – 如果给定,则input只会在给定维度挤压
out (Tensor, optional) – 输出张量
创建一个4维的张量,其中有两个维度的大小为1
a = torch.rand(2,1,3,1)
print(a)
tensor([[[[ 0.3762],
[ 0.8454],
[ 0.6275]]],
[[[ 0.5402],
[ 0.9575],
[ 0.6968]]]])
# 把所有大小为1的维度给去掉了
a_squeeze = torch.squeeze(a)
print(a_squeeze)
print('size:', a_squeeze.size()) # 压缩之后维度变成了2*3
tensor([[ 0.3762, 0.8454, 0.6275],
[ 0.5402, 0.9575, 0.6968]])
size: torch.Size([2, 3])
# 也可以指定维度压缩
a_squeeze = torch.squeeze(a, 1)
print(a_squeeze)
print('size:', a_squeeze.size()) # 于是只去掉了第1维度上的1
tensor([[[ 0.3762],
[ 0.8454],
[ 0.6275]],
[[ 0.5402],
[ 0.9575],
[ 0.6968]]])
size: torch.Size([2, 3, 1])
沿着一个新维度对输入张量序列进行连接。 序列中所有的张量都应该为相同形状。
注意和torch.cat的区别,torch.stack是在新的维度上进行拼接,也就是说拼接后维度数会+1
torch.stack(sequence, dim=0)
参数:
sqequence (Sequence) – 待连接的张量序列
dim (int) – 插入的维度。必须介于 0 与 待连接的张量序列数之间。
a = torch.randn(2, 2)
b = torch.ones(2, 2)
c = torch.zeros(2, 2)
stack = torch.stack((a, b, c), 0)
print(stack)
tensor([[[ 1.1905, 0.0067],
[ 0.1899, -0.0446]],
[[ 1.0000, 1.0000],
[ 1.0000, 1.0000]],
[[ 0.0000, 0.0000],
[ 0.0000, 0.0000]]])
# 指定其他维度
stack = torch.stack((a, b, c), 1)
print(stack)
tensor([[[ 1.1905, 0.0067],
[ 1.0000, 1.0000],
[ 0.0000, 0.0000]],
[[ 0.1899, -0.0446],
[ 1.0000, 1.0000],
[ 0.0000, 0.0000]]])
# 指定其他维度
stack = torch.stack((a, b, c), 2)
print(stack)
tensor([[[ 1.1905, 1.0000, 0.0000],
[ 0.0067, 1.0000, 0.0000]],
[[ 0.1899, 1.0000, 0.0000],
[-0.0446, 1.0000, 0.0000]]])
输入一个矩阵(2维张量),并转置0, 1维。 可以被视为函数transpose(input, 0, 1)的简写函数。
torch.t(input, out=None) → Tensor
参数:
input (Tensor) – 输入张量
out (Tensor, optional) – 结果张量
a = torch.randn(2, 3)
print(a)
tensor([[-0.0530, 0.3038, 0.9280],
[ 0.0992, 0.6662, -0.4005]])
a_t = torch.t(a)
print(a_t)
tensor([[-0.0530, 0.0992],
[ 0.3038, 0.6662],
[ 0.9280, -0.4005]])
返回输入矩阵input的转置。交换维度dim0和dim1。 输出张量与输入张量共享内存,所以改变其中一个会导致另外一个也被修改。
torch.transpose(input, dim0, dim1, out=None) → Tensor
参数:
input (Tensor) – 输入张量
dim0 (int) – 转置的第一维
dim1 (int) – 转置的第二维
a = torch.randn(2, 3, 2)
print(a)
tensor([[[ 0.8596, 0.6972],
[ 0.8587, -0.4417],
[-2.0626, -1.9395]],
[[-0.5063, -0.9338],
[-0.0316, -1.2842],
[ 0.7219, -1.5864]]])
# 指定要交换的两个维度
a_trans = torch.transpose(a, 1, 2)
print(a_trans)
tensor([[[ 0.8596, 0.8587, -2.0626],
[ 0.6972, -0.4417, -1.9395]],
[[-0.5063, -0.0316, 0.7219],
[-0.9338, -1.2842, -1.5864]]])
移除指定维后,返回一个元组,包含了沿着指定维切片后的各个切片
torch.unbind(tensor, dim=0)
参数:
tensor (Tensor) – 输入张量
dim (int) – 删除的维度
a = torch.randn(2, 3, 2)
print(a)
tensor([[[-0.6012, -0.4857],
[-0.5015, -0.6248],
[-0.7119, -0.9076]],
[[ 1.4232, 0.0932],
[-0.6209, 1.1310],
[-0.7734, 0.0066]]])
a_unbind = torch.unbind(a, 0)
print(a_unbind) # 移除维度0, 拆分成了两个3*2的矩阵
(tensor([[-0.6012, -0.4857],
[-0.5015, -0.6248],
[-0.7119, -0.9076]]), tensor([[ 1.4232, 0.0932],
[-0.6209, 1.1310],
[-0.7734, 0.0066]]))
返回一个新的张量,对输入的制定位置插入维度 1
注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
如果dim为负,则将会被转化dim+input.dim()+1
torch.unsqueeze(input, dim, out=None)
参数:
tensor (Tensor) – 输入张量
dim (int) – 插入维度的索引
out (Tensor, optional) – 结果张量
# 先创建一个只有一个维度的tensor
a = torch.rand(4)
print('a:', a)
print('size:', a.size())
a: tensor([ 0.2107, 0.0282, 0.5163, 0.3185])
size: torch.Size([4])
# 在维度1上新增一个维度
a_1 = torch.unsqueeze(a, 1)
print('a_1', a_1)
print('size:', a_1.size()) # 维度变成了2维:4*1
a_1 tensor([[ 0.2107],
[ 0.0282],
[ 0.5163],
[ 0.3185]])
size: torch.Size([4, 1])
设定生成随机数的种子,并返回一个 torch._C.Generator 对象.
参数: seed (int or long) – 种子.
x = torch.manual_seed(10)
print(x)
x = torch.initial_seed()
print(x)
10
# 获得当前状态
print(torch.get_rng_state())
tensor([ 10, 0, 0, ..., 0, 0, 0], dtype=torch.uint8)
# 设置状态
torch.set_rng_state(torch.get_rng_state())
print(torch.default_generator)
从伯努利分布中抽取二元随机数(0 或者 1)。
输入张量须包含用于抽取上述二元随机值的概率。 因此,输入中的所有值都必须在[0,1]区间,即 0<=inputi<=1
输出张量的第i个元素值, 将会以输入张量的第i个概率值等于1。
返回值将会是与输入相同大小的张量,每个值为0或者1 参数:
input (Tensor) – 输入为伯努利分布的概率值
out (Tensor, optional) – 输出张量(可选)
# 创建一个0-1分布的矩阵,表示概率
a = torch.Tensor(3, 3).uniform_(0,1)
print(a)
tensor([[ 0.4581, 0.4829, 0.3125],
[ 0.6150, 0.2139, 0.4118],
[ 0.6938, 0.9693, 0.6178]])
# 转换成0/1伯努利分布,即在伯努利分布中抽取随机数,1表示抽取出的数
b = torch.bernoulli(a)
print(b)
tensor([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 1., 1., 1.]])
返回一个张量,每行包含从input相应行中定义的多项分布中抽取的num_samples个样本。
[注意]:输入input每行的值不需要总和为1 (这里我们用来做权重),但是必须非负且总和不能为0。
当抽取样本时,依次从左到右排列(第一个样本对应第一列)。
如果输入input是一个向量,输出out也是一个相同长度num_samples的向量。如果输入input是有 m行的矩阵,输出out是形如m×n的矩阵。
如果参数replacement 为 True, 则样本抽取可以重复。否则,一个样本在每行不能被重复抽取。
参数num_samples必须小于input长度(即,input的列数,如果是input是一个矩阵)。
参数:
input (Tensor) – 包含概率值的张量
num_samples (int) – 抽取的样本数
replacement (bool, optional) – 布尔值,决定是否能重复抽取
out (Tensor, optional) – 结果张量
weights = torch.Tensor([0, 10, 3, 0])
# 无放回,num_samples 必须小于等于weights的长度
b = torch.multinomial(weights, 3)
print(b)
tensor([ 2, 1, 0])
# 有放回,num_samples 任意
c = torch.multinomial(weights, 4, replacement=True)
print(c)
tensor([ 1, 1, 1, 2])
返回一个张量,包含从给定参数means,std的离散正态分布中抽取随机数。 均值means是一个张量,包含每个输出元素相关的正态分布的均值。 std是一个张量,包含每个输出元素相关的正态分布的标准差。 均值和标准差的形状不须匹配,但每个张量的元素个数须相同。
参数:
means (Tensor) – 均值
std (Tensor) – 标准差
out (Tensor) – 可选的输出张量
torch.normal(mean=0.5, std=torch.arange(1, 6))
tensor([-1.2336, 2.2541, -0.6556, -1.9196, 0.8095])
保存一个对象到一个硬盘文件上 参考: Recommended approach for saving a model
torch.save(obj, f, pickle_module=
参数:
obj – 保存对象
f - 类文件对象 (返回文件描述符)或一个保存文件名的字符串
pickle_module – 用于pickling元数据和对象的模块
pickle_protocol – 指定pickle protocal 可以覆盖默认参数
# 假设有如下模型和优化器需要被保存到硬盘文件
model = Net()
optimizer = optim.Adam(model.parameters(), lr=args.lr)
# 先建立一个词典
state = {'net': model.state_dict(), 'optimizer':optimizer.state_dict(), 'epoch': epoch}
# 保存
torch.save(state, dir)
从磁盘文件中读取一个通过torch.save()保存的对象。 torch.load() 可通过参数map_location 动态地进行内存重映射,使其能从不动设备中读取文件。一般调用时,需两个参数: storage 和 location tag. 返回不同地址中的storage,或着返回None (此时地址可以通过默认方法进行解析). 如果这个参数是字典的话,意味着其是从文件的地址标记到当前系统的地址标记的映射。 默认情况下, location tags中 "cpu"对应host tensors,‘cuda:device_id’ (e.g. ‘cuda:2’) 对应cuda tensors。 用户可以通过register_package进行扩展,使用自己定义的标记和反序列化方法。
torch.load(f, map_location=None, pickle_module=
参数:
f – 类文件对象 (返回文件描述符)或一个保存文件名的字符串
map_location – 一个函数或字典规定如何remap存储位置
pickle_module – 用于unpickling元数据和对象的模块 (必须匹配序列化文件时的pickle_module )
# 直接读取对象
torch.load('tensor.pt')
# 将所有tensor读取到GPU上
torch.load('tensor.pt', map_location=lambda storage, loc:storage)
# 将tensor从GPU1映射到GPU0上
torch.load('tensor.pt', map_location={'cuda:1':'cuda:0'})
若想读取回5.1操作中保存的参数
checkpoint = torch.load(dir)
model.load_state_dict(checkpoint['net'])
optimizer.load_state_dict(checkpoint['optimizer'])
state_epoch = checkpoint['epoch'] + 1
torch.set_num_threads(2)