🤖머신러닝/개인공부및 삽질

머신러닝 공부일지 (선형회귀 Matrics Multiplication과 로지스틱회귀)

Mawile 2021. 10. 2.
728x90

오늘도 공부내용과 함께 직접 작성한 소스코드를 가져왔습니다!

 

우선 이번에는 선형회귀에서 여러개의 X값을 받을때 무조건!! 알아야하는 개념인 "Matrics Multiplication"

로지스틱회귀의 Hypnothesis, cost function에 관하여 공부하였습니다.

 

사실 지금은 "Multinomial Logistic Regression"에 관하여 공부하고있지만,

차곡차곡 공부내용을 올린다는 마인드로 가고있습니다!

 

 

우선 이제부터 Input의 값이 많아지기때문에, 파일에 값들을 저장하고 읽어들이는 방법에 관하여도 공부했습니다.

 

우선 "Matrics Multiplication" 에 관하여 아래링크를 남겨놓았으니, 궁금한 분들은 아래링크로 타고 들어가 주시기바랍니다.

https://ko.wikipedia.org/wiki/%ED%96%89%EB%A0%AC_%EA%B3%B1%EC%85%88

 

행렬 곱셈 - 위키백과, 우리 모두의 백과사전

행렬 곱셈을 위해선 첫째 행렬의 열 갯수와 둘째 행렬의 행 갯수가 동일해야한다. 곱셈의 결과 새롭게 만들어진 행렬은 첫째 행렬의 행 갯수와 둘째 행렬의 열 갯수를 가진다. 행렬 곱셈(matrix mul

ko.wikipedia.org

 

import tensorflow.compat.v1 as tf
import matplotlib.pyplot as plt
import numpy as np
tf.disable_v2_behavior()

# 파일에서 X, Y값 불러오기
npData = np.loadtxt('data.csv', delimiter = ',', dtype = np.float32)
xData = npData[:, 0:-1] # numpy에서 -1은 마지막을 의미
yData = npData[:, [-1]]

# 행렬곱셈에서 None즉, N과 한번에 입력받는 X의 수인 3을 넣는다
X = tf.placeholder(tf.float32, shape = [None, 3])
Y = tf.placeholder(tf.float32, shape = [None, 1])

# 행렬곱셈에서 한번에 입력받을수 X(3)와 한개의 값만을 배출하는 Y(1)
W = tf.Variable(tf.random_normal([3, 1]), name = 'weight')
b = tf.Variable(tf.random_normal([1]), name = 'bias')

# matmul은 행렬곱셈을 수행하는 텐서플로우 라이브러리 함수 (자리중요** 무조건 X가 앞으로)
H = tf.matmul(X, W) + b
cost = tf.reduce_mean(tf.square(H - Y))

# learning_rate는 0.001로 함.
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 1e-3)
train = optimizer.minimize(cost)

# 여기부분은 일반적인 선형회귀 구현부분과 비슷.
sess = tf.Session()
sess.run(tf.global_variables_initializer())

w1_list = []
w2_list = []
w3_list = []
cost_list = []

for i in range(10001):
    sess.run(train, feed_dict = {X: xData, Y: yData})
    
    if i % 1000 == 0:
        print(i, sess.run(W), sess.run(b), sess.run(cost, feed_dict = {X: xData, Y: yData}))
    
    lstW, lstCost = sess.run([W, cost], feed_dict = {X: xData, Y: yData})
    w1_list.append(lstW[0])
    w2_list.append(lstW[1])
    w3_list.append(lstW[2])
    cost_list.append(lstCost)

# 여기서 25, 25, 25를 넣은이유는 앞에서 넣은 X값들은 모두 5단위로 올라가는데,
# 예를들어서 (x1, x2, x3)이라고한다면, (x1 + x2 + x3) * 5가 Y가 된다.
# 따라서, 예상값은 아마 (25 + 25 + 25) * 5인 375와 비슷한값이 나올것이다.
# 5단위로 올려나간이유는 '값이 정확히 나왔는지, 바로 알아내기위하여' 이다.
print('예상값: ', sess.run(H, feed_dict = {X: [[25., 25., 25.,]]}))

plt.plot(w1_list, cost_list)
plt.plot(w2_list, cost_list)
plt.plot(w3_list, cost_list)
plt.show()

 

위 코드를 실행해보면, 아래와 같이 나옵니다.

 

와우!!

저가 소스코드내에 주석문에서 적어놨다시피, 저가 예상한 값이 똭! 나왔준것같습니다.

 

 

 

 

