參考鏈接:
https://mp.weixin.qq.com/s?__biz=MzI5MDUyMDIxNA==&mid=2247514888&idx=2&sn=3884cf50b88eaee6744d35cb528c0fa7&chksm=ec1c56f1db6bdfe7585830d13a3673648c1b9f5098af15d53e4efb96e16a1b22003b1b56ba43&mpshare=1&scene=1&srcid=1103IwBjWjTF3h8l3Smh5ohu&sharer_sharetime=1604478585079&sharer_shareid=3839dc73cba9ba6f5a6eb2fee58f300f&key=966b233910e1aa6df0e367067aa3169852053729d9052e5342c78c9521b069153beb74b5e5136bf692087ad3f33b8e74113962a2cb47ef61279a45edfb79e1a1f8e2a1f99ffb03b137b906f25ce6b92abd156e73faa83b558301cfaf0612deeca4803458512fba340ae9f489ef073cf96c4031c2bd491bf7f53d3a58c3d2cc62&ascene=1&uin=MjAyMjA0NjY3MA%3D%3D&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=AwmXeExcmzVZ1BaQZJvCJ3o%3D&pass_ticket=jMBlpDzYyeU7%2BXpQJxN0X6ddKC13bpbPaoJh%2FjGTz2GR%2BAB4Bu7Rui39ieh3Oxic&wx_header=0
https://blog.csdn.net/bigbennyguo/article/details/87956434
https://blog.csdn.net/zouxiaolv/article/details/105192739
https://pytorch.apachecn.org/docs/1.2/tensorboard.html
https://gist.github.com/anonymous/bf16430f7750c023141c562f3e9f2a91
https://github.com/lanpa/tensorboardX/blob/master/README.md
https://blog.csdn.net/goldxwang/article/details/76855200 Matplotlib調用imshow()函數繪制熱圖
首先進行環境的配置
我的基本環境:ubuntu 16 py3.6
安裝對應的tensorboard tensorboard X ,還有tensorflow-gpu
具體的方法可參考本文開頭的第一篇鏈接
如果出現
啟動Tensorboard時發生錯誤:class BeholderHook(tf.estimator.SessionRunHook): AttributeError: module 'tensorflow.python.estimator.estimator_lib' has no attribute 'SessionRunHook'
主要原因是tensorflow 和tensorboard的版本不一致(要做到上面截圖紅線所示)
如果出現
cl@gxz:~/visual$ python test.py
[W common_gpu.cc:35] Insufficient cuda driver. Cannot use cuda.
這是因為cuda 和torch 的版本不對應,具體可參考https://www.cnblogs.com/tingtin/p/13900424.html
具體實現過程:
1.
代碼:
from tensorboardX import SummaryWriter # Creates writer1 object. # The log will be saved in 'runs/exp' writer1 = SummaryWriter('runs/exp1') for i in range(10): writer1.add_scalar('quadratic', i**2, global_step=i) writer1.add_scalar('exponential', 2**i, global_step=i)
需要先運行代碼,生成
2.命令行執行:tensorboard --logdir=<your_log_dir> #這里需要注意your_log_dir 為
writer1 = SummaryWriter('runs/exp1')
此時的tensorboard --logdir='runs/exp1'
來開啟tensorboard
3.那么現在可以在瀏覽器地址欄輸入相應地址
如果是服務器需要服務器地址+端口號 ,如:http://192.1.27.110:6006/
如果輸入相關地址后沒反應,可以參考 https://blog.csdn.net/index20001/article/details/82871634
注意:這里的 Smoothing =0 ,不然會在一幅圖上顯示2條曲線
很容易發現上圖沒有對應的label,也就是希望下圖的
要實現上圖,可以在windows環境下
前提:已經得到數據,然后用曲線表示
import requests import bs4 import re import time import xlwt import xlrd import telnetlib import urllib import matplotlib # matplotlib.use('Agg') from bs4 import BeautifulSoup from urllib import request from urllib.request import urlopen # from tensorboardX import SummaryWriter # from my_fake_useragent import UserAgent import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np xlsx_path='.\psnr+60.xlsx' data_xsls = xlrd.open_workbook(xlsx_path) sheet_name = data_xsls.sheets()[0] count_nrows = sheet_name.nrows #獲取總行數 x1 = [] x2 = [] x3= [] y1 =[] y2 = [] y3 = [] for i in range(1,count_nrows): y1.append(sheet_name.cell(i,1).value) #根據行數來取對應列的值,並添加到字典中 y2.append(sheet_name.cell(i, 2).value) y3.append(sheet_name.cell(i, 3).value) x1.append(i) x2.append(i) x3.append(i) plt.figure() plt.plot(x1, y1, color='red', label='middlebury') plt.plot(x2, y2, color='black', label='KITTI2012') plt.plot(x3, y3, color='blue', label='KITTI2015') plt.xlabel('Steps',fontsize=20) plt.ylabel('PSNR',fontsize=20) plt.legend(fontsize=16) plt.show()
但是add_iamge() 能夠接受的格式是[C,H,W], 范圍[0,1],C<=4,數據類型tensor.FloatTensor。
以一副圖展示C張圖片
#多通道特征圖可視化 # print(' buffer_left:size', buffer_left.shape) # print(' buffer_right:size', buffer_right.shape)#[B,C,H,W] # print(' buffer_left[0]:size', buffer_left[0].shape)#[C,H,W],#buffer_left[0]像素點范圍不是[0,1] # y = buffer_left[0].detach().cpu().unsqueeze(dim=1)#[C,1,H,W] # print(' buffer_left[0]:size', buffer_left[0].shape) # print(' y:size', y.shape)#一般為[C,1,H,W] # a, _,c ,d= buffer_left.shape # # # #buffer_left[0] 才可以,也就是[1,H,W]才沒有歧義 # grid = torchvision.utils.make_grid( y, normalize=True, scale_each=True) # print('grid.size :', grid.size())#grid一定要三維,grid的像素點值范圍[0,1] # # writer.add_image('images',grid , 0,dataformats='CHW') # writer.add_image('images',y[31], 0, dataformats='CHW')#這是第32張特征圖 # writer.close()
第32張特征圖
把網絡某環節的特征圖以熱圖形式可視化
每個通道一張熱力圖
參考博客:https://blog.csdn.net/GrayOnDream/article/details/99090247
#下面是某卷積部分,
init_feature維特征提取網絡
buffer_left = self.init_feature(x_left)#[B,C,H,W]
buffer_right = self.init_feature(x_right) l = buffer_left[0].shape[0]#通道數目 dst = './feautures' therd_size = 256#有些圖太小,會放大到這個尺寸 def make_dirs(path): if os.path.exists(path) is False: os.makedirs(path) dst_path = os.path.join(dst) make_dirs(dst_path) for i in range(l): y =np.asarray(buffer_left[0].data.cpu())#處理成array格式 y_ = y[i, :, :] print('y_.shape:', y_.shape)#2維 print('y_type:',y_.dtype)#float32 y_ = np.asarray(y_ * 255, dtype=np.uint8)#[0,255] print('y_type:', y_.dtype)#uint8 # y_ = cv2.applyColorMap(y_, cv2.COLORMAP_JET) y_ = cv2.applyColorMap(y_, cv2.COLORMAP_RAINBOW)#https://www.sohu.com/a/343215045_120197868創建偽彩色 if y_.shape[0] < therd_size:#大小調整 tmp_file = os.path.join(dst_path, str(i) + '_' + str(therd_size) + '.png') tmp_img = y_.copy()#將src中的元素復制到tensor tmp_img = cv2.resize(tmp_img, (therd_size, therd_size), interpolation=cv2.INTER_NEAREST)#https://www.cnblogs.com/jyxbk/p/7651241.html cv2.imwrite(tmp_file, tmp_img) dst_file = os.path.join(dst_path, str(i) + '.png') cv2.imwrite(dst_file, y_)
但是上面 的顯示結果不美觀,因此對像素值范圍修改
l = buffer_left[0].shape[0] # 通道數目 dst = './feauture' therd_size = 256 # 有些圖太小,會放大到這個尺寸 def make_dirs(path): if os.path.exists(path) is False: os.makedirs(path) dst_path = os.path.join(dst) make_dirs(dst_path) for i in range(l): y = buffer_left[0].data.cpu().numpy() # 處理成array格式 y_ = y[i, :, :] minn = 1000 maxx = -1000 [a, b] = y_.shape # for ii in range(a): # for jj in range(b): # minn = min(minn,y_[ii,jj]) # maxx = max(maxx,y_[ii][jj]) # print('minn maxx',minn,maxx)#並不在0-1之間,有些像素值<0.但是灰度圖像像素值[0,1] for ii in range(a): for jj in range(b): y_[ii][jj] = max(0, y_[ii][jj]) # 先去掉負值 y_ = (y_ - np.min(y_)) / np.max(y_) # 歸一化 [0,1] y_ = np.asarray(y_ * 255, dtype=np.uint8) # [0,255] # if i == 0: # print('y_.shape:', y_.shape) # 2維 # print('y_type:', y_.dtype) # float32 # # if i == 0: # print('y_type:', y_.dtype) # uint8 # if i == 0: # print('yqian _ ', y_) y_ = cv2.applyColorMap(y_, cv2.COLORMAP_OCEAN) # https://www.sohu.com/a/343215045_120197868創建偽彩色 # if i == 0: # print('ycaise )_ ', y_) if y_.shape[0] < therd_size: # 大小調整 tmp_file = os.path.join(dst_path, str(i) + '_' + str(therd_size) + '.png') tmp_img = y_.copy() # 將src中的元素復制到tensor tmp_img = cv2.resize(tmp_img, (therd_size, therd_size), interpolation=cv2.INTER_NEAREST) # https://www.cnblogs.com/jyxbk/p/7651241.html cv2.imwrite(tmp_file, tmp_img) dst_file = os.path.join(dst_path, str(i) + '.png') cv2.imwrite(dst_file, y_)
linux服務器無法plt.imshow() 怎么辦
https://blog.csdn.net/qq_33292662/article/details/106755325
# l = buffer[0].shape[0] # 通道數目 # plt.figure(figsize=(18,18))#如果一次展示36個,最好(18,18)。不然子圖會重疊 # for i in range(36): # y = buffer[0].data.cpu().numpy() # 處理成array格式 # y_ = y[i, :, :] # plt.subplot(6, 6, i + 1) # plt.title('{}'.format(i)) # plt.imshow(y_)#默認會自動歸一化 # #plt.tight_layout() # tight_layout會自動調整子圖參數,使之填充整個圖像區域,但會導致部分子圖不顯示 # plt.show() # 不加無法顯示圖像 # # # # plt.savefig('save_pam.png')#36張子圖一起顯示
多個通道融合為一張熱力圖
每個通道有一個權重,該通道的權重就是特征圖的均值
[c, h, w] = out[0].shape # print('buffer_left[0]',buffer_left[0].shape) # print('c h w',c,h,w) ans = np.zeros((h, w)) dst = './feautures' therd_size = 256 # 有些圖太小,會放大到這個尺寸 dst_path = os.path.join(dst) make_dirs(dst_path) ret = [] y = np.asarray(out[0].data.cpu()) # 處理成array格式 for i in range(c): y_ = y[i, :, :] ret.append(np.mean(y_))#把每個feature map的均值作為對應權重 for j in range(h): for k in range(w): for i in range(c): ans[j][k] += ret[i] * y[i][j][k]#加權融合 for i in range(h): for j in range(w): ans[i][j] = max(0, ans[i][j])#不需要負值 ans = (ans - np.min(ans)) / np.max(ans)#歸一化 print('ans\n', ans) ans = np.asarray(ans * 255, dtype=np.uint8) # [0,255] print('ans _type:', ans.dtype) # uint8 # y_ = cv2.applyColorMap(y_, cv2.COLORMAP_JET) ans = cv2.applyColorMap(ans, cv2.COLORMAP_JET) # https://www.sohu.com/a/343215045_120197868創建偽彩色 if ans.shape[0] < therd_size: # 大小調整 tmp_file = os.path.join(dst_path, str(therd_size) + 'sr.png') tmp_img = ans.copy() # 將src中的元素復制到tensor tmp_img = cv2.resize(tmp_img, (therd_size, therd_size), interpolation=cv2.INTER_NEAREST) # https://www.cnblogs.com/jyxbk/p/7651241.html cv2.imwrite(tmp_file, tmp_img) dst_file = os.path.join(dst_path, 'sr.png') cv2.imwrite(dst_file, ans) return out
[c, h, w] = buffer_left[0].shape # print('buffer_left[0]',buffer_left[0].shape) # print('c h w',c,h,w)n ans = np.zeros((h, w)) ret = [] y = np.asarray(buffer_left[0].data.cpu()) # 處理成array格式 # for i in range(c): # y_ = y[i, :, :] # ret.append(np.mean(y_)) # 把每個feature map的均值作為對應權重 for j in range(h): for k in range(w): for i in range(c): ans[j][k] += y[i][j][k] # 同等權重融合 ans = ans / c plt.figure() # plt.subplot(6, 6, i + 1 - 36) plt.title('init') plt.imshow(ans) # 默認會自動歸一化 # plt.tight_layout() # tight_layout會自動調整子圖參數,使之填充整個圖像區域,但會導致部分子圖不顯示 plt.show() # 不加無法顯示圖像 plt.savefig('save_init.png')
[c, h, w] = buffer_left[0].shape # print('buffer_left[0]',buffer_left[0].shape) # print('c h w',c,h,w)n ans = np.zeros((h, w)) ret = [] y = np.asarray(buffer_left[0].data.cpu()) # 處理成array格式 for i in range(c): y_ = y[i, :, :] ret.append(np.mean(y_)) # 把每個feature map的均值作為對應權重 for j in range(h): for k in range(w): for i in range(c): ans[j][k] += ret [i] * y[i][j][k] # 加權融合 plt.figure() # plt.subplot(6, 6, i + 1 - 36) plt.title('init') plt.imshow(ans) # 默認會自動歸一化 # plt.tight_layout() # tight_layout會自動調整子圖參數,使之填充整個圖像區域,但會導致部分子圖不顯示 plt.show() # 不加無法顯示圖像 plt.savefig('save_init.png')
結果:
同等權重融合
加權融合
CAM 可視化
參考:https://blog.csdn.net/sinat_37532065/article/details/103362517
print('out shape',out.shape) [c, h, w] = out[0].shape # print('buffer_left[0]',buffer_left[0].shape) heatmap = out.cpu().numpy() print('heat',heatmap.shape) heatmap = np.mean(heatmap, axis=0) heatmap = np.maximum(heatmap, 0) heatmap /= np.max(heatmap) print('max heat', heatmap.shape) img = cv2.imread('/home/cl/cvcnet/dataset/test/ceshi/1/hr/000000/hr0.png') print('img',img.shape) sr = np.zeros((img.shape[0], img.shape[1],3)) numc = heatmap.shape[0] print('img', img.shape) print('numx',numc) for i in range(numc): # 可視化原始熱力圖 # if visual_heatmap: # plt.matshow(heatmap) # plt.show() # img = cv2.imread('/home/cl/cvcnet/dataset/test/ceshi/2/hr/000000/hr0.png') # 用cv2加載原始圖像 heatmap = cv2.resize(heatmap[i], (img.shape[1], img.shape[0])) # 將熱力圖的大小調整為與原始圖像相同 print('heap', heatmap.shape) heatmap = np.uint8(255 * heatmap) # 將熱力圖轉換為RGB格式 heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) # 將熱力圖應用於原始圖像 print('after heap', heatmap.shape) superimposed_img = heatmap * 0.4 + img # 這里的0.4是熱力圖強度因子 print('su shape',superimposed_img.shape) sr =sr +superimposed_img # cv2.imwrite(str(i+1)+'.png', superimposed_img) sr = sr/numc cv2.imwrite('sr.png', sr)
out shape torch.Size([1, 64, 93, 310])
heat (1, 64, 93, 310)
max heat (64, 93, 310)
img (372, 1240, 3)
img (372, 1240, 3)
numx 64
heap (372, 1240)
after heap (372, 1240, 3)
su shape (372, 1240, 3)
注意如果
ERROR: TensorBoard could not bind to port 6006, it was already in use
表示目前的端口正在被使用,需要lsof -i:6006
kill -9 32683
在重新在瀏覽器輸入地址+端口才可,不要用其他的端口,不然會無法顯示曲線
上述解決方案來源於 https://blog.csdn.net/c20081052/article/details/81974847
如果第二次運行tensorboard時發現不顯示圖像,只有一個點(此時的gxz文件可能比正常的小)
那可能是上一次沒有writer.close()
調用日志書寫器實例對象summary_writer的close()方法寫入內存,否則它每隔120s寫入一次
close() 方法是把事件文件寫到硬盤,並且關閉文件,一般是在不再需要writer的時候調用這個函數。
如果
add_image() got an unexpected keyword argument 'dataformats'
請
pip install tensorboardX==1.6
如果遇到:
No dashboards are active for the current data set.
請參考:https://www.cnblogs.com/ipersevere/p/10843115.html