2017-02-27 10 views
21

何か方法はありますか?model.summary()のように、PyTorchのモデルの要約を次のように印刷できますか?モデルの概要をpytorchで

Model Summary: 
____________________________________________________________________________________________________ 
Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_1 (InputLayer)    (None, 1, 15, 27)  0            
____________________________________________________________________________________________________ 
convolution2d_1 (Convolution2D) (None, 8, 15, 27)  872   input_1[0][0]      
____________________________________________________________________________________________________ 
maxpooling2d_1 (MaxPooling2D) (None, 8, 7, 27)  0   convolution2d_1[0][0]    
____________________________________________________________________________________________________ 
flatten_1 (Flatten)    (None, 1512)   0   maxpooling2d_1[0][0]    
____________________________________________________________________________________________________ 
dense_1 (Dense)     (None, 1)    1513  flatten_1[0][0]     
==================================================================================================== 
Total params: 2,385 
Trainable params: 2,385 
Non-trainable params: 0 
+0

は、モジュール上state_dict()メソッドを見てきました?これは、モデルのさまざまなパラメータを提供します。ダイレクトサマリーメソッドはありませんが、state_dict()メソッドを使用してフォームを作成できます – Kashyap

答えて

22

しばらくのような素敵なvisualizatonを与えるszagoruykoによってscriptを参照することができますKerasのmodel.summaryのように、モデルに関する詳細な情報は得られません。モデルを印刷するだけで、関連するさまざまなレイヤーとその仕様についていくつかのアイデアが得られます。例えば

from torchvision import models 
model = models.vgg16() 
print(model) 

次のようにこの場合の出力は、何かのようになります。

VGG (
    (features): Sequential (
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (1): ReLU (inplace) 
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (3): ReLU (inplace) 
    (4): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (6): ReLU (inplace) 
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (8): ReLU (inplace) 
    (9): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (11): ReLU (inplace) 
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (13): ReLU (inplace) 
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (15): ReLU (inplace) 
    (16): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (18): ReLU (inplace) 
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (20): ReLU (inplace) 
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (22): ReLU (inplace) 
    (23): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (25): ReLU (inplace) 
    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (27): ReLU (inplace) 
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 
    (29): ReLU (inplace) 
    (30): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
) 
    (classifier): Sequential (
    (0): Dropout (p = 0.5) 
    (1): Linear (25088 -> 4096) 
    (2): ReLU (inplace) 
    (3): Dropout (p = 0.5) 
    (4): Linear (4096 -> 4096) 
    (5): ReLU (inplace) 
    (6): Linear (4096 -> 1000) 
) 
) 

今、あなたは、Kashyapで述べたように、の重みを取得するためにstate_dictメソッドを使用することができます異なる層。しかし、このレイヤーのリストを使用することは、モデルの要約のようなKerasを得るためのヘルパー関数を作成することで、おそらくより多くの方向性を提供するでしょう!お役に立てれば!

1

AFAK何model.summaryは(ありません)と同等のようなpytorch

における一方あなたはresnet18-example

乾杯

10

これは、モデルの重みとパラメータを表示します(出力形状は表示されません)。

from torch.nn.modules.module import _addindent 
import torch 
import numpy as np 
def torch_summarize(model, show_weights=True, show_parameters=True): 
    """Summarizes torch model by showing trainable parameters and weights.""" 
    tmpstr = model.__class__.__name__ + ' (\n' 
    for key, module in model._modules.items(): 
     # if it contains layers let call it recursively to get params and weights 
     if type(module) in [ 
      torch.nn.modules.container.Container, 
      torch.nn.modules.container.Sequential 
     ]: 
      modstr = torch_summarize(module) 
     else: 
      modstr = module.__repr__() 
     modstr = _addindent(modstr, 2) 

     params = sum([np.prod(p.size()) for p in module.parameters()]) 
     weights = tuple([tuple(p.size()) for p in module.parameters()]) 

     tmpstr += ' (' + key + '): ' + modstr 
     if show_weights: 
      tmpstr += ', weights={}'.format(weights) 
     if show_parameters: 
      tmpstr += ', parameters={}'.format(params) 
     tmpstr += '\n' 

    tmpstr = tmpstr + ')' 
    return tmpstr 

# Test 
import torchvision.models as models 
model = models.alexnet() 
print(torch_summarize(model)) 

# # Output 
# AlexNet (
# (features): Sequential (
#  (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2)), weights=((64, 3, 11, 11), (64,)), parameters=23296 
#  (1): ReLU (inplace), weights=(), parameters=0 
#  (2): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0 
#  (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)), weights=((192, 64, 5, 5), (192,)), parameters=307392 
#  (4): ReLU (inplace), weights=(), parameters=0 
#  (5): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0 
#  (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((384, 192, 3, 3), (384,)), parameters=663936 
#  (7): ReLU (inplace), weights=(), parameters=0 
#  (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((256, 384, 3, 3), (256,)), parameters=884992 
#  (9): ReLU (inplace), weights=(), parameters=0 
#  (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((256, 256, 3, 3), (256,)), parameters=590080 
#  (11): ReLU (inplace), weights=(), parameters=0 
#  (12): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0 
# ), weights=((64, 3, 11, 11), (64,), (192, 64, 5, 5), (192,), (384, 192, 3, 3), (384,), (256, 384, 3, 3), (256,), (256, 256, 3, 3), (256,)), parameters=2469696 
# (classifier): Sequential (
#  (0): Dropout (p = 0.5), weights=(), parameters=0 
#  (1): Linear (9216 -> 4096), weights=((4096, 9216), (4096,)), parameters=37752832 
#  (2): ReLU (inplace), weights=(), parameters=0 
#  (3): Dropout (p = 0.5), weights=(), parameters=0 
#  (4): Linear (4096 -> 4096), weights=((4096, 4096), (4096,)), parameters=16781312 
#  (5): ReLU (inplace), weights=(), parameters=0 
#  (6): Linear (4096 -> 1000), weights=((1000, 4096), (1000,)), parameters=4097000 
# ), weights=((4096, 9216), (4096,), (4096, 4096), (4096,), (1000, 4096), (1000,)), parameters=58631144 
#) 

編集:isaykatsmanは正確にkeras https://github.com/pytorch/pytorch/pull/3043/files

+0

グレートコード!これはあなたが書いたことですか? – acgtyrant

+1

ありがとう、ええ:)私はトーチ__repr__から借りてきましたが、それを再帰的にして、ケラのようなより多くの情報を与えました。 – wassname

+0

更新コード:https://gist.github.com/wassname/0fb8f95e4272e6bdd27bd7df386716b7/ – wassname