Исследование поведения предложенного функционала. Часть II.

Пора перейти к более реалистичным тестам. Логичным шагом будет начать работать с операторами, а не с их имитацией. Предполагаются следующие цели:

  1. Показать, что значение предлагаемой меры неивариантности будет равно нулю, на операторе второй производной и наборе и парных синусов и косинусов аргумента $kx$, для некоторых $k \in [1 \dots M-1]$
  2. Показать, что значение меры инвариантности относительно оператора второй производной будет ненулевым, если посчитать его на наборе парных синусов и косинусов аргумента $kx$, для некоторых $k \in [1 \dots M]$ с некоторой дополнительной функцией $\alpha \cdot f(x)$, вторая производная которой явно не может быть аппроксимированна тригонометрическими функциями с аргументами $kx$ для того же набора $k$, и самой $\alpha \cdot f(x)$. Примером такой функции может служить та же сигмоида, что и в части I. Её вторая производная локальна(значит не должна воспроизвестись синусами и косинусами), не воспроизводится самой сигмоидой. Оказывается, что результат зависит от $\alpha$.
  3. Исследовать поведение функционала в зависимости от $\alpha$ и сделать выводы. С точки зрения алгебры, зависимости от коэффициента перед базисной функции - быть не должно.

In [77]:
import numpy as np
import tensorflow as tf
from matplotlib import pylab as plt
%matplotlib inline

m = 4500 
k_max = 6
M = k_max*2-2
a = -10
b = 10

x_grid = np.linspace(a, b, m, endpoint=True)
sess = tf.Session()
x = tf.placeholder(tf.double)
k_vec = [i for i in range(1, k_max)]
trial_func = []
for i in range(len(k_vec)):
    trial_func.append(tf.sin(k_vec[i]*x))
    trial_func.append(tf.cos(k_vec[i]*x))
    
alpha = tf.Variable(50, dtype=tf.double)
sess.run(tf.global_variables_initializer(), {x:x_grid})
alpha_loc = tf.placeholder(tf.double)
ass_alpha = tf.assign(alpha, alpha_loc)

trial_func.append(alpha*tf.sigmoid(x))

deriatives = [tf.gradients(trial_func[i], x)[0] for i in range(M+1)]
images = ([tf.gradients(trial_func[i], x)[0] for i in range(M+1)])

print(np.array(sess.run(images, {x:x_grid})).shape)

def get_noninv_index_tensor(trial_func, images, x):
    A = tf.transpose(trial_func)
    A_T = trial_func
    y_0 = tf.reduce_sum(input_tensor=images, axis=0)
    y = tf.expand_dims(y_0, -1)
    omega = tf.matmul(tf.matmul(tf.matrix_inverse(tf.matmul(A_T, A)), A_T), y)
    regression_fit = tf.matmul(tf.transpose(trial_func), omega)
    noninvariance_index = (1 / m) * tf.reduce_sum(tf.square(y - regression_fit))
    return regression_fit, noninvariance_index

regression_fit_sig, noninv_sig = get_noninv_index_tensor(trial_func, images, x)
regression_fit_nosig, noninv_nosig = get_noninv_index_tensor(trial_func[:M], images[:M], x)


print('1) Calculated measure of noninvariance: ', sess.run(noninv_nosig, {x:x_grid}))
print('2) Calculated measure of noninvariance: ', sess.run(noninv_sig, {x:x_grid}))


(11, 4500)
1) Calculated measure of noninvariance:  5.299143668641333e-29
2) Calculated measure of noninvariance:  16.197830514441446

In [ ]:
def plot_all(x_in,title):
    fig = plt.figure(figsize=(16,8))
    func_set_matrix = sess.run(trial_func, {x:x_in})
    images_matrix = sess.run(images, {x:x_in})
    regression_fit = sess.run(regression_fit_sig, {x:x_grid})
    plt.title(title, fontsize = 16)
    plt.grid(True)
    for i in range(np.array(trial_func).shape[0]):
        plt.plot(x_in, func_set_matrix[i])
    plt.plot(x_in, np.sum(images_martix, axis=0), 'g--')

In [ ]:
noninv_list = []
noninv_list_nosig = []
i_list = []
local_alpha = 1e-5
x_grid_obs = np.linspace(a-5, b+5, 10000, endpoint=True)
for i in range(15):
    sess.run(ass_alpha, {alpha_loc:local_alpha})
    noninv_list.append(sess.run(noninv_sig, {x:x_grid}))
    noninv_list_nosig.append(sess.run(noninv_nosig, {x:x_grid}))
    i_list.append(local_alpha)
    
    if i==14:
        title = r'$\alpha$'+'='+ str(local_alpha)
        plot_all(x_grid_obs, title)
    if i==5:
        title = r'$\alpha$'+'='+ str(local_alpha)
        plot_all(x_grid_obs, title)
    if i==0:
        title = r'$\alpha$'+'='+ str(local_alpha)
        plot_all(x_grid_obs, title)
    local_alpha += 5

In [ ]:
fig = plt.figure(figsize=(20,10))
plt.grid(True)
plt.title('Noninvariance index', fontsize=26)
plt.xlabel(r'$\alpha$', fontsize=20)
plt.ylabel('J', fontsize=20)
plt.plot(i_list, noninv_list, 'rx--')
plt.plot(i_list, noninv_list_nosig, 'gx--')

Результат.

Как и ожидалось, в случае использования инвариантного базиса, мера неивариантности $\approx 0$, а в случае неинвариантного $\neq 0$.

Это даёт основания считать предложенную меру пригодной для использования с операторами, а не только с синтетическими наборами функций.