質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3833閲覧

Pytorchでnn.ModuleListで作成したモデルのtorchsummaryによる表示結果に不整合がある

mikan_professor

総合スコア28

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/04/07 13:15

編集2021/04/15 08:26

pytorchにて以下のAlexNetのコードを書きました。
torchsummaryにてモデルを確認しようとしたところ、すべてが二回繰り返されて表示されました。

コードは間違っていない気がするのですが、原因を知りたいです。

Python

1import torch 2import torch.nn as nn 3import torch.nn.functional as F 4import torchsummary 5 6 7class AlexNet(nn.Module): 8 def __init__(self, conv_channels_list=[96, 256, 384, 384, 256]): 9 super(AlexNet, self).__init__() 10 11 self.layer1 = nn.Sequential( 12 nn.Conv2d( 13 in_channels=3, 14 out_channels=conv_channels_list[0], 15 kernel_size=11, 16 stride=4, 17 padding=2 18 ), 19 nn.MaxPool2d(kernel_size=3, stride=2), 20 nn.LocalResponseNorm(size=5, k=2), 21 nn.ReLU(inplace=True) 22 ) 23 24 self.layer2 = nn.Sequential( 25 nn.Conv2d( 26 in_channels=conv_channels_list[0], 27 out_channels=conv_channels_list[1], 28 kernel_size=3, 29 padding=1, 30 ), 31 nn.MaxPool2d(kernel_size=3, stride=2), 32 nn.LocalResponseNorm(size=5, k=2), 33 nn.ReLU(inplace=True) 34 ) 35 36 self.layer3 = nn.Sequential( 37 nn.Conv2d( 38 in_channels=conv_channels_list[1], 39 out_channels=conv_channels_list[2], 40 kernel_size=3, 41 padding=1, 42 ), 43 nn.ReLU(inplace=True) 44 ) 45 46 self.layer4 = nn.Sequential( 47 nn.Conv2d( 48 in_channels=conv_channels_list[2], 49 out_channels=conv_channels_list[3], 50 kernel_size=3, 51 padding=1, 52 ), 53 nn.ReLU(inplace=True) 54 ) 55 56 self.layer5 = nn.Sequential( 57 nn.Conv2d( 58 in_channels=conv_channels_list[3], 59 out_channels=conv_channels_list[4], 60 kernel_size=3, 61 padding=1, 62 ), 63 nn.MaxPool2d(kernel_size=3, stride=2), 64 nn.ReLU(inplace=True), 65 nn.Flatten() 66 ) 67 68 self.layer6 = nn.Sequential( 69 nn.Linear(9216, 4096), 70 nn.Dropout(p=0.5), 71 nn.ReLU(inplace=True) 72 ) 73 74 self.layer7 = nn.Sequential( 75 nn.Linear(4096, 4096), 76 nn.Dropout(p=0.5), 77 nn.ReLU(inplace=True) 78 ) 79 80 self.layer8 = nn.Sequential( 81 nn.Linear(4096, 1000), 82 nn.Softmax(dim=1) 83 ) 84 85 self.layers = nn.ModuleList([ 86 self.layer1, 87 self.layer2, 88 self.layer3, 89 self.layer4, 90 self.layer5, 91 self.layer6, 92 self.layer7, 93 self.layer8, 94 ]) 95 96 def forward(self, x): 97 for layer in self.layers: 98 x = layer(x) 99 return x 100 101 102 103device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 104net = AlexNet() 105net = net.to(device) 106 107torchsummary.summary(net, input_size=(3, 224, 224))

bash