다음은 로지스틱회귀에 관하여 공부한 내용입니다.

먼저 로지스틱회귀의 cost function은 이렇게 생겼습니다.

y가 1일때와 y가 0일때를 고려하여 만든 식입니다.

다음은 sigmoid function의 생김새입니다.

이 함수는 0보다 작거나 1보다 큰수를 모두 0~1사이의 값으로 치환하기 위하여 만들어진 함수라고합니다.

시그모이드함수를 Hypnothesis에 대입한뒤, 해당 Hypnothesis를 이용하여,

위의 cost function에 대입하면 그것이 로지스틱회귀라고 합니다.

 

 

우선 로지스틱회귀에 관한 강의를 보면서, 저가 직접 작성한 소스코드입니다.

 

위 그림은 우선 x값이 2개이고, y는 1개입니다.

각각 x1, x2의 의미는, 첫날 1시간의 공부와, 다음날 2시간의 공부를 하면 시험에 관하여 떨어진다는(0) 의미입니다.

반면 첫날 5시간의 공부와, 다음날 3시간의 공부를 하면 시험에 관하여 합격할수있다는(1) 의미입니다.

 

import tensorflow.compat.v1 as tf
import matplotlib.pyplot as plt
import numpy as np
tf.disable_v2_behavior()

npData = np.loadtxt('data_1.csv', delimiter = ',', dtype = np.float32)
xData = npData[:, 0:-1]
yData = npData[:, [-1]]

X = tf.placeholder(tf.float32, shape = [None, 2])
Y = tf.placeholder(tf.float32, shape = [None, 1])

W = tf.Variable(tf.random_normal([2, 1]), name = 'weight')
b = tf.Variable(tf.random_normal([1]), name = 'bias')

# 행렬곱셈한 결과를 시그모이드함수에 대입
H = tf.sigmoid(tf.matmul(X, W) + b)

# 위에 설명한 식과 같습니다.
cost = -tf.reduce_mean((Y * tf.log(H)) + ((1 - Y) * tf.log(1 - H)))

# 경사하강법 개시!~@@
train = tf.train.GradientDescentOptimizer(learning_rate = 1e-2).minimize(cost)

# 예상결과 | Hypnothesis가 0.5이상이면 참! 아니면 거짓!
predicted = tf.cast(H > 0.5, dtype = tf.float32)

# 정확성 | 모든 예상결과에 관하여 reduce_mean(평균값)계산 실시!
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype = tf.float32))


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    
    # 학습 10000번 실행
    for i in range(10001):
        cost_val, _ = sess.run([cost, train], feed_dict = {X: xData, Y: yData})
        
        if i % 1000 == 0:
            print(i, cost_val)
            
    h, p, a = sess.run([H, predicted, accuracy], feed_dict = {X: xData, Y: yData})
    print('Hypothesis: ', h, '\nPredicted: ', p, '\nAccuracy: ', a, '\n')
    
    # 이부분은 강의에 안나왔지만, 저가 직접 응용한 부분입니다.
    # 만약??? 첫날 6시간공부하고, 다음날 2시간공부하면 시험에 합격할까?? 에관한
    # 결과를 출력하는 부분입니다.
    # 아시다시피 0이면 불합격, 1이면 합격이겠습니다.
    print('Answer: ', sess.run(tf.cast(sess.run(H, feed_dict = {X: [[6, 2]]}) > 0.5, dtype = tf.float32), feed_dict = {X: xData, Y: yData}))

 

지금까지 보지못했던, 텐서플로우 함수가 몇몇 출현했는데,

우선 tf.cast는 첫번째 파라미터의 식이 참이면 1, 거짓이면 0을 반환하는 함수이죠.

아 물론, 1과 0을 바로 반환한다는 의미는 아닙니다, sess.run()함수로 매꿔줘야겠죠?

또, tf.equal은 함수이름에서 예상하시다시피, 두 텐서플로우의 플레이스홀더값이 같냐?? 물어보는 함수이죠.

 

 

그러면, 결과는 다음과 같이 나옵니다.

 

 

음~~ 그렇군!!

Answer이 1이 나왔으니,

저가 예상한 '첫날 6시간공부 + 다음날 2시간공부' 하면 시험에 합격할까? 에 관한 답은 이되겠군요!

 

 

그럼 오늘은 이쯤하고 물러나겠습니다!

다음에 봐용~~~~바이바이

 


 

 

 

 

 

 

728x90

댓글