最近刚入手Pytorch框架,因为论文中需要贴出损失函数的训练过程的曲线,因此就自己写了个函数,通过列表的形式,将训练数据记录下来,并且保存成CSV文件,方便我们以后读取并绘制图像。

一、数据保存成CSV文件

在这里,我们以拟合二次函数为例,首先需要定义一个空的二维列表

定义二维列表:

lossData=[[]]

 

 接着,向里面添加每一步的训练数据,iter代表训练的次数,loss.data.numpy()代表每一次训练的损失值,因为pytorch中,loss是variable类型,因此要使用data,提取其中的数值(tensor类型),再使用numpy,转换成数值类型,方便我们后续绘图使用

 将数据保存在二维列表中:

lossData.append([iter,loss.data.numpy()]) #先转成普通tensor,再转成numpy形式

 

 最后,就是自定义一个函数,在训练结束时,将列表数据转换CSV文件

数据转成CSV:

def data_write_csv(file_name, datas):  # file_name为写入CSV文件的路径,datas为要写入数据列表
    file_csv = codecs.open(file_name, 'w+', 'utf-8')  # 追加
    writer = csv.writer(file_csv, delimiter=' ', quotechar=' ', quoting=csv.QUOTE_MINIMAL)
    for data in datas:
        writer.writerow(data)
    print("保存文件成功,处理结束")

完整的代码如下: 

import torch
from  torch.autograd import Variable
import torch.nn.functional as F
import matplotlib.pyplot as plt
import torch.utils.data as Data
torch.manual_seed(1)    # reproducible
import csv
import codecs
import numpy as np

def data_write_csv(file_name, datas):  # file_name为写入CSV文件的路径,datas为要写入数据列表
    file_csv = codecs.open(file_name, 'w+', 'utf-8')  # 追加
    writer = csv.writer(file_csv, delimiter=' ', quotechar=' ', quoting=csv.QUOTE_MINIMAL)
    for data in datas:
        writer.writerow(data)
    print("保存文件成功,处理结束")

if __name__ == '__main__':
    '''快速搭建网络'''
    Net = torch.nn.Sequential(
        torch.nn.Linear(1, 10),
        torch.nn.ReLU(),
        torch.nn.Linear(10, 1)
    )

    '''生成数据'''
    #linespace 返回一维的tensor,从step到end,分成Steps个线段得到的向量
    #unsqueeze 增加一个维度,tensor要求的数据是二维的
    x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1) #shape=(100,1)
    #生成标签,前一项是二次函数,后一项是加上随机噪声
    #返回一个张量,包含了从区间[0, 1)的均匀分布中抽取的一组随机数
    y=x.pow(2)+0.2*torch.rand(x.size())

    '''数据批量化'''
    BATCH_SIZE=10
    EPOCH=20
    # 先转换成 torch 能识别的 Dataset
    torch_dataset = Data.TensorDataset(x, y)

    # 把 dataset 放入 DataLoader
    loader = Data.DataLoader(
        dataset=torch_dataset,  # torch TensorDataset format
        batch_size=BATCH_SIZE,  # mini batch size
        shuffle=True,  #  (打乱比较好)
        num_workers=2,  # 多线程来读数据
    )

    '''训练过程'''
    optimizer = torch.optim.SGD(Net.parameters(), lr=0.1)  # 传入 net 的所有参数, 学习效率,实例化类,生成对象
    loss_func = torch.nn.MSELoss()  # 预测值和真实值的误差计算公式 (均方差处理回归),实例化类,生成对象

    '''可视化操作'''
    lossData=[[]]
    iter=0
    for epoch in range(EPOCH):
        print('Epoch:  ', epoch)
        for step, (batch_x, batch_y) in enumerate(loader):
            b_x = Variable(batch_x)  # 务必要用 Variable 包一下,可以在GPU上运算
            b_y = Variable(batch_y) #Variable类型的变量会被放到一个计算图中
            prediction = Net(b_x)  # 喂给 net 训练数据 x, 输出预测值
            loss = loss_func(prediction, b_y)  # 计算两者的误差
            lossData.append([iter,loss.data.numpy()]) #先转成普通tensor,再转成numpy形式
            iter+=1
            optimizer.zero_grad()  # 清空上一步的残余更新参数值
            loss.backward()  # 误差反向传播, 计算参数更新值
            optimizer.step()  # 将参数更新值施加到 net 的 p
            print("Epoch[{}].step[{}]:loss:{}".format(epoch,step,loss))
            if epoch % 10 == 0:
                torch.save(Net, ".\\checkpoint\\net_{}.pkl".format(epoch))  # 保存整个网络
    data_write_csv(".\\parametres.csv", lossData)

 二、读取CSV文件

这里就是自定义一个函数,根据保存的文件形式,按行读取CSV文件的内容,并且使用空格作为分隔符,将每一行的数据分隔成两个,前一个是训练次数,后一个是对应的损失值,特别地,因为首行为空,所以要先将CSV文件的第一行,剔除出来。

这是CSV保存数据的形式:

pytorch读取cifar10 pytorch读取csv数据集并训练_机器学习

完整代码:

import torch
from  torch.autograd import Variable
import torch.nn.functional as F
import matplotlib.pyplot as plt
import csv

'''读取csv文件'''
def readcsv(files):
    csvfile = open(files, 'r')
    plots = csv.reader(csvfile, delimiter=' ')#按行读取CSV文件中的数据,每一行以空格作为分隔符,再将内容保存成列表的形式
    next( plots)  # 读取首行
    x = []
    y = []
    for row in plots:
        x.append(float(row[0]))#从csv读取的数据是str类型,转成float类型
        y.append(float(row[1]))
    return x ,y

plt.figure()
x2,y2=readcsv("parametres.csv")
plt.plot(x2, y2, color='red', linewidth = '1',label='SGD_loss')

plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

plt.ylim(0, 0.2) #y轴取值范围
plt.xlim(0, 200) #x轴取值范围
plt.xlabel('Training Steps',fontsize=15) #x轴标签
plt.ylabel('Training loss',fontsize=15) #y轴标签
plt.legend(fontsize=16)  #标签的字号
plt.show()

 出图结果:

pytorch读取cifar10 pytorch读取csv数据集并训练_深度学习_02