最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

對Tensorflow中權值和feature map的可視化詳解

 更新時間:2018年06月14日 09:52:39   作者:無空ty  
今天小編就為大家分享一篇對Tensorflow中權值和feature map的可視化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

前言

Tensorflow中可以使用tensorboard這個強大的工具對計算圖、loss、網絡參數(shù)等進行可視化。本文并不涉及對tensorboard使用的介紹,而是旨在說明如何通過代碼對網絡權值和feature map做更靈活的處理、顯示和存儲。本文的相關代碼主要參考了github上的一個小項目,但是對其進行了改進。

原項目地址為(https://github.com/grishasergei/conviz)。

本文將從以下兩個方面進行介紹:

卷積知識補充

網絡權值和feature map的可視化

1. 卷積知識補充

為了后面方便講解代碼,這里先對卷積的部分知識進行一下簡介。關于卷積核如何在圖像的一個通道上進行滑動計算,網上有諸多資料,相信對卷積神經網絡有一定了解的讀者都應該比較清楚,本文就不再贅述。這里主要介紹一組卷積核如何在一幅圖像上計算得到一組feature map。

以從原始圖像經過第一個卷積層得到第一組feature map為例(從得到的feature map到再之后的feature map也是同理),假設第一組feature map共有64個,那么可以把這組feature map也看作一幅圖像,只不過它的通道數(shù)是64, 而一般意義上的圖像是RGB3個通道。為了得到這第一組feature map,我們需要64個卷積核,每個卷積核是一個k x k x 3的矩陣,其中k是卷積核的大?。僭O是正方形卷積核),3就對應著輸入圖像的通道數(shù)。下面我以一個簡單粗糙的圖示來展示一下圖像經過一個卷積核的卷積得到一個feature map的過程。

如圖所示,其實可以看做卷積核的每一通道(不太準確,將就一下)和圖像的每一通道對應進行卷積操作,然后再逐位置相加,便得到了一個feature map。

那么用一組(64個)卷積核去卷積一幅圖像,得到64個feature map就如下圖所示,也就是每個卷積核得到一個feature map,64個卷積核就得到64個feature map。

另外,也可以稍微換一個角度看待這個問題,那就是先讓圖片的某一通道分別與64個卷積核的對應通道做卷積,得到64個feature map的中間結果,之后3個通道對應的中間結果再相加,得到最終的feature map,如下圖所示:

可以看到這其實就是第一幅圖擴展到多卷積核的情形,圖畫得較為粗糙,有些中間結果和最終結果直接用了一樣的子圖,理解時請稍微注意一下。下面代碼中對卷積核進行展示的時候使用的就是這種方式,即對應著輸入圖像逐通道的去顯示卷積核的對應通道,而不是每次顯示一個卷積核的所有通道,可能解釋的有點繞,需要注意一下。通過下面這個小圖也許更好理解。

圖中用紅框圈出的部分即是我們一次展示出的權重參數(shù)。

2. 網絡權值和feature map的可視化

(1) 網絡權重參數(shù)可視化

首先介紹一下Tensorflow中卷積核的形狀,如下代碼所示:

weights = tf.Variable(tf.random_normal([filter_size, filter_size, channels, filter_num]))

前兩維是卷積核的高和寬,第3維是上一層feature map的通道數(shù),在第一節(jié)(卷積知識補充)中,我提到了上一層的feature map有多少個(也就是通道數(shù)是多少),那么對應著一個卷積核也要有這么多通道。第4維是當前卷積層的卷積核數(shù)量,也是當前層輸出的feature map的通道數(shù)。

以下是我更改之后的網絡權重參數(shù)(卷積核)的可視化代碼:

from __future__ import print_function

#import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import os
import visualize_utils


