Download network.py from end000/Checkers-WSPForge-Russian-v2: direct link, hf CLI and curl.
- Browser
- Download file 3.41 kB
-
https://huggingface.co/end000/Checkers-WSPForge-Russian-v2/resolve/main/network.py
- Command line
-
hf download hf://end000/Checkers-WSPForge-Russian-v2/network.py
-
curl -L -o network.py https://huggingface.co/end000/Checkers-WSPForge-Russian-v2/resolve/main/network.py
3.41 kB
| import hashlib | |
| import json | |
| from pathlib import Path | |
| import numpy as np | |
| from scipy.sparse import csr_matrix | |
| class FixedNetwork: | |
| def __init__(self, layers, metadata): | |
| self.layers = layers | |
| self.metadata = metadata | |
| def forward(self, x, dense=False): | |
| x = np.asarray(x, dtype=np.float32) | |
| if x.ndim != 2 or x.shape[1] != 128: | |
| raise ValueError("Нужен массив [число позиций, 128]") | |
| for i, (w, b) in enumerate(self.layers): | |
| x = x @ w.toarray().T + b if dense else (w @ x.T).T + b | |
| if i + 1 < len(self.layers): | |
| x = np.maximum(x, 0) | |
| return x[:, 0] | |
| def save(self, path): | |
| path = Path(path) | |
| path.mkdir(parents=True, exist_ok=False) | |
| arrays = {} | |
| for i, (w, b) in enumerate(self.layers): | |
| for key, value in (("data", w.data), ("indices", w.indices), ("indptr", w.indptr), ("shape", w.shape), ("bias", b)): | |
| arrays[f"l{i}_{key}"] = np.asarray(value) | |
| np.savez(path / "weights.npz", **arrays) | |
| digest = hashlib.sha256((path / "weights.npz").read_bytes()).hexdigest() | |
| metadata = dict(self.metadata, sha256=digest, layers=len(self.layers), **self.stats()) | |
| (path / "model.json").write_text(json.dumps(metadata, ensure_ascii=False, indent=2) + "\n") | |
| def load(cls, path): | |
| path = Path(path) | |
| meta = json.loads((path / "model.json").read_text()) | |
| if hashlib.sha256((path / "weights.npz").read_bytes()).hexdigest() != meta["sha256"]: | |
| raise ValueError("Контрольная сумма весов не совпала") | |
| layers = [] | |
| with np.load(path / "weights.npz", allow_pickle=False) as z: | |
| for i in range(meta["layers"]): | |
| w = csr_matrix((z[f"l{i}_data"], z[f"l{i}_indices"], z[f"l{i}_indptr"]), shape=tuple(z[f"l{i}_shape"])) | |
| layers.append((w, z[f"l{i}_bias"])) | |
| return cls(layers, meta) | |
| def stats(self): | |
| return { | |
| "architecture": [128] + [w.shape[0] for w, b in self.layers], | |
| "nonzero_weights": sum(w.nnz for w, b in self.layers), | |
| "nonzero_biases": sum(int(np.count_nonzero(b)) for w, b in self.layers), | |
| "dense_parameters_including_zeros": sum(w.shape[0] * w.shape[1] + len(b) for w, b in self.layers), | |
| "neurons_excluding_input": sum(w.shape[0] for w, b in self.layers), | |
| "sparse_array_bytes": sum(w.data.nbytes + w.indices.nbytes + w.indptr.nbytes + b.nbytes for w, b in self.layers), | |
| "float_weight_and_bias_bytes": sum(w.data.nbytes + b.nbytes for w, b in self.layers), | |
| } | |
| class Layer: | |
| def __init__(self, inputs): | |
| self.inputs = inputs | |
| self.rows, self.cols, self.values, self.bias = [], [], [], [] | |
| def node(self, terms, bias=0): | |
| row = len(self.bias) | |
| for col, value in terms: | |
| if value: | |
| self.rows.append(row) | |
| self.cols.append(col) | |
| self.values.append(value) | |
| self.bias.append(bias) | |
| return row | |
| def finish(self): | |
| w = csr_matrix((np.asarray(self.values, np.float32), (self.rows, self.cols)), shape=(len(self.bias), self.inputs), dtype=np.float32) | |
| w.sum_duplicates() | |
| w.eliminate_zeros() | |
| return w, np.asarray(self.bias, np.float32) | |