tensorboard可视化,FashionMNIST数据集上搭建网络、训练、预测
注意numpy版本不要使用2.x,否则提醒 AttributeError: `np.string_` was removed in the NumPy 2.0 release. Use `np.bytes_` instead.
安装1.x版本,查看版本
conda search numpy
安装1.24.3
conda install numpy=1.24.3
写入tensorboard,可视化图像、模型网络
# 图像可视化 writer.add_image("four_fashion_mnist_images", img_grid) #写入到指定的存放位置 # 模型网络可视化 writer.add_graph(net, images)
然后,在pycharm的本地终端——具体的conda虚拟环境,用如下命令查看可视化结果(其实 tensorboard --logdir=fit_logs 也可以)
数据分布的可视化,可能打开浏览器后无显示,刷新浏览器即可显示出来
# 数据分布可视化 writer.add_embedding(features, metadata=class_labels, label_img=images.unsqueeze(1))
整理数据、搭建模型、训练、预测、可视化的整体代码
#~~~~~~~~~~~~~~~~~~~ 1、数据准备~~~~~~~~~~~~~~~~~~~# import matplotlib import torch import torch.utils.data.dataloader as Loader import torchvision import torchvision.transforms as transforms import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.tensorboard import SummaryWriter BATCH_AIZE = 4 # 定义对数据集的预处理方式 transform = transforms.Compose( [transforms.ToTensor(), #转张量,并归一化到[0,1] transforms.Normalize((0.5,),(0.5,))]) #标准化。本案例是单通道图像,若是3通道图像写成transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)) # 准备数据集,并预处理 trainset = torchvision.datasets.FashionMNIST( #训练集 "./data", download=True, train=True, transform=transform) testset = torchvision.datasets.FashionMNIST( #测试集 "./data", download=True, train=False, transform=transform) # 加载数据集 trainloader = Loader.DataLoader(trainset, batch_size=BATCH_AIZE, shuffle=True) testloader = Loader.DataLoader(testset, batch_size=BATCH_AIZE, shuffle=False) # 具体类别 #由于数据集的标签是数字0~9,因此定义classes这个元组进行标签的映射 classes = ("T-shirt/top", "Trousers", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle Boot") #~~~~~~~~~~~~~~~~~~~ 2、模型搭建~~~~~~~~~~~~~~~~~~~# IN_CHANNELS = 1 #输入的是单通道 OUT_CHANNELS = 10 #输出的是10分类 class Net(nn.Module): # 初始化网络,并定义具体的层 def __init__(self): super(Net, self).__init__() #初始化 self.conv1 = nn.Conv2d(IN_CHANNELS, 6, 5) #卷积 self.pool = nn.MaxPool2d(2, 2) #池化 self.conv2 = nn.Conv2d(6, 16, 5) #卷积 self.fc1 = nn.Linear(16*4*4, 120) #全连接 self.fc2 = nn.Linear(120, 84) #全连接 self.fc3 = nn.Linear(84, OUT_CHANNELS) #全连接 # 具体的层的连接方式 def forward(self, x): x = self.pool(F.relu(self.conv1(x))) #先卷积,再池化 x = self.pool(F.relu(self.conv2(x))) #先卷积,再池化 x = x.view(-1, 16*4*4) x = F.relu(self.fc1(x)) #先全连接,再激活函数处理 x = F.relu(self.fc2(x)) #先全连接,再激活函数处理 x = self.fc3(x) #全连接,得到一个1*10的列向量 return x # 创建网络对象 net = Net() # 指定网络的损失函数 criterion = nn.CrossEntropyLoss() #交叉熵损失函数 # 指定网络参数的更新方式(优化器) optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) #指定优化器,随机梯度下降法 #~~~~~~~~~~~~~~~~~~~ 3、Tensorboard可视化:数据、模型网络 ~~~~~~~~~~~~~~~~~~~# writer = SummaryWriter("./fit_logs/fashion_mnist_experiment_1") #指定Tensorboard要展示的数据的存放位置 # writer = SummaryWriter() #默认路径,runs文件夹 # 随机获取1个batch训练图片 dataiter = iter(trainloader) images, labels = next(dataiter) #图像和标签。batch为4,所以一次4幅图 # 创建图像网格 img_grid = torchvision.utils.make_grid(images) #将4幅图拼成1个图像 # 图像可视化 writer.add_image("four_fashion_mnist_images", img_grid) #写入到指定的存放位置 # 模型网络可视化 writer.add_graph(net, images) # 数据分布可视化 def select_n_random(data, targets, n=100): #随机选出100个样本和对应标签 assert len(data) == len(targets) #假定图与标签一样多 perm = torch.randperm(len(data)) #生成0至len(data)-1的数,不重复,乱序 return data[perm][:n], targets[perm][:n] images ,labels = select_n_random(trainset.data, trainset.targets) class_labels = [classes[lab] for lab in labels] #数字标签对应的文本 features = images.view(-1, 28*28) #二维矩阵展平成一维 writer.add_embedding(features, metadata=class_labels, label_img=images.unsqueeze(1)) #label_img应该是N*C*H*W的张量,本案例是灰度图是N*H*W的,所以用unsqueeze扩充第1维。NCHW分别是第0~3维 #~~~~~~~~~~~~~~~~~~~ 4、Tensorboard可视化:训练模型 ~~~~~~~~~~~~~~~~~~~# import matplotlib.pyplot as plt import numpy as np matplotlib.use('TkAgg') # 输出预测标签和对应的概率 def images_to_probs(net, images): output = net(images) #对样本进行预测 _, preds_tensor = torch.max(output, 1) #得到最大预测概率的标签 preds = np.squeeze(preds_tensor.numpy()) return preds, [F.softmax(el, dim=0)[i].item() for i, el in zip(preds, output)] # 绘制1个batch的图像预测结果,对的标题为绿色,错的为红色 def plot_classes_preds(net, images, labels): preds, probs = images_to_probs(net, images) #标签和概率 fig = plt.figure(figsize=(8,2)) for idx in np.arange(4): ax = fig.add_subplot(1,4,idx+1,xticks=[],yticks=[]) img = images[idx].squeeze() img = img/2+0.5 #逆标准化,用于plt绘图显示 npimg = img.numpy() ax.imshow(npimg,cmap="Greys") ax.set_title("{0},{1:.1f}%\n(label:{2})".format( classes[preds[idx]], #预测的类别 probs[idx]*100.0, #概率 classes[labels[idx]]), #真实类别 color=("green" if preds[idx]==labels[idx].item() else "red")) return fig # 训练模型 running_loss = 0.0 print("Start training") for epoch in range(5): #训练5轮 for i,data in enumerate(trainloader,0): #每次1batch inputs, labels = data optimizer.zero_grad() #梯度置零 #forward,backward,optimize 网络训练的一般过程,进行参数更新 outputs = net(inputs) loss = criterion(outputs,labels) loss.backward() optimizer.step() running_loss += loss.item() if i%5000 == 4999: #每5000batch输出一次loss print("Epoch:%d Batch:%d Loss:%f" % (epoch+1,i+1,running_loss/5000)) #可视化loss走向图表 writer.add_scalar("training_loss",running_loss/5000,epoch*len(trainloader)+i) #可视化预测的图像 writer.add_figure("predictions vs. actuals",plot_classes_preds(net,inputs,labels),global_step=epoch*len(trainloader)+i) running_loss = 0.0 print("Finished Training") #~~~~~~~~~~~~~~~~~~~ 5、Tensorboard可视化:预测模型 ~~~~~~~~~~~~~~~~~~~# class_probs = [] class_preds = [] with torch.no_grad(): for data in testloader: images,labels = data output = net(images) #预测所有测试集样本 class_probs_batch = [F.softmax(el,dim=0) for el in output] #概率 _,class_preds_batch = torch.max(output,1) #标签 class_probs.append(class_probs_batch) #收集所有概率 class_preds.append(class_preds_batch) #收集所有标签 # 概率、标签整合进张量中 test_probs = torch.cat([torch.stack(batch) for batch in class_probs]) test_preds = torch.cat(class_preds) # 1个类的PR曲线 def add_pr_curve_tensorboard(class_index,test_probs,test_preds,global_step=0): tensorboard_labels = testset.targets == class_index #所有测试集样本是否是某一类的bool向量 tensorboard_probs = test_probs[:,class_index] #所有测试集样本预测为每个类的概率 writer.add_pr_curve(classes[class_index], tensorboard_labels, tensorboard_probs, global_step=global_step) # 可视化每个类别的PR曲线 for i in range(len(classes)): add_pr_curve_tensorboard(i, test_probs,test_preds) writer.close()