1---------------------------------------------------------------- 2 Layer (type) Output Shape Param # 3================================================================ 4 Conv2d-1 [-1, 96, 55, 55] 34,944 5 Conv2d-2 [-1, 96, 55, 55] 34,944 6 MaxPool2d-3 [-1, 96, 27, 27] 0 7 MaxPool2d-4 [-1, 96, 27, 27] 0 8 LocalResponseNorm-5 [-1, 96, 27, 27] 0 9 LocalResponseNorm-6 [-1, 96, 27, 27] 0 10 ReLU-7 [-1, 96, 27, 27] 0 11 ReLU-8 [-1, 96, 27, 27] 0 12 Conv2d-9 [-1, 256, 27, 27] 221,440 13 Conv2d-10 [-1, 256, 27, 27] 221,440 14 MaxPool2d-11 [-1, 256, 13, 13] 0 15 MaxPool2d-12 [-1, 256, 13, 13] 0 16LocalResponseNorm-13 [-1, 256, 13, 13] 0 17LocalResponseNorm-14 [-1, 256, 13, 13] 0 18 ReLU-15 [-1, 256, 13, 13] 0 19 ReLU-16 [-1, 256, 13, 13] 0 20 Conv2d-17 [-1, 384, 13, 13] 885,120 21 Conv2d-18 [-1, 384, 13, 13] 885,120 22 ReLU-19 [-1, 384, 13, 13] 0 23 ReLU-20 [-1, 384, 13, 13] 0 24 Conv2d-21 [-1, 384, 13, 13] 1,327,488 25 Conv2d-22 [-1, 384, 13, 13] 1,327,488 26 ReLU-23 [-1, 384, 13, 13] 0 27 ReLU-24 [-1, 384, 13, 13] 0 28 Conv2d-25 [-1, 256, 13, 13] 884,992 29 Conv2d-26 [-1, 256, 13, 13] 884,992 30 MaxPool2d-27 [-1, 256, 6, 6] 0 31 MaxPool2d-28 [-1, 256, 6, 6] 0 32 ReLU-29 [-1, 256, 6, 6] 0 33 ReLU-30 [-1, 256, 6, 6] 0 34 Flatten-31 [-1, 9216] 0 35 Flatten-32 [-1, 9216] 0 36 Linear-33 [-1, 4096] 37,752,832 37 Linear-34 [-1, 4096] 37,752,832 38 Dropout-35 [-1, 4096] 0 39 Dropout-36 [-1, 4096] 0 40 ReLU-37 [-1, 4096] 0 41 ReLU-38 [-1, 4096] 0 42 Linear-39 [-1, 4096] 16,781,312 43 Linear-40 [-1, 4096] 16,781,312 44 Dropout-41 [-1, 4096] 0 45 Dropout-42 [-1, 4096] 0 46 ReLU-43 [-1, 4096] 0 47 ReLU-44 [-1, 4096] 0 48 Linear-45 [-1, 1000] 4,097,000 49 Linear-46 [-1, 1000] 4,097,000 50 Softmax-47 [-1, 1000] 0 51 Softmax-48 [-1, 1000] 0 52================================================================ 53Total params: 123,970,256 54Trainable params: 123,970,256 55Non-trainable params: 0 56---------------------------------------------------------------- 57Input size (MB): 0.57 58Forward/backward pass size (MB): 17.91 59Params size (MB): 472.91 60Estimated Total Size (MB): 491.39 61----------------------------------------------------------------

=================補足====================
nn.ModuleListを通常のリストとした場合は正しく動いたのですが、以下のように新しいモデルを継承により作った場合に、エラーが発生しました。

Python

1class ZFNet(AlexNet): 2 def __init__(self, conv_channels_list=[96, 256, 384, 384, 256]): 3 super(ZFNet, self).__init__() 4 self.layer1 = nn.Sequential( 5 nn.Conv2d( 6 in_channels=3, 7 out_channels=conv_channels_list[0], 8 kernel_size=7, 9 stride=2, 10 padding=2 11 ), 12 nn.MaxPool2d(kernel_size=3, stride=2), 13 nn.LocalResponseNorm(size=5, k=2), 14 nn.ReLU(inplace=True) 15 ) 16

bash

