<jupyter_start><jupyter_text>Лабораторная работа №7 Исследование рекуррентной нейронной сети Хопфилда на примере задачи распознавания образов<jupyter_code>import numpy as np
import matplotlib.pyplot as plt

from itertools import chain

from enum import IntEnum
# Образы согласно варианту
A = [
    [-1,  1, -1],
    [ 1, -1,  1],
    [ 1,  1,  1],
    [ 1, -1,  1],
    [ 1, -1,  1]
]

I = [
    [ 1,  1,  1],
    [-1,  1, -1],
    [-1,  1, -1],
    [-1,  1, -1],
    [ 1,  1,  1]
]

F = [
    [ 1,  1,  1],
    [ 1, -1, -1],
    [ 1,  1, -1],
    [ 1, -1, -1],
    [ 1, -1, -1]
]

# Векторизуем
A, I, F = [
    np.fromiter(
        chain(*np.transpose(img)),
        dtype=int
    ) for img in [A, I, F]
]

# Вывод
A, I, F
def img_to_str(img):
    return ''.join(str(elem) for elem in img)

def create(imgs):
    # Начальные веса как векторная сумма матричных произведений образов на транспонированных себя же
    W = sum(np.dot(np.transpose([img]), [img]) for img in imgs)

    # Зануляем диагональ
    np.fill_diagonal(W, 0)

    return W


class StopState(IntEnum):
    NONE = 0
    LAST = 1
    ASYNC = 2
    SYNC = 3

def stopper(imgs):
    imgs = [img_to_str(im) for im in imgs]

    def _stopper(Y):
        sY = [img_to_str(y) for y in Y]

        # Проверяем совпадение с одним из образов
        if any(sY[-1] == im for im in imgs):
            return StopState.LAST
        
        # Проверяем зацикленность для асинхронного режима
        if len(Y) > 1 and sY[-1] == sY[-2]:
            return StopState.ASYNC

        # Проверяем зацикленность для синхронного режима
        if len(Y) > 3 and sY[-1] == sY[-3] and sY[-2] == sY[-4]:
            return StopState.SYNC
        
        return StopState.NONE
    
    return _stopper


def operate(W, imgs, img):
    stop = stopper(imgs)

    Y = [img]
    while True:
        state = stop(Y)
        if state != StopState.NONE:
            return Y, state

        Net = np.dot(W, Y[-1])

        y = [actF(net, i) for net, i in zip(Net, Y[-1])]
        Y.append(y)

imgs = [A, I, F]

W = create(imgs)

for img in imgs:
    print(f"Образ:     {np.array(img)}")
    Y, state = operate(W, imgs, img)
    print(f"Результат: {Y[-1]}, {state}")<jupyter_output>Образ:     [-1  1  1  1  1  1 -1  1 -1 -1 -1  1  1  1  1]
Результат: [-1  1  1  1  1  1 -1  1 -1 -1 -1  1  1  1  1], 1
Образ:     [ 1 -1 -1 -1  1  1  1  1  1  1  1 -1 -1 -1  1]
Результат: [ 1 -1 -1 -1  1  1  1  1  1  1  1 -1 -1 -1  1], 1
Образ:     [ 1  1  1  1  1  1 -1  1 -1 -1  1 -1 -1 -1 -1]
Результат: [ 1  1  1  1  1  1 -1  1 -1 -1  1 -1 -1 -1 -1], 1
{'fraction_non_alphanumeric': 0.14613291877186163, 'fraction_numerical': 0.060629615235134084, 'mean_word_length': 1.7647690655209451, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '663268', 'license': 'MIT', 'n_tokens_mistral': 1200, 'n_tokens_neox': 1228, 'n_words': 354, 'path': 'lab-07.ipynb', 'repo_name': 'mocurin/ITIS', 'size': '2573'}