SpTn-Model-only-1P / save_model.py
KtiyaKK's picture
Update 1P model architecture and generation
a03c99b
Raw History Blame Contribute Delete
2.24 kB
import numpy as np
# SpTn-Model-only-1P
# Exactly ONE trainable parameter.
MODEL_FILE = "sp_tn_1p.npz"
# Fixed training corpus.
# These are data, not trainable parameters.
text = """
hello world
this is a tiny experimental model
sp tn one parameter
research experiment
hello model
"""
# Fixed vocabulary.
# These values are NOT trainable parameters.
vocab = sorted(set(text))
char_to_id = {c: i for i, c in enumerate(vocab)}
# Training examples: previous character -> next character.
pairs = []
for i in range(len(text) - 1):
x = text[i]
y = text[i + 1]
pairs.append((char_to_id[x], char_to_id[y]))
# Exactly ONE trainable parameter.
w = np.array(0.5, dtype=np.float32)
learning_rate = 0.05
steps = 5000
def logits(parameter, input_id):
"""
Fixed feature function.
The only trainable value is `parameter`.
"""
n = len(vocab)
ids = np.arange(n, dtype=np.float32)
# Fixed features.
# No trainable weights here.
feature = np.sin((ids + 1.0) * (input_id + 1.0))
return parameter * feature
def softmax(values):
values = values - np.max(values)
exp_values = np.exp(values)
return exp_values / np.sum(exp_values)
for step in range(steps):
total_loss = 0.0
total_gradient = 0.0
for input_id, target_id in pairs:
z = logits(w, input_id)
probabilities = softmax(z)
loss = -np.log(probabilities[target_id] + 1e-12)
total_loss += loss
ids = np.arange(len(vocab), dtype=np.float32)
feature = np.sin((ids + 1.0) * (input_id + 1.0))
expected_feature = np.sum(probabilities * feature)
gradient = expected_feature - feature[target_id]
total_gradient += gradient
total_gradient /= len(pairs)
w -= learning_rate * total_gradient
if step % 500 == 0:
average_loss = total_loss / len(pairs)
print(
f"step={step} "
f"loss={average_loss:.6f} "
f"w={float(w):.6f}"
)
np.savez(
MODEL_FILE,
w=w,
vocab=np.array(vocab),
)
print()
print("SpTn-Model-only-1P")
print("Model saved:", MODEL_FILE)
print("Trainable parameters:", 1)
print("Parameter:", float(w))
print("Final loss:", float(total_loss / len(pairs)))