yolo卷积层及其他中间层梯度权值数据可视化

         针对有自己训练任务或者模型设计任务的同学来说,训练过程中的参数变化是判断自己模型梯度消失与否的重要评价标准,本文以yolo卷积层的梯度值为例,给出如何进行数据可视化的方法

         对于darknet框架来说,由于不存在内存共享,因此如果有使用到GPU的话,需要使用CUDA的函数将GPU内存中的数据传递到CPU中方可进行访问

cuda_pull_array(l.delta_gpu, l.delta, l.outputs);

之后就可以将l.delta中的数据写入文件了,上句代码中,l.outputs是l.delta中的数据量

FILE *fp = fopen("delta.txt", "w");
int num;
for( num = 0; num < l.outputs; num++)
{
	fprintf(fp, "%f\n", l.delta[num]);
}

就可以得到最终的文件,下面就是针对输出的数据进行分析,不得不说,python真的是写工具的最佳编程语言,各种库的支持无语伦比,顺便推荐一个python中超级厉害的作图工具 seaborn

#!usr/bin/python3
# -*- coding:utf-8 -*-
# 作者:ArtyZe

import matplotlib.pyplot as plt
import numpy as np


# 设置曲线图绘制精度,并采集平均值样点数据
class AvgValueObj:
    X = []
    Y = []
    precision = 1

    def __init__(self):
        self.X = []
        self.Y = []
        self.precision = 1

    def set_precision(self, precision):
        self.precision = precision

    def get_value(self, scatter_obj):
        x_tmp = []
        y_tmp = []

        i = 0
        while scatter_obj.X.index(scatter_obj.X[-1]) >= i+self.precision:
            sum_y = 0
            for x in scatter_obj.X[i: i+self.precision]:
                sum_y += scatter_obj.Y[x]
            y_avg = sum_y / self.precision
            x_tmp.append(i+self.precision/2)
            y_tmp.append(y_avg)
            i += self.precision

        self.X = x_tmp
        self.Y = y_tmp


class PointObj:
    x = 0
    y = 0

    def __init__(self):
        self.x = 0
        self.y = 0

    # def id_x(self, x):
    #     if self.x == x:
    #         return self
    #
    # def id_y(self, y):
    #     if self.y == y:
    #         return self


# 设置包络线精度,先设置横轴取点的精度,根据纵轴上在精度范围内点的个数决定是否要包络在内
class EnvelopeValueObj:
    x_precision = 1
    y_precision = 0.1
    X_max = []
    Y_max = []
    X_min = []
    Y_min = []

    def __init__(self):
        self.X_max = []
        self.Y_max = []
        self.X_min = []
        self.Y_min = []
        self.x_precision = 1
        self.y_precision = 0.1

    def import_point_obj(self, scatter_obj):
        i = 0
        while i+self.x_precision < len(scatter_obj.X):
            point_obj_list = []
            y_list = []
            # point_obj = PointObj()
            sum_y = 0
            for x in scatter_obj.X[i: i+self.x_precision]:
                point_obj = PointObj()
                point_obj.x = x
                tem_y = scatter_obj.Y[scatter_obj.X.index(x)]
                point_obj.y = tem_y
                sum_y += tem_y
                point_obj_list.append(point_obj)
            avg_y = sum_y / self.x_precision
            for point in point_obj_list:
                y_list.append(point.y)
            y_list.sort(reverse=True)
            for y in y_list:
                if (y_list.index(y)+1) < len(y_list) and \
                        y >= avg_y and \
                        abs(y - y_list[y_list.index(y)+1]) > self.y_precision:
                    for point in point_obj_list:
                        if point.y == y:
                            point_obj_list.remove(point)
                    y_list.remove(y)
            y_list.reverse()
            for y in y_list:
                if y_list.index(y)+1 < len(y_list) and \
                        y <= avg_y and \
                        abs(y_list[y_list.index(y)+1] - y) > self.y_precision:
                    for point in point_obj_list:
                        if point.y == y:
                            point_obj_list.remove(point)
            for point in point_obj_list:
                if point.y == y_list[-1]:
                    point_max = point
                    self.X_max.append(point_max.x)
                    self.Y_max.append(point_max.y)
                elif point.y == y_list[0]:
                    point_min = point
                    self.X_min.append(point_min.x)
                    self.Y_min.append(point_min.y)
                else:
                    pass
            print("已经处理完前%s个数据..." % i)
            i += self.x_precision


# 绘制曲线图
class DrawLine:
    X = []
    Y = []

    def __init__(self):
        self.X = []
        self.Y = []

    # 导入对象
    def get_value(self, value_obj, tp):
        if tp == "avg":
            self.X = value_obj.X
            self.Y = value_obj.Y
        elif tp == "env_max":
            self.X = value_obj.X_max
            self.Y = value_obj.Y_max
        elif tp == "env_min":
            self.X = value_obj.X_min
            self.Y = value_obj.Y_min

    # 绘制曲线
    def draw_line(self):
        plt.plot(self.X, self.Y, color='yellow', linewidth=1.5)


class ScatterObj:
    path = ""
    X = []
    Y = []

    def __init__(self):
        self.path = ""
        self.X = []
        self.Y = []

    def set_path(self, path):
        self.path = path

    def get_xy(self):
        with open(self.path, "r") as file:
            lines = file.readlines()
            i = 0
            for line in lines:
                value = float(line.split()[0])
                self.X.append(i)
                self.Y.append(value)
                i = i + 1

