refactor: separate gradient back and weight updates
This commit is contained in:
@@ -82,9 +82,11 @@ class ClassicalAutoencoder(AAutoencoder):
|
|||||||
self.encoder.forward(v)
|
self.encoder.forward(v)
|
||||||
)
|
)
|
||||||
error = out - v
|
error = out - v
|
||||||
self.encoder.backprop(
|
self.encoder.back(
|
||||||
self.decoder.backprop(error)
|
self.decoder.back(error)
|
||||||
)
|
)
|
||||||
|
self.encoder.backprop()
|
||||||
|
self.decoder.backprop()
|
||||||
return np.sum(np.abs(error)) / len(v)
|
return np.sum(np.abs(error)) / len(v)
|
||||||
|
|
||||||
@interruptable
|
@interruptable
|
||||||
@@ -109,7 +111,7 @@ class ClassicalAutoencoder(AAutoencoder):
|
|||||||
error += self.train(x)
|
error += self.train(x)
|
||||||
error /= len(data_set)
|
error /= len(data_set)
|
||||||
derror = prev_error - error
|
derror = prev_error - error
|
||||||
if derror <= 0 or abs(derror) < 1e-4:
|
if abs(derror) < 1e-4:
|
||||||
no_improv += 1
|
no_improv += 1
|
||||||
else:
|
else:
|
||||||
no_improv = 0
|
no_improv = 0
|
||||||
@@ -167,11 +169,14 @@ class VariationalAutoencoder(AAutoencoder):
|
|||||||
def train(self, v: np.ndarray) -> tuple[float, float]:
|
def train(self, v: np.ndarray) -> tuple[float, float]:
|
||||||
out, _ = self.forward(v)
|
out, _ = self.forward(v)
|
||||||
error = out - v
|
error = out - v
|
||||||
self.encoder.backprop(
|
self.encoder.back(
|
||||||
self.sampler.backprop(
|
self.sampler.back(
|
||||||
self.decoder.backprop(error)
|
self.decoder.back(error)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
self.encoder.backprop()
|
||||||
|
self.sampler.backprop()
|
||||||
|
self.decoder.backprop()
|
||||||
return np.mean(error ** 2), self.sampler.DKL()
|
return np.mean(error ** 2), self.sampler.DKL()
|
||||||
|
|
||||||
@interruptable
|
@interruptable
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class NNLayer:
|
|||||||
self.input = None
|
self.input = None
|
||||||
self.output = None
|
self.output = None
|
||||||
self.output_linear = None
|
self.output_linear = None
|
||||||
|
self.error = None
|
||||||
self.activation_func = activation_func
|
self.activation_func = activation_func
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -27,15 +28,16 @@ class NNLayer:
|
|||||||
self.output_linear
|
self.output_linear
|
||||||
)
|
)
|
||||||
return self.output
|
return self.output
|
||||||
|
|
||||||
|
def back(self, error: np.ndarray) -> np.ndarray:
|
||||||
|
self.error = error * self.activation_func.d(self.output_linear)
|
||||||
|
return self.W @ self.error
|
||||||
|
|
||||||
def backprop(self, error: np.ndarray) -> np.ndarray:
|
def backprop(self) -> np.ndarray:
|
||||||
error *= self.activation_func.d(self.output_linear)
|
dW = np.outer(self.input, self.error) * self.lr
|
||||||
ret = self.W @ error
|
dB = self.error * self.lr
|
||||||
dW = np.outer(self.input, error) * self.lr
|
|
||||||
dB = error * self.lr
|
|
||||||
self.W -= dW
|
self.W -= dW
|
||||||
self.B -= dB
|
self.B -= dB
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class SampleLayer:
|
class SampleLayer:
|
||||||
@@ -66,13 +68,17 @@ class SampleLayer:
|
|||||||
self.eps = np.random.normal(0, 1, self.mean.shape)
|
self.eps = np.random.normal(0, 1, self.mean.shape)
|
||||||
return 0.5 * self.eps * self.std + self.mean
|
return 0.5 * self.eps * self.std + self.mean
|
||||||
|
|
||||||
def backprop(self, error: np.ndarray) -> np.ndarray:
|
def back(self, error: np.ndarray) -> np.ndarray:
|
||||||
dmean = error + self.mean
|
dmean = error + self.mean
|
||||||
dstd = error * self.eps + 0.5 * (np.exp(self.logvar) - 1)
|
dstd = error * self.eps + 0.5 * (np.exp(self.logvar) - 1)
|
||||||
mean_error = self.mean_nn.backprop(dmean)
|
mean_error = self.mean_nn.back(dmean)
|
||||||
logvar_error = self.std_nn.backprop(dstd * self.std)
|
logvar_error = self.std_nn.back(dstd * self.std)
|
||||||
return mean_error + logvar_error
|
return mean_error + logvar_error
|
||||||
|
|
||||||
|
def backprop(self):
|
||||||
|
self.mean_nn.backprop()
|
||||||
|
self.std_nn.backprop()
|
||||||
|
|
||||||
|
|
||||||
class DeepNNLayer:
|
class DeepNNLayer:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@@ -100,7 +106,12 @@ class DeepNNLayer:
|
|||||||
v = layer.forward(v)
|
v = layer.forward(v)
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def backprop(self, error: np.ndarray) -> np.ndarray:
|
def back(self, error: np.ndarray):
|
||||||
for layer in self.layers[::-1]:
|
for layer in self.layers[::-1]:
|
||||||
error = layer.backprop(error)
|
error = layer.back(error)
|
||||||
return error
|
return error
|
||||||
|
|
||||||
|
def backprop(self) -> np.ndarray:
|
||||||
|
for layer in self.layers:
|
||||||
|
layer.backprop()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user