[bugfix] - fix momentum reset, cd_gaussian_gaussian noise, rms_error, label CuPy compat
- train.py: grad_zero() was called inside the epoch loop, resetting momentum to zero before every update — momentum had no effect in the default full-batch case. Moved outside the loop so momentum accumulates across epochs. - train.py: cd_gaussian_gaussian: use mean h for weight updates and sampled h to drive the negative visible reconstruction (same pattern as cd_gaussian_binary fix). Remove spurious Gaussian noise added to data_neg before computing h_probs_neg. - matrix.py: rms_error divided by d_err_squared[1] (row 1) instead of d_err_squared.shape[1] (column count). - label.py: _dec_binary used reversed() on a CuPy array — replaced with np.flip(). label2vec_onehot now returns np.stack() array instead of a Python list. vec2label_onehot implemented via np.argmax (was returning None). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-4
@@ -69,7 +69,7 @@ class Label:
|
||||
def _dec_binary(vec: np.array):
|
||||
res = 0
|
||||
e = 1
|
||||
for v in reversed(vec):
|
||||
for v in np.flip(vec):
|
||||
res += v*e
|
||||
e *= 2
|
||||
|
||||
@@ -81,11 +81,10 @@ class Label:
|
||||
vec = np.zeros(self.voc_size)
|
||||
vec[label] = 1.0
|
||||
res.append(vec)
|
||||
return res
|
||||
return np.stack(res, axis=0)
|
||||
|
||||
def vec2label_onehot(self, label_vecs: np.array, thresh=0.9):
|
||||
# ToDo:
|
||||
return None
|
||||
return np.argmax(label_vecs, axis=-1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
voc_size = 100
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ def prob(src: Mat) -> Mat:
|
||||
|
||||
def rms_error(d_err: Mat):
|
||||
d_err_squared = d_err * d_err
|
||||
return np.sum(d_err_squared, 1) / d_err_squared[1]
|
||||
return np.sum(d_err_squared, 1) / d_err_squared.shape[1]
|
||||
|
||||
def rms_error_accu(d_err: Mat):
|
||||
d_err_squared = d_err * d_err
|
||||
|
||||
+7
-9
@@ -113,19 +113,18 @@ def cd_gaussian_binary(entity: Entity, data_pos: Mat):
|
||||
return dw, dbv, dbh
|
||||
|
||||
def cd_gaussian_gaussian(entity: Entity, data_pos: Mat):
|
||||
# Positive phase
|
||||
# Positive phase — use mean h for weight update, sample h to drive reconstruction
|
||||
h_probs_pos = entity.h_given_v(data_pos)
|
||||
h_sample_pos = h_probs_pos + sample_gaussian(h_probs_pos)
|
||||
|
||||
# Update weights (positive phase)
|
||||
dw = np.dot(np.transpose(data_pos), h_probs_pos + sample_gaussian(h_probs_pos))
|
||||
dw = np.dot(np.transpose(data_pos), h_probs_pos)
|
||||
dbh = np.sum(h_probs_pos, 0)
|
||||
dbv = np.sum(data_pos-entity.state.b_v, 0)
|
||||
|
||||
# Negative phase
|
||||
data_neg = entity.v_given_h(h_probs_pos)
|
||||
h_probs_neg = entity.h_given_v(data_neg + sample_gaussian(data_neg))
|
||||
# Negative phase — reconstruct from sampled h, use means for weight update
|
||||
data_neg = entity.v_given_h(h_sample_pos)
|
||||
h_probs_neg = entity.h_given_v(data_neg)
|
||||
|
||||
# Update weights (negative phase)
|
||||
dw -= np.dot(np.transpose(data_neg), h_probs_neg)
|
||||
dbh -= np.sum(h_probs_neg, 0)
|
||||
dbv -= np.sum(data_neg-entity.state.b_v, 0)
|
||||
@@ -214,12 +213,11 @@ def train(entity: Entity, batch: Mat, status: Status):
|
||||
if entity.type == Entity.Type.BG_RBM:
|
||||
cd_func = cd_binary_gaussian
|
||||
|
||||
entity.grad_zero()
|
||||
for epochs in range(params.num_epochs):
|
||||
if not keep_running:
|
||||
break
|
||||
|
||||
# Reset gradient
|
||||
entity.grad_zero()
|
||||
for mini_batch in to_mini_batch(batch, mini_batch_size):
|
||||
# Contrastive divergence learning: calculate gradients
|
||||
dwhv, dbv, dbh = cd_func(entity, mini_batch)
|
||||
|
||||
Reference in New Issue
Block a user