1Traceback (most recent call last): 2 File "/home/〇〇/workspace/machineLearning/popularModel/alexNet.py", line 824, in <module> 3 summary(net, input_size=(3, 224, 224)) 4 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torchsummary/torchsummary.py", line 72, in summary 5 model(*x) 6 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/module.py", line 889, in _call_impl 7 result = self.forward(*input, **kwargs) 8 File "/home/〇〇/workspace/machineLearning/popularModel/alexNet.py", line 161, in forward 9 x = layer(x) 10 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/module.py", line 889, in _call_impl 11 result = self.forward(*input, **kwargs) 12 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/container.py", line 119, in forward 13 input = module(input) 14 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/module.py", line 889, in _call_impl 15 result = self.forward(*input, **kwargs) 16 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 399, in forward 17 return self._conv_forward(input, self.weight, self.bias) 18 File "/home/〇〇/.local/share/virtualenvs/machineLearning-WvLHzLrB/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 395, in _conv_forward 19 return F.conv2d(input, weight, bias, self.stride, 20RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same

modelはGPUに乗せており、printでも確認できました。このエラーの理由も教えていただきたいです。

-----------補足追加----------------

以下が全体のコードです。
ModuleListからリストに変え、ZFnetを使ったものです。

Python

1import 同様 2 3 4class AlexNet(nn.Module): 5 6 //最初のコードと同様。文字数制限にて省略 7 //self.layersをModuleListからListに変更 8 9 10 self.layers = [ 11 self.layer1, 12 self.layer2, 13 self.layer3, 14 self.layer4, 15 self.layer5, 16 self.layer6, 17 self.layer7, 18 self.layer8, 19 ] 20 21 def forward(self, x): 22 同様 23 24 25class ZFNet(AlexNet): 26 同様 27 28 29device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 30net = ZFNet() 31net = net.to(device) 32 33torchsummary.summary(net, input_size=(3, 224, 224))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikan_professor

2021/04/08 01:38

わかりました!ありがとうございます。
guest

回答1

0

ベストアンサー

nn.ModuleListの使い方が間違っています。

PyTorchのモジュールは、フォワードメソッドと、各層のパラメータリストを保持最適化する構造になっています。質問者様のコードは、フォワードメソッドは意図通り動作すると思いますが、__init__で各層とModuleListでまとめた層のパラメータリストを二重に登録してしまっています。なお、余計なものが登録されているというだけで、動作は正常かもしれません。

修正する方針は2種類あります。

  1. __init__で、self.layersnn.ModuleListは使わずに通常のリストとする。こうすると、self.layersはモジュールとして認識されませんので、パラメータリストは登録されません。フォワードメソッド側だけで使われます。

  2. __init__で、各階層self.layerxをモジュールのメンバ変数としてとして登録するのはやめて、layerxというローカル変数にして、nn.ModuleListは各ローカル変数をモジュールリストにしてモジュールのメンバ変数として登録する。この場合、各層の名前は残りませんが、インデックスでアクセス可能になるという利点があります。

投稿2021/04/07 23:30

toast-uz

総合スコア3266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikan_professor

2021/04/07 23:38

ご回答ありがとうございます。 1) 通常のリストは一番最初に試し、動作したのですが、このAlexNetを継承して別のモデルを作成し、layerを書き換えた場合に、エラーが発生しました。(補足参照) この原因もわからないのですが、教えていただけますでしょうか。 2)試してみます。ありがとうございます。
toast-uz

2021/04/08 03:53

補足のどこでエラーが出ていますでしょうか?
mikan_professor

2021/04/08 10:33

エラーに詳細を追記しました。 forward内の最初のconvでしょうか。
toast-uz

2021/04/08 15:28

いえ、ZFNetのクラスを書いて実行しただけでエラーが出たのか?という質問です。
mikan_professor

2021/04/09 05:50

はい、netをZFNetに変更し、同じコードを実行したのみです。
toast-uz

2021/04/10 23:29 編集

> はい、netをZFNetに変更し、同じコードを実行したのみです。 これは、はい、ZFNetのクラスを書いて実行した「だけではなく、さらに」netをZFNetに変更し、同じコードを実行した、ということですね?「クラスを書いただけで、それ以上何もしないのに実行してエラーが出たのですか?」という、私の質問の意図が伝わらなかったようです。私の質問の意図通りだと、質問者様の答えは「いいえ」ですね。 よって、質問文に書かれた > 新しいモデルを継承で作ったらエラーが出た も正確ではなく、新しいモデルを継承で作って「同様にオブジェクトをGPUにロードしてtorchsummaryをしたらエラーが出た」ということが暗黙に省略されているものと思います。 どう書き換えたか含め、暗黙にせず、質問文に明記修正お願いします。
toast-uz

2021/04/10 23:30 編集

計算をするのが大変ですが、単純に、層を書き換えたのでinput_sizeが変わったにもかかわわらず、同じサイズでtorchsummaryしたから怒られただけだと思います。それを確定するために、質問者様の完全なコードが必要です。実際、サイズ指定が不要なtorchinfoは普通に実行できます。
mikan_professor

2021/04/15 08:27

追記しました。すみませんが文字数制限で完全なコードはあげられず、以前の部分と変更がないところは同様と記述しております。
toast-uz

2021/04/15 09:26

ありがとうございます。「層を書き換えたのでinput_sizeが変わったにもかかわわらず、同じサイズでtorchsummaryしたから怒られた」で確定だと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問