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

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

ただいまの
回答率

89.09%

pytorch なぜ400*400の画像でモデルを動かしただけなのに10gbメモリが足りなくなるんですか?

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 211

Flan.

score 17

メモリ使用の確認は タスクマネージャー

for _ in range(30):
    next_state=mask_input(np.random.rand(1,400,400,3))
    action=mainQN.forward(next_state,"net_a")
    reward=1
    print(action.is_cuda,next_state.is_cuda)


推論 画像をいれてモデルを動かす 関係ない部分を消すためrandnを使ってる
is_cudaの結果は当然false
mask_inputは型を変換to(cuda)は使用してないためこれが原因のはずはない
こっち単体で動かしても まったくメモリは侵食されません

memory.add((next_state, action, reward))  # メモリの更新する


インプットとアウトプットを保存する
これ単体で動かしても まったくメモリは侵食されません

for _ in range(30):
    next_state=mask_input(np.random.rand(1,400,400,3))
    action=mainQN.forward(next_state,"net_a")
    reward=1
    print(action.is_cuda,next_state.is_cuda)
    memory.add((next_state, action, reward))  # メモリの更新する


ですがなぜか上の二つを組み合わせると10gbのgpuメモリが半分以上侵食されます
単体に原因があるならわかるのですが
なぜ組み合わせたらおかしなことになるのですか?is_cudaの結果はもちろんfalse

もしかしてだが pytorchは計算結果すべて保存してる?
でもそうならmemory.addと組みあせなくてもメモリが悲惨なことになるはず
原因がわかりません わかる人教えてください
コード全体 関係ないとこは省略

class QNetwork(nn.Module):
    def __init__(self, num_inputs, num_outputs):
        super(QNetwork, self).__init__()
        self.LSTMs=[]
        self.net_type="noisy"

        self.hidden_size=25*25#NAF用 最後の層         nn.ZeroPad2d(1)
        self.hidden_CNN=256*25*25
        self.hidden_size1=25*25
        self.hidden_size2=None

        self.cnn1 = nn.Sequential(
            nn.Conv2d(3, 16, kernel_size=(3,3), padding=1),
            swish(0.7),
            nn.Conv2d(16, 16, kernel_size=(3,3), padding=1),
            nn.MaxPool2d(kernel_size=(2,2), stride=(2,2)),

            cnn15層 

            swish(0.7),
            nn.Conv2d(256, 256, kernel_size=(3,3), padding=1),
            swish(0.7),
            nn.MaxPool2d(kernel_size=(2,2), stride=(2,2)))
        self.cnn1.apply(init_weights)

        self.free_net=  nn.Sequential(
            nn.Linear(self.hidden_CNN, self.hidden_size1),
            swish(0.7),
            nn.Linear(self.hidden_size1, self.hidden_size1),
            swish(0.7),
            nn.Linear(self.hidden_size1, self.hidden_size1),
            swish(0.7),
        )
        self.free_net.apply(init_weights)

        self.a = nn.Linear(self.hidden_size, self.hidden_size)
        self.swish=swish(0.7)
        init_weights(self.a)

        if self.net_type=="noisy":
            self.V_q = Noisy_net(self.hidden_size, 1)#                    V_q
            self.V = Noisy_net(self.hidden_size, 1)#                      V
            self.mu = Noisy_net(self.hidden_size, num_outputs)#           mu
        else:
            self.V_q = nn.Linear(self.hidden_size, 1)#                  V_q
            self.V = nn.Linear(self.hidden_size, 1)#                    V
            self.mu = nn.Linear(self.hidden_size, num_outputs)#         mu
        self.L = nn.Linear(self.hidden_size, num_outputs ** 2)

        init_weights(self.V)
        init_weights(self.V_q)
        init_weights(self.mu)
        init_weights(self.L)
    def forward(self,inputs,net):
        if net=="net_q":
            x, u = inputs
            u=u.to('cuda:0')
            x=x.to("cuda:0")
        else:
            x = inputs.to('cuda:0')
        #------------------------------------


        x=self.cnn1(x)
        x=x.contiguous().view(-1, 1).T
        x=self.free_net(x)


        #----------------------------------
        x=self.swish(self.a(x))
        if net=="net_v":
            V=self.V(x)-self.V_q(x)
            return V
        if net=="net_a":
            mu =self.mu(x)
            return mu.to("cpu")

