1.张量创建及转化
import torch
import numpy as np
#初始化张量的几种方法
#可用python自带列表创建一个张量
t = torch.tensor([1, 2 , 3])
t.dtype
t = torch.floattensor([1.1, 2 , 3])#float32
t = torch.longtensor([1.1, 2 , 3]) #int64
#也可从array转化为tensor
np_array = np.arange(12).reshape(3, 4)
t = torch.from_numpy(np_array)
t = torch.tensor([1, 2 , 3], dtype=torch.float32)#也可指定类型
2.
import torch
import numpy as np
#创建随机值.都为tensor
torch.arange(2, 3)
#创建标准正态分布随机数
t = torch.randn(2, 3)
#创建全零,一
torch.zeros(2, 3)
torch.ones(2, 3)
#创建一个和输入张量相同类型的全零张量
x = torch.zeros_like(t)
#返回t的形状
t.size()
t.shape
#在哪里运行
t.device
#显存是否可用,讲t的计算转到显存上
if torch.cuda.is_available():
t = t.to('cuda')
#张量转换数据类型
t.type(torch.float16)
3.张量运算
#运算,规则与矩阵相同
t+3
t+x
t.add(x) #t的值未改变
t.add_(x) #t的值被覆盖,节省内存
t.T #转置
#矩阵乘法
t.matmul(t.T)
t@(t.T) #矩阵乘法的简便写法
t.num()
result = t.num().item() #将维度为0的tensor转变为数据类型。这里从tensor变为了float32
#将t1从tensor重新改为ndarray格式
t1 = torch.from_numpy(np.random.randn(3, 5))
t1.numpy() #ndarray格式
4.张量变形与自动微分
import torch
import numpy as np
t = torch.randn(3, 8)
#转化形状
t1 = t.view(4,6)
t.view(-1,1) #展开为24的维度为1的形状
#展平
x = torch.randn(12,3,4,5)#12张图,长宽为3*4,通道为5,4维
x1 = x.view(12,3*4*5) #由4维数据变为2维
x1 = x1.view(1,12,60) #view也可添加维度
x2 = torch.squeeze(x1) #squeeze可去掉为1的维度
#是否跟踪t这个张量的所有计算,true,false
t.requires_grad
#设置一个二维全为1的张量t,跟踪其梯度变化。注意:True要大写
t = torch.ones(2,2,requires_grad= True)
y = t+5
y.grad_fn
print(y)#可看到y的梯度变化
z = y*2
out = z.mean() #会返回一个标量均值
out.backward()#自动微分
t.grad #打印出t的梯度 d(out)/d(t)
t.grad_fn #因为t是创建出来的,所以没有方法
out.grad_fn #out是通过mean运算得到的。就有
#当不想跟踪t的梯度时
with torch.no_grad() :
y = t+2
print(y.requires_grad)
#也可以直接设置为false
t.requires_grad_(False) #加的_表示直接改变t的状况
#还可以用detach
results = out.detach()
5.实例 收入数据集(可与之前那个线性回归的例子详细比较)
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.read_csv('C:\\Users\\qjjt\\Desktop\\python\\dataset\\part2\\Income1.csv')
print(data)
from torch import nn
X = torch.from_numpy(data.Education.values.reshape(-1, 1).astype(np.float32))
Y = torch.from_numpy(data.Income.values.reshape(-1, 1).astype(np.float32))
#初始化w和b
w = torch.randn(1,requires_grad=True) #因为w要优化,所以跟踪其梯度变化。w就是一个系数,所以为1维
b = torch.randn(1,requires_grad=True)
#模型公式w@x+b
learing_rate = 0.0001#学习率
for epoch in range(5000):
#同时对x,y进行迭代,保证一一对应
for x, y in zip(X, Y):
#以前是直接调用已有的线性回归模型,现在是自己写公式
y_pred = x@w+b
loss = (y- y_pred).pow(2).mean() #差的平方求均值
#在计算梯度时记得先置零,因为梯度会累计
if not w.grad is None:
w.grad.data.zero_() #使w的梯度直接变为0
if not b.grad is None:
b.grad.data.zero_()
loss.backward() #计算变量与输出间的梯度,这一步计算了w和b的grad值
with torch.no_grad(): #使loss下降,随机梯度下降
w.data -= w.grad.data *learing_rate #梯度下降更新w值
b.data -= b.grad.data * learing_rate
print(w,b) #与之前模型计算十分相似
plt.scatter(data.Education, data.Income)
plt.plot(X.numpy(), (X@w+b).data.numpy(), c='r')
plt.show()