pytorch 常见函数
概率分布
torch.randn_like() 函数:返回一个与 input 形状相同的服从 N(0,1) 的张量
GPU 相关
查看 torch 的版本
1 | torch.__version__ |
查看 cuda 是否 available:
1 | torch.cuda.is_available() |
查看 GPU 数量
1 | torch.cuda.device_count() |
数据读入
从文件中读取数据是必要的操作.
从文件中读取
1 | input = open ( "D:/hw/chapter1/w4/input.txt" , "r" ) |
遍历数据每一行
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np import torch import torch.nn.functional as F input = open ( "D:/hw/chapter1/w4/input.txt" , "r" ) # 遍历 input 数据中的每一行 for line in input : # 将 line 中的每一行都以 float 的形式读入. item = [ float (i) for i in line.split()] b = torch.tensor(item) print (b) |
判断字符串是否能转换成是数字
1 2 3 4 5 6 | def is_number(s): try : float (s) return True except ValueError: return False |
构建矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import torch # 构建全 0 的 (5, 3) 矩阵 x = torch.empty( 5 , 3 ) # 构建随机数填充的 (5, 3) 矩阵 x = torch.rand( 5 , 3 ) # 定义矩阵类型为 long x = torch.zeros( 5 , 3 , dtype = torch. long ) # 直接定义 torch 矩阵 x = torch.tensor([ 5.5 , 3 ]) # 覆盖 x, 且全部元素为 0 x = x.new_zeros( 5 , 3 , dtype = torch.double) # 覆盖 x, 且全部元素为 1 x = x.new_ones( 5 , 3 , dtype = torch. long ) # 用随机数覆盖 x, 矩阵大小不发生变化. x = torch.randn_like(x, dtype = torch. float ) print (x) <br> |
基本操作
这里是一些常见的对于 的操作,如果手写的话速度会很慢而且不方便.
防止类型转换错误
1 | torch.set_default_tensor_type(torch.DoubleTensor) |
赋值
1 2 3 | # 将 y 赋值为 x y.copy_(x) |
输出第 i 列 / 行
1 2 3 4 5 | # 输出 x 的第 i 列/行 x = torch.rand( 5 , 3 ) print (x[:, 2 ]) # 输出 x 的第 3 列. print (x[ 2 , :]) # 输出 x 的第 3 行. |
改变尺寸
1 2 3 4 5 | # 改变尺寸. x = torch.randn( 4 , 4 ) y = x.view( 16 ) # y 为 x 平展的结果. z = x.view( 2 , - 1 ) # 将 x 展为 (2, k) z = x.view( - 1 , 8 ) # 将 x 展为 (k, 8) |
拼接
1 2 3 4 5 | x = torch.ones( 2 , 3 ) z = torch.zeros( 2 , 3 ) y = torch.cat([x, z], dim = 0 ) y = torch.cat([x, z], dim = 1 ) print (y) |
矩阵乘法
1 2 3 4 5 6 | # 矩阵乘法:y1, y2, y3 获取的都是 x 与 x.T 的矩阵乘法. x = torch.ones( 2 , 3 ) y1 = x @ x.T y2 = x.matmul(x.T) y3 = torch.empty( 1 , 1 ) torch.matmul(x, x.T, out = y3) |
矩阵对应元素相乘
1 2 3 4 5 6 7 8 9 10 | # 两个矩阵对应位置元素的乘积. z = torch.ones( 2 , 3 ) z1 = z * z z2 = z.mul(z) z3 = torch.rand_like(z) torch.mul(z, z, out = z3) y = torch.ones( 2 , 3 ) # 具有广播功能. y.mul_(torch.tensor([[ 2 ], [ 233 ]])) # 带有 _ 结尾的运算会直接改变矩阵. |
将 tensor 变量转为数值变量
1 2 3 4 | # item(): 将 torch 变量转换为普通数值变量 h = torch.tensor([[ 1 , 2 ], [ 3 , 4 ]]) agg = h. sum () agg_item = agg.item() |
矩阵每个位置乘/加数字
1 2 3 4 | # 给矩阵的每个位置加一个数 / 乘一个数 z = torch.ones( 2 , 3 ) z.mul_( 233 ) z.add_( - 233 ) |
numpy 和 torch 共享地址
1 2 3 4 5 | # numpy 和 torch 可以共享存储地址(即同时进行改变) t = torch.ones( 2 , 3 ) n = t.numpy() t.mul_( 233 ) # 这里 t 和 n 会被同时乘以 233 |
numpy 转为 tensor
1 2 3 4 | # numpy 转为 tensor n = np.ones(( 1 , 5 )) t = torch.from_numpy(n) # t 就变成一个 tensor 了. |
普通矩阵转为 tensor
1 2 3 4 | # 将普通数据(矩阵)转为 tensor data = [[ 1 , 2 ],[ 3 , 4 ]] x_data = torch.tensor(data) print (x_data) |
压缩数组与解压数组
dim = 0: 变为 (1, n)
dim = 1: 变为 (n, 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 将 (1, n) 或 (n, 1) 压缩成 (n) x = torch.ones( 1 , 3 ) x = torch.squeeze(x) print (x.shape) y = torch.ones( 3 , 1 ) y = torch.squeeze(y) print (y.shape) # dim = 0 -> (1, n) # dim = 1 -> (n, 1) z = torch.ones( 1 , 5 ) z = torch.squeeze(z) z = torch.unsqueeze(z, dim = 1 ) print (z.shape) |
交换/重排矩阵的维度
1 2 3 4 5 6 7 8 | # 可以将 3 * (2, 3) 的矩阵转为 (2, 3) * 3 的矩阵. x = torch.tensor( [[[ 2 , 2 , 2 ], [ 2 , 2 , 2 ]], [[ 1 , 1 , 1 ], [ 1 , 1 , 1 ]], [[ 3 , 3 , 3 ], [ 3 , 3 , 3 ]]]) x = x.permute( 1 , 2 , 0 ) for i in range ( 2 ) : for j in range ( 3 ): print (x[i][j][ 0 ], x[i][j][ 1 ], x[i][j][ 2 ]) |
将 numpy 数据保存到文件中
1 2 3 4 5 6 7 8 9 10 11 12 | np.savez( 'e.npz' , ep = iep, train_loss = itrain_loss, test_acc = itest_acc) e = np.load( 'e.npz' ) h = np.load( 'h.npz' ) ep = e[ 'ep' ] train_loss = e[ 'train_loss' ] test_acc = e[ 'test_acc' ] |
保存网络框架
1 2 | torch.save(net, './net' ) net = torch.load( './net' ) |
梯度计算
手写反向传播过程是深度学习中最困难的过程之一,极易出错而且不好写。
pytorch 威力最大之处就是提供自动计算梯度的功能,可以极大方便反向传播的构建。
追踪梯度
1 2 3 4 5 6 7 8 9 10 11 | # requires_grad = True: 要求追踪 w 的梯度 # s.backward(): 由最后的变量向后传播. x = torch.ones( 5 ) # input tensor y = torch.zeros( 3 ) # expected output w = torch.randn( 5 , 3 , requires_grad = True ) b = torch.randn( 3 , requires_grad = True ) z = torch.matmul(x, w) + b p = z. sum () p.backward() # print(w.grad) # 得到 w 中每一个元素相对于 p 的梯度. |
将变量从计算图中移除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 将 z 从计算图中移除掉. # 法一 z = torch.matmul(x, w) + b print (z.requires_grad) with torch.no_grad(): z = torch.matmul(x, w) + b print (z.requires_grad) # 发现 z 并不在计算图中了. # 法二 z = torch.matmul(x, w) + b z_det = z.detach() print (z_det.requires_grad) # z 从计算图中脱落了. |
深度学习框架
提供了可以直接调用的深度学习框架,速度和准确率都很高.
损失函数
CrossEntropyLoss
交叉熵函数,这里注意训练样本不能用 one - hot 表示,要直接存入结果
参数初始化
高斯初始化
这里 是正态分布均值, 是正态分布标准差
1 | torch.nn.init.normal_( self .hidden.weight, mean = 0 , std = 1 ) |
均匀分布
分别为均匀分布的下界和上界
1 | torch.nn.init.uniform_(x, a = - 100 , b = 100 ) |
Xavier均匀分布初始化
1 | torch.nn.init.xavier_normal_(tensor, gain = 1.0 ) |
Xavier正态分布初始化
1 | torch.nn.init.xavier_normal_(tensor, gain = 1.0 ) |
kaiming正态分布初始化
原则上只能配合 函数使用
1 | torch.nn.init.kaiming_normal_(tensor, a = 0 , mode = 'fan_in' , nonlinearity = 'leaky_relu' ) |
正则化
为了防止过拟合,可以加入 正则化:
1 | optimizer = torch.optim.Adam([{ "params" :net.hidden.weight, 'weight_decay' : wd}], lr = 0.01 ) |
框架默认是不进行正则化的,这里要正则化的矩阵是 矩阵,.
回归问题
基本框架:
意味着继承 中的属性并在起之上进行修改.
1 2 3 4 5 6 7 8 9 10 11 | class Net(torch.nn.Module): def __init__( self , n_feature, n_hidden, n_out): super (Net, self ).__init__() self .hidden = torch.nn.Linear(n_feature, n_hidden) self .predict = torch.nn.Linear(n_hidden, n_out) def forward( self , X): X = F.relu( self .hidden(X)) X = self .predict(X) return X |
调用函数:
1 2 3 4 5 6 7 8 9 10 | step = 2002 net = Net(n_feature = 1 , n_hidden = 10 , n_out = 1 ) # 构建神经网络 optimizer = torch.optim.SGD(net.parameters(), lr = 0.2 ) # 选择梯度下降算法和学习率 loss_func = torch.nn.MSELoss() # 选择损失函数种类 for st in range ( 1000 ): out = net(x) loss = loss_func(out, y) optimizer.zero_grad() # 梯度清空 loss.backward() # 开始反向传播 optimizer.step() # 按照梯度更新参数 |
CNN
基础知识
设原图为 , 过滤器为 , 填充为 , 步长为
则有新图 , 且一般过滤器长度为奇数.
流程:卷积 -> 激活函数激活 -> 池化 -> 下一轮卷积...... -> 平展为向量并连向全连接神经网络
基本框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class CNN(nn.Module): def __init__( self ): super (CNN, self ).__init__() self .conv1 = nn.Sequential( # input shape (209, 3, 64, 64) nn.Conv2d( in_channels = 3 , out_channels = 5 , kernel_size = 4 , # filter size stride = 2 , # filter step padding = 1 , # 填充大小. ), # output shape (209, 5, 32, 32) nn.ReLU(), # activation nn.MaxPool2d(kernel_size = 2 ), # 在 2x2 空间里向下采样, output shape (5, 16, 16) ) self .conv2 = nn.Sequential( # input shape (209, 5, 16, 16) nn.Conv2d( 5 , 32 , 5 , 1 , 0 ), # out shape (209, 32, 12, 12) nn.ReLU(), nn.MaxPool2d( 2 ), # output shape (209, 32, 6, 6) ) self .out = nn.Linear( 32 * 6 * 6 , 2 ) # fully connected layer, output 2 classes def forward( self , x): x = self .conv1(x) x = self .conv2(x) x = x.view(x.size( 0 ), - 1 ) # 展平多维的卷积图成 (209, 32 * 6 * 6) output = self .out(x) return output |
例:吴恩达第 3 次课程作业.
训练数据正确率达到 % 的时候测试准确率达到了 %,对于二维图片的识别率非常好.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import torch import numpy as np import torch.nn.functional as F import torch.nn as nn import torchvision from lr_utils import load_dataset torch.set_default_tensor_type(torch.DoubleTensor) def debug(a, b): print ( "训练次数 " + str (a) + ": " + str (b)) def trans_torch(a, b, c, d): return torch.from_numpy(a), torch.from_numpy(b), torch.from_numpy(c), torch.from_numpy(d) class CNN(nn.Module): def __init__( self ): super (CNN, self ).__init__() self .conv1 = nn.Sequential( # input shape (209, 3, 64, 64) nn.Conv2d( in_channels = 3 , out_channels = 5 , kernel_size = 4 , # filter size stride = 2 , # filter step padding = 1 , # 填充大小. ), # output shape (209, 5, 32, 32) nn.ReLU(), # activation nn.MaxPool2d(kernel_size = 2 ), # 在 2x2 空间里向下采样, output shape (5, 16, 16) ) self .conv2 = nn.Sequential( # input shape (209, 5, 16, 16) nn.Conv2d( 5 , 32 , 5 , 1 , 0 ), # out shape (209, 32, 12, 12) nn.ReLU(), nn.MaxPool2d( 2 ), # output shape (209, 32, 6, 6) ) self .out = nn.Linear( 32 * 6 * 6 , 2 ) # fully connected layer, output 2 classes def forward( self , x): x = self .conv1(x) x = self .conv2(x) x = x.view(x.size( 0 ), - 1 ) # 展平多维的卷积图成 (209, 32 * 6 * 6) output = self .out(x) return output X, Y, tx, ty , classes = load_dataset() X, Y, tx, ty = trans_torch(X, Y, tx, ty) X , tx = X.permute( 0 , 3 , 1 , 2 ) / 255 , tx.permute( 0 , 3 , 1 , 2 ) / 255 Y = torch.squeeze(Y) ty = torch.squeeze(ty) # CNN 卷积神经网络: 达到了非常高的检测效果. cnn = CNN() optimizer = torch.optim.SGD(cnn.parameters(), lr = 0.03 ) loss_func = nn.CrossEntropyLoss() step = 4000 for i in range (step): output = cnn(X) loss = loss_func(output, Y) optimizer.zero_grad() loss.backward() optimizer.step() if i % 100 = = 0 : cc = 0 for j in range ( 209 ): cur = 0 if output[j][ 1 ] > output[j][ 0 ]: cur = 1 if cur = = Y[j]: cc + = 1 debug(i + 1 , cc / 209 * 100 ) cc = 0 outt = cnn(tx) for j in range ( 50 ): cur = 0 if outt[j][ 1 ] > outt[j][ 0 ]: cur = 1 if cur = = ty[j]: cc + = 1 print ( "测试数据 " + str (i + 1 ) + ": " + str (cc * 2 )) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY