file-type

PyTorch中torch.max与F.softmax函数的维度解析

版权申诉

PDF文件

5星 · 超过95%的资源 | 91KB | 更新于2024-09-14 | 33 浏览量 | 5 评论 | 1 下载量 举报 收藏
download 限时特惠:#14.90
在PyTorch中,`torch.max`和`F.softmax`是两个非常重要的张量操作函数,它们在神经网络计算和模型训练中起着关键作用。本文将深入探讨这两个函数的用法,特别是关于维度参数的理解。 `torch.max`函数用于找到张量中的最大值。它有两种模式:返回最大值(values)和对应的索引(indices)。当设置`dim`参数时,可以指定在哪个维度上进行最大值查找。例如,在二维张量中,`dim=0`意味着按列找最大值,而`dim=1`则表示按行找最大值。在给出的例子中: ```python d = torch.max(input, dim=0) # 按列取max ``` 这将返回每一列的最大值和它们对应的位置。同样,`dim=1`会返回每一行的最大值。 ```python e = torch.max(input, dim=1) # 按行取max ``` `F.softmax`函数则是将输入张量的每个元素转换为其对应的概率值,使得所有元素之和为1。这个函数常用于神经网络的激活函数,特别是在分类问题中。`dim`参数决定了哪个维度上的元素被转换为概率。例如: ```python b = F.softmax(input, dim=0) # 按列SoftMax, 列和为1 c = F.softmax(input, dim=1) # 按行SoftMax, 行和为1 ``` 在二维张量中,`dim=0`意味着对每一列进行SoftMax运算,得到的b张量每一列的元素和为1。反之,`dim=1`是对每一行进行运算,使得每行元素和为1。 对于三维张量,`F.softmax`和`torch.max`的使用方式类似,只是处理的维度多了一个。假设我们有一个形状为`(3, 16, 20)`的张量`a`,如果我们希望在第三维(索引为2)上进行SoftMax或最大值查找,我们将设置`dim=2`。例如: ```python b = F.softmax(a, dim=2) # 对第三维进行SoftMax ``` 这样,我们将在第三维上得到概率分布,其他维度保持不变。 总结来说,理解`torch.max`和`F.softmax`的`dim`参数对于有效地处理张量数据至关重要。正确设置该参数可以确保在正确的维度上执行所需的操作,无论是查找最大值还是计算概率分布。在实际编程中,务必根据具体的任务需求来调整`dim`值,以确保计算结果符合预期。

相关推荐

filetype

