[深度学习]-训练和测试模型的常用代码

人工智能98

数据转换

data2 = torch.tensor(data1)

非训练数据(训练结束后的tensor)的转换:
data2 = np.array(data1)
如果您需要在培训过程中进行更改,则:

[En]

If you need to change during the training process, then:

data2 = data1.cpu().data.numpy() 动态,会一起改变
data2 = data1.cpu().detach().numpy() 静态

如果第一维,维度为1,可以去掉:(1,8,8)-> (8,8)
data2 = np.concatenate(datat1, axis=0)
如果包含维度为1的维度,可以去掉:(1,8,8,1)-> (8,8)
data2 = data1.squeeze()
转换维度层数:(1,8,3)-> (8,1,3)
data2 = np.swapaxes(1, 0, 2)

加载数据集dataloader

from torch.utils.data import DataLoader
form 自己写的dataset import Dataset

train_set = Dataset(train=True)
val_set = Dataset(train=False)

image_datasets = {
    'train': train_set, 'val': val_set
}

batch_size = 4

dataloaders = {
    'train': DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=2),
    'val': DataLoader(val_set, batch_size=batch_size, shuffle=False, num_workers=2)
}

dataset_sizes = {
    x: len(image_datasets[x]) for x in image_datasets.keys()
}
print(dataset_sizes)

for epoch in range(num_epochs):
    for phase in ['train', 'val']:
        if phase == 'train':
            # for param_group in optimizer.param_groups:
                # print("LR", param_group['lr'])
            model.train()
        else:
            model.eval()

以上适用于train一遍test一遍的情况

或将培训和测试分开加载:

[En]

Or load the training and testing separately:

train_dataset = Dataset('train')
train_data_loader = torch.utils.data.DataLoader(train_dataset, batch_size=8, shuffle=True,
                                                    num_workers=2, collate_fn=collate_fn)

test_dataset = Dataset('eval')
test_data_loader = torch.utils.data.DataLoader(test_dataset, batch_size=8, shuffle=False,
                                                   num_workers=2, collate_fn=collate_fn)

自己写Dataset

from torch.utils.data import Dataset
import os
import cv2
import torch
import numpy as np

class Dataset(Dataset):
    def __init__(self,train):
        if train:
            self.datapath = {'image': '/home/myy/code/Final_Project/data_train.txt', 'target':'/home/myy/code/Final_Project/gt_train.txt'}
        else:
            self.datapath = {'image': '/home/myy/code/Final_Project/data_test.txt', 'target':'/home/myy/code/Final_Project/gt_test.txt'}
            # self.datapath = {'image': '/home/myy/code/Final_Project/test_small_data.txt', 'target':'/home/myy/code/Final_Project/test_small.txt'}
        self.image_list, self.target_list = self.read_txt(self.datapath)

# 此处可以依据需要自己定义一些函数
# 注意调用前要加上`self.`
# 比如以下两个读取数据的函数,read_txt、read_json就是自己定义的
    def read_txt(self,datapath):
        im =[]
        target_image = []
        print(datapath)
        with open(datapath['image'], 'r') as f:
            image_list = f.readlines()
        with open(datapath['target'], 'r') as f:
            target_list = f.readlines()
        return image_list, target_list

    def read_json(save_path, encoding='utf8'):
        jsondata = []
        with open(save_path, 'r', encoding=encoding) as f:
            content = f.read()
            content = json.loads(content)
            for key in content:
                jsondata.append(content[key])
            return jsondata

    def __getitem__(self, item):
        # 最核心的部分,经过处理,要返回输入和gt

        return img, target

    def __len__(self):
        # 这可以根据具体情况修改,不写也行
        return len(self.data)

模型训练

torch.save(model.state_dict(), model_path)

import copy
best_model_wts = copy.deepcopy(model.state_dict())
trainable_vars = list(model.roi_heads.box_predictor.parameters())+ \
                 list(model.roi_heads.box_head.parameters())+ \
                 list(model.rpn.head.parameters())
                #  list(model.backbone.body.parameters())+ \
                #  list(model.backbone.fpn.parameters())+ \
 optimizer = torch.optim.SGD(trainable_vars , lr=1e-3, momentum=0.5)

模型测试

主要代码

device = torch.device("cuda:0" if  torch.cuda.is_available() else "cpu")
print(device)
num_class = 1
model_path = '训练模型保存路径/保存名称.pth'
model = 模型(num_class).to(device)
model.load_state_dict(torch.load(model_path))
model.eval()
import cv2
from torchvision import transforms, datasets, models
from torch.utils.data import  DataLoader
import torch
import numpy as np
import os
from sklearn import metrics
import matplotlib.pyplot as plt

device = torch.device("cuda:2" if torch.cuda.is_available() else "cpu")
print(device)
num_class = 3
model_path = 模型路径
model = 模型(num_class).to(device)
model.load_state_dict(torch.load(model_path))
model.eval()   # Set model to evaluate mode

test_dataset = 数据集读取(train=False)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False, num_workers=2)

