任务1- 读取.txt文件画折线图(曲线图)
任务2- 将.txt文件转换成.xls(excel)文件
任务3- 将.xls(excel)文件转换成.txt文件
任务4- 读取.txt文件画折线图(曲线图)
任务5- xml格式的数据集标签文件转.txt文件
任务6- 读取两个.txt文件画折线图(曲线图)
最近在做目标检测的任务,但是由于自己训练的损失函数不是自己想要的,但是自己的程序在训练的时候每个E p o c h EpochEpoch都会生成一个模型的损失数值,所以想根据这些数值自己画图。
任务1:根据t x t txttxt文件内的数值,生成损失曲线。
t x t txttxt文件内的数据样例如下图所示:
因为我的模型训练了150次,所以这样的数据有150个,且只有一列。直接在代码里详细叙述:
#导入必须的包
import matplotlib.pyplot as plt
import numpy as np
#----------- 打开txt文件 ----------
file = open('YOLOV4.txt')
#----------- 逐行读取文件内的数据 ------------
data = file.readlines()
#----------- 根据自己的需要查看data的内容 ---------
#print(data)
'''
txt文件的数值为y轴的数据
所以x要根据y的个数有序生成
'''
#------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围) ----
x = np.arange(0,150)
#---------- 新建一个空的列表,用于存储上一步逐行读取的data ------------
y = []
#---------- 用循环的方式添加进列表 -----------
for num in data:
#------split用于将每一行数据用逗号分割成多个对象-----
#------取分割后的第0列,转换成float格式后添加到列表中-------
y.append(float(num.split(',')[0]))
#--------------- 输出图 ----------------------
#--------- 可以理解为在图上加载x和y的数据 label为关于x和y曲线的标签------------
pic = plt.plot(x,y,label='Yolov4')
#--------- x轴的小标题 -------------
plt.xlabel('Epoch')
#--------- y轴的小标题 -------------
plt.ylabel('Loss')
#--------- 整个图的标题 ----------
plt.title('yolov4-loss')
plt.legend()
plt.show()
代码关于画图的每个细节写的很详细,下面生成的折线图。
任务2- 将.txt文件转换成.xls(excel)文件
需要的同学直接复制代码,代码中注释了你需要修改的地方。
import xlwt
def txt_xls(filename, xlsname):
try:
f = open(filename, 'r', encoding='utf-8')
xls = xlwt.Workbook()
sheet = xls.add_sheet('sheet1', cell_overwrite_ok=True)
x = 0
while True:
# 按行循环,读取文本文件
line = f.readline()
if not line:
break
for i in range(len(line.split('\t'))):
item = line.split('\t')[i]
sheet.write(x, i, item)
x += 1
f.close()
# 保存xls文件
xls.save(xlsname)
except:
raise
'''
下面的地址中就是自己根据自己的需要修改的地方
为什么看上去没有路径呢?因为我是把txt文件和运行的此程序放在了同一个文件夹中
所以生成的.xls文件也在同级文件下,也就是他们在同一个文件夹中
如果你没放在一起,建议使用E://Path//...
'''
if __name__ == "__main__":
#---------- 需要转化的.txt文件 -----------
filename = "YOLOV4.txt"
#---------- 转换后的.xls文件名 -----------
xlsname = "YOLOV4.xls" # 保存及命名
txt_xls(filename, xlsname)
任务3- 将.xls(excel)文件转换成.txt文件
将. x l s .xls.xls文件转换成. t x t .txt.txt文件。
python
import pandas as pd
#---------- 如果你的.xls文件开了多个窗口文件(sheet1,sheet2,sheet3....)使用下面的代码 -----------
#df = pd.read_excel('YOLOV4.xls', sheet_name='Sheet1',header=None)
#---------- 如果你的.xls文件没有开多个窗口(没有sheet1,sheet2,sheet3....)试用下面的代码
data = pd.read_excel('YOLOV4.xls', sheet_name='Sheet1',header=None)
print('正在读取将.xls文件内容')
#---------- 写入txt文件,seq表示逗号分隔 --------------
data.to_csv('YOLOV4.txt', header=None, sep=',', index=False)
print('.xls文件转换成.txt文件成功')
任务4- 读取.txt文件画折线图(曲线图)
该任务算是任务一的进阶版,通过文件数据的转换,我的. t x t .txt.txt文件的内容不再是一列,而是两列,第一列为序号,第二列为数值,基于此种情况,读取. t x t .txt.txt文件,将其以折线图(曲线图)表示出来。
下图是我现在. t x t .txt.txt数据的图例。
可以发现和任务一数据唯一不同就是多了一列的序列号,下面的是基于任务一改进的,就是改了几行,修改后的内容以注释的形式保存。话不多说直接代码中详细介绍:
#导入必须的包
import matplotlib.pyplot as plt
import numpy as np
#----------- 打开txt文件 ----------
file = open('file2.txt')
#----------- 逐行读取文件内的数据 ------------
data = file.readlines()
#----------- 根据自己的需要查看data的内容 ---------
#print(data)
'''
txt文件的数值为y轴的数据
所以x要根据y的个数有序生成
'''
#------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围) ----
#x = np.arange(0,150)
#---------- 新建一个空的列表,用于存储上一步逐行读取的data ------------
x = []
y = []
#---------- 用循环的方式添加进列表 -----------
for num in data:
#------split用于将每一行数据用逗号分割成多个对象-----
#------x读取data数据的第一列(也就是序列号)
x.append(float(num.split(',')[0]))
#------取分割后的第0列,转换成float格式后添加到列表中-------
#------y读取data数据的第二列(也就是数值)
y.append(float(num.split(',')[1]))
#--------------- 输出图 ----------------------
#--------- 可以理解为在图上加载x和y的数据 label为关于x和y曲线的标签------------
pic = plt.plot(x,y,label='Yolov4')
#--------- x轴的小标题 -------------
plt.xlabel('Epoch')
#--------- y轴的小标题 -------------
plt.ylabel('Loss')
#--------- 整个图的标题 ----------
plt.title('yolov4-loss')
plt.legend()
plt.show()
下面是得到的折线图(曲线图),和任务一得到的一模一样。
任务5- xml格式的数据集标签文件转.txt文件
在做目标检测任务时,我们手工打的标签往往都是.xml的文件,但是对于很多的网络,标签文件都需要.txt的文件,所以需要将.xml文件转换成模型需要的.txt文件,直接下面的代码可以转换:
#------------------------------- successful ----------------------------------
import os
import xml.etree.ElementTree as ET
from decimal import Decimal
#------------------------- xml文件夹路径 ----------------------------
dirpath = 'E:\\pycharm\\py_shiyancode\\LYD-Champion-Function\\xml_origan'
#---------------------- 转换后的txt文件夹路径 ----------------------
newdir = 'E:\\pycharm\\py_shiyancode\\LYD-Champion-Function\\txt'
if not os.path.exists(newdir):
os.makedirs(newdir)
for fp in os.listdir(dirpath):
root = ET.parse(os.path.join(dirpath, fp)).getroot()
xmin, ymin, xmax, ymax = 0, 0, 0, 0
sz = root.find('size')
width = float(sz[0].text)
height = float(sz[1].text)
filename = root.find('filename').text
print(fp)
with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:
for child in root.findall('object'): # 找到图片中的所有框
sub = child.find('bndbox') # 找到框的标注值并进行读取
sub_label = child.find('name')
xmin = float(sub[0].text)
ymin = float(sub[1].text)
xmax = float(sub[2].text)
ymax = float(sub[3].text)
try: # 转换成yolov的标签格式,需要归一化到(0-1)的范围内
x_center = Decimal(str(round(float((xmin + xmax) / (2 * width)), 6))).quantize(Decimal('0.000000'))
y_center = Decimal(str(round(float((ymin + ymax) / (2 * height)), 6))).quantize(Decimal('0.000000'))
w = Decimal(str(round(float((xmax - xmin) / width), 6))).quantize(Decimal('0.000000'))
h = Decimal(str(round(float((ymax - ymin) / height), 6))).quantize(Decimal('0.000000'))
print(str(x_center) + ' ' + str(y_center) + ' ' + str(w) + ' ' + str(h))
# 读取需要的标签
if sub_label.text == 'armor':
f.write(' '.join([str(0), str(x_center), str(y_center), str(w), str(h) + '\n']))
except ZeroDivisionError:
print(filename, '的 width有问题')
任务6- 读取两个.txt文件画折线图(曲线图)
由于技术有限,只能使用最笨的方式读取每个文本的数据,然后再逐个遍历文本中的内容,将其添加进入列表内,然后画图,方法不是最优的,但是结果没问题。由于我没有之前的损失函数的文件了,所以自己手动添加进入文件几个数,作为教程。
这里需要注意:
- 如果你的t x t txttxt文本数据内只有一列,且这一列就是你要绘制图的y yy数值,则只需要将以下代码中的y 1 y1y1直接读取第0 00列就可以了,y 2 y2y2也同理,读取第0 00列(1默认为第2例)。至于x xx,你只需要根据y的个数生成1 − − l e n ( y 1 ) 1--len(y1)1−−len(y1)的数就可以画图了。(下面就是t x t txttxt文本数据内的内容,仅作为参考)
- 保持y 1 y1y1的个数与y 2 y2y2的个数一致,不然会超出x xx坐标的范围

