7月11日
#以下のソースコードはそのままでは動かない.何箇所か修正し,活性化関数ReLUの3層のnnの計算を実行せよ.
```python
import torch
from torch import nn
class Net(nn.Module):
def __init__(self, networks): #networks修正
super(Net, self).__init__()#スーパークラス
self.networks = networks
def forward(self, x):
for net in self.networks:
return net(x)
net = Net([nn.Linear(3,5), nn.ReLU(), nn.Linear(5,4)]) #活性化関数ReLU追加
x = torch.tensor([1, 2, 3]) #forwardの引数xに修正
```
エラーは起こらないのですが、多分合っていない気がしています。。
おかしい箇所が2つありますね。
まず、エラーメッセージは何と出ていますかね?
net(x)を実行すると
RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #3 'mat2' in call to _th_addmm_out
と出ます。xをスカラーにしないといけないということでしょうか。
竹川: エラーメッセージ自体は何を意味していますかね?
/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in linear(input, weight, bias)
1610 ret = torch.addmm(bias, input, weight.t())
1611 else:
-> 1612 output = input.matmul(weight.t())
1613 if bias is not None:
1614 output += bias
RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #3 'mat2' in call to _th_addmm_out
つまり。。。行列をかける(matmul)の時に scalat typeがLongを期待していたけど,Float型が来たよ(型があってないよ)というエラーメッセージです.
とかきましたが、自分の実装で上のエラーが該当する(影響ありそうな)箇所はわかりますでしょうか?
forwardに渡してるxのところでしょうか?float型がどこを指してるかがわからず、、
そうですね。行列の演算から連想できるようになるといいのですが、nn.Linearのweightとxが行列をかけている部分でエラーになっています.
weightはfloat型で,xがintなのでこのエラーが出ているということです.
直すには、weightをlongやintにするのではなく,xをfloatにしてください(floatでないと微分等ができなくなるため)
ありがとうございます!もう一度直して試してみます
ちなみに、もう一箇所おかしい箇所があります。
```
x = torch.tensor([1, 2, 3],dtype=float) #forwardの引数xに修正 float型へ変更
net(x)
```
`RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #3 'mat2' in call to _th_addmm_out`
xをfloat型にして実行したらDouble typeにしてほしいというのが出たのですが、ここが何を指しているかがわからないです。
もう一か所おかしいところがわからず、上記のエラーに該当するところでしょうか?
違いますね。
```
for net in self.networks:
return net(x)
```
です。これをしてしまうと最初の`net`を実行した段階でreturnされてしまいます。
どうですかね?
def forward(self, x):
for net in self.networks:
x = net(x)
return self.networks(x)
良さそうな気がしますね。全体修正したコードみせていただけると.
```python
import torch
from torch import nn
class Net(nn.Module):
def __init__(self, networks): #networks修正
super(Net, self).__init__()#スーパークラス
self.networks = networks
def forward(self, x):
for net in self.networks:
x = net(x)
return self.networks(x)
net = Net([nn.Linear(3,5), nn.ReLU(), nn.Linear(5,4)]) #活性化関数ReLU追加
x = torch.tensor([1, 2, 3],dtype=float) #forwardの引数xに修正 float型へ変更
net(x)
```
これでまだ下記エラーがでます・・・・
`RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #3 'mat2' in call to _th_addmm_out`
xがfloat64、つまりdouble型になってますね。
`x = x.float()`とするといいと思います.
ありがとうございます。 x=x.float()で行ったら
下記のエラーが出たのですが、float()だとlist型になってしまっているということでしょうか?
```
---> 13 return self.networks(x)
14 net = Net([nn.Linear(3,5), nn.ReLU(), nn.Linear(5,4)]) #活性化関数ReLU追加
15 x = torch.tensor([1, 2, 3]) #forwardの引数xに修正 float型へ変更
TypeError: 'list' object is not callable
```
それは駄目でした.
self.networks(x)はそもそもリストに対して実行することなってしまうので。。。
def forward(self, x):
for net in self.networks:
x = net(x)
return x
でいいと思います.
```python
import torch
from torch import nn
class Net(nn.Module):
def __init__(self, networks): #networks修正
super(Net, self).__init__()#スーパークラス
self.networks = networks
def forward(self, x):
for net in self.networks:
x = net(x)
return x
net = Net([nn.Linear(3,5), nn.ReLU(), nn.Linear(5,4)]) #活性化関数ReLU追加
x = torch.tensor([1, 2, 3]) #forwardの引数xに修正 float型へ変更
x = x.float()
net(x)
```
relUがこれで計算されないのはなぜでしょうか・・・
```
```
すいません。僕が勘違いしてました。計算されてますね(汗)。申し訳ないです。
あ、良かったです!!ありがとうございます!
いえいえ。すいません。
次回も頑張りましょう。なれるまで大変だと思いますが、こういう書き方自体に慣れてしまえば実装でそこまで悩まなやくなるので。
ありがとうございます。演習で慣れていきたいです。
またよろしくお願いいたします。