import torch import numpy as np from matplotlib import pyplot as plt from torch.utils.data import DataLoader from torchvision import transforms from torchvision import datasets import torch.nn.functional as F """ 卷积运算 使用mnist数据集,和10-4,11类似的,只是这里:1.输出训练轮的acc 2.模型上使用torch.nn.Sequential """ # Super parameter ------------------------------------------------------------------------------------ batch_size = 64 learning_rate = 0.01 momentum = 0.5 EPOCH = 10 # Prepare dataset ------------------------------------------------------------------------------------ transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) # softmax归一化指数函数(https://blog.csdn.net/lz_peter/article/details/84574716),其中0.1307是mean均值和0.3081是std标准差 train_dataset = datasets.MNIST(root='./data/mnist', train=True, transform=transform) # 本地没有就加上download=True test_dataset = datasets.MNIST(root='./data/mnist', train=False, transform=transform) # train=True训练集,=False测试集 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) fig = plt.figure() for i in range(12): plt.subplot(3, 4, i+1) plt.tight_layout() plt.imshow(train_dataset.train_data[i], cmap='gray', interpolation='none') plt.title("Labels: {}".format(train_dataset.train_labels[i])) plt.xticks([]) plt.yticks([]) plt.show() # 训练集乱序,测试集有序 # Design model using class ------------------------------------------------------------------------------ class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = torch.nn.Sequential( torch.nn.Conv2d(1, 10, kernel_size=5), torch.nn.ReLU(), torch.nn.MaxPool2d(kernel_size=2), ) self.conv2 = torch.nn.Sequential( torch.nn.Conv2d(10, 20, kernel_size=5), torch.nn.ReLU(), torch.nn.MaxPool2d(kernel_size=2), ) self.fc = torch.nn.Sequential( torch.nn.Linear(320, 50), torch.nn.Linear(50, 10), ) def forward(self, x): batch_size = x.size(0) x = self.conv1(x) # 一层卷积层,一层池化层,一层激活层(图是先卷积后激活再池化,差别不大) x = self.conv2(x) # 再来一次 x = x.view(batch_size, -1) # flatten 变成全连接网络需要的输入 (batch, 20,4,4) ==> (batch,320), -1 此处自动算出的是320 x = self.fc(x) return x # 最后输出的是维度为10的,也就是(对应数学符号的0~9) model = Net() # Construct loss and optimizer ------------------------------------------------------------------------------ criterion = torch.nn.CrossEntropyLoss() # 交叉熵损失 optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum) # lr学习率,momentum冲量 # Train and Test CLASS -------------------------------------------------------------------------------------- # 把单独的一轮一环封装在函数类里 def train(epoch): running_loss = 0.0 # 这整个epoch的loss清零 running_total = 0 running_correct = 0 for batch_idx, data in enumerate(train_loader, 0): inputs, target = data optimizer.zero_grad() # forward + backward + update outputs = model(inputs) loss = criterion(outputs, target) loss.backward() optimizer.step() # 把运行中的loss累加起来,为了下面300次一除 running_loss += loss.item() # 把运行中的准确率acc算出来 _, predicted = torch.max(outputs.data, dim=1) running_total += inputs.shape[0] running_correct += (predicted == target).sum().item() if batch_idx % 300 == 299: # 不想要每一次都出loss,浪费时间,选择每300次出一个平均损失,和准确率 print('[%d, %5d]: loss: %.3f , acc: %.2f %%' % (epoch + 1, batch_idx + 1, running_loss / 300, 100 * running_correct / running_total)) running_loss = 0.0 # 这小批300的loss清零 running_total = 0 running_correct = 0 # 这小批300的acc清零 #保存模型 torch.save(model.state_dict(), './model_Mnist.pth') # torch.save(optimizer.state_dict(), './optimizer_Mnist.pth') def test(): correct = 0 total = 0 with torch.no_grad(): # 测试集不用算梯度 for data in test_loader: images, labels = data outputs = model(images) _, predicted = torch.max(outputs.data, dim=1) # dim = 1 列是第0个维度,行是第1个维度,沿着行(第1个维度)去找1.最大值和2.最大值的下标 total += labels.size(0) # 张量之间的比较运算 correct += (predicted == labels).sum().item() acc = correct / total print('[%d / %d]: Accuracy on test set: %.1f %% ' % (epoch+1, EPOCH, 100 * acc)) # 求测试的准确率,正确数/总数 return acc # Start train and Test -------------------------------------------------------------------------------------- if __name__ == '__main__': acc_list_test = [] for epoch in range(EPOCH): train(epoch) # if epoch % 10 == 9: #每训练10轮 测试1次 acc_test = test() acc_list_test.append(acc_test) plt.plot(acc_list_test) plt.xlabel('Epoch') plt.ylabel('Accuracy On TestSet') plt.show() # 在原始训练代码文件末尾追加以下内容(确保Net类已定义) import torch import onnx import onnxruntime as ort # 模型定义必须与训练时完全一致(此处直接使用原文件中的Net类) class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = torch.nn.Sequential( torch.nn.Conv2d(1, 10, kernel_size=5), torch.nn.ReLU(), torch.nn.MaxPool2d(kernel_size=2), ) self.conv2 = torch.nn.Sequential( torch.nn.Conv2d(10, 20, kernel_size=5), torch.nn.ReLU(), torch.nn.MaxPool2d(kernel_size=2), ) self.fc = torch.nn.Sequential( torch.nn.Linear(320, 50), torch.nn.Linear(50, 10), ) def forward(self, x): batch_size = x.size(0) x = self.conv1(x) x = self.conv2(x) x = x.view(batch_size, -1) x = self.fc(x) return x # 导出配置 ------------------------------------------------------------------ PTH_PATH = './model_Mnist.pth' ONNX_PATH = './model_Mnist.onnx' # 初始化并加载模型 model = Net() model.load_state_dict(torch.load(PTH_PATH)) model.eval() # 创建符合MNIST输入的虚拟数据(1,1,28,28) dummy_input = torch.randn(1, 1, 28, 28) # 执行导出 torch.onnx.export( model, dummy_input, ONNX_PATH, input_names=["input"], output_names=["output"], opset_version=13, dynamic_axes={ 'input': {0: 'batch_size'}, 'output': {0: 'batch_size'} } ) # 验证导出结果 ------------------------------------------------------------- def validate_onnx(): # 加载ONNX模型 onnx_model = onnx.load(ONNX_PATH) onnx.checker.check_model(onnx_model) # 对比原始模型与ONNX模型输出 with torch.no_grad(): torch_out = model(dummy_input) ort_session = ort.InferenceSession(ONNX_PATH) onnx_out = ort_session.run( None, {'input': dummy_input.numpy()} )[0] # 输出相似度验证 print(f"PyTorch输出: {torch_out.numpy()}") print(f"ONNX输出: {onnx_out}") print(f"最大差值: {np.max(np.abs(torch_out.numpy() - onnx_out))}") validate_onnx() 这是我的生成onnx的源码,请结合你上面全部的回答,生成正确的生成onnx模型的代码,和能成功转化rknn的代码

