Darknet框架模型Inference过程的feature-map可视化

Darknet框架模型Inference过程的feature-map可视化

  • 说明
  • 简介
  • 步骤及代码

说明

本篇文章针对YOLO-v3官方提供的c语言版的darknet进行了修改(CPU模式),添加了一些函数,进行可视化feature-map处理,主要针对Inference过程中,对中间计算结果feature-map数据进行转换,将转换结果用图片是形式直观感受。

简介

主要方法是将卷积计算后的outputs使用sigmoid函数进行归一化,乘以255后将参数写入txt文件中,使用Python将txt文件转为图片,最终得到每一层的feature map,将每个通道都可视化,如下图所示:
Darknet框架模型Inference过程的feature-map可视化_第1张图片

步骤及代码

在network.c中设计将浮点数转换为像素值的函数,步骤如下:
1、保存文件到特定文件夹(feature_txt)中并根据ai大小命名;
2、创建一个1维的空图片;
3、设计一个数组保存该图片内容;
4、转换feature-map值,保存到文件;
5、关闭文件流。
代码如下所示:

image float_to_cow_image(int w, int h, int c, signed char *data, int ai)
{
	char tp[1000];
	//保存文件到特定文件夹(feature_txt)中并根据ai大小命名
	//创建一个1维的空图片
	image out = make_empty_image(w, h, 1);

	for (int k = 0; k < c; k++) {
		if (ai < 10)
			sprintf(tp, "feature_pic/out_000%d", ai);
		else
			sprintf(tp, "feature_pic/out_00%d", ai);
		mkdir(tp);
		if (ai < 10)
			sprintf(tp, "feature_txt/out_000%d", ai);
		else
			sprintf(tp, "feature_txt/out_00%d", ai);
		mkdir(tp);
		if (ai < 10)
			sprintf(tp, "feature_txt/out_000%d/out_000%d_%d.txt", ai, ai, k);
		else
			sprintf(tp, "feature_txt/out_00%d/out_00%d_%d.txt", ai, ai, k);

		FILE * stream = fopen(tp, "w+");

		int i, j;
		//设计一个数组保存该图片内容
		float * tempData = calloc(w*h, sizeof(float));
		//初始化
		for (i = 0; i < w*h; i++)
		{
			tempData[i] = 0;
		}
		for (i = 0; i < w*h; i++)
		{
			tempData[i] = 1.0 / (1 + exp(-1 * data[k*w*h + i]));
		}
		//保存到文件
		for (i = 0; i < w*h; i++)
		{
			tempData[i] *= 255;
			fprintf(stream, " %f", tempData[i]);
			if ((i + 1) % w == 0)
				fprintf(stream, "\n");
		}
		//关闭文件流
		fclose(stream);
		out.data = tempData;
	}
	return out;
}

将生成feature-map转换为像素值的txt文件,如下目录:
Darknet框架模型Inference过程的feature-map可视化_第2张图片
Darknet框架模型Inference过程的feature-map可视化_第3张图片
将txt文件中的像素值转为图片,为了更方便对比每一层卷积计算后的feature-map,这里将每一层不同通道的feature-map拼接在一个大的图片中,使用Python来实现,代码如下:

# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
import os
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import matplotlib.image as mpimg

def process(filepath,outpath):
    for fileName in os.listdir(filepath):
        a=np.loadtxt(filepath+"/"+fileName)        
        im = Image.fromarray(np.uint8(a))
        plt.title(fileName)
        plt.imshow(im),plt.axis('off')
        im.save(outpath+"/"+fileName[:-4]+".jpg")
        #plt.savefig(outpath+"/"+fileName[:-4]+".jpg",bbox_inches="tight",transparent=True,pad_inches=0)
   
# 定义图像拼接函数
def image_compose(IMAGE_SIZE,IMAGE_ROW,IMAGE_COLUMN,image_names,IMAGE_SAVE_PATH):
    to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE)) #创建一个新图
    # 循环遍历,把每张图片按顺序粘贴到对应位置上
    for y in range(1, IMAGE_ROW + 1):
        for x in range(1, IMAGE_COLUMN + 1):
            from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
                (IMAGE_SIZE, IMAGE_SIZE),Image.ANTIALIAS)
            to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
    return to_image.save(IMAGE_SAVE_PATH) # 保存新图
      
if __name__ == "__main__":
	outpath = "feature_pic"
	filepath="feature_txt"

	IMAGES_FORMAT = ['.jpg', '.JPG']  # 图片格式
	IMAGE_SIZE_t = [512,256,256,128,128,64,64,32,32,32,32,32,32,32,32]  # 每张小图片的大小
	IMAGE_ROW_t = [4,4,4,4,8,8,8,8,8,8,8,8,8,5,5]  # 图片间隔,也就是合并成一张图后,一共有几行
	IMAGE_COLUMN_t = [4,4,4,4,4,4,4,4,8,8,8,8,4,6,6]  # 图片间隔,也就是合并成一张图后,一共有几列
	
	count = 0
	plt.figure()
	for fpathe,fpathe1 in zip(os.walk(filepath),os.walk(outpath)):
		#for f in fs:
		if(count!=0):
			plt.subplot(4,4,count)
			IMAGE_SAVE_PATH = 'feature_pic_final/final_00'+str(count-1)+'.jpg'  # 图片转换后的地址
			process(fpathe[0],fpathe1[0])
			IMAGES_PATH = fpathe1[0] + "\\"
			# 获取图片集地址下的所有图片名称
			
			image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if os.path.splitext(name)[1] == item]
			# 简单的对于参数的设定和实际图片集的大小进行数量判断
			if len(image_names) != IMAGE_ROW_t[count -1] * IMAGE_COLUMN_t[count-1]:
				raise ValueError("合成图片的参数和要求的数量不能匹配!")
			image_compose(IMAGE_SIZE_t[count-1],IMAGE_ROW_t[count-1],IMAGE_COLUMN_t[count-1],image_names,IMAGE_SAVE_PATH) #调用函数
			lena = mpimg.imread(IMAGE_SAVE_PATH)
			img = plt.imshow(lena) # 显示图片

		count = count + 1
	plt.show()
	

未拼接前结果:
Darknet框架模型Inference过程的feature-map可视化_第4张图片
拼接后结果:
Darknet框架模型Inference过程的feature-map可视化_第5张图片

你可能感兴趣的:(CNN,机器学习)