

ニューラルネットを作成していますが，損失関数とSGDの更新のプログラムでエラーがでます．出力yは0～5の6つのラベルがあり，それぞれ[1,0,0,0,0,0]（ラベル0）のようなone-
hot表現となっています．torch.Size([19573, 6])となっていることは確認済みです．

下記エラーの直し方をどなたかご教示の程，よろしくお願い致します．

### エラーメッセージ

[code]

    grads['dl/df'][y] -= 1                                                                     
    IndexError: index 1 is out of bounds for dimension 0 with size 1
    
[/code]

### コード

[code]

    import torch
    from bindsnet.network import Network
    from bindsnet.network.nodes import Input, LIFNodes
    from bindsnet.network.topology import Connection
    from bindsnet.network.monitors import Monitor
    import numpy as np
    
     # pytorchの呼び出し　
     # bindsnetのNetworkディレクトリを呼び出し，全ての主な要素に関する
     # bindsnetのnetworkディレクトリのnodes.pyを呼び出し
     # レイヤーの作成，この場合はLIFニューロンの層の作成
     # ネットワーク要素の構成　topology
     # bindsnetのnetworkディレクトリのtopologyのClassのConnectionを呼び出し
     # bindsnetのnetworkディレクトリのmonitorのClassのMonitorを呼び出し
    time = 25
     # ネットワークの作成
    network = Network()
    
     # 2つのニューロンの母集団を作成，1つはsourceとして作用
     # もう一つはtarget ニューロンのレイヤー 5層作成
    inpt = Input(n=64,shape=[1,64], sum_input=True) # n=64は入力サイズの等しくする
    middle = LIFNodes(n=40, trace=True, sum_input=True)
    center = LIFNodes(n=40, trace=True, sum_input=True)
    final = LIFNodes(n=40, trace=True, sum_input=True)
    out = LIFNodes(n=6, sum_input=True) # n=6はラベルと同じ数にする
    
     # レイヤー同士の接続
    inpt_middle = Connection(source=inpt, target=middle, wmin=0, wmax=1e-1)
    middle_center = Connection(source=middle, target=center, wmin=0, wmax=1e-1)
    center_final = Connection(source=center, target=final, wmin=0, wmax=1e-1)
    final_out = Connection(source=final, target=out, wmin=0, wmax=1e-1)
    
     # 全てのレイヤー5層をネットワークに接続
    network.add_layer(inpt, name='A')
    network.add_layer(middle, name='B')
    network.add_layer(center, name='C')
    network.add_layer(final,  name='D')
    network.add_layer(out, name='E')
    
    foward_connection = Connection(source=inpt, target=middle, w=0.05 + 0.1*torch.randn(inpt.n, middle.n))
    network.add_connection(connection=foward_connection, source="A", target="B")
    foward_connection = Connection(source=middle, target=center, w=0.05 + 0.1*torch.randn(middle.n, center.n))
    network.add_connection(connection=foward_connection, source="B", target="C")
    foward_connection = Connection(source=center, target=final, w=0.05 + 0.1*torch.randn(center.n, final.n))
    network.add_connection(connection=foward_connection, source="C", target="D")
    foward_connection = Connection(source=final, target=out, w=0.05 + 0.1*torch.randn(final.n, out.n))
    network.add_connection(connection=foward_connection, source="D", target="E")
    recurrent_connection = Connection(source=out, target=out, w=0.025*(torch.eye(out.n)-1),)
    network.add_connection(connection=recurrent_connection, source="E", target="E")
    
     # 入力と出力層だけMonitorを作成(電圧とスパイクを記録)
    inpt_monitor = Monitor(obj=inpt, state_vars=("s","v"), time=500,)
    middle_monitor = Monitor(obj=inpt, state_vars=("s","v"), time=500,)
    center_monitor = Monitor(obj=inpt, state_vars=("s","v"), time=500,)
    final_monitor = Monitor(obj=inpt, state_vars=("s","v"), time=500,)
    out_monitor = Monitor(obj=inpt, state_vars=("s","v"), time=500,)
     # Monitorをネットワークに接続
    network.add_monitor(monitor=inpt_monitor, name="A")
    network.add_monitor(monitor=middle_monitor, name="B")
    network.add_monitor(monitor=center_monitor, name="C")
    network.add_monitor(monitor=final_monitor, name="D")
    network.add_monitor(monitor=out_monitor, name="E")
    
    for l in network.layers:
        m = Monitor(network.layers[l], state_vars=['s'], time=time)
        network.add_monitor(m, name=l)
    
      # トレーニングデータをロード
    npzfile = np.load("C:/Users/name/Desktop/myo-python-1.0.4/myo-armband-nn-master/data/train_set.npz")
    x = npzfile['x'] # データをロードndarray型　1×64の配列
    y = npzfile['y'] # データをロードndarry型　　1×6の配列
      # tensor型に変換
    x = torch.from_numpy(x).clone() # xは1×64のtensor配列
    y = torch.from_numpy(y).clone() # yは1×6のtensor配列
      # 保存されたトレーニングデータの開始とニューロンのごとのスパイクとラベルを保存する
      # データの反映と保存，（1ニューロンのスパイクと，ラベル）をペアにする
    grads = {}
    lr, lr_decay = 1e-2, 0.95
    criterion = torch.nn.CrossEntropyLoss() # 交差損失関数の計算
    spike_ims, spike_axes, weight_im = None, None, None
    
    for i,(x,y) in enumerate(zip(x.view(-1,64), y)):
      # repeat関数　（要素や配列, 繰り返し回数）　"E"の方は(時間数×1行列）を生成　（time=25) iはインデックス番号
    inputs = {'A': x.repeat(time, 1),'E_b': torch.ones(time, 1)}
    network.run(inputs=inputs, time=time)
    # スパイクを全層からまとめる（'s'はスパイク）
    y = torch.tensor(y).long()
    spikes = {l: network.monitors[l].get('s') for l in network.layers}
    # 全層から入力をまとめる　
    summed_inputs = {l: network.layers[l].summed for l in network.layers}
    # 出力のsoftmax関数,予測ラベルの取得
    output = spikes['E'].sum(-1).float().softmax(0).view(1,-1)
    predicted = output.argmax(1).item()
    # 損失とSGDの更新
    grads['dl/df'] = summed_inputs['E'].softmax(0)
    grads['dl/df'][y] -= 1 ☚ここです
    grads['dl/dw'] = torch.ger(summed_inputs['A'], grads['dl/df'])
    network.connections['A','B','C','D','E'].w -= lr*grads['dl/dw']
    # 減衰率
    if i > 0 and i % 300 == 0:
       lr = lr_decay
    network.reset_()
    
[/code]


CC BY-SA 4.0
2020-11-17T08:41:21.553
72005
2022-06-24T09:06:20.613
2020-11-18T07:31:07.493
3060
41671
question
python pytorch
index 1 is out of bounds for dimension 0 with size 1 を直したい


エラーメッセージにあるように、grads['dl/df']のサイズが1なので、インデックス1は指定できません。

* * *

よりよい回答を得るために、こちらも参考にしてみてください。

  * [良い質問をするには？ - stackoverflow](https://ja.stackoverflow.com/help/how-to-ask)
  * [再現可能な短いサンプルコードの書き方 - stackoverflow](https://ja.stackoverflow.com/help/minimal-reproducible-example)


CC BY-SA 4.0
2021-01-23T21:54:59.727
73535
2021-01-23T21:54:59.727
41038
72005
answer