Небольшое подозрение на топологию весов


Что если поискать модель от весов (другой модели) к её лоссу, ну или к скору?

Вообще, изначально идея была в другом. Вот в топологическом анализе данных растят шары из каждой точки данных, и анализируют число компонент связности (получают persistence diagrams).

Что если данные это веса сетки, одномерные такие вот точки, а диаграммы дают какую-то информацию про качество сетки?

Ответ: дают больше, чем сами веса.

def make_data(iterations=10000):
    units = []
    scores = []
    for index in tqdm.tqdm(range(iterations)):
        np.random.seed(index)
        random_x = np.random.normal(size=X.shape)
        random_y = np.random.randint(0, 2, size=y.shape)
        classifier = MLPClassifier([10, 10], max_iter=1, random_state=index).fit(random_x, random_y)
        current = []
        for layer in range(len(classifier.coefs_)):
            current += classifier.coefs_[layer].flatten().tolist() + classifier.intercepts_[layer].tolist()
        score = classifier.score(X, y)
        scores.append(score)
        units.append(current)

    return np.array(units).reshape(iterations, -1), np.array(scores)

где X, y — это например two moons dataset.

К слову, MLPClassifier([10, 10]) из scikit-learn выдаёт > 0.99 на трэйне и тесте. Ну а mean cross val score от весов напрямую к скору даёт… R2 -0.349.

Здесь выкинуты скоры между 0.49 и 0.51. Так как их процентов 70. А если взять диаграммы:

def get_diagrams(points):
    rips = ripser.Rips(maxdim=1, verbose=False)
    dgm = rips.fit_transform(points)[0]
    dgm = dgm[:-1][:, 1]
    if len(dgm) < len(points) - 1:
        dgm = np.array([0] * (len(points) - len(dgm) - 1) + dgm.tolist())
    return dgm

… то тогда регрессия от диаграмм к скору даёт на кроссвалидации R2 -0.003. Считай, средним предсказывает. Уже лучше.

Поэтому это и слабое подозрение. А что важно заметить, процедура рандомного «весования» сетки для two moons дала внезапно accuracy 0.94 в 1 из 10 тысяч случаев. Вот это интересно, конечно.

Ну а топология здесь причем… а при том что малые шевеления весов не должны менять классификацию серьезно. А эти малые шевеления и выражаются в компонентах связности.

А изначально думалось, что можно построить пошаговый оптимизатор, который бы брал (какую-то или) самую большую компоненту связности для весов и усреднял бы веса в ней итеративно. То есть без дифференцирования. Но что-то не задалось сегодня. Может быть, когда-нибудь, кто знает. А может и нет 🙂


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *