main
hy.kim 1 year ago
parent da4a42038d
commit dddf5f73ed

@ -50,9 +50,10 @@
[https://untitledtblog.tistory.com/5](https://untitledtblog.tistory.com/5)
### SOM 예제 코드[¶]()
### SOM 예제 코드 1[¶]()
<details>
<summary>Code View</summary>
<summary>입력 데이터 생성</summary>
<div markdown="1">
@ -258,21 +259,154 @@ array(\[\[0.76959259, 0.03105338\],
</details>
### 참고[¶]()
- ChatGPT
### SOM 예제 코드 2[¶]()
<details>
<summary>Code View</summary>
<summary>Randomize 함수</summary>
<div markdown="1">
````python
def randomize(A, rowcol=0):
"""
행렬 A를 행 혹은 열을 랜덤하게 섞기
rowcol: 0 혹은 없으면 행을 랜덤하게 섞기 (default)
1 이면, 열을 랜덤하게 섞기
"""
np.random.seed(int(sum([int(x) for x in str(time.time()) if x.isdigit()])))
if rowcol == 0:
m, n = A.shape
p = np.random.rand(m, 1)
p1, I = np.sort(p, axis=0), np.argsort(p, axis=0)
B = A[I, :]
return B.reshape(A.shape)
elif rowcol == 1:
Ap = A.T
m, n = Ap.shape
p = np.random.rand(m, 1)
p1, I = np.sort(p, axis=0), np.argsort(p, axis=0)
B = Ap[I, :]
return B.reshape(Ap.shape).T
````
</div>
<summary>Data Generator 함수</summary>
<div markdown="1">
````python
def datagen(Nvec, mean_var):
m, c = mean_var.shape
if m != 3 or c != len(Nvec):
print("dimension not match, break")
return None
X = np.empty((0, 2))
for i in range(c):
np.random.seed(int(sum([int(x) for x in str(time.time()) if x.isdigit()])))
tmp = np.sqrt(mean_var[2, i]) * np.random.randn(Nvec[i], 2) # scaled by variance
mean = mean_var[0:2, i] # mean is a 2 by 1 vector
X = np.vstack((X, tmp + np.ones((Nvec[i], 2)) * mean))
return X
````
### SOM [¶]()
</div>
<details>
<summary>Code View</summary>
<summary>SOM 구현</summary>
<div markdown="1">
````python
import os
import logging
import time
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib as mpl
# 마이너스 기호 표시 설정
mpl.rcParams['axes.unicode_minus'] = False
# 한글 폰트 설정 - Windows
# font_location = fm.findfont(fm.FontProperties(family='Malgun Gothic'))
# fm.FontProperties(fname=font_location)
# plt.rcParams['font.family'] = 'Malgun Gothic'
# 로거 수준을 ERROR로 설정하여 경고 메시지를 제거
matplotlib_logger = logging.getLogger("matplotlib")
matplotlib_logger.setLevel(logging.ERROR)
# 한글 폰트 설정 - Linux
font_dir = "/usr/share/fonts/truetype/nanum"
nanum_gothic_ttf = os.path.join(font_dir, "NanumGothic.ttf")
nanum_gothic = fm.FontProperties(fname=nanum_gothic_ttf)
# plt.rcParams["font.family"] = nanum_gothic.get_name()
plt.rcParams["axes.unicode_minus"] = False
def onces(rows, cols):
return np.ones((rows, cols))
# Parameters
N = 100 # 각 클러스터의 표본의 개수
N2 = N + N
eta = 0.2
means = np.array([[0.7, -0.8],
[0.7, -0.8]])
var = np.array([0.2, 0.2])
x = datagen([N, N], np.vstack((means, var))) # x: N2 by 2
x = randomize(x) # 행의 값을 랜덤하게 섞기
ncenter = 11 # 사용할 클러스터 뉴런의 개수
w = np.random.rand(ncenter, 2) - 0.5 * onces(ncenter, 2) # 초기 뉴런은 특징 공간상에 임의로 위치시킴
plt.figure()
plt.subplot(121)
plt.plot(x[:, 0], x[:, 1], 'r.', w[:, 0], w[:, 1], '*-')
plt.axis([-2, 2, -2, 2])
plt.title('초기화', fontproperties=nanum_gothic)
i = 1
iter = 1
converge = 0
while converge == 0:
dn = np.ones((ncenter, 1)) * x[i, :] - w
ddn = np.sum((dn * dn), axis=1) # ddn: ncenter by 1
istar = np.argmin(ddn)
if istar == 0:
w[[istar, istar + 1], :] = w[[istar, istar + 1], :] + eta * (np.ones((2, 1)) * x[i, :] - w[[istar, istar + 1], :])
elif istar == ncenter - 1:
w[[istar - 1, istar], :] = w[[istar - 1, istar], :] + eta * (np.ones((2, 1)) * x[i, :] - w[[istar - 1, istar], :])
else:
w[[istar - 1, istar, istar + 1], :] = w[[istar - 1, istar, istar + 1], :] + eta * (np.ones((3, 1)) * x[i, :] - w[[istar - 1, istar, istar + 1], :])
plt.subplot(122)
plt.plot(x[:, 0], x[:, 1], 'r.', x[i, 0], x[i, 1], 'o', w[:, 0], w[:, 1], '*-')
plt.title(f'Iteration = {iter}')
plt.pause(0.01)
i = (i + 1) % N2
iter += 1
if i == 0:
x = randomize(x) # 클러스터의 순서를 랜덤하게 섞는다.
i = 1 # 재배치된 입력으로 시작
if iter % 50 == 0:
eta *= 0.9
if iter >= 200:
converge = 1
plt
````
</div>
</details>
</details>
### 참고[¶]()
- ChatGPT
Loading…
Cancel
Save