關於pytorch網絡模型可視化函數make_dot的一些問題

關於pytorch網絡模型可視化函數make_dot的一些問題

首先,放上make_dot函數的源碼(實驗室同門給的,出處不詳= =)

def make_dot(var, params=None):
    """
    畫出 PyTorch 自動梯度圖 autograd graph 的 Graphviz 表示.
    藍色節點表示有梯度計算的變量Variables;
    橙色節點表示用於 torch.autograd.Function 中的 backward 的張量 Tensors.

    Args:
        var: output Variable
        params: dict of (name, Variable) to add names to node that
            require grad (TODO: make optional)
    """
    if params is not None:
        assert all(isinstance(p, Variable) for p in params.values())
        param_map = {id(v): k for k, v in params.items()}

    node_attr = dict(style='filled', shape='box', align='left',
                              fontsize='12', ranksep='0.1', height='0.2')
    dot = Digraph(node_attr=node_attr, graph_attr=dict(size="12,12"))
    seen = set()

    def size_to_str(size):
        return '(' + (', ').join(['%d' % v for v in size]) + ')'

    output_nodes = (var.grad_fn,) if not isinstance(var, tuple) else tuple(v.grad_fn for v in var)

    def add_nodes(var):
        if var not in seen:
            if torch.is_tensor(var):
                # note: this used to show .saved_tensors in pytorch0.2, but stopped
                # working as it was moved to ATen and Variable-Tensor merged
                dot.node(str(id(var)), size_to_str(var.size()), fillcolor='orange')
            elif hasattr(var, 'variable'):
                u = var.variable
                name = param_map[id(u)] if params is not None else ''
                node_name = '%s\n %s' % (name, size_to_str(u.size()))
                dot.node(str(id(var)), node_name, fillcolor='lightblue')
            elif var in output_nodes:
                dot.node(str(id(var)), str(type(var).__name__), fillcolor='darkolivegreen1')
            else:
                dot.node(str(id(var)), str(type(var).__name__))
            seen.add(var)
            if hasattr(var, 'next_functions'):
                for u in var.next_functions:
                    if u[0] is not None:
                        dot.edge(str(id(u[0])), str(id(var)))
                        add_nodes(u[0])
            if hasattr(var, 'saved_tensors'):
                for t in var.saved_tensors:
                    dot.edge(str(id(t)), str(id(var)))
                    add_nodes(t)

    # 多輸出場景 multiple outputs
    if isinstance(var, tuple):
        for v in var:
            add_nodes(v.grad_fn)
    else:
        add_nodes(var.grad_fn)
    return dot

這個函數使用方法如下:

graph=make_dot(model_output,params=dict(list(model.named_parameters()))) 第一個參數是模型的輸出,第二個是模型的參數先列表化再字典化
graph.view('model_structure.pdf','.\\figure\\')  #第一個參數是文件名 第二個是保存路徑

可能會出現的問題

problem one

emmm  還是會出現一些問題的= =,因爲make_dot要用到graphviz,要注意graphviz的安裝方法,不僅在實驗環境上要安裝,還要在系統裏安裝,否則就會出現graphviz.backend.ExecutableNotFound: failed to execute ['dot', '-Tpdf', '-O', 'Digraph.gv']graphviz.backend.,make sure the Graphviz executables are on your systems' PATH這樣的錯誤([]裏的內容可能不一樣,但是問題是一樣的,而且都會有'dot'),這裏有一個博客總結的很好,————傳送門————
這裏要加一句,安裝好系統裏的呵環境裏的之後,一定要重啓python內核,至於怎麼做到我也不清楚,但是重啓電腦一定可以(›´ω`‹ ) ,因爲我就是重啓電腦之後才work的~

problem two

之後可能還會出現這樣的錯誤ImportError: cannot import name 'PILLOW_VERSION' from 'PIL',這個錯誤,就是pillow版本太高了,可以使用命令

pip install pillow==6.2.1

或者小於7.0.0的版本都行,但是注意有時候,pip安裝不上,那就用conda安裝,conda不行就用pip,還有就是編輯器內部的命令行安裝以及anaconda的prompt shell,總共有四種組合方式,分別如下:
1.在IDE內部的terminal用conda install
2.在IDE內部的terminal用pip install
3.在anaconda prompt shell 用conda install
4.在anaconda prompt shell 用pip install

有時候你安裝好了還報錯,就很有可能是沒有安裝上,這四種方式都要試一下,安裝都能出bug,我也很無奈= =

problem three

後面還有可能出現一個問題就是graphviz.backend.CalledProcessError: Command '['dot', '-Tpdf', '-O', 'model_structure.pdf']' returned non-zero exit status 1. [stderr: b'Error: Could not open "modelstructure.pdf.pdf" for writing : Permission denied\r\n'] 類似這種錯誤,這個實際上是因爲你多次調用make_dot,而調用make_dot會將畫好的模型圖打開,第二次調用就會報寫錯誤,因爲打開操作被拒絕,這個問題解決方法很簡單,加上判斷語句,只調用一次就行了~

就這麼多啦,有什麼疑問大家可以評論區交流呀!~( ˘•ω•˘ )~

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