def turn(l):
    l = l.data.cpu().numpy()
    l = l.squeeze()
    l = np.swapaxes(l, 0, 2)
    l = np.swapaxes(l, 0, 1)
    return l

for inputs, labels in test_loader:
    model.to(device)
    inputs = inputs.to(device)
    labels = labels.to(device)

    pred = model(inputs)
    # pred = torch.relu(pred)
    pred = turn(pred)
    gt = turn(labels)

评价指标

以分割为例,经过.flatten()处理。

def acc(pred, gt):
    tp = 0
    tn = 0
    fp = 0
    fn = 0
    num = len(pred)
    for i in range(num):
        if pred[i] > 0 and gt[i] == 1:
            tp += 1
        if pred[i] > 0 and gt[i] == 0:
            fp += 1
        if pred[i] == 0 and gt[i] == 1:
            fn += 1
        if pred[i] == 0 and gt[i] == 0:
            tn += 1
    acc = (tp + tn) / num
    iou = tp / (tp + fp + fn)
    rec = tp / (tp + fn)
    pre = tp / (tp + fp)
    f1 = 2 * pre * rec / (pre + rec)
    print("mAcc is :{},  mIou is :{}, recall is :{}, precision is :{}, f1 is :{}".format(acc, iou, rec, pre, f1))
def draw_roc(pred, gt, name):
    tpr, fpr, thresholds = metrics.roc_curve(gt, pred, pos_label=0)
    plt.figure
    plt.plot(fpr, tpr, label = name)
    plt.xlabel('FPR')
    plt.ylabel('TPR')
    plt.legend(loc = 'lower right')
    plt.title(name)
    plt.savefig('路径/{}.png'.format(name))
    # plt.close()  如果有多个类别,不close()就会画在一张图上

Original: https://www.cnblogs.com/camilia/p/16000412.html
Author: CAMILIA
Title: [深度学习]-训练和测试模型的常用代码



相关阅读

Title: 2021/11/13

但基于python的项目,尤其是目前流行的智能应用项目,存在一个很大的问题,就是向后兼容性差。具体表现为,同一个项目源码,在其它机器上经常无法正常运行。这是因为:

为此,基于python的软件开发,提出了虚拟环境的概念。思想很简单,就是为一个项目安装一个python。这也是被逼出来的,方法就是:针对每一个项目,建立一个对应的python环境,该环境包括:这个项目用到的python版本,项目依赖的每一个包,以及这些包的具体版本。

目前这种思想已经成为共识,并进一步发展出了基于docker的python项目开发,这个有时间后面再讲。

下面,贯彻这种思想,介绍如何从一个开源项目开始自己的工作。为了叙述方便,假设:

  • 我在windows操作系统上工作。
  • 我已经安装了python,是一个较新的版本,但不要太新,比如python3.8。
  • 我在D盘建立了目录D:\myWorkshop,后面的开发都在这个目录上完成,称之为 工作目录
  • 我在github.com发现了一个开源项目,名为openProject,对我很有用,我准备开始用它。

1 创建虚拟环境

如果你安装了anaconda,那么创建虚拟环境,只需要点几下鼠标就能完成。但其实python本身就提供了创建虚拟环境的包,只需要执行下面的语句,来创建一个名为myPython的虚拟环境:

cd D:\myWorkshop\myPython
python -m venv myPython

其实一个虚拟环境,就是一个同名的目录。这里是D:\myWorkshop\myPython.

创建虚拟环境后,现在你的机子上,至少有两个python了。一个是开始安装的,我们可以称之为 原生python, 另一个就是我们刚才创建的 虚拟环境。因此,每次使用,你需要指出使用哪一个。如果选择使用虚拟环境,称为 激活该环境,使用下面的命令。

cd D:\myWorkshop/myPython/Scripts
activate myPython

如果不想使用虚拟环境了,通过下面的命令:

cd d:\myWorkshop\myPython\Scripts
deactivate myPython

现在,你就在使用原生python,这个称为 去激活

2 下载开源项目

如果使用git,则:

git clone https://github.com/openProject.git

也可以直接下载项目的zip文件,然后解压到自己的工作目录.

操作后,在D:\myWorkshop下会有两个目录:

3 安装相关的包

有经验的开发者,会将项目运行所需要的包,写在一个名为requirements.txt的文件中。因此,快速检查一下这个开源项目有没有这个文件,如果有,那就比较简单了。直接执行下面的命令:

pip install -r requirements.txt

然后安静地等待完成。

如果比较慢,甚至报错,这不是你的问题,而是因为这些包所在的仓库pypi.org位于国外,网速太慢。因此,只要使用国内的镜像站点,就可以解决。使用下面的命令:

你也看出来了,只是在后面加了一个地址,这是清华大学提供的镜像。

如果在开源项目中没有发现requirements.txt文件,就需要你自己来创建了。这个文件包含了需要安装的包的列表,每一行一个,如下面的样子:

tensorflow==1.14
keras==2.23
pillow

每一行前面是包的名字,你也猜的出,后面通过==、>和

Original: https://blog.csdn.net/qq_43687094/article/details/121300357
Author: xing yongkang
Title: 2021/11/13