PIV_4:自组织映射(self organized map)

2019-08-17  本文已影响0人  闪电侠悟空

1.SOM算法思想:

关于自组织映射(SOM),可以看做一层前向线性全连接网络,隐层为feature map, 也就完成了SOM中的M(映射)的理解。自组织是什么意思呢?就是相邻位置的响应需要有一致性,p1响应值很大,那么相邻的p2也应该有个不小的响应值,这就是空间自组织的“分子机制”。当然SOM是通过无监督的方法进行训练。


个人理解的SOM

基学习算法:

  1. 初始化w_m
  2. 给一个样本x_i,找到对应的状态点p_m (也就是w_m产生最大的内积);
  3. 更新对应的w_m = w_m +\lambda (x_i-w_m)
  4. 邻域状态点也稍微更新下 w_k = w_k +0.5*\lambda (x_i-w_k), k点属于i的关联邻域;
  5. 重复更新过程,直至收敛。

2.snapshot POD和SOM对流场principal curves分析的测试(python)

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
%matplotlib inline
#- 合成100个时刻的流场
N = 32
x,y = np.meshgrid(np.linspace(0,1,N),np.linspace(0,1,N))
u,v = [],[] 
for t in range(100):
    T = 1+t/100.0
    u.append(np.cos(2*np.pi*x/T+np.pi/2)*np.cos(2*np.pi*y/T))
    v.append(np.sin(2*np.pi*x/T+np.pi/2)*np.sin(2*np.pi*y/T))

plt.figure(figsize=(12,12))
plt.quiver(u[0],v[0])
plt.title("T= 1")
plt.figure(figsize=(12,12))
plt.quiver(u[99],v[99])
plt.title("T=2")
<matplotlib.text.Text at 0x7f5c56669828>
output_2_1.png output_2_2.png
#- 做POD分解
snapshot_u =  np.swapaxes(np.array(u).reshape(100,-1),0,1)
snapshot_v =  np.swapaxes(np.array(v).reshape(100,-1),0,1)
snapshot = np.concatenate((snapshot_u,snapshot_v),axis = 0)
print(snapshot.shape)
U,s,V =np.linalg.svd(snapshot) # SVD就实现了POD分解

#- 利用前2个模态的系数,画POD的空间轨迹
pod_t1,pod_t2 = [],[]
for i in range(100):
    snapshot_i = snapshot[:,i]
    pod_t1.append(np.dot(U[:,0],snapshot_i))
    pod_t2.append(np.dot(U[:,1],snapshot_i))

plt.plot(pod_t1,pod_t2,"-o")
plt.xlabel("1st POD modal")
plt.ylabel("2nd POD modal")
plt.title("principal curves(POD)") # 也不是直线呀,很规律的轨迹
(2048, 100)


<matplotlib.text.Text at 0x7f5c56448828>
output_3_2.png
#SOM 分解
# 采用10*10(100)个隐藏状态
Nx,Ny = 12,12
W = np.random.randn(2*N*N,Nx*Ny)
W_temp = np.copy(W)

labmda = 0.05
for epoch in range(2000): # SOM学习的挺慢的,需要较大的迭代次数
    if (epoch +1)%200==0:
        print("training : %d (epoch)"%(epoch+1)) 
    for x in snapshot.T:
        # 前向计算一波
        p = np.matmul(x.reshape(1,-1),W)
        # print(p.shape)
        
        # 找到最佳的特征点 与四个邻居
        p_star = np.argmax(p)
        i_star,j_star = p_star//Nx,p_star%Nx
        
        p_n = []
        i_star_1 = i_star-1 if i_star>0 else np.NaN
        p_n.append( i_star_1*Nx+j_star)
        j_star_1 = j_star-1 if j_star>0 else np.NaN
        p_n.append(i_star*Nx+j_star_1)
        i_star_2 = i_star+1 if i_star+1<Nx else np.NaN
        p_n.append( i_star_2*Nx+j_star)
        j_star_2 = j_star+1 if j_star+1<Ny else np.NaN
        p_n.append( i_star*Nx+j_star_2)
        
        #print(p_star,p_n[0],p_n[1],p_n[2],p_n[3])
        
        # 更新W参数
        W_temp[:,p_star] = W[:,p_star]+labmda *(x-W[:,p_star])
        for pn in p_n:
            if not np.isnan(pn):
                W_temp[:,pn] = W[:,pn]+0.95*labmda *(x-W[:,pn])  
    W = np.copy(W_temp)
                
# 也不知道学习的好坏,看看SOM的基算了
for i in range(0,100,20):
    plt.figure(figsize=(8,8))
    model_u,model_v = W[:N**2,i].reshape(N,N),W[N**2:,i].reshape(N,N)
    plt.quiver(model_u,model_v)
    plt.title("SOM basis")


training : 200 (epoch)
training : 400 (epoch)
training : 600 (epoch)
training : 800 (epoch)
training : 1000 (epoch)
training : 1200 (epoch)
training : 1400 (epoch)
training : 1600 (epoch)
training : 1800 (epoch)
training : 2000 (epoch)
output_4_1.png output_4_2.png output_4_3.png output_4_4.png output_4_5.png
# 看看SOM的轨迹吧
som_t1,som_t2 = [],[]
for i in range(100):
    snapshot_i = snapshot[:,i]
    p = np.matmul(snapshot_i.reshape(1,-1),W)
    p_star = np.argmax(p)
    i_star,j_star = p_star//Nx,p_star%Nx
    som_t1.append(i_star)
    som_t2.append(j_star)

plt.plot(som_t1,som_t2,"-o")
plt.xlabel("SOM x")
plt.ylabel("SOM y")
plt.title("principal curves(SOM)") # 也不是直线,也不是曲线,都他妈的是什么玩意儿,很不规律,啥也说明不了。
<matplotlib.text.Text at 0x7f5c5be670f0>
output_5_1.png

3.总结

4. 参考资料

上一篇 下一篇

猜你喜欢

热点阅读