yolov4,darknet特徵圖可視化

yolov4,darknet特徵圖可視化

拼接參考:https://blog.csdn.net/lxk2017/article/details/97911371
在network_nernel.cu文件中加入前向傳播顯示代碼:

/*****************************************************
*func: 主要是爲了將output結果能夠映射到0-255區間(初始化,使用sigmoid函數進行歸一化,),便於進行可視化操作。 將所有維度合成到一個維度,然後取平均,×255,便於查看
*****************************************************/
image float_to_cow_image(int w, int h, int c, float *data,int ai)
{
    char tp[1000];
    //保存文件到特定文件夾(feature_txt)中並根據ai大小命名
    sprintf(tp,"/home/xxx/Pictures/feature_txt/out_%d.txt",ai);
    FILE * stream = fopen(tp,"w+");
    //創建一個1維的空圖片
    image out = make_empty_image(w,h,1);
    int i, j;
    //設計一個數組保存該圖片內容
    float *tempData = (float*)calloc(w*h,sizeof(float));
    //初始化
    for(i = 0 ; i < w*h ; i++)
    {
        tempData[i] = 0;
    }
    //歸一化,sigmoid
    for(i = 0 ; i < w*h*c ; i++)
    {
        data[i] = 1.0/(1+exp(-1*data[i]));
    }
    //合併通道
    for(i = 0 ; i < w*h ; i++)
    {
        for(j = 0 ; j < c ; j++)
        {
            tempData[i] += data[i+j*w*h];
        }
    }
    //保存到文件
    for(i = 0 ; i < w*h; i++)
    {
        tempData[i] /= c;
        tempData[i] *= 255;
        fprintf(stream," %f",tempData[i]);
        if((i+1)%w==0)
            fprintf(stream,"\n");
    }
    //關閉文件流
    fclose(stream);
    out.data = tempData;
    return out;
}
image get_network_cow_image_layer(network *net, int i)
{
//    image a;
    layer l = net->layers[i];

#ifdef GPU
    cuda_pull_array(l.output_gpu, l.output, l.outputs);
#endif
    printf("w:%d,h:%d,c:%d\n",l.out_w,l.out_h,l.out_c);
    if (l.out_w && l.out_h && l.out_c){
//        return a;
        return float_to_cow_image(l.out_w,l.out_h,l.out_c,l.output,i);
    }
    image def = {0};
    return def;
}

在network_nernel.cu文件的forward_network_gpu函數中加入如下代碼:

在這裏插入圖片描述

void forward_network_gpu(network net, network_state state)
{
    static time_benchmark_layers *avg_time_per_layer = NULL;
    static time_benchmark_layers *sorted_avg_time_per_layer = NULL;
    double start_time, end_time;
    if (net.benchmark_layers) {
        if (!avg_time_per_layer) {
            avg_time_per_layer = (time_benchmark_layers *)calloc(net.n, sizeof(time_benchmark_layers));
            sorted_avg_time_per_layer = (time_benchmark_layers *)calloc(net.n, sizeof(time_benchmark_layers));
        }
        cudaDeviceSynchronize();
    }
    //printf("\n");
    state.workspace = net.workspace;
    int i;
    for(i = 0; i < net.n; ++i){
        state.index = i;
        layer l = net.layers[i];
        if(l.delta_gpu && state.train){
            fill_ongpu(l.outputs * l.batch, 0, l.delta_gpu, 1);
        }
        if (net.benchmark_layers) {
            start_time = get_time_point();
        }
        l.forward_gpu(l, state);
        if (net.benchmark_layers) {
            CHECK_CUDA(cudaDeviceSynchronize());
            end_time = get_time_point();
            const double took_time = (end_time - start_time) / 1000;
            const double alpha = 0.9;
            if (avg_time_per_layer[i].time == 0) {
                avg_time_per_layer[i].layer_id = i;
                avg_time_per_layer[i].layer_type = l.type;
                avg_time_per_layer[i].time = took_time;
            }
            else avg_time_per_layer[i].time = avg_time_per_layer[i].time * alpha + took_time * (1 - alpha);
            sorted_avg_time_per_layer[i] = avg_time_per_layer[i];
            printf("\n fw-layer %d - type: %d - %lf ms - avg_time %lf ms \n", i, l.type, took_time, avg_time_per_layer[i].time);
        }
        if(net.wait_stream)
            cudaStreamSynchronize(get_cuda_stream());
        state.input = l.output_gpu;
        bool show_featuremap = true;
        if (show_featuremap){
            //這個函數是新加的,用來得到圖片保存圖片
            image tmp = get_network_cow_image_layer(&net,i);
        }
    }
    if (net.benchmark_layers) {
        printf("\n\nSorted by time (forward):\n");
        qsort(sorted_avg_time_per_layer, net.n, sizeof(time_benchmark_layers), time_comparator);
        for (i = 0; i < net.n; ++i) {
            //printf("layer %d - type: %d - avg_time %lf ms \n", avg_time_per_layer[i].layer_id, avg_time_per_layer[i].layer_type, avg_time_per_layer[i].time);
            printf("%d - fw-sort-layer %d - type: %d - avg_time %lf ms \n", i, sorted_avg_time_per_layer[i].layer_id, sorted_avg_time_per_layer[i].layer_type, sorted_avg_time_per_layer[i].time);
        }
    }

}