def plot_conv_weights(weights, plot_dir, name, channels_all=True, filters_all=True, channels=[0], filters=[0]):
 """
 Plots convolutional filters
 :param weights: numpy array of rank 4
 :param name: string, name of convolutional layer
 :param channels_all: boolean, optional
 :return: nothing, plots are saved on the disk
 """

 w_min = np.min(weights)
 w_max = np.max(weights)

 # make a list of channels if all are plotted
 if channels_all:
 channels = range(weights.shape[2])

 # get number of convolutional filters
 if filters_all:
 num_filters = weights.shape[3]
 filters = range(weights.shape[3])
 else:
 num_filters = len(filters)

 # get number of grid rows and columns
 grid_r, grid_c = visualize_utils.get_grid_dim(num_filters)

 # create figure and axes
 fig, axes = plt.subplots(min([grid_r, grid_c]),
    max([grid_r, grid_c]))

 # iterate channels
 for channel_ID in channels:
 # iterate filters inside every channel
 if num_filters == 1:
  img = weights[:, :, channel_ID, filters[0]]
  axes.imshow(img, vmin=w_min, vmax=w_max, interpolation='nearest', cmap='seismic')
  # remove any labels from the axes
  axes.set_xticks([])
  axes.set_yticks([])
 else:
  for l, ax in enumerate(axes.flat):
  # get a single filter
  img = weights[:, :, channel_ID, filters[l]]
  # put it on the grid
  ax.imshow(img, vmin=w_min, vmax=w_max, interpolation='nearest', cmap='seismic')
  # remove any labels from the axes
  ax.set_xticks([])
  ax.set_yticks([])
 # save figure
 plt.savefig(os.path.join(plot_dir, '{}-{}.png'.format(name, channel_ID)), bbox_inches='tight')

原項目的代碼是對某一層的權重參數(shù)或feature map在一個網格中進行全部展示,如果參數(shù)或feature map太多,那么展示出來的結果中每個圖都很小,很難看出有用的東西來,如下圖所示:

所以我對代碼做了些修改,使得其能顯示任意指定的filter或feature map。

代碼中,

w_min = np.min(weights)
w_max = np.max(weights)

這兩句是為了后續(xù)顯示圖像用的,具體可查看matplotlib.pyplot的imshow()函數(shù)進行了解。

接下來是判斷是否顯示全部的channel(通道數(shù))或全部filter。如果是,那就和原代碼一致了。若不是,則畫出函數(shù)參數(shù)channels和filters指定的filter來。

再往下的兩句代碼是畫圖用的,我們可能會在一個圖中顯示多個子圖,以下這句是為了計算出大圖分為幾行幾列比較合適(一個大圖會盡量分解為方形的陣列,比如如果有64個子圖,那么就分成8 x 8的陣列),代碼細節(jié)可在原項目中的utils中找到。

grid_r, grid_c = visualize_utils.get_grid_dim(num_filters)

實際畫圖時,如果想要一個圖一個圖的去畫,需要單獨處理一下。如果還是想在一個大圖中顯示多個子圖,就按源代碼的方式去做,只不過這里可以顯示我們自己指定的那些filter,而不是不加篩選地全部輸出。主要拿到數(shù)據(jù)的是以下這句代碼:

img = weights[:, :, channel_ID, filters[l]]

剩下的都是是畫圖相關的函數(shù)了,本文就不再對畫圖做更多介紹了。

使用這段代碼可視化并保存filter時,先加載模型,然后拿到我們想要可視化的那部分參數(shù),之后直接調用函數(shù)就可以了,如下所示:

with tf.Session(graph=tf.get_default_graph()) as sess: 
 init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
 sess.run(init_op)
 saver.restore(sess, model_path)

 with tf.variable_scope('inference', reuse=True):
  conv_weights = tf.get_variable('conv3_1_w').eval()
  visualize.plot_conv_weights(conv_weights, dir_prefix, 'conv3_1')

這里并沒有對filter進行額外的指定,在feature map的可視化中,我會給出相關例子。

(2) feature map可視化

其實feature map的可視化與filter非常相似,只有細微的不同。還是先把完整代碼貼上。

