欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

對Tensorflow中權(quán)值和feature map的可視化詳解

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

前言

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

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

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

卷積知識補充

網(wǎng)絡權(quán)值和feature map的可視化

1. 卷積知識補充

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

以從原始圖像經(jīng)過第一個卷積層得到第一組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ù)。下面我以一個簡單粗糙的圖示來展示一下圖像經(jīng)過一個卷積核的卷積得到一個feature map的過程。

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

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

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

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

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

2. 網(wǎng)絡權(quán)值和feature map的可視化

(1) 網(wǎng)絡權(quán)重參數(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ù)。

以下是我更改之后的網(wǎng)絡權(quán)重參數(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')

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

所以我對代碼做了些修改,使得其能顯示任意指定的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]]

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

使用這段代碼可視化并保存filter時,先加載模型,然后拿到我們想要可視化的那部分參數(shù),之后直接調(diào)用函數(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的可視化中,我會給出相關(guān)例子。

(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]]

神經(jīng)網(wǎng)絡一般都是一個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,那么構(gòu)建網(wǎng)絡時還要動點手腳,定義計算圖時,每得到一組激活值都要將其加到Tensorflow的collection中,如下:

tf.add_to_collection('activations', current)

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

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中是按卷積層劃分的。

最終得到的結(jié)果如下圖所示:

第一個文件夾下的全部結(jié)果:

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

相關(guān)文章

  • 談談Python:為什么類中的私有屬性可以在外部賦值并訪問

    談談Python:為什么類中的私有屬性可以在外部賦值并訪問

    這篇文章主要介紹了談談Python:為什么類中的私有屬性可以在外部賦值并訪問,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python抓取京東價格分析京東商品價格走勢

    python抓取京東價格分析京東商品價格走勢

    本文介紹使用python抓取京東價格的代碼,用于分析京東商品價格走勢或者用于其它,大家參考使用吧
    2014-01-01
  • Python常用外部指令執(zhí)行代碼實例

    Python常用外部指令執(zhí)行代碼實例

    這篇文章主要介紹了Python常用外部指令執(zhí)行代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • 淺談Python線程的同步互斥與死鎖

    淺談Python線程的同步互斥與死鎖

    這篇文章主要介紹了淺談Python線程的同步互斥與死鎖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • python for循環(huán)remove同一個list過程解析

    python for循環(huán)remove同一個list過程解析

    這篇文章主要介紹了python for循環(huán)remove同一個list過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • ?python用matplotlib可視化繪圖詳解

    ?python用matplotlib可視化繪圖詳解

    這篇文章主要介紹了?python用matplotlib可視化繪圖詳解,Matplotlib?是一個python的?2D繪圖庫,它以各種硬拷貝格式和跨平臺的交互式環(huán)境生成出版質(zhì)量級別的圖形,下面我們就來看看關(guān)于matplotlib可視化繪圖的詳細過程吧
    2022-01-01
  • python 如何用terminal輸入?yún)?shù)

    python 如何用terminal輸入?yún)?shù)

    這篇文章主要介紹了python 如何用terminal輸入?yún)?shù)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python中enumerate函數(shù)遍歷元素用法分析

    python中enumerate函數(shù)遍歷元素用法分析

    這篇文章主要介紹了python中enumerate函數(shù)遍歷元素用法,結(jié)合實例形式分析了enumerate函數(shù)遍歷元素的相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-03-03
  • pytest-fixture簡介及其用法講解

    pytest-fixture簡介及其用法講解

    這篇文章主要介紹了pytest-fixture及其用法,最基本的用法就是一個fixture作為一個測試用例的參數(shù)傳入,然后就可以在該測試用例中使用該fixture,需要的朋友可以參考下
    2023-01-01
  • PyQt4 treewidget 選擇改變顏色,并設置可編輯的方法

    PyQt4 treewidget 選擇改變顏色,并設置可編輯的方法

    今天小編就為大家分享一篇PyQt4 treewidget 選擇改變顏色,并設置可編輯的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06

最新評論