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()

 

posted @ 2024-10-22 18:04  夕西行  阅读(41)  评论(0编辑  收藏  举报