import matplotlib.pyplot as plt
if __name__== '__main__':
# ----------- 打开txt文件(路径一定要修改成自己的路径) ----------
file1 = open('./dataloader_experience/1.txt')
file2 = open('./dataloader_experience/2.txt')
# ----------- 逐行读取文件内的数据 ------------
data1 = file1.readlines()
data2 = file2.readlines()
# ----------- 根据自己的需要查看data的内容 ---------
# print(data)
'''
txt文件的数值为y轴的数据
所以x要根据y的个数有序生成
'''
# ------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围) ----
# x = np.arange(0,150)
# ---------- 新建一个空的列表,用于存储上一步逐行读取的data ------------
x1 = []
y1 = []
y2 = []
# ---------- 用循环的方式添加进列表 -----------
for num1 in data1:
# ------split用于将每一行数据用逗号分割成多个对象-----
# ------x读取data数据的第一列(也就是序列号)
#-------建议以float类型添加,因为得到的损失值,一般都为小数
x1.append(float(num1.split(',')[0]))
# ------取分割后的第0列,转换成float格式后添加到列表中-------
# ------y读取data数据的第二列(也就是数值)
y1.append(float(num1.split(',')[1]))
for num2 in data2:
y2.append(float(num2.split(',')[1]))
# --------------- 输出图 ----------------------
# --------- 可以理解为在图上加载x和y的数据 label为关于x和y曲线的标签------------
# 根据需求变换线的格式和颜色
plt.plot(x1, y1,label= 'yolov4_loss2')
plt.plot(x1, y2, color='red', linestyle='--',label = 'yolov4_loss1')
# --------- x轴的小标题 -------------
plt.xlabel('Epoch')
# --------- y轴的小标题 -------------
plt.ylabel('Loss')
# --------- 整个图的标题 ----------
plt.title('yolov4-loss')
plt.legend()
plt.show()
结果图如下
总结:
- 如果你的数据是. t x t .txt.txt文件,数据只有一列,那么任务一就可以解决你的问题
- 如果你有. x l s .xls.xls格式的文件,你可以通过任务三将其转换成. t x t .txt.txt文件,然后通过任务一或者四解决你的问题
- 如果你将. t x t .txt.txt文件转换成. x l s .xls.xls文件,任务二可以解决你的问题
- 如果你将. x m l .xml.xml文件转换成. t x t .txt.txt文件,任务五可以解决你的问题
如果对您有用,不妨点个赞吧
版权声明:本文为qq_46497842原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。