입력 1개와 출력 2개에 대한 선형회귀 신경망 구성 (복합 출력 / 다중 출력 신경망 모델)

다음과 같은 구조의 신경망을 구현에 대한 내용이다.

위의 신경망을 통해 판단할 수 있는 것은 입력값은 1개이고 출력값이 2개이므로 각각의 텐서구조는 [x], [y1, y2]라는 것이다. 신경망의 마지막 은닉층의 뉴런개수는 출력 개수와 동일하므로 2개이다.

코드를 보자. 먼저 필요한 패키지의 임포트이다. 파이토치를 사용한 예이다.

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.init as init

데이터를 준비한다.

num_data = 4000

x = torch.Tensor(num_data,1)
init.uniform_(x,-10,10)

noise = torch.FloatTensor(num_data,2)
init.normal_(noise, std=1)

def func1(x): return 4*x+5 
def func2(x): return 7*x+3 

y1 = func1(x)
y2 = func2(x)

y_noise = torch.Tensor(num_data,2)
y_noise[:,0] = y1[:,0] + noise[:,0]
y_noise[:,1] = y2[:,0] + noise[:,1]

데이터셋의 구성 개수는 4000개로 했다. 입력값(x)에 대해 2개의 출력값을 위한 선형공식이 9와 10 라인에 보인다. 12-17라인은 데이터에 잡음을 추가한 것이다. 잡음이 추가된 데이터를 통해 가중치(기울기)인 4, 7과 편향(y절편)인 5, 3을 결과를 얻어내면 된다. 아래는 이를 위한 학습 코드다.

model = nn.Linear(1,2)
loss_func = nn.L1Loss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
label = y_noise
num_epoch = 2000

for i in range(num_epoch):
    optimizer.zero_grad()
    output = model(x)
    loss = loss_func(output, label)
    loss.backward()
    optimizer.step()

    if i%10 == 0:
        print(loss.data)

param_list = list(model.parameters())
print(param_list[0], param_list[1])

결과는 다음과 같다.

tensor(28.9745)
tensor(27.7681)
tensor(26.5639)
tensor(25.3614)
tensor(24.1623)
tensor(22.9677)
tensor(21.7777)
.
.
.
tensor(0.7945)
tensor(0.7945)
tensor(0.7945)
Parameter containing:
tensor([[3.9986],
        [7.0006]], requires_grad=True) Parameter containing:
tensor([4.9845, 3.0214], requires_grad=True)

총 2000번 학습 시켰고, 그 결과로 손실값이 약 27로 시작해서 약 0.79 줄었다. 그리고 결과는 4, 7 그리고 5, 3에 근사한 값이 나온것을 알 수 있다.

이 코드를 통해 알아낸 것은 1개의 특성을 통해 그보다 더 많은 2개의 특성을 얻어내야 하는 이 경우에는 입력 데이터가 상대적으로 많아야 한다는 것이다. 이 경우는 4000개이다. 아울러 적당한 손실함수를 사용해야 한다. 위의 예제는 L1 손실함수를 사용했지만 평균제곱오차 손실함수를 사용하면 더 적은 데이터(이 부분은 확인이 필요함)와 반복학습이 가능하다.

여기서 입력 데이터와 분석 결과를 그래프로 시각화 해보자. 해당 코드는 아래와 같다. 지금까지의 코드에서 마지막에 붙이면 된다.

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(15,15))
plt.scatter(x.numpy(),y_noise[:,0].numpy(),s=3,c="gray")
plt.scatter(x.numpy(),y_noise[:,1].numpy(),s=3,c="black")

x = np.arange(-10, 10, 0.01)
plt.plot(x, func1(x), linestyle='-', label="func1", c='red')
plt.plot(x, func2(x), linestyle='-', label="func2", c='blue')

plt.axis([-10, 10, -30, 30])
plt.show()

그래프는 다음과 같다.

회색점과 검정색점은 입력 데이터이고, 빨간색선과 파란색선은 선형회귀 결과를 표시한 것이다.

[Linux] 콘솔 출력에 색상값 넣기

리눅스는 쓰면 쓸수록 최선이자 최고이다. 더욱이 Windows 운영체제에서도 WSL로 리눅스를 활용할 수 있으니 리눅스의 가치상승은 더 높아졌다. 그와함께 Windows의 가치도 Up!

본론으로 돌아와서.. 리눅스에서 서버를 기동하고 그 사용 로그를 화면에 출력한다. 여기에 중요한 내용에 색상값을 넣어 시각적으로 보다 더 쉽게 내용을 파악하고자 한다. 즉, 최종 결과물은 다음과 같다.

