作ったモジュールの取り込みがうまくいかない。

core.py

1import dezero 2import numpy as np 3import weakref 4import contextlib 5 6######################################################################## 7 8class Config: 9 enable_backprop = True 10 11######################################################################## 12 13#微分値をVariableインスタンスにすることで逆伝播の計算のつながりも記憶されるため高階微分も自動で求めることが可能になる。 14 15 16class Variable: 17 def __init__(self, data, name=None): 18 if data is not None: 19 if not isinstance(data, np.ndarray): 20 raise TypeError("{} is not supported".format(type(data))) 21 22 self.data = data 23 self.name = name 24 self.grad = None 25 self.creater = None 26 self.generation = 0 27 28 def __len__(self): 29 return len(self.data) 30 31 #__repr__()はprint()で出力される文字列をカスタマイズするもの 32 def __repr__(self): 33 if self.data is None: 34 return 'variable(None)' 35 p = str(self.data).replace('\n','\n' + ' ' * 9) 36 return 'variable(' + p + ')' 37 38 39 40 def set_creater(self, func): 41 self.creater = func 42 self.generation = func.generation + 1 43 44 def backward(self, retain_flag=False, create_graph=False): 45 if self.grad is None: 46 self.grad = Variable(np.ones_like(self.data)) 47 48 funcs = [] 49 seen_set = set() 50 51 def add_func(f): 52 if f not in seen_set: 53 funcs.append(f) 54 seen_set.add(f) 55 funcs.sort(key=lambda x: x.generation) 56 57 add_func(self.creater) 58 59 60 while funcs: 61 #pop()は”最後尾”の要素を取り出す 62 f = funcs.pop() 63 gys = [output().grad for output in f.outputs] 64 65 #using_configは逆伝播するかどうかのもので、ここでは逆伝播の計算の中で逆伝播を求めるかどうかのflagになっている。 66 with using_config('enable_backprop', create_graph): 67 gxs = f.backward(*gys) 68 if not isinstance(gxs, tuple): 69 gxs = (gxs,) 70 71 for x, gx in zip(f.inputs, gxs): 72 #同じ変数を使って計算するとき用 73 if x.grad is None: 74 x.grad = gx 75 else: 76 x.grad = gx + x.grad 77 78 if x.creater is not None: 79 add_func(x.creater) 80 81 #機械学習において必要なのは末端の変数の微分値だから中間はいらない 82 #だから何らかの関数に出力されている変数の微分値だけ消している 83 if not retain_flag: 84 for y in f.outputs: 85 y().grad = None 86 87 88 def cleargrad(self): 89 self.grad = None 90 91 def reshape(self, *shape): 92 #一次元配列だった場合第二引数は数字だけでいい 93 if len(shape) == 1 and isinstance(shape[0], (tuple, list)): 94 shape = shape[0] 95 return dezero.functions.reshape(self, shape) 96 97 def sum(self, axis=None, keepdims=False): 98 return dezero.functions.sum(self, axis, keepdims) 99 100 @property 101 def shape(self): 102 return self.data.shape 103 @property 104 def ndim(self): 105 return self.data.ndim 106 @property 107 def size(self): 108 return self.data.size 109 @property 110 def dtype(self): 111 return self.data.dtype 112 @property 113 def T(self): 114 return dezero.functions.transpose(self) 115 __array_priority__ = 200 116 117######################################################################## 118 119class Function: 120 # *をつけると各々の引数がタプルとして渡される 121 def __call__(self, *inputs): 122 inputs = [as_variable(x) for x in inputs] 123 xs = [x.data for x in inputs] 124 ys = self.forward(*xs) 125 if not isinstance(ys, tuple): 126 ys = (ys,) 127 outputs = [Variable(as_array(y)) for y in ys] 128 129 if Config.enable_backprop: 130 #推論時の順伝播のみの時には不必要 131 self.generation = max([x.generation for x in inputs]) 132 133 for output in outputs: 134 output.set_creater(self) 135 136 self.inputs = inputs 137 #Funtion classと出力のVariable classで循環参照が起きてしまっていたことの解消 138 self.outputs = [weakref.ref(output) for output in outputs] 139 140 141 return outputs if len(outputs) > 1 else outputs[0] 142 143 def forward(self, xs): 144 raise NotImplementedError() 145 def backward(self, gys): 146 raise NotImplementedError() 147################################################################ 148#core.pyでの修正点:今まではgradインスタンスはndarrayインスタンスを参照にしていたが、それをVariableインスタンス 149#に変えるため、各々のbackwardメソッドの入力値は ~.data から ~ にする 150 151 152class Square(Function): 153 def forward(self, x): 154 y = x ** 2 155 return y 156 157 def backward(self, gy): 158 ###二乗の計算の入力値は常に一つだが元々inputがリストの形になっているから[0]が必要 159 x = self.inputs 160 gx = 2 * x * gy 161 return gx 162 163class Exp(Function): 164 def forward(self, x): 165 y = np.exp(x) 166 return y 167 168 def backward(self, gy): 169 x = self.inputs 170 gx = np.exp(x) * gy 171 return gx 172 173class Add(Function): 174 def forward(self, x0, x1): 175 self.x0_shape, self.x1_shape = x0.shape, x1.shape 176 y = x0 + x1 177 return(y,) 178 179 def backward(self,gy): 180 gx0, gx1 = gy, gy 181 if self.x0_shape != self.x1_shape: 182 gx0 = dezero.functions.sum_to(gx0, self.x0_shape) 183 gx1 = dezero.functions.sum_to(gx1, self.x1_shape) 184 return gx0, gx1 185 186class Mul(Function): 187 def forward(self, x0, x1): 188 self.x0_shape, self.x1_shape = x0.shape, x1.shape 189 y = x0 * x1 190 return y 191 192 def backward(self,gy): 193 x0, x1 = self.inputs 194 gx0 = gy * x1 195 gx1 = gy * x0 196 if self.x0_shape != self.x1_shape: 197 gx0 = dezero.functions.sum_to(gx0, self.x0_shape) 198 gx1 = dezeto.unctions.sum_to(gx1, self.x1_shape) 199 return gx0, gx1 200 201class Neg(Function): 202 def forward(self, x): 203 return -x 204 205 def backward(self, gy): 206 return -gy 207 208class Sub(Function): 209 def forward(self, x0, x1): 210 self.x0_shape, self.x1_shape = x0.shape, x1.shape 211 y = x0 - x1 212 return y 213 214 def backward(self, gy): 215 gx0, gx1 = gy, -gy 216 if self.x0_shape != self.x1_shape: 217 gx0 = dezero.functions.sum_to(gx0, self.x0_shape) 218 gx1 = dezero.functions.sum_to(gx1, self.x1_shape) 219 return gx0, gx1 220 221class Div(Function): 222 def forward(self, x0, x1): 223 self.x0_shape, self.x1_shape = x0.shape, x1.shape 224 x1 = as_array(x1) 225 y = x0 / x1 226 return y 227 228 def backward(self, gy): 229 x0, x1 = self.inputs 230 gx0, gx1 = gy / x1 , -gy * x0 / x1**2 231 if self.x0_shape != self.x1_shape: 232 gx0 = dezero.functions.sum_to(gx0, self.x0_shape) 233 gx1 = dezero.functions.sum_to(gx1, self.x1_shape) 234 return gx0, gx1 235 236class Pow(Function): 237 def __init__(self, c): 238 self.c = c 239 240 def forward(self, x): 241 y = x ** self.c 242 return y 243 244 def backward(self, gy): 245 x, = self.inputs 246 c = self.c 247 return c * x ** (c-1) * gy 248 249 250# class Sum(Function): 251# def forward(self, x): 252# self.x_shape = x.shape 253# y = x.sum() 254# return y 255# def backward(self, gy): 256# gx = broadcast_to(gy, self.x_shape) 257# return gx 258# def sum(x): 259# return Sum()(x) 260######################################################################## 261 262def square(x): 263 return Square()(x) 264 265def exp(x): 266 f = Exp() 267 return f(x) 268 269def mul(x0, x1): 270 x1 = as_array(x1) 271 return Mul()(x0, x1) 272 273def add(x0, x1): 274 x1 = as_array(x1) 275 return Add()(x0, x1) 276 277def neg(x): 278 return Neg()(x) 279 280def sub(x0, x1): 281 x1 = as_array(x1) 282 return Sub()(x0, x1) 283 284def rsub(x0, x1): 285 x1 = as_array(x1) 286 return Sub()(x1, x0) 287 288def div(x0, x1): 289 x1 = as_array(x1) 290 return Div()(x0, x1) 291 292def rdiv(x0,x1): 293 x1 = as_array(x1) 294 return Div()(x1, x0) 295 296def pow(x, c): 297 c = as_array(c) 298 return Pow(c)(x) 299 300def no_grad(): 301 return using_config('enable_backprop', False) 302 303######################################################################## 304 305省略

コメントを投稿

0 コメント