Пора перейти к более реалистичным тестам. Логичным шагом будет начать работать с операторами, а не с их имитацией. Предполагаются следующие цели:
In [103]:
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}))
In [104]:
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_in})
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_matrix, axis=0), 'g--')
plt.plot(x_in, regression_fit, 'r--')
In [105]:
noninv_list = []
noninv_list_nosig = []
i_list = []
local_alpha = 1e-5
x_grid_obs = np.linspace(a-50, b+50, 10000, endpoint=True)
for i in range(50):
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==45:
title = r'$\alpha$'+'='+ str(local_alpha)
plot_all(x_grid_obs, title)
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 [106]:
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--')
Out[106]:
Как и ожидалось, в случае использования инвариантного базиса, мера неивариантности $\approx 0$, а в случае неинвариантного $\neq 0$. Это даёт основания считать предложенную меру пригодной для использования с операторами, а не только с синтетическими наборами функций.
Однако, удалось показать относительно ожидаемый, но неприятный эффект: значение функционала зависит от линейных коэффициентов перед базисными функциями. Это легко понять, вспомнив, как формируется функция, к которой производится аппроксимация. Если в наборе функций есть функция с номером $l$: $f_l(x) = \alpha \cdot g_l(x)$, при этом аппроксимация происходит к функции $y(x)$ : $$y(x)= \sum_i \beta_i \cdot f_i(x)$$ при этом $\forall i: \beta_i=1$. Можно переопределить $y(x)$: $$y(x)=\sum_{i\neq l} f_i(x) + \alpha \cdot g(x)$$ Таким образом, малый $\alpha$ фактически выводит функцию $g_l(x)$ "из игры".
В данном случае, при малом $\alpha$, сигмоида, которая "портит" инвариантность набора, сходит на нет и ситуация вырождается в набор без сигмоиды. При увеличении $\alpha$, $y(x)$ "растягивается" в сторону неивариантной части, увеличивая значение функционала.
Этот эффект может оказаться достаточно проблематичным явлением при использовании этого функционала для решения уравнений. По крайней мере, о нем не стоит забывать. Именно в этом месте появляется существенная разница между такой численной оценкой неинвариантности и тем, что бы мы хотели ожидать с точки зрения алгебры. Хотя, с точки зрения алгебры мне незнакомы ситуации, когда ставилась бы задачи количественно оценивать инвариантность наборов векторов/функций относительно оператора.