import torch
import numpy as np
#直接创建一个张量
# t = torch.tensor([1,2,3])
# print(t)
# #pytorch里面常用两种类型,float32,int64
#
t =torch.FloatTensor([1,2,3])
print(t.dtype)
#
# #默认返回int64类型
# t=torch.LongTensor([1,2])
#通过numpy转化为tensor类型
np_arry= np.arange(12).reshape(3,4)
# print(np_arry)
# t =torch.from_numpy(np_arry)
# print(t.dtype)
#可以直接指定tensor类型
# t =torch.FloatTensor([1,2,3],dtype = torch.float)
#创建随机数 创建0-1之间随机数
x=torch.rand(2,3)
# print(x)
#随机创建正态分布的数据
y = torch.randn(2,3)
#创建全0全1的
# torch.zeros([3,4])
x1=torch.ones([3,2])
#创建一个新的和某一个一样的数据,其他同理 常用于GAN
x2 = torch.ones_like(x1)
# print(x2)
#dtype 发挥类型,shape返回形状,size返回维度大小
# print(t.device)#
#将t的device转化到GPU上
# if torch.cuda.is_available():
# t = t.to('cuda')
#将t的类型进行转换
t=t.type(torch.float16)
print(t.dtype)
#long(),float() 可以直接转换 int64 和 float32
t = t.long()
print(t.dtype)
#########张量运算#########
#会广播到每一个元素 ,每个都会+3
print(t+3)
#对应位置相加
print(x1,x2)
print(x1+x2)
t.add(1) #原t不会被覆盖
t.add_(1) #会将原t覆盖
# t.abs(),t.abs_() 也是一样的
#matmul 矩阵乘法 t.T -->表示转置 t.matmul(t.T)表示t乘以t的转置
# t@(t.T) 简写
#t.sum().item()将一个维度为0的tensor t.sum()转化为python的数据类型
#将numpy类型转化为tensor
t1 = torch.from_numpy(np.random.randn(3,2))
#转化为ndarry
t1 = t1.numpy()
##############张量的变形和自动微分##############
T=torch.rand(2,3)
print(T.requires_grad)
#框架是否跟踪此张量的所有运算
s = torch.ones(2,2,requires_grad=True)
print(s.requires_grad)
S = s+5
print(S)
#tensor([[6., 6.],[6., 6.]], grad_fn=<AddBackward0>)
#grad_fn 会返回得到此张量的方法,S的requires_gurd属性仍然是True
out = S.mean() #转化成了一个标量值
#调用自动微分运算
out.backward()
print(s.grad)
#打印S的梯度,grad属性会记录计算得到的梯度 d(out)/ds
#s 没有grad_fn 因为s由torch得到的不是计算得来的
#这是一个上下文管理器
with torch.no_grad():
y1 = s+2
print(y1.requires_grad)
#这样就可以使得在某一步可以不跟踪计算
#直接改变设置
s.requires_grad_(False)
#如果在训练中不想优化某些参数就可以将requires_grad设置为False
#还可以使用detach()也可以达到不跟踪的效果
result = out.detach()
print(result.requires_grad)