1 问题
1.问题1:为什么需要if __name__ == '__main__':?
2.问题2: 如果tensor有多个值比如x,如何转移x到cpu上
3.问题3: 探索其他指标的实现方法,例如precision, recall, f1-score?
2 方法
问题1:为什么需要if __name__ == '__main__':?
if__name__ == '__main__':的作用一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。__name__ == '__main__' 就表示在当前文件中,可以在if __name__ == '__main__':条件下写入测试代码,如此可以避免测试代码在模块被导入后执行。
问题2: 如果tensor有多个值比如x,如何转移x到cpu上
Tensor的含义Tensor,又名张量。如果一个物理量,在物体的某个位置上只是一个单值,那么就是普通的标量,比如密度。如果它在同一个位置、从不同的方向上看,有不同的值,而且这个数恰好可以用矩阵乘观察方向来算出来,就是张量。几何代数中定义的张量是基于向量和矩阵的推广,通俗一点理解的话,我们可以将标量视为零阶张量,矢量视为一阶张量,那么矩阵就是二阶张量。Tensor转换Torch定义了七种CPU tensor类型和八种GPU tensor类型。从工程角度来讲,可简单地认为它就是一个数组,且支持高效的科学计算。它可以是一个数(标量)、一维数组(向量)、二维数组(矩阵)和更高维的数组(高阶数据)。Tensor可以存放在不同的device(cpu/gpu):cpu –> gpu,使用data.cuda()。gpu –> cpu,使用data.cpu()。
例如
import torch
# 创建一个张量
tensor = torch.randn(3, 3) # 一个3x3的随机张量
# 将张量移动到 CPU
tensor_on_cpu = tensor.to('cpu')
# 检查移动后的设备
print(tensor_on_cpu.device)
问题3: 探索其他指标的实现方法,例如precision, recall, f1-score?
1.精确度(Precision):精确度是指被分类为正类别的样本中实际为正类别的比例。精确度可用于衡量模型在正类别上的准确性。
2.召回率(Recall):召回率是指实际为正类别的样本中被正确分类为正类别的比例。召回率可用于衡量模型对正类别样本的覆盖程度。
例如
from sklearn.metrics import precision_score, recall_score, f1_score
true_labels = [1, 0, 1, 1, 0, 0]
predicted_labels = [1, 1, 1, 0, 0, 1]
precision = precision_score(true_labels, predicted_labels, average='weighted')
recall = recall_score(true_labels, predicted_labels, average='weighted')
f1 = f1_score(true_labels, predicted_labels, average='weighted')
print(f'Precision: {precision}')
print(f'Recall: {recall}')
print(f'F1 Score: {f1}')
import torch import matplotlib.pyplot as plt from torch.optim import SGD from torch import nn from torchvision import datasets from torchvision.transforms import ToTensor from torch.utils.data import DataLoader #问题1:为什么需要if __name__ == '__main__':?? if __name__ == '__main__': device = ( 'cuda' if torch.cuda.is_available() else 'cpu' ) print(device) train_ds = datasets.MNIST( root='data', # 数据集下载的路径 download=True, train=True, # True表示训练集 False表示测试集 transform=ToTensor(), # ToTensor()对象, 转换 ) test_ds = datasets.MNIST( root='data', download=True, train=False, transform=ToTensor(), ) batch_size = 256 train_dataloader = DataLoader( dataset=train_ds, # 对哪个数据集进行切分 batch_size=batch_size, num_workers=8, ) test_dataloader = DataLoader( dataset=test_ds, batch_size=batch_size, num_workers=8, # 可选参数, ) class MyNet(nn.Module): def __init__(self): super().__init__() self.fc1 = nn.Linear( in_features= 784, # 前一层的神经元个数 out_features= 512, # 当前层的神经元个数 ) self.fc2 = nn.Linear( in_features=512, out_features=10, ) def forward(self, x): x = torch.flatten(x, start_dim=1) # 向上方向键 [32, 784] x = self.fc1(x) out = self.fc2(x) return out net = MyNet().to(device) loss_fn = nn.CrossEntropyLoss() optimizer = SGD(net.parameters(), lr=1e-3) losses = [] def train(dataloader, net, loss_fn, optimizer): batch_num = len(dataloader) net.train() for batch_index, (X,y) in enumerate(dataloader): X, y = X.to(device), y.to(device) pred = net(X) loss = loss_fn(pred, y) loss.backward() optimizer.step() optimizer.zero_grad() losses.append(loss.item()) if batch_index % 100 == 0: print(f'[{batch_index+1:>3d}/{batch_num}] loss: {loss.item()}') epoch_num = 1 for t in range(epoch_num): print(f'Epoch {t+1}/{epoch_num}') train(train_dataloader, net, loss_fn, optimizer) # 测试网络 def test(dataloader, net, loss_fn): size = len(dataloader.dataset) correct = 0 net.eval() for batch_idx, (X,y) in enumerate(dataloader): X,y = X.to(device), y.to(device) pred = net(X) batch_correct = (pred.argmax(1) == y).type(torch.float).sum().item() correct += batch_correct #问题2: 如果tensor的shape不是1,那么怎么转移到CPU呢? acc = correct / size print(f'Accurac: {acc}') # 问题3: 探索其他指标的实现方法,例如precision, recall, f1-score test(test_dataloader, net, loss_fn) |
输出:

3 结语
本次对实验中出现if __name__ == '__main__'报错的相关问题,知道了该代码只有在py文件作为脚本直接执行时才会被执行,而 import 到其他脚本中是不会被执行的,所以在调用脚本时需要输入调用。对于tensor转移到CPU上运行,对于单个张量可直接进行转移,多个张量可采用循环或列表推导式。关于提升MNIST数据集的准确率涉及到使用更复杂的模型、调整超参数、数据增强等方法。了解如何在 PyTorch 中实现训练和测试循环,包括使用交叉熵损失函数和随机梯度下降(SGD)优化器;如何在测试阶段计算准确率,并进一步学习如何计算其他指标,如精确度、召回率和 F1 分数,以综合评估模型性能。