回答者コメントの欄でMarkdownが使えないので,こちらに回答します.
MyChainクラス内で同列にメソッドを定義したことで解消できているという認識でした。
というのは,関数__call__(self, x)
内のo = self.l2(h)
でo
を定義したつもりでいるということでしょうか.
これは変数のスコープの勉強をされるとわかると思いますが,特殊メソッド__call__()
内でしか扱えないようになっていますし,上のコードでは一度も__call__()
を呼んでいないので,h
やo
の定義すらされていません.
本題
そもそも論,Chainer.links.Linearのドキュメントを読むと
class chainer.links.Linear(in_size: Optional[int], out_size: Optional[int] = None, ...)
・in_size (int or None) – Dimension of input vectors. If unspecified or None
, parameter initialization will be deferred until the first forward data pass at which time the size will be determined.
・out_size (int) – Dimension of output vectors. If only one value is passed for in_size
and out_size
, that value will be used for the out_size
dimension.
と書いてあることから第一引数が入力の数in_size
,第二引数が出力の数out_size
であることがわかります.
上のようにl2=L.Linear(3, 2)
で定義したレイヤを出力にするのであれば,出力の次元数out_size
は第二引数に設定した2
のはずです.
この数字は,以下のコードに改修すると確認できます.
def check_cnn_size(self,size_check):
- out = o(size_check)
+ out = self(size_check)
return out
size_check = numpy.array([[1, 2, 3, 4, ] , [3 ,4, 5, 6, ] , [5, 6, 7, 8,] , [7, 8, 9, 10,]], dtype = numpy.float32)
-print(MyChain().check_cnn_size(size_check).size()) # .size()はPyTorch.Tensorに対して行えるが
+print(MyChain().check_cnn_size(size_check).shape) # 今回はNumPy.array用の.shapeを使う
出力は(4, 2)
になりました.値の意味としては(batch_size, output_shape)
でしょうか,参考ページではPyTorchのTensorのサイズとして.size()
を使っていましたが,今回は入力をNumPyのndarrayで使ったので出力もndarrayになることから,サイズ確認に使えそうな.shape
にしました.
もう少し合理的にコードを改修すると
class MyChain(Chain):
def __init__(self):
super(MyChain, self).__init__(
l1=L.Linear(4, 3),
l2=L.Linear(3, 2)
)
def __call__(self, x):
h = F.sigmoid(self.l1(x))
o = self.l2(h)
return o
size_check = numpy.array([[1, 2, 3, 4, ] , [3 ,4, 5, 6, ] , [5, 6, 7, 8,] , [7, 8, 9, 10,]], dtype = numpy.float32)
print(MyChain()(size_check).shape)
これだけで良いです.いちいちcheck_cnn_size()
なんて関数を用意せずとも,__call__(self, x)
が定義されているので,このインスタンスはCallableになっています.このことを利用して,インスタンスを定義MyChain()
したあとCallable呼び出し()
が行えるからです.したがって,引数を渡すだけで値が出力されることを利用して,サイズ確認を行えます.
わかりやすく書くと
my_chain = MyChain()
print(my_chain(size_check).shape)
ですかね.
Pythonの基礎でつまづいているみたいなので,応用的な機械学習から取り組まれるのではなく,ちゃんと基礎から勉強されることをお勧めします.
なんなら機械学習もあまりよくわかっていないのでは...という気にさせます.そもそも,参考にされたページで畳み込み層の出力次元数を求めたのは,入力のshapeだけでなくstrideやpaddingに依存して決まるため計算するのがダルいからです.それに対して,全層結合層は用意したユニットの数だけ値が出力されるのでとてもシンプルで良いです.なのに全層結合層の出力サイズをコーディングして求めようとするとは...🤔