list和tuple的最大区别就是是否可以修改,对于list而言是可变的数据类型可以进行增删改查,而tuple就是不可变的数据类型,tuple一旦被创建就不能增删改。
然后数组与list、tuple的最大区别就是:前者要求数组内的所有的数据类型一致,而后者内的元素数据类型可以不一致.
在List中存放的是元素的指针,因此一个元素需要存放指针+数据,增加了存储和消耗CPU.
numpy数组中的轴(axis):
numpy数组的某个轴,指的是:该数组的某个维度的方向,其方向从索引号由低到高。许多numpy方法或函数在调用时,常常需要指定一个关键参数“axis=X”,它表示的是沿哪个轴的方向进行运算(例如,求均值,方差等),这里的X表示的是轴的索引号(axis=0表示轴0,axis=1表示轴1,…,依此类推)。
numpy的维度与轴数一致.以维度(3,4,5)的三维数组为例,它有3个维度,因此,它的轴有3个,即”轴0“,”轴1“,”轴2“长度分别为3,4,5。
比如:
a.mean(axis=1):表示沿轴1方向求每个元素的均值.
a.mean(axis=0):表示沿着轴0方向求每个元素的均值.
a.mean的结果维度肯定是剩余轴构成的维度.
比如:图像批处理
一幅RGB图像的1个通道的数据可表示为一个(H,W)的数组,现在有3个通道,因此,一幅RGB图像可以用维度为(3,H,W)的数组来表示,而N幅图像则可以用维度为(N,3,H,W)的数组来表示。
参考:https://blog.csdn.net/caijungan/article/details/119861315
Tensors 和Numpy的n维数组是类似的.除了如此,Tensors也可以运行在GPU上或者其他硬件加速器上. 并且NumPy和Tensors之间互换的时候经常是分享内存的,因此无需有额外的拷贝开销. Tensors也是可以自动微分优化的.
Tuple/List=>np.array()=>nArray=>torch.tensor(List)/torch.from_numpy(nArray)=>Tensor:
张量操作有成千上万,这些操作都可以在GPU上运行,默认情况下,张量是在CPU上创建的.我们需要使用.to方法,蒋张量显式移动到GPU。
1.把张量移动到GPU上加速
if torch.cuda.is_available():
tensor=tensor.to("cuda")
2. 张量拼接
torch.cat([tensor,tensor,tensor],dim=1):对三个张量在1维度进行拼接.
3. 矩阵乘法和矩阵元素相乘:
# This computes the matrix multiplication between two tensors. y1, y2, y3 will have the same value
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)
# This computes the element-wise product. z1, z2, z3 will have the same value
z1 = tensor*tensor
z2 = tensor.mul(tensor.T)
z3 = torch.rand_like(z1)
tensor.mul(tensor,tensor.T,out=z3)
4. In-place operations 将结果存储到操作数中的操作称为就地操作,以_为后缀,
tensor.add_(5):在原来操作数的张量上进行修改,对每个元素加上5,然后存放在tensor张量上.
in-place操作可以节省一些内存空间,但是在计算倒数的时候,由于失去一些历史记录,会出错,因此in-place操作是不推荐的.
the torch.nn包命名空间提供了你构建自己神经网络所需要的所有块(building blocks).比如torch.nn.modules包中含有一些模块,torch.nn.functional包含有各种损失函数等.
Get Device for Training:
device = "gpu" if torch.cuda.is_available() else "cpu"
print(device)
Define the class
我们定义的类是torch.nn.Module类的子类,里面必须包含有**_ _init _ _ 方法(初始化),并且每个torch.nn.Module的子类都要在forward**方法中实现对输入数据的操作.
class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork,self).__init__()
def forward(self,x):
然后:实例化NeuralNetwork,然后把他搬到GPU上运行
model = NeuralNetwork().to(device)
print(model)
Model Parameters
神经网络中的所有层都是参数化的,有在训练过程中被优化的相关权重和偏置.使用你模型的parameters()方法和named_parameters()方法 可以访问这些参数.
print(f"Model structure: {model}\n\n")
for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")
完整的代码如下:
from tkinter import N
from turtle import forward
import torch
import torch.nn as nn
import torch.nn.modules as m
import torch.nn.functional as f
class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork,self).__init__()
self.flatten=nn.Flatten()
# nn.Sequential 是有序的模块容器.数据按照定义的顺序通过所有模块
self.linear_relu_stack=nn.Sequential(
nn.Linear(28*28,512),
nn.ReLU(),
nn.Linear(512,512),
nn.ReLU(),
nn.Linear(512,10)
)
def forward(self,x):
x=self.flatten(x)
logits=self.linear_relu_stack(x)
return logits
device = "cuda" if torch.cuda.is_available() else "cpu"
print(device)
model=NeuralNetwork().to(device)
print(model)
X=torch.rand(1,28,28,device=device)
logits=model(X)
# he logits are scaled to values [0, 1] representing the model’s predicted probabilities for each class.
#其中dim 参数决定了沿着这一维度的值加起来和为1
y_pred=torch.nn.Softmax(dim=1)(logits)
print(y_pred)
建立好了模型后,需要对模型进行训练,使模型中的权重调整到最优即优化问题.
其中在训练神经网络过程中,最经常使用的优化算法就是反向传播(back propagation).
模型中的参数会根据loss function的梯度被调整.
torch.autograd: 支持任意可计算图的自动梯度计算.
为了优化我们神经网络的权重参数,我们需要计算我们损失函数中参数的梯度,比如,我们需要固定 x 和 y x和y x和y中计算 δ l o s s δ w \frac{\delta loss}{\delta w} δwδloss和 δ l o s s δ b \frac{\delta loss}{\delta b} δbδloss
loss.backward()
print(w.grad)
print(b.grad)
Disabling Gradient Tracking
默认,对于requires_grad=True的所有张量(tensor)都会被跟踪它们的计算记录和支持梯度计算.但很多时候我们不需要做这些.比如说,我们已经训练完整个模型了,只需要把这个模型应用在一些输入数据上时,i.e. we only want to do forward computations through the network. We can stop tracking computations by surrounding our computation code with torch.no_grad()
block:
with torch.no_grad():
#这个方法块内的计算记录不会被记录.
或者同样的在张量上使用*detach()*方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-feACyDWn-1666968898096)(Pytorch.assets/image-20221028222434407-16669670768179.png)]
forward和backward的过程:
Hyperparameters
超参数是控制你模型优化速度的可变参数.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6e32shm-1666968898098)(Pytorch.assets/image-20221028223037097-166696743853513.png)]
Optimization Loop
一旦我们设置好超参,那么我们就可以训练和优化我们的模型.每一个优化循环的iteration叫做epoch
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofuoJe4q-1666968898100)(Pytorch.assets/image-20221028223213136-166696753448515-166696756380517.png)]
select the loss function and Optimizer
optimizer优化器是在torch.optim包上
定义一个优化器:
optimizer=torch.optim.SGD(model.parameters(),lr=learning_rate)
在Training Loop中,optimization happens in three steps
def train_loop(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
for batch, (X, y) in enumerate(dataloader):
# Compute prediction and loss
pred = model(X)
loss = loss_fn(pred, y)
# Backpropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
if batch % 100 == 0:
loss, current = loss.item(), batch * len(X)
print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
def test_loop(dataloader, model, loss_fn):
size = len(dataloader.dataset)
num_batches = len(dataloader)
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in dataloader:
pred = model(X)
test_loss += loss_fn(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batches
correct /= size
print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
epochs = 10
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(train_dataloader, model, loss_fn, optimizer)
test_loop(test_dataloader, model, loss_fn)
print("Done!")
Save:Pytorch模型将已经学习后的参数存放在内部状态文件夹中,叫做 state_dict ,可以用 torch.save() 方法保存.
model = models.vgg16(pretrained=True)
torch.save(model.state_dict(), 'model_weights.pth')
Load: 需要创建相同模型的实例,然后加载参数model.load_state_dict(torch.load(path)),然后再用model.eval()
model = models.vgg16() # we do not specify pretrained=True, i.e. do not load default weights
model.load_state_dict(torch.load('model_weights.pth'))
model.eval()
如果我们想要保存和加载参数和模型,那么
torch.save(model,path)
model=
https://pytorch.org/tutorials/beginner/basics/saveloadrun_tutorial.html