Python读取txt文件画Loss曲线图---txt文件转xls文件---xls文件转txt文件--xml文件转txt文件

这篇博客介绍了如何处理目标检测任务中的损失数据,包括从txt文件读取数据绘制损失曲线,txt与xls文件之间的相互转换,以及xml标签文件转为txt文件。同时,展示了如何读取两个txt文件并绘制折线图,适用于多组数据比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最近在做目标检测的任务,但是由于自己训练的损失函数不是自己想要的,但是自己的程序在训练的时候每个 E p o c h Epoch Epoch都会生成一个模型的损失数值,所以想根据这些数值自己画图。

任务1:根据 t x t txt txt文件内的数值,生成损失曲线。

t x t txt txt文件内的数据样例如下图所示:
在这里插入图片描述
因为我的模型训练了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 xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
def convert(size, box):
    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    x = x_center / size[0]
    y = y_center / size[1]
    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]
    return (x, y, w, h)
def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = open(os.path.join(xml_files_path, xml_name))
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)

        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            # b=(xmin, xmax, ymin, ymax)
            print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == "__main__":
    # 类别  txt中会取类别索引
    classes1 = ['aocao', 'cashang','huahen']
    # xml标签文件路径
    xml_files1 = r'E:\\pycharm\\py_shiyancode\\LYD-CGN\\xml_convert_txt\\Annotations'
    # txt标签文件存储路径
    save_txt_files1 = r'E:\\pycharm\\py_shiyancode\\LYD-CGN\\xml_convert_txt\\txt'
    convert_annotation(xml_files1, save_txt_files1, classes1)

任务6- 读取两个.txt文件画折线图(曲线图)

由于技术有限,只能使用最笨的方式读取每个文本的数据,然后再逐个遍历文本中的内容,将其添加进入列表内,然后画图,方法不是最优的,但是结果没问题。由于我没有之前的损失函数的文件了,所以自己手动添加进入文件几个数,作为教程。
这里需要注意:

  • 如果你的 t x t txt txt文本数据内只有一列,且这一列就是你要绘制图的 y y y数值,则只需要将以下代码中的 y 1 y1 y1直接读取第 0 0 0列就可以了, y 2 y2 y2也同理,读取第 0 0 0列(1默认为第2例)。至于 x x x,你只需要根据y的个数生成 1 − − l e n ( y 1 ) 1--len(y1) 1len(y1)的数就可以画图了。(下面就是 t x t txt txt文本数据内的内容,仅作为参考)
  • 保持 y 1 y1 y1的个数与 y 2 y2 y2的个数一致,不然会超出 x x x坐标的范围
    在这里插入图片描述

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文件,任务五可以解决你的问题
    如果对您有用,不妨点个赞吧在这里插入图片描述
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢牛牛@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值