def plot_conv_output(conv_img, plot_dir, name, filters_all=True, filters=[0]):
 w_min = np.min(conv_img)
 w_max = np.max(conv_img)

 # get number of convolutional filters
 if filters_all:
 num_filters = conv_img.shape[3]
 filters = range(conv_img.shape[3])
 else:
 num_filters = len(filters)

 # get number of grid rows and columns
 grid_r, grid_c = visualize_utils.get_grid_dim(num_filters)

 # create figure and axes
 fig, axes = plt.subplots(min([grid_r, grid_c]),
    max([grid_r, grid_c]))

 # iterate filters
 if num_filters == 1:
 img = conv_img[0, :, :, filters[0]]
 axes.imshow(img, vmin=w_min, vmax=w_max, interpolation='bicubic', cmap=cm.hot)
 # remove any labels from the axes
 axes.set_xticks([])
 axes.set_yticks([])
 else:
 for l, ax in enumerate(axes.flat):
  # get a single image
  img = conv_img[0, :, :, filters[l]]
  # put it on the grid
  ax.imshow(img, vmin=w_min, vmax=w_max, interpolation='bicubic', cmap=cm.hot)
  # remove any labels from the axes
  ax.set_xticks([])
  ax.set_yticks([])
 # save figure
 plt.savefig(os.path.join(plot_dir, '{}.png'.format(name)), bbox_inches='tight')

代碼中和filter可視化相同的部分就不再贅述了,這里只講feature map可視化獨特的方面,其實就在于以下這句代碼,也就是要可視化的數(shù)據(jù)的獲得:

img = conv_img[0, :, :, filters[0]]

神經網絡一般都是一個batch一個batch的輸入數(shù)據(jù),其輸入的形狀為

image = tf.placeholder(tf.float32, shape = [None, IMAGE_SIZE, IMAGE_SIZE, 3], name = "input_image")

第一維是一個batch中圖片的數(shù)量,為了靈活可以設置為None,Tensorflow會根據(jù)實際輸入的數(shù)據(jù)進行計算。二三維是圖片的高和寬,第4維是圖片通道數(shù),一般為3。

如果我們想要輸入一幅圖片,然后看看它的激活值(feature map),那么也要按照以上維度以一個batch的形式進行輸入,也就是[1, IMAGE_SIZE, IMAGE_SIZE, 3]。所以拿feature map數(shù)據(jù)時,第一維度肯定是取0(就對應著batch中的當前圖片),二三維取全部,第4維度再取我們想要查看的feature map的某一通道。

如果想要可視化feature map,那么構建網絡時還要動點手腳,定義計算圖時,每得到一組激活值都要將其加到Tensorflow的collection中,如下:

tf.add_to_collection('activations', current)

而實際進行feature map可視化時,就要先輸入一幅圖片,然后運行網絡拿到相應數(shù)據(jù),最后把數(shù)據(jù)傳參給可視化函數(shù)。以下這個例子展示的是如何將每個指定卷積層的feature map的每個通道進行單獨的可視化與存儲,使用的是VGG16網絡:

visualize_layers = ['conv1_1', 'conv1_2', 'conv2_1', 'conv2_2', 'conv3_1', 'conv3_2', 'conv3_3', 'conv4_1', 'conv4_2', 'conv4_3', 'conv5_1', 'conv5_2', 'conv5_3']

with tf.Session(graph=tf.get_default_graph()) as sess: 
 init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
 sess.run(init_op)
 saver.restore(sess, model_path)

 image_path = root_path + 'images/train_images/sunny_0058.jpg'
 img = misc.imread(image_path)
 img = img - meanvalue
 img = np.float32(img)
 img = np.expand_dims(img, axis=0)

 conv_out = sess.run(tf.get_collection('activations'), feed_dict={x: img, keep_prob: 1.0})
 for i, layer in enumerate(visualize_layers):
  visualize_utils.create_dir(dir_prefix + layer)
  for j in range(conv_out[i].shape[3]):
  visualize.plot_conv_output(conv_out[i], dir_prefix + layer, str(j), filters_all=False, filters=[j])

 sess.close()