보면 SUCCESSED와 FAILED에 대해 각각 초록색과 빨간색으로 표시하고 그외는 하얀색으로 표시하고 있다. 이를 위해서 리눅스의 sed 명령어가 활용되는데, 이를 위한 쉘은 다음과 같다.

# color
szColBk="";	szColBk1=""	# black
szColRe="";	szColRe1=""	# red
szColGr="";	szColGr1=""	# green
szColYe="";	szColYe1=""	# yellow
szColBl="";	szColBl1=""	# blue
szColPu="";	szColPu1=""	# magenta(purple)
szColCy="";	szColCy1=""	# cyan
szColGy="";	szColWh=""	# white
szNormal=""

# command
sed \
    -e "s/\(SUCCESSED\)/${szColGr1}\\1$szNormal/g" \
    -e "s/\(FAILED\)/${szColRe1}\\1$szNormal/g" \

위의 코드를 coloring.sh라는 파일로 저장하고 실행할 수 있도록 권한을 부여해 두고.. 로그 출력을 위해 다음 명령을 수행하면 된다.

 tail /web_home/2020-06-13.log -f | ./coloring.sh

[Java] 두 문자열간의 유사도 구하기

두개의 문자열이 있을때, 얼마나 유사한지를 백분율의 개념인 0~1사이의 값으로 확인할 수 있을까? 즉 똑같은 문자열이라면 1을 전혀 다른 문자열이라면 0이라는 값으로 말이다. 구글링해보니 edit distance 계산을 통해 얻을 수 있단다. 가장 일반적은 구현체는 Levenshtein의 Distance Algorithm이라고 하고, 그 구현 함수는 다음과 같다. (출처: http://rosettacode.org/wiki/Levenshtein_distance#Java)

private double similarity(String s1, String s2) {
    String longer = s1, shorter = s2;
	
    if (s1.length() < s2.length()) {
        longer = s2; 
        shorter = s1;
    }
	
    int longerLength = longer.length();
    if (longerLength == 0) return 1.0;

    return (longerLength - editDistance(longer, shorter)) / (double) longerLength;
}

private int editDistance(String s1, String s2) {
	s1 = s1.toLowerCase();
    s2 = s2.toLowerCase();
    int[] costs = new int[s2.length() + 1];
    
    for (int i = 0; i <= s1.length(); i++) {
        int lastValue = i;
        for (int j = 0; j <= s2.length(); j++) {
            if (i == 0) {
            	costs[j] = j;
            } else {
                if (j > 0) {
                    int newValue = costs[j - 1];
                    
                    if (s1.charAt(i - 1) != s2.charAt(j - 1)) {
                    	newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1;
                    }
                    
                    costs[j - 1] = lastValue;
                    lastValue = newValue;
                }
            }
        }
        
        if (i > 0) costs[s2.length()] = lastValue;
    }
    
    return costs[s2.length()];
}

사용은 similarity 함수에 비교할 문자열 2개를 지정하면 비슷한 정도가 0~1 사이의 값으로 반환된다.

CAD 색상 테이블 (Color Table)

지리정보시스템(GIS)의 원시 데이터 중 CAD에 대한 시각화를 위한 색상 테이블을 정리한 표입니다.

0 (#000000)
1 (#FF0000)
2 (#FFFF00)
3 (#00FF00)
4 (#00FFFF)
5 (#0000FF)
6 (#FF00FF)
7 (#FFFFFF)
8 (#414141)
9 (#808080)
10 (#FF0000)
11 (#FFAAAA)
12 (#BD0000)
13 (#BD7E7E)
14 (#810000)
15 (#815656)
16 (#680000)
17 (#684545)
18 (#4F0000)
19 (#4F3535)
20 (#FF3F00)
21 (#FFBFAA)
22 (#BD2E00)
23 (#BD8D7E)
24 (#811F00)
25 (#816056)
26 (#681900)
27 (#684E45)
28 (#4F1300)
29 (#4F3B35)
30 (#FF7F00)
31 (#FFD4AA)
32 (#BD5E00)
33 (#BD9D7E)
34 (#814000)
35 (#816B56)
36 (#683400)
37 (#685645)
38 (#4F2700)
39 (#4F4235)
40 (#FFBF00)
41 (#FFEAAA)
42 (#BD8D00)
43 (#BDAD7E)
44 (#816000)
45 (#817656)
46 (#684E00)
47 (#685F45)
48 (#4F3B00)
49 (#4F4935)
50 (#FFFF00)
51 (#FFFFAA)
52 (#BDBD00)
53 (#BDBD7E)
54 (#818100)
55 (#818156)
56 (#686800)
57 (#686845)
58 (#4F4F00)
59 (#4F4F35)
60 (#BFFF00)
61 (#EAFFAA)
62 (#8DBD00)
63 (#ADBD7E)
64 (#608100)
65 (#768156)
66 (#4E6800)
67 (#5F6845)
68 (#3B4F00)
69 (#494F35)
70 (#7FFF00)
71 (#D4FFAA)
72 (#5EBD00)
73 (#9DBD7E)
74 (#408100)
75 (#6B8156)
76 (#346800)
77 (#566845)
78 (#274F00)
79 (#424F35)
80 (#3FFF00)
81 (#BFFFAA)
82 (#2EBD00)
83 (#8DBD7E)
84 (#1F8100)
85 (#608156)
86 (#196800)
87 (#4E6845)
88 (#134F00)
89 (#3B4F35)
90 (#00FF00)
91 (#AAFFAA)
92 (#00BD00)
93 (#7EBD7E)
94 (#008100)
95 (#568156)
96 (#006800)
97 (#456845)
98 (#004F00)
99 (#354F35)
100 (#00FF3F)
101 (#AAFFBF)
102 (#00BD2E)
103 (#7EBD8D)
104 (#00811F)
105 (#568160)
106 (#006819)
107 (#45684E)
108 (#004F13)
109 (#354F3B)
110 (#00FF7F)
111 (#AAFFD4)
112 (#00BD5E)
113 (#7EBD9D)
114 (#008140)
115 (#56816B)
116 (#006834)
117 (#456856)
118 (#004F27)
119 (#354F42)
120 (#00FFBF)
121 (#AAFFEA)
122 (#00BD8D)
123 (#7EBDAD)
124 (#008160)
125 (#568176)
126 (#00684E)
127 (#45685F)
128 (#004F3B)
129 (#354F49)
130 (#00FFFF)
131 (#AAFFFF)
132 (#00BDBD)
133 (#7EBDBD)
134 (#008181)
135 (#568181)
136 (#006868)
137 (#456868)
138 (#004F4F)
139 (#354F4F)
140 (#00BFFF)
141 (#AAEAFF)
142 (#008DBD)
143 (#7EADBD)
144 (#006081)
145 (#567681)
146 (#004E68)
147 (#455F68)
148 (#003B4F)
149 (#35494F)
150 (#007FFF)
151 (#AAD4FF)
152 (#005EBD)
153 (#7E9DBD)
154 (#004081)
155 (#566B81)
156 (#003468)
157 (#455668)
158 (#00274F)
159 (#35424F)
160 (#003FFF)
161 (#AABFFF)
162 (#002EBD)
163 (#7E8DBD)
164 (#001F81)
165 (#566081)
166 (#001968)
167 (#454E68)
168 (#00134F)
169 (#353B4F)
170 (#0000FF)
171 (#AAAAFF)
172 (#0000BD)
173 (#7E7EBD)
174 (#000081)
175 (#565681)
176 (#000068)
177 (#454568)
178 (#00004F)
179 (#35354F)
180 (#3F00FF)
181 (#BFAAFF)
182 (#2E00BD)
183 (#8D7EBD)
184 (#1F0081)
185 (#605681)
186 (#190068)
187 (#4E4568)
188 (#13004F)
189 (#3B354F)
190 (#7F00FF)
191 (#D4AAFF)
192 (#5E00BD)
193 (#9D7EBD)
194 (#400081)
195 (#6B5681)
196 (#340068)
197 (#564568)
198 (#27004F)
199 (#42354F)
200 (#BF00FF)
201 (#EAAAFF)
202 (#8D00BD)
203 (#AD7EBD)
204 (#600081)
205 (#765681)
206 (#4E0068)
207 (#5F4568)
208 (#3B004F)
209 (#49354F)
210 (#FF00FF)
211 (#FFAAFF)
212 (#BD00BD)
213 (#BD7EBD)
214 (#810081)
215 (#815681)
216 (#680068)
217 (#684568)
218 (#4F004F)
219 (#4F354F)
220 (#FF00BF)
221 (#FFAAEA)
222 (#BD008D)
223 (#BD7EAD)
224 (#810060)
225 (#815676)
226 (#68004E)
227 (#68455F)
228 (#4F003B)
229 (#4F3549)
230 (#FF007F)
231 (#FFAAD4)
232 (#BD005E)
233 (#BD7E9D)
234 (#810040)
235 (#81566B)
236 (#680034)
237 (#684556)
238 (#4F0027)
239 (#4F3542)
240 (#FF003F)
241 (#FFAABF)
242 (#BD002E)
243 (#BD7E8D)
244 (#81001F)
245 (#815660)
246 (#680019)
247 (#68454E)
248 (#4F0013)
249 (#4F353B)
250 (#333333)
251 (#505050)
252 (#696969)
253 (#828282)
254 (#BEBEBE)
255 (#FFFFFF)