class Memory:
    def __init__(self, max_size=1000):
        self.buffer = deque(maxlen=max_size)
    def add(self, experience):
        self.buffer.append(experience)
    def sapp(self, batch_size):
        idx = np.random.choice(np.arange(len(self.buffer)), size=batch_size, replace=False)
        return idx
class Memory_TDerror(Memory):# Memoryクラスを継承 TD誤差格納クラス
    def __init__(self, max_size=1000,):
        super().__init__(max_size)
    # TD誤差をすべて更新
    def update_TDerror(self,gamma,multireward_steps):
        for i in range(multireward_steps, (len(memory.buffer))):
            inpp=[memory.buffer[i-multireward_steps][0],memory.buffer[i-multireward_steps][1]]
            next_state=memory.buffer[i][0]
            reward=memory.buffer[i][2]
            target = reward.to("cuda:0") + (gamma**multireward_steps) * targetQN.forward(next_state,"net_v")[0]
            TD=target - mainQN.forward(inpp,"net_q")[0]
            self.buffer.append(TD.to("cpu",torch.float32))
            print(TD)




def mask_input(x):#                 データの前処理 to("cuda")は入れなくていい
    if type(x)==np.ndarray:
        x = torch.from_numpy(x)
        x=x.permute(0 ,3, 1, 2)
    return x
def Q_e(epsilon,next_state,action_size):
        if epsilon <= np.random.uniform(0, 1):
            action = targetQN.forward(next_state,"net_a")
        else:
            action = torch.randn(1,action_size).half()
        return action

#ハイパーパラメータ--------------------------------------------------------
#                        ==レイヤー== Noisy_net
#            == 関数  == mish() swish()

num_episodes = 10 #                 総試行回数
max_number_of_steps = 500  #        1試行のstep数
goal_average_reward = 100  #        この報酬を超えると学習終了
num_consecutive_iterations = 10#    学習完了評価の平均計算を行う試行回数
gamma = 0.99  #                     割引係数
islearned = 0  #                    学習が終わったフラグ
isrender = 0  #                     描画フラグ
learning_rate = 0.001  #           Q-networkの学習係数
memory_size = 10000  #              バッファーメモリの大きさ
batch_size = 32  #                  Q-networkを更新するバッチ
multireward_steps=2 #               マルチステップ
rank_baes = 0.5#                        ランクベース

beta_initial=0.0#                 重要度サンプリング初期値
beta_steps=10000#                  重要度サンプリング終了ステップ
enable_is=True#                   重要度サンプリングを使用するか


Q_ebeir= True#                      Qーgraay bool値
action_size=2 #                     モデルのoutput
state=np.zeros((400,400,3))#        モデルのinput
def mask_input(x):#                 データの前処理 to("cuda")は入れなくていい
    if type(x)==np.ndarray:
        x = torch.from_numpy(x)
        x=x.permute(0 ,3, 1, 2)
    return x


#前処理-------------------------------------------------------
#Qネットワークとメモリ、Actorの生成--------------------------------------------------------

mainQN = QNetwork(state.shape,action_size).to('cuda:0')
optimizer = optim.Adam(mainQN.parameters(), lr=learning_rate)
mainQN, optimizer = amp.initialize(mainQN, optimizer, opt_level="O1")#--------------

criterion = nn.MSELoss()
targetQN = mainQN
targetQN.eval()
mainQN.eval()



total_reward_vec = np.zeros(num_consecutive_iterations)
memory = Memory(max_size=memory_size)
memory_TDerror = Memory_TDerror(max_size=memory_size)
acthon=np.array([np.zeros(action_size)])
state_=np.array([state])





#mainQN.sample_noise
print("start")
for _ in range(30):
    next_state=mask_input(np.random.rand(1,400,400,3))
    action=mainQN.forward(next_state,"net_a")
    reward=1
    print(action.is_cuda,next_state.is_cuda)
    memory.add((next_state, action, reward))  # メモリの更新する
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

https://qiita.com/tyo_yo_/items/5f2c41e0dbea9276f42b
を参考にして、pytorch_memlabをインストールして各処理のメモリ使用を確認してみてはいかがでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • CUDAに関する質問
  • pytorch なぜ400*400の画像でモデルを動かしただけなのに10gbメモリが足りなくなるんですか?