Dieser Artikel ist der erste Tag von Furukawa Lab Advent_calendar. Dieser Artikel wurde von einem Studenten des Furukawa Lab als Teil seines Lernens geschrieben. Der Inhalt kann mehrdeutig sein oder der Ausdruck kann leicht abweichen.
In diesem Artikel möchte ich das vorstellen, was ich als UKR (Unsupervised Kernel Regression) bezeichnet habe, das ich tatsächlich zusammengestellt habe. Übersetzt ins Japanische ist es eine unbeaufsichtigte Kernel-Regression. Ich habe [dieses Dokument] gelesen und implementiert (https://www.sciencedirect.com/science/article/pii/S0925231206004802).
Wenn Sie sich für Mehrkörperlernen interessieren, probieren Sie es bitte aus.
Was UKR tun möchte, sind Beobachtungsdaten $ \ mathbf {Y} = (\ mathbf {y} _1, \ mathbf {y} _2, ... \ mathbf {y} _N) \ in \ mathbb {R} ^ {D × Latente Variable entsprechend N} $ und den einzelnen Beobachtungsdaten
$ \ mathbf {X} = (\ mathbf {x} _1, \ mathbf {x} _2, ... \ mathbf {x} _N) \ in \ mathbb {R} ^ {M × N} $ So schätzen Sie die Zuordnung $ \ mathbf {f}: \ mathbb {R} ^ {M} → \ mathbb {R} ^ {D} $.
Die Zuordnung $ \ mathbf {f} $ wird durch die folgende Formel geschätzt.
\mathbf{f}(\mathbf{x} ; \mathbf{X})=\sum_{i} \mathbf{y}_{i} \frac{K\left(\mathbf{x}-\mathbf{x}_{i}\right)}{\sum_{j} K\left(\mathbf{x}-\mathbf{x}_{j}\right)}\tag{1}
Vielleicht sind einige Leute damit vertraut. Diese Formel entspricht fast der Nadaraya-Watoson-Schätzung. Für Unbekannte wird $ K $ in einem Ausdruck als Kernelfunktion bezeichnet und in diesem Artikel mit dem folgenden Ausdruck definiert.
K\left(\mathbf{x}-\mathbf{x}^{\prime}\right)=\exp \left(\frac{-1}{2h}\left\|\mathbf{x}-\mathbf{x}^{\prime}\right\|^{2}\right)
Diese Kernelfunktion wird auch als Gaußscher Kernel bezeichnet. Der einzige Unterschied zu Nadaraya-Watoson besteht darin, dass die Kernelbreite $ h $ im Papier auf $ 1 $ festgelegt ist.
Die latente Variable wird durch die Formel (1) auf den Beobachtungsraum abgebildet, und der Fehler aus den Beobachtungsdaten wird durch die folgende Formel berechnet.
R(\mathbf{X})=\frac{1}{N} \sum_{i}\left\|\mathbf{y}_{i}-\mathbf{f}\left(\mathbf{x}_{i} ; \mathbf{X}\right)\right\|^{2}\tag{2}
Dieser Fehler wird durch die Gradientenmethode reduziert und die latente Variable wird aktualisiert. Bei der Implementierung haben Sie keine andere Wahl, als die automatische Differenzierung zu verwenden oder die Differenzierung selbst durchzuführen und die Formel in das Programm zu schreiben. In diesem Artikel versuche ich mein Bestes, um die Formel zu verwenden, die ich selbst differenziert habe. Wenn Sie alle Ausdruckserweiterungen schreiben, wird es ziemlich lang und die Belastung für mich wird groß sein, so dass ich nur das Endergebnis veröffentlichen werde.
r_{ij}=\frac{K\left(\mathbf{x}_{i}-\mathbf{x}_{j}\right)}{\sum_{j^{\prime}} K\left(\mathbf{x}_{i}-\mathbf{x}_{j^{\prime}}\right)}
\mathbf{d}_{ij}=\mathbf{f}(\mathbf{x}_{j};\mathbf{X})-\mathbf{y}_{i}
\mathbf{\delta}_{ij}=\mathbf{x}_{i}-\mathbf{x}_{j}
Unter Verwendung dieser Variablen wird die Differenzierung von Gleichung (2) wie folgt ausgedrückt.
\frac{1}{N} \frac{\partial}{\partial \mathbf{x}_{n}} \sum_{i}\left\|\mathbf{y}_{i}-\mathbf{f}(\mathbf{x}_{i};\mathbf{X})\right\|^{2}=\frac{2}{N}\sum_{i}\left[r_{n i} \mathbf{d}_{n n}^{\mathrm{T}} \mathbf{d}_{n i} \boldsymbol{\delta}_{n i}-r_{i n} \mathbf{d}_{i i}^{\mathrm{T}} \mathbf{d}_{i n} \boldsymbol{\delta}_{i n}\right]
Als Ganzes fließen Schätzen Sie die Abbildung durch Gleichung (1) Wiederholen Sie die Aktualisierung der latenten Variablen mit der Gradientenmethode, damit der Fehler in Gleichung (2) minimiert wird. Es wird sein.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import*
import matplotlib.animation as anm
fig = plt.figure(1,figsize=(14, 6))
ax1 = fig.add_subplot(121,projection='3d')
ax2 = fig.add_subplot(122)
class UKR:
def __init__(self,N,w,z,D,L):
self.N = N
self.zeta = z
self.x = w
self.f = []
self.hist =[]
self.sigma = 1.0
self.lamda = 0.1
self.test = []
self.lr = 1.0
self.D = D
self.L = L
self.gamma = 1.0 / (self.sigma * self.sigma)
def fit(self,T):
self.history = {"z":np.zeros((T, self.N, self.L)),
"Y":np.zeros((T, self.N ,self.D))}
for t in range(T):
self.delta = self.zeta[:,None,:] - self.zeta[None,:,:]
self.h_kn = np.exp(-1 / (2*self.sigma ** 2) * np.sum((self.zeta[None, :, :] - self.zeta[:, None, :]) ** 2,axis=2))
self.g_k = np.sum(self.h_kn,axis=1)
self.r_ij = self.h_kn/self.g_k[:,None]
self.f = np.zeros((self.N,self.D))
self.f = self.r_ij @ self.x
self.d_ij = self.f[:,None,:] - self.x[None,:,:]
self.A = self.gamma * self.r_ij * np.einsum('nd,nid->ni', self.f - self.x, self.d_ij)
self.bibun = np.sum((self.A + self.A.T)[:, :, None] * self.delta, axis=1)
self.zeta -= self.lr*(self.bibun + self.lamda*self.zeta)
self.history["Y"][t] = self.f
self.history["z"][t] = self.zeta
if __name__=="__main__":
N=20#Die Anzahl der Daten
T=50
w = np.zeros((N*N,3))
latent_space=np.random.normal
zeta = np.dstack(np.meshgrid(np.linspace(-1,1,N),np.linspace(-1,1,N),indexing='ij'))
zeta = np.reshape(zeta,(N*N,2))
for i in range (N*N):
mesh = zeta[i,0]**2-zeta[i,1]**2
w[i] = np.append(zeta[i],mesh)
np.random.seed(1)
i=0
ukr = UKR(N*N,w,zeta,3,2)
ukr.fit(T)
kekka = ukr.history["Y"]
kekka = np.reshape(kekka,(T,N,N,3))
k = ukr.history["z"]
k = np.array(k)
def update(i, zeta,w):
print(i)
ax1.cla()
ax2.cla()
ax1.scatter(w[:, 0], w[:, 1], w[:, 2], c=w[:, 0])
ax1.plot_wireframe(kekka[i,:,:,0],kekka[i,:,:,1],kekka[i,:,:,2])
ax2.scatter(k[i,:,0],k[i,:,1],c=w[:,0])
ax1.set_xlabel("X_axis")
ax1.set_ylabel("Y_axis")
ax1.set_zlabel("Z_axis")
ax2.set_title('latentspace')
ax2.set_xlabel("X_axis")
ax2.set_ylabel("Y_axis")
ani = anm.FuncAnimation(fig, update, fargs = (zeta,w), interval = 500, frames = T-1)
ani.save("test.gif", writer = 'imagemagick')
Dies ist das Implementierungsergebnis, wenn Satteltypdaten als Beobachtungsdaten angegeben werden. Die Abbildung links zeigt den Beobachtungsraum, in dem jeder Punkt die Beobachtungsdaten und die Vielfalt zeigt, die die Mesh-Mapping-Daten verbindet. Die Abbildung rechts zeigt den latenten Raum.
Es ist gut, dass die Sorten nach und nach die Beobachtungsdaten abdecken. Es ist schwer, müde zu werden, sie zu sehen.
Variants of unsupervised kernel regression: General cost functions