# def distribute(self, color, label, linewidth):
#     plt.scatter(self.X, self.Y, color=color, label=label, linewidth=linewidth)


delta0_path = "/home/gaoyang/Desktop/SeNet/delta_0.txt"
delta1_path = "/home/gaoyang/Desktop/SeNet/delta_1.txt"
avg_path = "/home/gaoyang/Desktop/SeNet/avg_0.txt"
scale_path = "/home/gaoyang/Desktop/SeNet/scale_0.txt"

# 平均值散点图
avg_obj = ScatterObj()
avg_obj.set_path(avg_path)
avg_obj.get_xy()

scale_obj = ScatterObj()
scale_obj.set_path(scale_path)
scale_obj.get_xy()

#如果你只要看delta而不看其他的权值参数
if 0:	
	# delta区域散点图
	delta0_obj = ScatterObj()
	delta0_obj.set_path(delta0_path)
	delta0_obj.get_xy()

	delta1_obj = ScatterObj()
	delta1_obj.set_path(delta1_path)
	delta1_obj.get_xy()

	ax2 = plt.subplot(2, 1, 2)
	# delta1_obj.distribute('black', 'delta', 0.05)
	# delta0_obj.distribute('blue', 'delta', 0.01)
	plt.scatter(delta0_obj.X, delta0_obj.Y, color='black', label='delta', linewidth=0.01)
	plt.scatter(delta1_obj.X, delta1_obj.Y, color='blue', label='delta', linewidth=0.05)

	if 1:
		'''
		此处用于delta值的上下界拟合线
		x_precision越大,横轴取点越少,折线越平滑,精度越低
		y_precision越大,包含的散点值越多,为了让拟合线更贴近边界,应取比游离点离集中值的距离更小的值,但尽量大
		'''
		envelope_value_obj = EnvelopeValueObj()
		envelope_value_obj.x_precision = 2000
		envelope_value_obj.y_precision = 0.07
		envelope_value_obj.import_point_obj(delta0_obj)
		env_max_line = DrawLine()
		env_max_line.get_value(envelope_value_obj, "env_max")
		env_max_line.draw_line()
		env_min_line = DrawLine()
		env_min_line.get_value(envelope_value_obj, "env_min")
		env_min_line.draw_line()

	plt.legend(loc='upper right', frameon=False, borderaxespad=0.1)
	plt.xlabel('count')
	plt.ylabel('value')
	plt.grid()
	
#如果同时需要看delta和weight等参数
if 1:
	ax1 = plt.subplot(2, 1, 1)
	# avg_obj.distribute('red', 'avg', 0.8)
	# scale_obj.distribute('green', 'scale', 0.8)
	plt.scatter(avg_obj.X, avg_obj.Y, color='red', label='avg', linewidth=0.8)

	# 平均线
	avg_value_obj = AvgValueObj()
	avg_value_obj.precision = 5
	avg_value_obj.get_value(avg_obj)
	avg_line = DrawLine()
	avg_line.get_value(avg_value_obj, "avg")
	avg_line.draw_line()

	plt.scatter(scale_obj.X, scale_obj.Y, color='green', label='scale', linewidth=0.8)
	plt.legend(loc='upper right', frameon=False, borderaxespad=0.1)
	plt.ylim(-0.2, 1)
	plt.xlabel('count')
	plt.ylabel('value')
	plt.grid()


	# delta区域散点图
	delta0_obj = ScatterObj()
	delta0_obj.set_path(delta0_path)
	delta0_obj.get_xy()

	delta1_obj = ScatterObj()
	delta1_obj.set_path(delta1_path)
	delta1_obj.get_xy()

	ax2 = plt.subplot(2, 1, 2)
	# delta1_obj.distribute('black', 'delta', 0.05)
	# delta0_obj.distribute('blue', 'delta', 0.01)
	plt.scatter(delta0_obj.X, delta0_obj.Y, color='black', label='delta', linewidth=0.01)
	plt.scatter(delta1_obj.X, delta1_obj.Y, color='blue', label='delta', linewidth=0.05)

	if 1:
		'''
		此处用于delta值的上下界拟合线
		x_precision越大,横轴取点越少,折线越平滑,精度越低
		y_precision越大,包含的散点值越多,为了让拟合线更贴近边界,应取比游离点离集中值的距离更小的值,但尽量大
		'''
		envelope_value_obj = EnvelopeValueObj()
		envelope_value_obj.x_precision = 2000
		envelope_value_obj.y_precision = 0.07
		envelope_value_obj.import_point_obj(delta0_obj)
		env_max_line = DrawLine()
		env_max_line.get_value(envelope_value_obj, "env_max")
		env_max_line.draw_line()
		env_min_line = DrawLine()
		env_min_line.get_value(envelope_value_obj, "env_min")
		env_min_line.draw_line()

	plt.legend(loc='upper right', frameon=False, borderaxespad=0.1)
	plt.xlabel('count')
	plt.ylabel('value')
	plt.grid()

plt.savefig("0.png")

这里呢,我是会有四个文件要做图,不过我在代码里也给出了只看delta的接口,把if 0改成if 1就可以了,不过要记得把下面的if 1改成if 0关掉该接口,最后给出我的处理图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值