運行後生成txt文件特徵圖數據

在這裏插入圖片描述

在這裏插入圖片描述

利用python程序讀取顯示拼接後的特徵圖

import os
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

outpath = "/home/xxx/Pictures/feature_pic"
outpath_joint = "/home/xxx/Pictures/feature_pic_joint"
filepath = "/home/xxx/Pictures/feature_txt"
final_size = 1024

# https://www.cnblogs.com/pprp/p/10146355.html
def process(filepath, outpath):
    feature_map_list = []
    for fileName in os.listdir(filepath):
        a = np.loadtxt(filepath + "/" + fileName)
        im = Image.fromarray(np.uint8(a))
        feature_map_list.append(im)
        plt.title(fileName)
        plt.imshow(im), plt.axis('off')
        im.save(outpath + "/" + fileName[:-4] + ".jpg")
    return feature_map_list
# 定義圖像拼接函數
# https://blog.csdn.net/lxk2017/article/details/97911371
# 輸入10張圖片,輸出4*4的方格,每一個方格放入相應圖片
def image_compose1(feature_map_list,IMAGE_ROW,IMAGE_COLUMN, outpath_joint):
    IMAGE_SIZE = feature_map_list[0].size[0]
    to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))  # 創建一個新圖
    for x in range(IMAGE_ROW):
        for y in range(IMAGE_COLUMN):
            img_index = x * IMAGE_ROW + y
            if img_index < len(feature_map_list):
                from_image = feature_map_list[img_index]
                to_image.paste(from_image, (x * IMAGE_SIZE, y * IMAGE_SIZE))
    to_image = to_image.resize((final_size, final_size), Image.ANTIALIAS)
    saveimg_path = str(IMAGE_SIZE) + "_" + str(IMAGE_COLUMN) + ".jpg"
    to_image.save(os.path.join(outpath_joint, saveimg_path))  # 保存新圖
# 輸入162張特徵圖,方格的大小
def image_compose(feature_map_list,feature_index,IMAGE_ROW_t,IMAGE_COLUMN_t, outpath_joint):
    for i in range(len(feature_index)-1):
        feature_map_list1 = []
        for j in range(feature_index[i],  feature_index[i + 1]):
            feature_map_list1.append(feature_map_list[j])
        image_compose1(feature_map_list1, IMAGE_ROW_t[i], IMAGE_COLUMN_t[i], outpath_joint)

if __name__ == "__main__":

    feature_map_list = process(filepath, outpath)
    IMAGES_FORMAT = ['.jpg', '.JPG']  # 圖片格式
    feature_index = [0, 10, 23, 54, 85, 117, 127, 140, 151, 161]
    IMAGE_ROW_t = [1, 4, 4, 6, 6, 6, 4, 4, 4, 4]  # 圖片間隔,也就是合併成一張圖後,一共有幾行
    IMAGE_COLUMN_t = [1, 4, 4, 6, 6, 6, 4, 4, 4, 4]  # 圖片間隔,也就是合併成一張圖後,一共有幾列
    image_compose(feature_map_list,feature_index,IMAGE_ROW_t,IMAGE_COLUMN_t, outpath_joint)  # 調用函數

特徵圖顯示

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章