直接上中点
当然了,我们想要在pytorch中使用tensorboardX你需要先安装这些依赖
我在安装的过程中也遇到了一些小问题,基本上都是一些安装依赖版本的问题。
pip install tensorflow==1.13.2
因为tensorboardX是tensorflow下的一个依赖,所以安装这个需要先安装tensorflow,在安装tensorflow会一起安装上tensorboard,一起安装tensorboard的版本应该也是1.13.几的版本吧,我也记得不是很清楚,
然后安装tensorboardX
pip install tensorboardX
然后所需要的依赖就安装完成了,接下来的就是重头戏了
tensorboardX的基本可视化是非常简单的,只需要在你训练脚本中添加几行代码就可以实现,
#-------------------------------------#
# 对数据集进行训练
#-------------------------------------#
import os
import numpy as np
import time
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
from utils.config import Config
from nets.yolo_training import YOLOLoss,Generator
from nets.yolo3 import YoloBody
from matplotlib import pyplot as plt
from tensorboardX import SummaryWriter
import torchvision.models.densenet
def get_lr(optimizer):
for param_group in optimizer.param_groups:
return param_group['lr']
def plot_curve(data):
#fig = plt.figure()
plt.plot(range(len(data)), data, color='blue')
plt.legend(['value'], loc='upper right')
plt.xlabel('step')
plt.ylabel('value')
plt.show()
def fit_ont_epoch(net,yolo_losses,epoch,epoch_size,epoch_size_val,gen,genval,Epoch):
total_loss = 0
val_loss = 0
for iteration in range(epoch_size):
start_time = time.time()
images, targets = next(gen)#这里对原始的图片和框子进行了预处理
with torch.no_grad():
images = Variable(torch.from_numpy(images).cuda().type(torch.FloatTensor))
targets = [Variable(torch.from_numpy(ann).type(torch.FloatTensor)) for ann in targets]
optimizer.zero_grad()
outputs = net(images)
losses = []
for i in range(3):#这里是计算三层yolo的损失
loss_item = yolo_losses[i](outputs[i], targets)
losses.append(loss_item[0])
loss = sum(losses)
loss.backward()
optimizer.step()
# 将loss写入tensorboard,每一步都写
writer.add_scalar('Train_loss', loss, (epoch * epoch_size + iteration))
total_loss += loss
waste_time = time.time() - start_time
print('\nEpoch:'+ str(epoch+1) + '/' + str(Epoch))
print('iter:' + str(iteration) + '/' + str(epoch_size) + ' || Total Loss: %.4f || %.4fs/step' % (total_loss/(iteration+1),waste_time))
print('Start Validation')
for iteration in range(epoch_size_val):
images_val, targets_val = next(gen_val)
with torch.no_grad():
images_val = Variable(torch.from_numpy(images_val).cuda().type(torch.FloatTensor))
targets_val = [Variable(torch.from_numpy(ann).type(torch.FloatTensor)) for ann in targets_val]
optimizer.zero_grad()
outputs = net(images_val)
losses = []
for i in range(3):
loss_item = yolo_losses[i](outputs[i], targets_val)
losses.append(loss_item[0])
loss = sum(losses)
val_loss += loss
print('Finish Validation')
print('\nEpoch:'+ str(epoch+1) + '/' + str(Epoch))
print('Total Loss: %.4f || Val Loss: %.4f ' % (total_loss/(epoch_size+1),val_loss/(epoch_size_val+1)))
print('Saving state, iter:', str(epoch+1))
torch.save(model.state_dict(), 'logs/Epoch%d-Total_Loss%.4f-Val_Loss%.4f.pth'%((epoch+1),total_loss/(epoch_size+1),val_loss/(epoch_size_val+1)))
if __name__ == "__main__":
# 参数初始化
annotation_path = '2007_train.txt'
model = YoloBody(Config)#传入的是config,里边有框子和类别和输入网络的图片大小
#model输出的是构建好的所有层,包括最后18通道的卷积
# print(model)
print('Loading weights into state dict...')
model_dict = model.state_dict()
pretrained_dict = torch.load("model_data/mobilenet_v2-b0353104.pth")
pretrained_dict1 = {}
for k, v in list(pretrained_dict.items())[:-8]:
#print(k)
if np.shape(model_dict["backbone."+ k]) == np.shape(v):
pretrained_dict1["backbone."+ k] = v
#print("it ok")
# pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
model_dict.update(pretrained_dict1)
model.load_state_dict(model_dict)
print('Finished!')
# pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
# model_dict.update(pretrained_dict)
# model.load_state_dict(model_dict)
net = model
#设置gpu运行的各种参数
net = torch.nn.DataParallel(model)#加载gpu训练,括号中还有其他参数,比如指定cuda1
cudnn.benchmark = True
net = net.cuda()
# 建立loss函数一共三个,猜测因为有三个yolo层,所以要有三个损失计算
yolo_losses = []
for i in range(3):
yolo_losses.append(YOLOLoss(np.reshape(Config["yolo"]["anchors"],[-1,2]),
Config["yolo"]["classes"], (Config["img_w"], Config["img_h"])))
# 0.1用于验证,0.9用于训练
val_split = 0.1
with open(annotation_path) as f:
lines = f.readlines()
np.random.seed(10101)
np.random.shuffle(lines)
np.random.seed(None)
num_val = int(len(lines)*val_split)
num_train = len(lines) - num_val
writer = SummaryWriter(log_dir='logs', flush_secs=60)
Cuda = True
if Cuda:
graph_inputs = torch.from_numpy(np.random.rand(1, 3, Config["img_w"], Config["img_h"])).type(
torch.FloatTensor).cuda()
else:
graph_inputs = torch.from_numpy(np.random.rand(1, 3, Config["img_w"], Config["img_h"])).type(torch.FloatTensor)
writer.add_graph(model, (graph_inputs,))
if True:
lr = 1e-3
Batch_size = 8
Init_Epoch = 0
Freeze_Epoch = 14
optimizer = optim.Adam(net.parameters(),lr)
lr_scheduler = optim.lr_scheduler.StepLR(optimizer,step_size=1,gamma=0.95)
#创建一个对象,将类中的参数初始化,这个貌似属于函数的多态
gen = Generator(Batch_size, lines[:num_train],
(Config["img_h"], Config["img_w"])).generate()
gen_val = Generator(Batch_size, lines[num_train:],
(Config["img_h"], Config["img_w"])).generate()
epoch_size = num_train//Batch_size#一共的数据/每次训练的数据=一共需要训练多少次
epoch_size_val = num_val//Batch_size#测试的次数
#------------------------------------#
# 冻结一定部分训练
#------------------------------------#
# for i in model.backbone.features:
# print(i)
for param in model.backbone.features.parameters():
param.requires_grad = False
#print("11")
for epoch in range(Init_Epoch,Freeze_Epoch):
fit_ont_epoch(net,yolo_losses,epoch,epoch_size,epoch_size_val,gen,gen_val,Freeze_Epoch)
lr_scheduler.step()
这个是我自己代码的训练脚本,主要改动的地方我标注一下,你们可以从代码中找到,复制到你们的train.py中就妥了,
从代码中找到这一块代码,这一部分是初始化部分,将它放到你初始化代码区,就是没有进入for循环的代码段,首先
writer = SummaryWriter(log_dir='logs', flush_secs=60)
是初始化writer对象,参数中log_dir='logs’指的是你将tensorboardx产生的文件存放的位置,flush_secs=60是60S保存一次,
Cuda = True
if Cuda:
graph_inputs = torch.from_numpy(np.random.rand(1, 3, Config["img_w"], Config["img_h"])).type(
torch.FloatTensor).cuda()
else:
graph_inputs = torch.from_numpy(np.random.rand(1, 3, Config["img_w"], Config["img_h"])).type(torch.FloatTensor)
writer.add_graph(model, (graph_inputs,))
这段是给writer对象指定一个输入,graph_inputs 是产生一个按照pytorch要求给出的一个四维输入,然后按照add_graph方法将模型和输入进行写入文件。是不是很nice
writer.add_scalar('Train_loss', loss, (epoch * epoch_size + iteration))
然后是找到这段代码,这段代码在fit_ont_epoch函数中,你可以找一下,fit_ont_epoch这个函数是我脚本进行for循环的函数,所以可想而知,上面这行代码是放在循环迭代中的,这三个参数中Train_loss是生成图表的标题,loss就是数值,手边一堆是图表横坐标的值,这就完事了,然后你就可以开始训练你的模型了,
开始训练之后,在你的项目指定存储文件中就会产生一个
类似于这样的文件,这个文件就是在当时你指定存储位置中
就是这个代码指定的,dir不是路径的意思么,都懂。
运行了网络之后,你需要打开命令行来得到网址来查看你的训练参数,因为这个服务是在网站上进行的
打开你的命令行之后输入
>tensorboard --logdir=D:\桌面\毕业论文相
关资料\yolo3-mobilenetv3-pytorch-master\logs
当然,tensorboard --logdir=这个是固定写法,但是后边 D:\桌面\毕业论文相
关资料\yolo3-mobilenetv3-pytorch-master\logs是你存放
的路径,我存放的路径就是那个,但是你需要改成你的,然后回车之后就会出现
出现这个说明已经成功了,将我箭头指向的网站复制到浏览器中打开就是这个东东了
这个是实时监控的,随着时间推移,loss就会不断变化,但是也不是所有浏览器都能打开这个网页,我的qq浏览器就打不来,用电脑自带的ie打开的,如果打不开你可以多试几个。
运行报错
在我装了那些依赖之后第一次使用是会报错的,基本上错误的原因都是包的版本对不上号,这个你可以将问题复制到网站上查一下,都是可以解决的,可能tensorboard的版本太低,让你换一个高版本的,可会遇到past错误,这个错误是需要安装一个包future
pip install future
然后你装上了基本上就ok了
我写这篇文章的时间是2020.09.12