filetype

def train_encoder_at_dB(dB, report=False): """在指定SNR(dB)下训练编码器和解码器""" SNR_dB = dB SNR = 10 **(SNR_dB / 10) sigma2 = 1 / SNR # 优化器,同时优化编码器、解码器和映射器参数 opt = optim.Adam( list(enc.parameters()) + list(dec.parameters()) + list(mapper.parameters()), lr=lr ) for j in range(nepochs): # 编码器输出符号的对数概率 logits = enc(torch.tensor([1], dtype=torch.float)) # 采样符号索引 onehot = nn.functional.gumbel_softmax(logits.expand(n, -1), tau=10, hard=True) indices = torch.argmax(onehot, dim=1) # 调制过程 alphabet_t = mapper(nn.functional.one_hot(torch.arange(M), M).float()).squeeze() probs = nn.functional.softmax(logits, -1) # 计算归一化因子,确保平均功率为1 norm_factor = torch.rsqrt(torch.sum(torch.pow(torch.abs(alphabet_t), 2) * probs)) alphabet_norm = alphabet_t * norm_factor symbols = torch.matmul( onehot, torch.transpose(input=alphabet_norm.reshape(1, -1), dim0=0, dim1=1) ) # 通过AWGN信道传输 y = AWGN_channel(symbols, sigma2) # 解码过程 ll = dec(y.reshape(-1, 1)) # 损失函数:最大化互信息 (MI = H(X) - CE) # 这里最小化-(H(X)-CE)等价于最大化MI loss = -(torch.sum(-probs * torch.log(probs)) - loss_fn(ll, indices.detach())) opt.zero_grad() loss.backward() opt.step() # 定期打印训练进度 if report and j % 500 == 0: print(f'epoch {j}: Loss = {loss.detach().numpy() / np.log(2) :.4f}') # 绘制星座图 with torch.no_grad(): alphabet_t = mapper(nn.functional.one_hot(torch.arange(M), M).float()).squeeze() probs = nn.functional.softmax(logits, -1) norm_factor = torch.rsqrt(torch.sum(torch.pow(torch.abs(alphabet_t), 2) * probs)) alphabet_norm = alphabet_t * norm_factor plot_constellation(alphabet_norm, probs, SNR_dB) return loss 运行之后显示: --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) /tmp/ipykernel_10992/2075127474.py in <module> 23 24 # 计算学习到的GeoPCS的互信息 ---> 25 mi_gcs.append(-2 * (train_encoder_at_dB(snrdB, report=True)).detach().numpy().tolist() / np.log(2)) 26 27 # 预定义的参考结果(Learnt PCS) /tmp/ipykernel_10992/2871997838.py in train_encoder_at_dB(dB, report) 44 norm_factor = torch.rsqrt(torch.sum(torch.pow(torch.abs(alphabet_t), 2) * probs)) 45 alphabet_norm = alphabet_t * norm_factor ---> 46 symbols = torch.matmul( 47 onehot, 48 torch.transpose(input=alphabet_norm.reshape(1, -1), dim0=0, dim1=1) RuntimeError: expected scalar type Float but found ComplexFloat

资源评论
用户头像
断脚的鸟
2025.06.20
通过具体代码示例,本文帮助读者理解了在PyTorch中如何正确选择维度。
用户头像
黄涵奕
2025.06.04
这篇文档对PyTorch中的torch.max和F.softmax函数的维度使用进行了详细解释,适合初学者阅读理解。
用户头像
thebestuzi
2025.03.17
对于PyTorch新手来说,本文是理解torch.max和F.softmax维度问题的绝佳资源。
用户头像
东方捕
2025.01.14
文档内容详实,标签精准,对理解深度学习框架中关键函数非常有帮助。
用户头像
东郊椰林放猪散仙
2024.12.28
文章以实例引导,清晰解释了torch.max和F.softmax函数在二维tensor中的维度应用。
weixin_38667403
  • 粉丝: 2
上传资源 快速赚钱