其中,conv_out包含了所有加入到collection中的feature map,這些feature map在conv_out中是按卷積層劃分的。

最終得到的結果如下圖所示:

第一個文件夾下的全部結果:

以上這篇對Tensorflow中權值和feature map的可視化詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • python生成可執(zhí)行exe控制Microsip自動填寫號碼并撥打功能

    python生成可執(zhí)行exe控制Microsip自動填寫號碼并撥打功能

    這篇文章主要介紹了python生成可執(zhí)行exe控制Microsip自動填寫號碼并撥打,在這需要注意一個問題,必須是已經運行Microsip.exe文件,具體實現(xiàn)代碼跟隨小編一起看看吧
    2021-06-06
  • python編程開發(fā)時間序列calendar模塊示例詳解

    python編程開發(fā)時間序列calendar模塊示例詳解

    這篇文章主要為大家介紹了python編程開發(fā)時間序列calendar模塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進步早日升職加薪
    2021-11-11
  • Win10下python 2.7.13 安裝配置方法圖文教程

    Win10下python 2.7.13 安裝配置方法圖文教程

    這篇文章主要為大家詳細介紹了Win10下python 2.7.13 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • python爬蟲模擬登錄之圖片驗證碼實現(xiàn)詳解

    python爬蟲模擬登錄之圖片驗證碼實現(xiàn)詳解

    眾所周知python是一個很強大的語言,它擁有眾多的庫,今天我嘗試了使用python進行驗證碼的識別,下面這篇文章主要給大家介紹了關于python爬蟲模擬登錄之圖片驗證碼實現(xiàn)的相關資料,需要的朋友可以參考下
    2022-08-08
  • Python集合基本概念與相關操作實例分析

    Python集合基本概念與相關操作實例分析

    這篇文章主要介紹了Python集合基本概念與相關操作,結合實例形式分析了Python集合的功能、原理、基本使用方法及操作注意事項,需要的朋友可以參考下
    2019-10-10
  • Python操作MySQL數(shù)據(jù)庫的方法

    Python操作MySQL數(shù)據(jù)庫的方法

    pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。接下來通過本文給大家介紹Python操作MySQL數(shù)據(jù)庫的方法,感興趣的朋友一起看看吧
    2018-06-06
  • Python關于print的操作(倒計時、轉圈顯示、進度條)

    Python關于print的操作(倒計時、轉圈顯示、進度條)

    這篇文章主要介紹了Python關于print的操作(倒計時、轉圈顯示、進度條),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 分享8?個常用pandas的?index設置

    分享8?個常用pandas的?index設置

    這篇文章主要介紹了分享8?個常用pandas的?index設置,pandas?中的?index?是行索引或行標簽。行標簽可以說是?pandas?的靈魂一簽,支撐了?pandas?很多強大的業(yè)務功能,比如多個數(shù)據(jù)框的?join,?merge?操作,自動對齊等,下面來看看文章得具體介紹吧
    2021-12-12
  • 快速進修Python指南之簡易跳表

    快速進修Python指南之簡易跳表

    這篇文章主要為大家介紹了Java開發(fā)者快速進修Python指南之簡易跳表示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • python使用 HTMLTestRunner.py生成測試報告

    python使用 HTMLTestRunner.py生成測試報告

    這篇文章主要介紹了python使用 HTMLTestRunner.py生成測試報告 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評論

临清市| 英德市| 芒康县| 望奎县| 来凤县| 自贡市| 谢通门县| 左云县| 佛教| 长子县| 阿图什市| 安图县| 于田县| 乌兰察布市| 丰都县| 保靖县| 萝北县| 垣曲县| 旅游| 丁青县| 南昌市| 健康| 醴陵市| 吉林省| 普定县| 朝阳市| 定边县| 肥东县| 清水县| 九台市| 兴业县| 屏南县| 景洪市| 西丰县| 西华县| 黑山县| 靖边县| 灌云县| 随州市| 武功县| 印江|