Введение
В этом практическом занятии мы научимся преобразовывать сигнал в разреженную комбинацию вейвлетов Рикера с использованием методов разреженного кодирования. Рикер (также известный как мексиканская шляпа или вторая производная Гаусса) не является особенно хорошим ядром для представления кусочно-стационарных сигналов такого типа. Таким образом, можно увидеть, насколько важен выбор атомов с разной шириной, и это мотивирует обучение словаря для наилучшего соответствия типу ваших сигналов.
Мы визуально сравним различные методы разреженного кодирования с использованием оценщика SparseCoder. Более богатый словарь справа не имеет большей размерности, более интенсивная субвыборка выполняется для того, чтобы оставаться на том же порядке величин.
Советы по использованию ВМ
После запуска ВМ кликните в левом верхнем углу, чтобы переключиться на вкладку Ноутбук и получить доступ к 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("Original Signal")
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("Wavelet Dictionary (%s)" % ("fixed width" if i == 0 else "multiple widths"))
plt.axis("off")
plt.show()
Sparse Coding
Мы выполним разреженное кодирование сигнала с использованием различных методов и визуализируем результаты.
## Списком различных методов разреженного кодирования в следующем формате:
## (title, transform_algorithm, transform_alpha,
## transform_n_nozero_coefs, color)
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), ("fixed width", "multiple widths"))
):
plt.subplot(1, 2, subplot + 1)
plt.title("Sparse coding against %s dictionary" % title)
plt.plot(y, lw=lw, linestyle="--", label="Original signal")
## Сделать аппроксимацию вейвлетом
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 nonzero coefs,\n%.2f error" % (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="Thresholding w/ debiasing:\n%d nonzero coefs, %.2f error"
% (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. Мы также сравнили различные методы разреженного кодирования и визуализировали результаты.