사전 계산된 사전을 사용한 희소 코딩

Beginner

This tutorial is from open-source community. Access the source code

소개

이 실험에서는 희소 코딩 방법을 사용하여 신호를 리커 (Ricker) 웨이블릿의 희소 조합으로 변환하는 방법을 배웁니다. 리커 (또한 멕시칸 해트 또는 가우시안의 이중 미분으로 알려짐) 는 이러한 신호와 같이 구간 상수 신호를 나타내는 데 특별히 좋은 커널이 아닙니다. 따라서 서로 다른 너비의 원자를 추가하는 것이 얼마나 중요한지, 그리고 이것이 신호 유형에 가장 적합한 사전을 학습하는 동기를 부여하는지 확인할 수 있습니다.

SparseCoder 추정기를 사용하여 다양한 희소 코딩 방법을 시각적으로 비교할 것입니다. 오른쪽의 더 풍부한 사전은 크기가 더 크지 않습니다. 동일한 크기 순서를 유지하기 위해 더 강력한 서브샘플링이 수행됩니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

라이브러리 가져오기

필요한 라이브러리를 가져오는 것으로 시작합니다.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import SparseCoder

리커 웨이블릿 함수 정의

리커 웨이블릿과 리커 웨이블릿 사전을 생성하는 함수를 정의합니다.

def ricker_function(resolution, center, width):
    """이산적으로 서브샘플링된 리커 (멕시칸 해트) 웨이블릿"""
    x = np.linspace(0, resolution - 1, resolution)
    x = (
        (2 / (np.sqrt(3 * width) * np.pi**0.25))
        * (1 - (x - center) ** 2 / width**2)
        * np.exp(-((x - center) ** 2) / (2 * width**2))
    )
    return x


def ricker_matrix(width, resolution, n_components):
    """리커 (멕시칸 해트) 웨이블릿 사전"""
    centers = np.linspace(0, resolution - 1, n_components)
    D = np.empty((n_components, resolution))
    for i, center in enumerate(centers):
        D[i] = ricker_function(resolution, center, width)
    D /= np.sqrt(np.sum(D**2, axis=1))[:, np.newaxis]
    return D

신호 생성

Matplotlib 을 사용하여 신호를 생성하고 시각화합니다.

resolution = 1024
subsampling = 3  ## 서브샘플링 계수
width = 100
n_components = resolution // subsampling

## 신호 생성
y = np.linspace(0, resolution - 1, resolution)
first_quarter = y < resolution / 4
y[first_quarter] = 3.0
y[np.logical_not(first_quarter)] = -1.0

## 신호 시각화
plt.figure()
plt.plot(y)
plt.title("원본 신호")
plt.show()

웨이블릿 사전 계산

Matplotlib 을 사용하여 웨이블릿 사전을 계산하고 시각화합니다.

## 웨이블릿 사전 계산
D_fixed = ricker_matrix(width=width, resolution=resolution, n_components=n_components)
D_multi = np.r_[
    tuple(
        ricker_matrix(width=w, resolution=resolution, n_components=n_components // 5)
        for w in (10, 50, 100, 500, 1000)
    )
]

## 웨이블릿 사전 시각화
plt.figure(figsize=(10, 5))
for i, D in enumerate((D_fixed, D_multi)):
    plt.subplot(1, 2, i + 1)
    plt.imshow(D, cmap=plt.cm.gray, interpolation="nearest")
    plt.title("웨이블릿 사전 (%s)" % ("고정 너비" if i == 0 else "여러 너비"))
    plt.axis("off")
plt.show()

희소 코딩

다양한 방법을 사용하여 신호에 대한 희소 코딩을 수행하고 결과를 시각화합니다.

## 다음 형식으로 다양한 희소 코딩 방법을 나열합니다.
## (제목, 변환 알고리즘, 변환 알파,
## 변환 비제로 계수, 색상)
estimators = [
    ("OMP", "omp", None, 15, "navy"),
    ("Lasso", "lasso_lars", 2, None, "turquoise"),
]
lw = 2

plt.figure(figsize=(13, 6))
for subplot, (D, title) in enumerate(
    zip((D_fixed, D_multi), ("고정 너비", "여러 너비"))
):
    plt.subplot(1, 2, subplot + 1)
    plt.title("%s 사전에 대한 희소 코딩" % title)
    plt.plot(y, lw=lw, linestyle="--", label="원본 신호")
    ## 웨이블릿 근사 수행
    for title, algo, alpha, n_nonzero, color in estimators:
        coder = SparseCoder(
            dictionary=D,
            transform_n_nonzero_coefs=n_nonzero,
            transform_alpha=alpha,
            transform_algorithm=algo,
        )
        x = coder.transform(y.reshape(1, -1))
        density = len(np.flatnonzero(x))
        x = np.ravel(np.dot(x, D))
        squared_error = np.sum((y - x) ** 2)
        plt.plot(
            x,
            color=color,
            lw=lw,
            label="%s: %s 비제로 계수,\n%.2f 오차" % (title, density, squared_error),
        )

    ## 소프트 임계값 편향 제거
    coder = SparseCoder(
        dictionary=D, transform_algorithm="threshold", transform_alpha=20
    )
    x = coder.transform(y.reshape(1, -1))
    _, idx = np.where(x != 0)
    x[0, idx], _, _, _ = np.linalg.lstsq(D[idx, :].T, y, rcond=None)
    x = np.ravel(np.dot(x, D))
    squared_error = np.sum((y - x) ** 2)
    plt.plot(
        x,
        color="darkorange",
        lw=lw,
        label="임계값 적용 편향 제거:\n%d 비제로 계수, %.2f 오차"
        % (len(idx), squared_error),
    )
    plt.axis("tight")
    plt.legend(shadow=False, loc="best")
plt.subplots_adjust(0.04, 0.07, 0.97, 0.90, 0.09, 0.2)
plt.show()

요약

이 실험에서 희소 코딩 방법과 SparseCoder 추정기를 사용하여 신호를 릭커 웨이블릿의 희소 조합으로 변환하는 방법을 배웠습니다. 또한 다양한 희소 코딩 방법을 비교하고 결과를 시각화했습니다.