赞
踩
python 深度学习,基于pytorch 的学习笔记,,
import numpy as np
from numpy import random as nr
a=np.arange(1,25,dtype=float)
c1=nr.choice(a,size=(3,4)) #size指定输出数组形状
c2=nr.choice(a,size=(3,4),replace=False) #replace缺省为True,即可重复抽取。
#下式中参数p指定每个元素对应的抽取概率,不设置就是每个元素被抽取的概率相同。
c3=nr.choice(a,size=(3,4),p=a / np.sum(a))
arr =np.arange(6).reshape(2, -1) print(arr) print("按照列优先,展平") print(arr.ravel('F')) print("按照行优先,展平") print(arr.ravel()) 输出结果: [[0 1 2] [3 4 5]] 按照列优先,展平 [0 3 1 4 2 5] 按照行优先,展平 [0 1 2 3 4 5] # flatten 将矩阵转为向量,通常在卷积网络与全连接层之间 a =np.floor(10*np.random.random((3,4))) print(a.flatten()) [[4. 0. 8. 5.] [1. 0. 4. 8.] [8. 2. 3. 7.]] [4. 0. 8. 5. 1. 0. 4. 8. 8. 2. 3. 7.] # squeeze降维的 arr =np.arange(3).reshape(3, 1) print(arr.shape) #(3,1) print(arr.squeeze().shape) #(3,) arr1 =np.arange(6).reshape(3,1,2,1) print(arr1.shape) #(3, 1, 2, 1) print(arr1.squeeze().shape) #(3, 2) # transpose 轴转换,深度学习中可以用来吧图片从 RGB -> GBR arr2 = np.arange(24).reshape(2,3,4) print(arr2.shape) #(2, 3, 4) print(arr2.transpose(1,2,0).shape) #(3, 4, 2)
a =np.array([[1, 2], [3, 4]]) b = np.array([[5, 6]]) c = np.concatenate((a, b), axis=0) # 跨行 print(c) d = np.concatenate((a, b.T), axis=1) print(d) [[1 2] [3 4] [5 6]] [[1 2 5] [3 4 6]] a =np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) print(np.stack((a, b), axis=0)) # 这个是按指定轴堆叠数组或矩阵 [[[1 2] [3 4]] [[5 6] [7 8]]] # 维数是不一样的
随机梯度下降法嘛,,SGD。分批次处理
#生成10000个形状为2X3的矩阵
data_train = np.random.randn(10000,2,3)
#这是一个3维矩阵,第一个维度为样本数,后两个是数据形状
print(data_train.shape)
#(10000,2,3)
#打乱这10000条数据
np.random.shuffle(data_train)
#定义批量大小
batch_size=100
#进行批处理
for i in range(0,len(data_train),batch_size):
x_batch_sum=np.sum(data_train[i:i+batch_size]) # 批处理数据集
print("第{}批次,该批次的数据之和:{}".format(i,x_batch_sum))
通用函数
广播机制
与numpy 相似,可以是零维,多维数组,并共享内存,区别就是Tensor 可以放到GPU 中加速计算。
针对 Tensor 的操作,按照接口划分:
针对修改方式:
x=torch.tensor([1,2])
y=torch.tensor([3,4])
z=x.add(y)
print(z)
print(x)
x.add_(y)
print(x)
tensor([4, 6])
tensor([1, 2])
tensor([4, 6])
函数 | 功能 |
---|---|
Tensor(*size) | 从参数中构造一个张量,支持List, Numpy数组 |
eye(row,column) | 创建指定行数,列数的二维单位Tensor |
linspace(start, end, stepes) | 等差数列 |
logspace(start,end,steps) | 从 10^start 到 10^end ,分成steps份 |
rand/randn(*size) | 生成 [0,1) 均匀分布/标准正态分布数据 |
ones/zeros/ones_likes/zeros_like/arange(start,end,step) | 都懂。。 |
from_Numpy(ndarray) | 从ndarray 创建一个Tensor |
torch.Tensor([1,2,3,4,5,6]) torch.Tensor(2,3) t=torch.Tensor([[1,2,3],[4,5,6]]) t.size(),t.shape # shape 与 size 等价 >>> (torch.Size([2, 3]), torch.Size([2, 3])) torch.Tensor(t.size()) # 根据已有形状创建 >>> tensor([[0., 0., 0.], [0., 0., 0.]]) # torch.Tensor and torch.tensor 的区别 t1 = torch.Tensor(1) t2= torch.tensor(1) print(t1,t1.type(),t2,t2.type()) # Tensor使用默认的dtype(FloatTensor) .tensor从数据中推断类型 >>> tensor([7.3447e-16]) torch.FloatTensor tensor(1) torch.LongTensor # tensor(1)返回一个固定值1,而Tensor() 返回的是大小为 1 的随机张量
函数 | 说明 |
---|---|
size() | 返回张量的 shape 值与函数,shape 等价 |
numel(input) | 计算Tensor 的元素个数 |
view(*shape) | 修改Tensor 的shape,与 Reshape类似,返回的对象与原Tensor 共享内存,修改一个都会修改。Reshape 就是生成一个新对象,而且不要求 原Tensor是连续的,View(-1) 展平数组 |
resize | 类似于view,但在 size 超出时重新分配内存。 |
item | 若Tensor是单元素,返回python 的标量 |
unsqueeze | 在指定维度加个1 |
squeeze | 在指定维度压缩一个1 |
x = torch.randn(2, 3) x.size() >>> torch.Size([2, 3]) #查看x的维度 x.dim() #结果为2 #把x变为3x2的矩阵 x.view(3,2) #把x展平为1维向量 y=x.view(-1) y.shape >>> torch.Size([6]) #添加一个维度 z=torch.unsqueeze(y,0) #查看z的形状 z.size() #结果为torch.Size([1, 6]) #计算Z的元素个数 z.numel() #结果为6
torch.view and torch.reshape 的区别:
索引操作与numpy类似,一般来说 索引结果与源数据共享内存。索引还可以通过一些函数
函数 | 说明 |
---|---|
index_select(input, dim, index) | 在指定维度上选择一些行或列 |
nonzero(input) | 获取非 0 元素的下标 |
masked_select(input, mask) | 使用二元值进行选择 |
gather( input, dim ,index) | 在指定维度上选择数据,输出的形状与 Index(LongTensor类型) 一致。 |
scatter_(input, dim, index, src) | gather 的反操作,根据指定索引补充数据 |
torch.manual_seed(100) # 一个随机种子 x = torch.randn(2,3) x >>> tensor([[ 0.3607, -0.2859, -0.3938], [ 0.2429, -1.3833, -2.3134]]) x[1,1:] # >>> tensor([-1.3833, -2.3134]) x[:,-1] # >>> tensor([-0.3938, -2.3134]) mask=x>0 # 生成是否大于零的 Byter 张量 # tensor([[ True, False, False], mask # [ True, False, False]]) torch.masked_select(x,mask) # >>> tensor([0.3607, 0.2429]) 大于零的值 torch.nonzero(mask) # tensor([[0, 0], # 非零下标,就是行,列的索引。 # [1, 0]]) torch.index_select(x,1,torch.tensor([0,2])) # 指定维度的跨行索引。。 >>> tensor([[ 0.3607, -0.3938], [ 0.2429, -2.3134]]) #获取指定索引对应的值,输出根据以下规则得到 #out[i][j] = input[index[i][j]][j] # if dim == 0 对行的操作 #out[i][j] = input[i][index[i][j]] # if dim == 1 对列的操作,,啥玩意。。 index=torch.LongTensor([[0,1,1],[1,1,1]]) a=torch.gather(x,1,index) a >>> tensor([[ 0.3607, -0.2859, -0.2859], [-1.3833, -1.3833, -1.3833]]) #把a的值返回到一个2x3的0矩阵中 z=torch.zeros(2,3) torch.scatter(z,1,index,a) # 顶层没有scratter_() 方法 z.scatter_(1,index,a) >>> tensor([[ 0.3607, -0.2859, 0.0000], # 对指定索引补充数据,,这又是啥。。 [ 0.0000, -1.3833, 0.0000]])
torch.gather 脑补连接
语言处理中,给每个单词上一个标签,现在我们有四个句子(由单词标签构成的不同长度的句子):
input = [
[2, 3, 4, 5],
[1, 4, 3],
[4, 2, 2, 5, 7],
[1]
]
进行填充,padding
input = [
[2, 3, 4, 5, 0, 0],
[1, 4, 3, 0, 0, 0],
[4, 2, 2, 5, 7, 0],
[1, 0, 0, 0, 0, 0]
]
现在要从填充后的input 中选出最后一个单词的标签。
input = [ [2, 3, 4, 5, 0, 0], [1, 4, 3, 0, 0, 0], [4, 2, 2, 5, 7, 0], [1, 0, 0, 0, 0, 0] ] input = torch.tensor(input) # 在指定维度上选择数据,输出的形状与 Index(LongTensor类型) 一致。 #注意index的类型 , # 将input的第i维的大小更改为y,且要满足y>=1(除了第i维之外的其他维度,大小要和input保持一致) length = torch.LongTensor([[3],[2],[4],[0]]) # 学废了吗 out = torch.gather(input, 1, length) out tensor([[5], [3], [7], [1]]) length = torch.LongTensor([[3,0],[2,0],[4,0],[0,0]]) out = torch.gather(input, 1, length) out tensor([[5, 2], [3, 1], [7, 4], [1, 1]]) length = torch.LongTensor([[2,3]]) # 前两行的第三个,第四个元素 out = torch.gather(input, 0, length) out tensor([[4, 0]])
torch.scatter 脑部链接
就是把input数组中的数据进行重新分配。index中表示了要把原数组中的数据分配到output数组中的位置,如果未指定,则填充0。就是index 中的是index 中元素在 output 中的位置。
不一定所有的input数据都会分到output中,output也不是所有位置都有对应的input,当output中没有对应的input时,自动填充0。
一般scatter用于生成onehot向量,
index = torch.tensor([[1], [2], [0], [3]])
onehot = torch.zeros(4, 4)
onehot.scatter_(1, index, 1)
print(onehot)
tensor([[0., 1., 0., 0.],
[0., 0., 1., 0.],
[1., 0., 0., 0.],
[0., 0., 0., 1.]])
A = np.arange(0, 40,10).reshape(4, 1) B = np.arange(0, 3) #把ndarray转换为Tensor A1=torch.from_numpy(A) #形状为4x1 B1=torch.from_numpy(B) #形状为3 print(A1.shape,B1.size()) #Tensor自动实现广播 C=A1+B1 # torch.Size([4, 1]) torch.Size([3]) -> 4,3 print(C) #我们可以根据广播机制,手工进行配置 #根据规则1,B1需要向A1看齐,把B变为(1,3) B2=B1.unsqueeze(0) #B2的形状为1x3 #使用expand函数重复数组,分别的4x3的矩阵 A2=A1.expand(4,3) B3=B2.expand(4,3) #然后进行相加,C1与C结果一致 C1=A2+B3 print(C1) >>> torch.Size([4, 1]) torch.Size([3]) tensor([[ 0, 1, 2], [10, 11, 12], [20, 21, 22], [30, 31, 32]], dtype=torch.int32) tensor([[ 0, 1, 2], [10, 11, 12], [20, 21, 22], [30, 31, 32]], dtype=torch.int32)
大多逐元素操作与numpy 类似,如果需要就地操作,可以在后面加个下划线 add_()
函数 | 说明 |
---|---|
abs/add | 绝对值,加法 |
addcdiv( t,v,t1, t2) | t1 ,t2 按元素除后,乘 v 加 t 。 |
addcmul( t, v, t1, t2) | t1,t2 按元素乘后,乘v 加 t |
ceil /floor | 向上取整,向下取整 |
clamp(t, min, max) | 将张量元素限制在指定区间 |
exp/log/pow | 指数,对数,幂 |
mul or * /neg | 逐元素乘法/ 取反 |
sigmoid/tanh/softmax | 激活函数,,专业 |
sign/sqrt | 取符号,开根 |
感受到了np 之处。。
t = torch.randn(1, 3)
t1 = torch.randn(3, 1)
t2 = torch.randn(1, 3)
#t+0.1*(t1/t2)
torch.addcdiv(t, 0.1, t1, t2)
#计算sigmoid
torch.sigmoid(t)
#将t限制在[0,1]之间
torch.clamp(t,0,1)
#t+2进行就地运算
t.add_(2)
对输入进行归并或合计等操作。。归并操作可以针对整个 Tensor or 针对某一个 axis
函数 | 说明 |
---|---|
cumprod(t, axis) | 累积 |
cumsum | 累加 |
dist(a,b,p=2) | 返回a,b 之间的 p 阶范数(二阶就是距离吧) |
mean/median | 均值/中位数 |
std/var | 标准差/方差 |
norm(t,p=2) | t 的 p 阶范数 |
prod(t)/sum(t) | t 中所用元素的积/和 |
归并操作一般有一个 dim 参数,指定在那个维度进行归并,keepdim 决定是否要保留维度1.默认不保留
a=torch.linspace(0,10,6)
a=a.view((2,3))
#沿y轴方向累加,即dim=0
b=a.sum(dim=0) #b的形状为[3] ,等于 a.sum(axis=0) 对列操作
>>> tensor([ 6., 10., 14.])
#沿y轴方向累加,即dim=0,并保留含1的维度
b=a.sum(dim=0,keepdim=True) #b的形状为[1,3]
>>>tensor([[ 6., 10., 14.]])
一般是逐元素比较,有些是按指定方向比较
函数 | 说明 |
---|---|
eq | 比较Tensor 是否相等 |
equal | 比较两个Tensor s是否有相同的shape与值 |
ge/le/gt/lt | 大于/小于 / 大于等于/小于等于 |
max/min(t,axis) | 最值,指定axis 额外返回下标 |
topk(t,k,axis) | 指定axis 维上取最高的K 个值 |
x=torch.linspace(0,10,6).view(2,3) #求所有元素的最大值 torch.max(x) #结果为10 #求y轴方向的最大值 torch.max(x,dim=0) #结果为[6,8,10] >>> torch.return_types.max( values=tensor([ 6., 8., 10.]), # 专业 indices=tensor([1, 1, 1])) #求最大的2个元素 torch.topk(x,2,dim=0) >>> torch.return_types.topk( values=tensor([[ 6., 8., 10.], [ 0., 2., 4.]]), indices=tensor([[1, 1, 1], [0, 0, 0]]))
函数 | 说明 |
---|---|
dot(t1,t2) | 内积或点积 |
mm(mat1,mat2)/bmm(batch1,batch2) | 计算矩阵乘法/含batch 的3D 矩阵乘法 |
mv(t1,t2) | 计算矩阵与向量乘法 |
svd(t) | 计算t 的SVD 分解 |
t | 转置 |
a=torch.tensor([2, 3]) b=torch.tensor([3, 4]) torch.dot(a,b) tensor(18) x=torch.randint(10,(2,3)) y=torch.randint(6,(3,4)) torch.mm(x,y) tensor([[36, 77, 81, 41], [45, 63, 69, 42]]) x=torch.randint(10,(2,2,3)) y=torch.randint(6,(2,3,4)) torch.bmm(x,y) (tensor([[[1, 8, 9], [0, 0, 6]], [[2, 4, 8], [0, 4, 3]]]), tensor([[[0, 2, 2, 0], [0, 1, 1, 5], [1, 5, 5, 0]], [[4, 2, 0, 1], [4, 5, 3, 3], [4, 0, 5, 1]]])) tensor([[[ 9, 55, 55, 40], [ 6, 30, 30, 0]], # 就是两个二维矩阵的点乘。。然后stack 堆叠起来 [[56, 24, 52, 22], [28, 20, 27, 15]]])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。