#!/usr/bin/env python3


Linear Support Vector Machine: Soft Margin


# x1 = Sepal Length

# x2 - Petal Width


구분 가능한 소프트 마진 SVM을 텐서플로에 구현하기 위해서는 다음과 같은 비용함수를 구현해야합니다.

$$\frac{1}{n} \sum^{n}_{i=1}{max \left(0,1-y_{i}(Ax_{i}-b) \right)}+a \parallel A \parallel ^{2}$$

$A$는 기울기 벡터, $b$는 절편, $x_{i}$는 입력벡터, $y_{i}$는 실제 분류 대상 값(-1, 1)이고 $a$는 소프트 마진 구분 정도를 가리키는 규칙화 매개변수 입니다.


그래프 세션을 시작하고, 필요한 데이터를 로드합니다. 꽃받침 길이와 꽃잎 폭에 해당하는 데이터셋의 첫번재, 네 번째 변수를 로딩합니다. setosa종일 때는 값이 1이고, 그 외의 경우에는 값이 -1이 되게 대상 값을 로드합니다.

from sklearn.datasets import load_iris

import numpy as np

import tensorflow as tf

from tensorflow.python.framework import ops


ops.reset_default_graph()


sess = tf.Session()

iris = load_iris()



# load the data

x_vals = iris.data[:, [0,3]]

print(x_vals[:6])

# [[5.1 0.2]

#  [4.9 0.2]

#  [4.7 0.2]

#  [4.6 0.2]

#  [5.  0.2]

#  [5.4 0.4]]


y_vals = np.array([1 if y==0 else -1 for y in iris.target])

print(y_vals)

# [ 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1

#   1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1

#   1  1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

#  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

#  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

#  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

#  -1 -1 -1 -1 -1 -1]



데이터셋을 학습셋과 테스트셋으로 분류합니다. 학습셋, 테스트셋 모두에 정확도를 평가할 것입니다. 선형적으로 구분이 가능한 데이터셋이기 때문에 둘 모두 100%의 정확도를 기대할 수 있습니다.

# split data

from sklearn.model_selection import train_test_split


x_train, x_test, y_train, y_test = train_test_split(x_vals, y_vals,

                                                    random_state=0, stratify=y_vals)



작업크기를 설정하고 placeholder와 model 변수를 선언합니다. SVM 알고리즘 수렴에 도움이 되게 일괄 작업 크기를 크게 설정하였습니다. 일괄 작업 크기가 작으면 최대 마진 직선이 조금씩 움직일 것을 예상할 수 있습니다. 수렴이 진행됨에 따라 학습률의 크기를 줄이는 것이 이상적입니다. 

Sepal Lentgh와 Petal Width 두가지 예상 변수가 있기 때문에 A는 2x1의 형태로 변수를 만듭니다.

# placeholder

x_data = tf.placeholder(shape=[None, 2], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


# create Variable

A = tf.Variable(tf.random_normal(shape=[2, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))



모델 출력값을 선언합니다. 올바르게 분류된 경우라면 대상 값이 setosa 일 때는 1보다 크거나 같은 값이 출력되고, 대상 값이 setosa가 아닐 때는 -1보다 작거나 같은 값이 출력됩니다.

# fomula (y = ax - b)

fomula = tf.subtract(tf.matmul(x_data, A), b)



이 내용들을 조합하여 최대 마진 비용에 필요한 구성 요소들을 선언합니다.

먼저 벡터의 norm(L2)을 계산하는 함수를 선언합니다. 그런 다음에 마진 매개변수 $a$를 추가합니다.

그리고 이 두 항을 더하는 분류 비용 함수를 선언합니다.

L2_norm = tf.reduce_sum(tf.square(A))

# declare loss function

# Loss = summation(max(0, 1 - pred*actual)) + alpha * L2_norm(A)^2

alpha = tf.constant([0.01])


# Margin term in loss

left_term = tf.reduce_mean(tf.maximum(0., tf.subtract(1., tf.multiply(fomula, y_target))))


# Put terms together

loss = tf.add(left_term, tf.multiply(alpha, L2_norm))


학습셋과 테스트셋을 대상으로 정확도를 측정하기 위해 예측 함수와 정확도 함수를 선언합니다.

# prediction function

prediction = tf.sign(fomula)

accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction, y_target), tf.float32))



최적화 함수를 선언하고 모델 변수를 초기화합니다.

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)


# initialize variable

init = tf.global_variables_initializer()

sess.run(init)



학습 루프를 실행합니다. 비용함수 값과 더불어 학습셋과 테스트셋 양쪽의 정확도를 기록합니다.

test_acc = []

train_acc = []

loss_vec = []

batch_size = 112

for i in np.arange(1000):

    rand_idx = np.random.choice(len(x_train), size=batch_size)

    rand_x = x_train[rand_idx]

    rand_y = y_train[rand_idx].reshape(-1, 1)


    sess.run(train_step, feed_dict={x_data:rand_x, y_target:rand_y})


    temp_loss = sess.run(loss, feed_dict={x_data:rand_x, y_target:rand_y})

    loss_vec.append(temp_loss)


    temp_train_acc = sess.run(accuracy, feed_dict={x_data:x_train, y_target:y_train.reshape(-1, 1)})

    train_acc.append(temp_train_acc)


    temp_test_acc = sess.run(accuracy, feed_dict={x_data:x_test, y_target:y_test.reshape(-1, 1)})

    test_acc.append(temp_test_acc)


    if (i+1) % 150 == 0:

        print('step {}:\n  A={}, b={}\nloss={}\n'.format(i+1, sess.run(A), sess.run(b), temp_loss))

        # step 150:

        # A=[[-0.1508689 ]

        #    [-0.02083003]], b=[[0.03109207]]

        # loss=[0.6171418]


        # step 300:

        # A=[[-0.06546283]

        #    [-0.4349473 ]], b=[[-0.04024722]]

        # loss=[0.39113477]


        # step 450:

        # A=[[ 0.01723341]

        #    [-0.8050836 ]], b=[[-0.12105083]]

        # loss=[0.41022006]


        # step 600:

        # A=[[ 0.07058643]

        #    [-1.1637722 ]], b=[[-0.19953299]]

        # loss=[0.2737451]


        # step 750:

        # A=[[ 0.14719042]

        #    [-1.503774  ]], b=[[-0.28408656]]

        # loss=[0.2209843]


        # step 900:

        # A=[[ 0.19714044]

        #    [-1.8002963 ]], b=[[-0.35890797]]

        # loss=[0.17502114]



결과를 그림으로 나타내려면 다음과 같이 계수를 추출하고, setosa 종 여부에 따라 x 값을 분리해야 합니다.

# visualization

import matplotlib.pyplot as plt

[[a1], [a2]] = sess.run(A)

[[b]] = sess.run(b)


slope = -a2/a1

icept = b


best_fit = []

for i in x_vals[:, 1]:

    temp = i * slope + icept

    best_fit.append(temp)


setosa_x = [setosa[1] for i, setosa in enumerate(x_vals) if y_vals[i] == 1]

setosa_y = [setosa[0] for i, setosa in enumerate(x_vals) if y_vals[i] == 1]

not_setosa_x = [setosa[1] for i, setosa in enumerate(x_vals) if y_vals[i] == -1]

not_setosa_y = [setosa[0] for i, setosa in enumerate(x_vals) if y_vals[i] == -1]



다음 코드를 이용하여 선형 구분자 및 정확도, 비용 함수를 그림으로 표현할 수 있습니다.

_, axe = plt.subplots(1, 3)


axe[0].scatter(setosa_x, setosa_y, marker='o', label='setosa')

axe[0].scatter(not_setosa_x, not_setosa_y, marker='o', label='non-setosa')

axe[0].plot(x_vals[:, 1], best_fit, c='red', label='Linear Separator')

axe[0].set_ylim([0, 10])

axe[0].legend(loc='best')

axe[0].set_title('Sepal Length vs Petal Width')

axe[0].set_xlabel('Petal Width')

axe[0].set_ylabel('Sepal Length')


axe[1].plot(train_acc, c='k', linestyle='-', label='Training Accuracy')

axe[1].plot(test_acc, c='r', linestyle='--', label='Test Accuracy')

axe[1].set_title('Train and Test Accuracy')

axe[1].set_xlabel('Genearation')

axe[1].set_ylabel('Accuracy')

axe[1].legend(loc='best')


axe[2].plot(loss_vec, c='k')

axe[2].set_title('Loss per Generation')

axe[2].set_xlabel('Generation')

axe[2].set_ylabel('loss')


plt.show()

학습 진행중인 모델의 최종 결과 그래프와 테스트셋과 학습셋의 정확도, 두 분류가 선형적으로 구분 가능하기 때문에 정확도가 100%에 도달




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook


'Tensorflow > Support Vector Machine' 카테고리의 다른 글

SVM intro  (0) 2018.05.01

Introduction


Support Vector Machine는 이진 분류 기법입니다. 기본 Idea는 두 분류 사이에 존재하는 선형 구분선hyperplane을 찾는 것입니다.

분류대상의 값을 -1, 1이라 가정합니다. 두 분류를 구분하는 직선은 무수히 많지만, 두 분류에서 가장 멀리 떨어진 구분선을 최적 선형 구분자라할 수 있습니다.


구분 가능한 두 분류 o, x가 주어졌을 때 두 분류를 구분하는 선형 구분 방정식을 찾고자 합니다.

왼쪽 그림을 보면 두 분류를 구분하는 여러 직선이 존재한다는 것을 알 수 있습니다. 오른쪽 그림은 분류 사이이의 magin을 최대로 하는 유일한 직선을 나타낸 것입니다.

마진의 폭은 $\frac{2}{llAll}$ 입니다.


초평면은 다음 방정식으로 표현할 수 있습니다.$$Ax-b=0$$

A는 기울기를 나태는 벡터고, $x$는 입력 벡터입니다. 최대 margin의 폭은 A L2 norm 값으로 나눈 값이 됩니다. 기하학적으로 2차원상의 한점에서 직선까지의 거리를 구하는 상황입니다.


선형적으로 구분 가능한 이진 분류 데이터의 경우 margin을 최대화 하려면 A의 L2 norm값을 최소화해야 합니다. 이 최솟값은 다음 제약도 만족해야 합니다.

$$y_{i}(Ax_{i}-b)\ge 1\forall i$$

이 제한을 만족해야만 한 분류에 속하는 모든 점이 구분선의 같은 편에 족재하게 됩니다.


모든 데이터셋을 선형적으로 구분할 수 있는 것은 아니기 때문에 선을 넘어가는 점을 대상으로 한 cost function을 도입할 수 있습니다. n개의 데이터 지점에 대해 soft margin cost function은 다음과 같이 정의합니다.

$$\frac{1}{n}\sum^{n}_{i=1}max \left(0,1 - y_{i}(Ax_{i}-b) \right) +a\parallel A \parallel ^{2}$$

데이터 포인트가 올바른 자리에 있으면 $y_{i}(Ax_{i}-b)$의 값은 항상 1보다 클 것입니다. 그러면 cost function의 좌측항은 0이 되어 cont function에 영향을 미치는 부분은

$a\parallel A\parallel ^{2}$인 margin의 크기만 남게 됩니다.


이 cost function을 사용하면 데이터 포인트가 margin line 을 넘어가는 경우를 허용하는 선형 구분 직선을 찾을 수 있습니다.

$a$ 값에 따라 허용하는 정도가 느슨할 수 있고, 엄격할 수 있습니다. 

$a$ 값이 클수록 margin의 폭이 늘어나고 작을 수록 엄격한 margin을 적용하게 됩니다.


'Tensorflow > Support Vector Machine' 카테고리의 다른 글

Linear Support Vector Machine: Soft Margin  (0) 2018.05.01

#!/usr/bin/env python3


Logistic Regression


logistic regression은 아래 1차 함수를 sigmoid와 함성합니다.

y = sigmoid(Ax + b)


birth weight data를 웹상에서 불러오겠습니다.


다음은 웹(github)에서 데이터를 불러오는 과정입니다.

현재 디렉토리에 'birth_weight.csv'가 없을 때 웹상에서 파일을 불러오는 코드는 다음과 같습니다.

import requests

import os.path


birth_weight_file = 'birth_weight.csv'

if not os.path.exists(birth_weight_file):

    url='https://raw.githubusercontent.com/nfmcclure/tensorflow_cookbook/master/01_Introduction/07_Working_with_Data_Sources/birthweight_data/birthweight.dat'

    load_file = requests.get(url)

    data = load_file.text.split('\r\n')

    header = data[0].split('\t')

    raw_birth_data = [[float(args) for args in row.split('\t') if len(args) >= 1] for row in data[1:] if len(row)>=1]

    length = len(raw_birth_data[0])

    birth_data = np.empty([0, length])

    for birth in raw_birth_data:

        birth_data = np.vstack([raw_birth_data, birth])


print(header)

# ['LOW', 'AGE', 'LWT', 'RACE', 'SMOKE', 'PTL', 'HT', 'UI', 'BWT']


print(birth_data)

# [[1.000e+00 2.800e+01 1.130e+02 ... 0.000e+00 1.000e+00 7.090e+02]

#  [1.000e+00 2.900e+01 1.300e+02 ... 0.000e+00 1.000e+00 1.021e+03]

#  [1.000e+00 3.400e+01 1.870e+02 ... 1.000e+00 0.000e+00 1.135e+03]

#  ...

#  [0.000e+00 2.400e+01 2.160e+02 ... 0.000e+00 0.000e+00 4.593e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]]


이제 이 파일을 다음 코드를 이용하여 만들어보겠습니다.

import csv


with open(birth_weight_file, 'w', newline='') as f:

    writer = csv.writer(f)

    writer.writerow(header)

    writer.writerows(birth_data)

    f.close()



이제 birth_weight_file.csv 가 현재 디렉토리에 생성되었습니다.

이 파일을 다시 불러오겠습니다.

import numpy as np


birth_data = []

with open(birth_weight_file, newline='') as csvfile:

    csv_reader = csv.reader(csvfile)

    birth_header = next(csv_reader)

    birth_data = [[float(args) for args in row] for row in csv_reader]

    birth_data = np.array(birth_data)


print(birth_data)

# [[1.000e+00 2.800e+01 1.130e+02 ... 0.000e+00 1.000e+00 7.090e+02]

#  [1.000e+00 2.900e+01 1.300e+02 ... 0.000e+00 1.000e+00 1.021e+03]

#  [1.000e+00 3.400e+01 1.870e+02 ... 1.000e+00 0.000e+00 1.135e+03]

#  ...

#  [0.000e+00 2.400e+01 2.160e+02 ... 0.000e+00 0.000e+00 4.593e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]]


pandas로도 csv파일을 불러올 수 있습니다.

import pandas as pd

birth_data = []

birth_data_pd = pd.read_csv(birth_weight_file)

birth_data = birth_data_pd.values


print(birth_data)

# [[1.000e+00 2.800e+01 1.130e+02 ... 0.000e+00 1.000e+00 7.090e+02]

#  [1.000e+00 2.900e+01 1.300e+02 ... 0.000e+00 1.000e+00 1.021e+03]

#  [1.000e+00 3.400e+01 1.870e+02 ... 1.000e+00 0.000e+00 1.135e+03]

#  ...

#  [0.000e+00 2.400e+01 2.160e+02 ... 0.000e+00 0.000e+00 4.593e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]

#  [0.000e+00 4.500e+01 1.230e+02 ... 0.000e+00 0.000e+00 4.990e+03]]



이제 데이터를 불러오는 과정이 끝났으니 tensorflow로 Logistic Regression을 적용해보겠습니다.

Losistic Regression을 적용하기 전에 algorithm을 살펴보겠습니다.

Logistic Regression의 흐름


우선 데이터셋에서 변수를 추출하겠습니다.

birth_m_data = birth_data[:,1:8]

print(birth_m_data)

# [[ 28. 113.   1. ...   1.   0.   1.]

#  [ 29. 130.   0. ...   0.   0.   1.]

#  [ 34. 187.   1. ...   0.   1.   0.]

#  ...

#  [ 24. 216.   0. ...   0.   0.   0.]

#  [ 45. 123.   0. ...   1.   0.   0.]

#  [ 45. 123.   0. ...   1.   0.   0.]]


birth_target = birth_data[:, 0]

print(birth_target)

# [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.

#  1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.

#  1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.

#  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.

#  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.

#  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.

#  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.

#  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]



scikit-learn의 train_test_split함수를 사용해도 되지만 파이썬 코드를 사용해서 훈련데이터와 학습데이터를 8:2로 분할하겠습니다.

# Split data into train/test = 80%/20%

data_size = len(birth_m_data)

train_idx = np.random.choice(data_size, round(data_size*0.8), replace=False)

temp_test_idx = set(np.arange(data_size)) - set(train_idx)

test_idx = np.array(list(temp_test_idx))


x_train = birth_m_data[train_idx]

x_test = birth_m_data[train_idx]

y_train = birth_target[test_idx]

y_test = birth_target[test_idx]


print(x_train)

# [[ 20. 105.   1. ...   0.   0.   0.]

#  [ 31. 100.   0. ...   0.   0.   1.]

#  [ 32. 132.   0. ...   0.   0.   0.]

#  ...

#  [ 20. 120.   1. ...   0.   0.   0.]

#  [ 20. 150.   0. ...   0.   0.   0.]

#  [ 16. 110.   1. ...   0.   0.   0.]]


print(x_test)

# [[ 20. 105.   1. ...   0.   0.   0.]

#  [ 31. 100.   0. ...   0.   0.   1.]

#  [ 32. 132.   0. ...   0.   0.   0.]

#  ...

#  [ 20. 120.   1. ...   0.   0.   0.]

#  [ 20. 150.   0. ...   0.   0.   0.]

#  [ 16. 110.   1. ...   0.   0.   0.]]



데이터셋 변수를 최솟값 0, 최댓값 1이 되도록 스케일링 해보겠습니다. 사용자 정의 함수를 이용하여 직접 코드를 짤 수도 있고,

scikit-learn의 MinMaxScaler 메소드로도 할 수 있습니다.

2가지 모두 해보겠습니다.

# user define function

def zero_to_one(m):

    col_max = np.max(x_train, axis=0)

    col_min = np.min(x_train, axis=0)

    return (m-col_min)/(col_max-col_min)


x_train_scaled_def = np.nan_to_num(zero_to_one(x_train))

print(x_train_scaled_def)

# [[0.19354839 0.14705882 1.         ... 0.         0.         0.        ]

#  [0.5483871  0.11764706 0.         ... 0.         0.         1.        ]

#  [0.58064516 0.30588235 0.         ... 0.         0.         0.        ]

#  ...

#  [0.19354839 0.23529412 1.         ... 0.         0.         0.        ]

#  [0.19354839 0.41176471 0.         ... 0.         0.         0.        ]

#  [0.06451613 0.17647059 1.         ... 0.         0.         0.        ]]


x_test_scaled_def = np.nan_to_num(zero_to_one(x_test))

print(x_test_scaled_def)

# [[0.19354839 0.14705882 1.         ... 0.         0.         0.        ]

#  [0.5483871  0.11764706 0.         ... 0.         0.         1.        ]

#  [0.58064516 0.30588235 0.         ... 0.         0.         0.        ]

#  ...

#  [0.19354839 0.23529412 1.         ... 0.         0.         0.        ]

#  [0.19354839 0.41176471 0.         ... 0.         0.         0.        ]

#  [0.06451613 0.17647059 1.         ... 0.         0.         0.        ]]


# scikit-learn

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

scaler.fit(x_train)


x_train_scaled = scaler.transform(x_train)

print(x_train_scaled)

# [[0.19354839 0.14705882 1.         ... 0.         0.         0.        ]

#  [0.5483871  0.11764706 0.         ... 0.         0.         1.        ]

#  [0.58064516 0.30588235 0.         ... 0.         0.         0.        ]

#  ...

#  [0.19354839 0.23529412 1.         ... 0.         0.         0.        ]

#  [0.19354839 0.41176471 0.         ... 0.         0.         0.        ]

#  [0.06451613 0.17647059 1.         ... 0.         0.         0.        ]]


x_test_scaled = scaler.transform(x_test)

print(x_test_scaled)

# [[0.19354839 0.14705882 1.         ... 0.         0.         0.        ]

#  [0.5483871  0.11764706 0.         ... 0.         0.         1.        ]

#  [0.58064516 0.30588235 0.         ... 0.         0.         0.        ]

#  ...

#  [0.19354839 0.23529412 1.         ... 0.         0.         0.        ]

#  [0.19354839 0.41176471 0.         ... 0.         0.         0.        ]

#  [0.06451613 0.17647059 1.         ... 0.         0.         0.        ]]



이제 데이터로딩과 전처리가 완료 되었으니 tensorflow로 logistic 분석을 해보겠습니다.

먼저 tensorflow로 학습 algorithm tool을 만듭니다.

import tensorflow as tf

from tensorflow.python.framework import ops

import matplotlib.pyplot as plt


ops.reset_default_graph()

# Create graph

sess = tf.Session()


# Set for reproducible results

np.random.seed(seed=99)

tf.set_random_seed(seed=99)


# Initialize placeholders

x_data = tf.placeholder(shape=[None, 7], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


# Create variables for linear regression

A = tf.Variable(tf.random_normal(shape=[7,1]))

b = tf.Variable(tf.random_normal(shape=[1,1]))


# Declare model operations

fomula = tf.add(tf.matmul(x_data, A), b)


# Declare loss function (Cross Entropy loss)

loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=fomula, labels=y_target))


# Declare optimizeraon

opt = tf.train.GradientDescentOptimizer(0.01)

train_step = opt.minimize(loss)


# Initialize variables

init = tf.global_variables_initializer()

sess.run(init)


# Actual Prediction

prediction = tf.round(tf.sigmoid(fomula))

predictions_correct = tf.cast(tf.equal(prediction, y_target), tf.float32) # tf.cast: 자료형태를 변환합니다. tf.cast(input tensor, dtype)

accuracy = tf.reduce_mean(predictions_correct)



이제 algorithm tool을 만들었으니 이를 바탕으로 학습을 시켜보겠습니다.

# Training loop

batch_size = 25

loss_vec = []

train_acc = []

test_acc = []

for i in range(1500):

    rand_idx = np.random.choice(len(x_train_scaled), size=batch_size)

    rand_x = x_train_scaled[rand_idx]

    rand_y = y_train[rand_idx].reshape(-1, 1) # reshape에 주의

    

    sess.run(train_step, feed_dict={x_data:rand_x, y_target:rand_y})

    temp_loss = sess.run(loss, feed_dict={x_data:rand_x, y_target:rand_y}) # train step을 실행

    loss_vec.append(temp_loss)


    temp_train = sess.run(accuracy, feed_dict={x_data:x_train_scaled, y_target:y_train.reshape(-1, 1)}) # accuracy를 실행, reshape 주의

    train_acc.append(temp_train)


    temp_test = sess.run(accuracy, feed_dict={x_data:x_test_scaled, y_target:y_test.reshape(-1, 1)}) # accuracy를 실행, reshape 주의

    test_acc.append(temp_test)

    

    if (i+1)%300==0:

        print('Loss = {}'.format(temp_loss))

        # Loss: 0.8982473015785217

        # Loss: 0.641773521900177

        # Loss: 0.630251944065094

        # Loss: 0.5026944279670715

        # Loss: 0.5662710070610046

        # Loss: 0.6175627708435059

        # Loss: 0.5372310876846313

sess.close()


위의 결과를 바탕으로 시각화를 하는 코드는 다음과 같습니다.

_, axe = plt.subplots(1, 2)

# Plot loss over time

axe[0].plot(loss_vec, 'k-')

axe[0].set_title('Cross Entropy Loss per Generation')

axe[0].set_xlabel('Generation')

axe[0].set_ylabel('Cross Entropy Loss')


# Plot train and test accuracy

axe[1].plot(train_acc, 'k-', label='Train Set Accuracy')

axe[1].plot(test_acc, 'r--', label='Test Set Accuracy')

axe[1].set_title('Train and Test Accuracy')

axe[1].set_xlabel('Generation')

axe[1].set_ylabel('Accuracy')

axe[1].legend(loc='lower right')

plt.show()

Loss 함수와 Accuracy




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

'Tensorflow > Linear Regression' 카테고리의 다른 글

Elastic Net Regression  (0) 2018.04.29
LASSO and Ridge Regression  (1) 2018.04.27
Deming Regression  (0) 2018.04.27
Loss Function in Linear Regressions  (0) 2018.04.26
TensorFlow Way of LinearRegression  (0) 2018.04.26

#!/usr/bin/env python3


Elastic Net Regression


elastic net regression을 풀기위해서는 아래 방정식을 적용합니다.

$$y = Ax + b$$


#  y = Sepal Length

#  x = Pedal Length, Petal Width, Sepal Width


사용자 정의 형태로 만들어 인자를 변경하며 결과를 확인해보겠습니다.

elastic net regression의 cost function은 다음과 같습니다.

$$cost = mean \left( \sum{\left (y - \overset{\wedge}{y}\right)^{2} }\right) + 1 \cdot mean \left (\sum{\left | x_{i} \right |}\right) +1 \cdot mean \left (\sum {x^{2}_{i}} \right ) $$

import matplotlib.pyplot as plt

import numpy as np

import tensorflow as tf

from sklearn import datasets

from tensorflow.python.framework import ops


def elastic_net_func(idx, batch_size):

    ops.reset_default_graph()


    # iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]

    iris = datasets.load_iris()

    x_vals = iris.data[:, idx]

    y_vals = iris.data[:, 0]


    # Initialize placeholders

    x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

    y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


    # Create variables for linear regression

    A = tf.Variable(tf.random_normal(shape=[1,1]))

    b = tf.Variable(tf.random_normal(shape=[1,1]))


    with tf.Session() as sess:

        fomula = tf.add(tf.matmul(x_data, A), b)

        np.random.seed(seed=42)

        tf.set_random_seed(seed=42)


        l1_a_loss = tf.reduce_mean(tf.abs(A))

        l2_a_loss = tf.reduce_mean(tf.square(A))

        y_loss = tf.reduce_mean(tf.square(y_target - fomula)) 


        loss = tf.add(tf.add(l1_a_loss, l2_a_loss), y_loss) # cost function


        opt = tf.train.GradientDescentOptimizer(0.001)

        train_step = opt.minimize(loss)


        # Initialize variables

        init = tf.global_variables_initializer()

        init.run()


        loss_vec = []

        for i in range(1000):

            rand_idx = np.random.choice(len(x_vals), size=batch_size)

            rand_x = x_vals[rand_idx].reshape(-1, 1)

            rand_y = y_vals[rand_idx].reshape(-1, 1)


            my_dict = {x_data:rand_x, y_target:rand_y}

            sess.run(train_step, feed_dict=my_dict)

            temp_loss = sess.run(loss, feed_dict=my_dict)

            loss_vec.append(temp_loss)

            if (i+1)%200==0:

                print('step {}: A={}, b={}, Loss={}'.format(i+1, A.eval()[0], b.eval()[0], temp_loss))


        [coef] = A.eval()[0]

        [intercept] = b.eval()[0]


        best_params = []

        for i in x_vals:

            poly = i*coef + intercept

            best_params.append(poly)


    _, axe = plt.subplots(1, 2)

    axe[0].scatter(x_vals, y_vals, edgecolors='k', label='data points')

    axe[0].plot(x_vals, best_params, c='red', label='best pit line')

    axe[0].set_title('index={}\nslope = {:.5f}, intercept = {:.5f}'.format(idx ,coef, intercept))

    axe[0].set_xlabel('{}'.format(iris.feature_names[idx]))

    axe[0].set_ylabel('{}'.format(iris.feature_names[0]))

    axe[0].legend(loc=2)


    axe[1].plot(loss_vec, c='k')

    axe[1].set_xlabel('Generation')

    axe[1].set_ylabel('Loss')

    axe[1].set_title('Loss per Generation')


    plt.show()


사용자 정의 함수를 이용하여 인자에 따른 시각화를 해보겠습니다.

elastic_net_func(idx=1, batch_size=50)

sepal width vs sepal length

# step 200: A=[1.70271], b=[-0.14161193], Loss=6.42409610748291

# step 400: A=[1.6244563], b=[0.16109753], Loss=6.042064189910889

# step 600: A=[1.5415831], b=[0.44974053], Loss=5.765136241912842

# step 800: A=[1.4513652], b=[0.72334766], Loss=4.744622707366943

# step 1000: A=[1.3864329], b=[0.99185705], Loss=5.004234790802002



elastic_net_func(idx=2, batch_size=50)

petal length vs sepal length

# step 200: A=[1.3025422], b=[-0.19726731], Loss=7.4931416511535645

# step 400: A=[1.2043393], b=[0.24439183], Loss=5.619389057159424

# step 600: A=[1.1216723], b=[0.6478416], Loss=4.893489837646484

# step 800: A=[1.0472624], b=[1.0189508], Loss=5.274661540985107

# step 1000: A=[0.9723399], b=[1.3565185], Loss=2.696936845779419



elastic_net_func(idx=3, batch_size=50)

petal width VS sepal length

# step 200: A=[1.3511531], b=[1.0177041], Loss=14.15509033203125

# step 400: A=[1.5765594], b=[2.0053844], Loss=8.151086807250977

# step 600: A=[1.4302077], b=[2.6739304], Loss=5.979291915893555

# step 800: A=[1.2245288], b=[3.1957018], Loss=4.475618362426758

# step 1000: A=[1.0373899], b=[3.6267276], Loss=3.252098560333252




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

'Tensorflow > Linear Regression' 카테고리의 다른 글

Logistic Regression  (0) 2018.05.01
LASSO and Ridge Regression  (1) 2018.04.27
Deming Regression  (0) 2018.04.27
Loss Function in Linear Regressions  (0) 2018.04.26
TensorFlow Way of LinearRegression  (0) 2018.04.26

#!/usr/bin/env python3


LASSO and Ridge Regression


이전 포스팅 보기

[1]Ridge, [2]Lasso


LASSO Ridge는 모두 출력 값에 미치는 regularization을 적용합니다.

tensorflow에서는 기울기A값에 의존하는 항을 cost function에 추가하면 이런 효과를 얻을 수 있습니다.


LASSO의 경우 기울기A가 특정 값 이상이 되면 cost를 크게 증가시키는 항을 추가해야합니다.

tensorflow의 논리 연산을 사용할 수도 있지만, 이렇게 하면 경사도를 계산할 수 없습니다. 대신에 step function을 연속 함수로 근사한 continuous heavyside step 함수를 조절해서 사용하여 문제를 해결 할 수 있습니다.


step function은 step이 중요합니다. step이 너무 높으면 수렴하지 않는 경우가 발생할 수 있습니다.


iris데이터셋으로 LASSO를 적용해보겠습니다. 


먼저 data를 로딩하고 placeholder를 생성하겠습니다.

import tensorflow as tf

from tensorflow.python.framework import ops

import numpy as np

from sklearn.datasets import load_iris


ops.reset_default_graph()


iris = load_iris()

# iris.keys(): dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])

# iris.feature_names: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


regression_type = 'LASSO' # LASSO, Ridge


x_vals = iris.data[:, 3] # petal width

y_vals = iris.data[:, 0] # sepal length


x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))


연속함수로 근사한 LASSO의 cost function인 heavyside step function은 다음과 같이 쓸 수 있습니다.$$y = \frac {1}{e^{ \left( x-\theta \right) \cdot (-\delta) }+1}$$


Ridge의 cost function은 다음과 같습니다.

$$mean\left(\sum { \left( y-\overset { \wedge  }{ y }  \right) ^{ 2 } }\right) + mean \left(\theta \sum {A^{ 2 } } \right)$$

여기서 $\theta$는 critical value임계값을 말하며 $\delta$는 step의 sensitivity민감도를 나타냅니다.


activate function인 continuous heavyside step함수는 다음 코드로 시각화 할 수 있습니다.

deltas = [0.1, 1, 5, 50]

_, axes = plt.subplots(2, 2)


for ax, delta in zip(axes.ravel(), deltas):

    line = np.linspace(-5, 5)

    theta = 0.9

    step = 1

    y = 1/(np.exp((line-theta)*(-delta)) + 1) * step

    ax.plot(line, y)

    ax.set_title('$\delta$={}'.format(delta))

plt.show()

$\delta$값에 따른 heavyside step function



따라서 LASSO와 Ridge의 cost function을 고려한 연산과정은 다음과 같습니다

with tf.Session() as sess:

    fomula = tf.add(tf.matmul(x_data, A), b)


    if regression_type == 'LASSO':

        lasso_params = tf.constant(0.9, dtype=tf.float32) # limit slope

        heavyside_step = tf.truediv(1., tf.add(tf.exp(tf.multiply(tf.subtract(A, lasso_params), -50)), 1))

        regularization = tf.multiply(99., heavyside_step)

        loss = tf.add(tf.reduce_mean(tf.square(y_target-fomula)), regularization)


    elif regression_type == 'Ridge':

        ridge_params = tf.constant(1., dtype=tf.float32)

        ridge_loss = tf.reduce_mean(tf.square(A))


loss = tf.expand_dims(tf.add(tf.reduce_mean(tf.square(y_target-fomula)),

                                     tf.multiply(ridge_params, ridge_loss)), 0) 


    opt = tf.train.GradientDescentOptimizer(learning_rate=0.001)

    train_step = opt.minimize(loss)


    init = tf.global_variables_initializer()

    init.run()


    loss_vec = []

    for i in range(1500):

        rnd_idx = np.random.choice(len(x_vals), size = batch_size)

        rnd_x = x_vals[rnd_idx].reshape(-1, 1)

        rnd_y = y_vals[rnd_idx].reshape(-1, 1)


        my_dict = {x_data:rnd_x, y_target:rnd_y}

        sess.run(train_step, feed_dict=my_dict)

        temp_loss = sess.run(loss, feed_dict=my_dict)

        loss_vec.append(temp_loss[0])


        if (i+1)%300 == 0:

            print('step={}: A={}, b={}, Loss={}'.format(i+1, A.eval(), b.eval(), temp_loss))

     # step=300: A=[[0.7634046]], b=[[2.8413053]], Loss=[[5.382721]]

     # step=600: A=[[0.75245243]], b=[[3.7877374]], Loss=[[1.4977918]]

     # step=900: A=[[0.7403701]], b=[[4.3101645]], Loss=[[0.6288415]]

     # step=1200: A=[[0.72969586]], b=[[4.60605]], Loss=[[0.40883213]]

     # step=1500: A=[[0.72272784]], b=[[4.7734385]], Loss=[[0.3297159]]

    slope = A.eval()[0]

    cept = b.eval()[0]



더 자세히 알아보기 위해  시각화 하면

best_fit = []    

for i in x_vals.ravel():

    poly = i*slope + cept

    best_fit.append(poly)


_, ax = plt.subplots(1, 2)

ax[0].scatter(x_vals, y_vals, edgecolors='k', label='Data Points')

ax[0].plot(x_vals, best_fit, c='red', label='Best fit line', linewidth=3)

ax[0].legend(loc=2)

ax[0].set_title('Petal Width vs Sepal Length')

ax[0].set_xlabel('Petal Width')

ax[0].set_ylabel('Sepal Length')


ax[1].plot(loss_vec, c='k')

ax[1].set_title(regression_type + ' Loss per Generation')

ax[1].set_xlabel('Generation')

ax[1].set_ylabel('Loss')


plt.show()

LASSO Regression과 Loss함수



위의 코드를 사용자 정의 함수로 만들어 LASSO, Ridge를 살펴보겠습니다



위의 결과는 아래 코드로 확인할 수 있습니다.

my_regression_type(regression_type='LASSO', batch_size=50)

# step=300: A=[[0.764575]], b=[[2.5382898]], Loss=[[5.8621655]]

# step=600: A=[[0.7535565]], b=[[3.618642]], Loss=[[1.8615394]]

# step=900: A=[[0.7427662]], b=[[4.2173624]], Loss=[[0.7045775]]

# step=1200: A=[[0.7338138]], b=[[4.5521526]], Loss=[[0.44136143]]

# step=1500: A=[[0.72335386]], b=[[4.739038]], Loss=[[0.23825285]]

LASSO Linear Regression과 Loss



my_regression_type(regression_type='Ridge', batch_size=50)

# step=300: A=[[1.9796406]], b=[[1.416961]], Loss=[8.540436]

# step=600: A=[[1.7114378]], b=[[2.419876]], Loss=[5.517313]

# step=900: A=[[1.4033114]], b=[[3.132286]], Loss=[3.4445624]

# step=1200: A=[[1.1520133]], b=[[3.6732914]], Loss=[2.298217]

# step=1500: A=[[0.95343864]], b=[[4.086554]], Loss=[1.4839184]

Ridge Linear Regression과 Loss 




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

'Tensorflow > Linear Regression' 카테고리의 다른 글

Logistic Regression  (0) 2018.05.01
Elastic Net Regression  (0) 2018.04.29
Deming Regression  (0) 2018.04.27
Loss Function in Linear Regressions  (0) 2018.04.26
TensorFlow Way of LinearRegression  (0) 2018.04.26

#!/usr/bin/env python3


Deming Regression


Deming regression은 total regression전회귀로도 불립니다.

Deming regression는 y값과 x값의 오차를 최소화 합니다.

Deming regression을 구현하기 위해서는 Loss Cost Function을 수정해야합니다.

일반적인 선형 회귀의 비용함수는 수직거리를 최소화 하기 때문입니다.

직선의 기울기와 y절편을 이용하여 점까지 수식 거리를 구하고

tensorflow가 그 값을 최소화 하게 합니다.




직선까지의 수직 거리를 최소화(좌) 직선까지의 전체거리를 최소화(우)

출처: https://github.com/nfmcclure/tensorflow_cookbook/


데이터를 로딩하고 placeholder를 다음과 같이 생성해보겠습니다.

import tensorflow as tf

from tensorflow.python.framework import ops

import numpy as np

from sklearn.datasets import load_iris


ops.reset_default_graph()


iris = load_iris()

print(iris.keys())

# dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])


print(iris.feature_names)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


# load the data

x_val = iris.data[:,3] # petal width

y_val = iris.data[:,0] # sepal length


# initialize placeholders

x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


# create variables for linear regression

A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_uniform(shape=[1, 1]))



직선 $y = mx +b$와 점 $(x_{0}, y_{0})$가 주어졌을 때 둘 사이의 수직 거리는 다음과 같이 쓸 수 있습니다.

$$d=\frac{\left |y_{0}-(mx_{0}+b) \right|}{\sqrt{m^{2}+1}}$$



따라서 이 식을 이용하여 loss function을 재구성하여 linear regression을 구현해보겠습니다.

with tf.Session() as sess:

    fomula = tf.add(tf.matmul(x_data, A) ,b)

    demm_numer = tf.abs(tf.subtract(fomula, y_target)) # numerator

    demm_denom = tf.sqrt(tf.add(tf.square(A), 1)) # denominator

    loss = tf.reduce_mean(tf.truediv(demm_numer, demm_denom)) # 점과 직선사이의 거리


    opt = tf.train.GradientDescentOptimizer(learning_rate=0.15)

    train_step = opt.minimize(loss)


    init = tf.global_variables_initializer()

    init.run()


    loss_vec = []

    batch_size = 125

    

    for i in range(1000):

        rand_idx = np.random.choice(len(x_val), size=batch_size)

        rand_x = x_val[rand_idx].reshape(-1, 1)

        rand_y = y_val[rand_idx].reshape(-1, 1)


        my_dict = {x_data:rand_x, y_target:rand_y}

        sess.run(train_step, feed_dict=my_dict)

        temp_loss = sess.run(loss, feed_dict=my_dict)

        loss_vec.append(temp_loss)


        if (i+1)%100==0:

            print('step {}: A={}, b={}, Loss={}'.format(i+1, A.eval(), b.eval(), temp_loss))

            # step 100: A=[[2.8481812]], b=[[2.1150784]], Loss=0.39886653423309326

            # step 200: A=[[2.4716957]], b=[[2.581221]], Loss=0.4149680733680725

            # step 300: A=[[2.0858126]], b=[[3.1767926]], Loss=0.37009572982788086

            # step 400: A=[[1.5102198]], b=[[3.989578]], Loss=0.30516621470451355

            # step 500: A=[[1.0213077]], b=[[4.55735]], Loss=0.25061553716659546

            # step 600: A=[[1.0353084]], b=[[4.609328]], Loss=0.2725234925746918

            # step 700: A=[[1.0107175]], b=[[4.6160936]], Loss=0.3082656264305115

            # step 800: A=[[1.0400845]], b=[[4.612001]], Loss=0.27881959080696106

            # step 900: A=[[1.0318567]], b=[[4.6159105]], Loss=0.27347463369369507

            # step 1000: A=[[0.9662517]], b=[[4.5973287]], Loss=0.2258552461862564


    [slope] = A.eval()

    [cept] = b.eval()



위의 결과를 시각화하는 코드는 다음와 같습니다.

import matplotlib.pyplot as plt


best_fit = []

for i in x_val.ravel():

    poly = i*slope[0] + cept[0]

    best_fit.append(poly)


_, axes = plt.subplots(1, 2)

axes[0].scatter(x_val, y_val, edgecolors='k', label='Data Points')

axes[0].plot(x_val, best_fit, c='red', label='Best fit line')

axes[0].set_title('Petal Width vs Sepal Length', size=12)

axes[0].set_xlabel('Petal Width')

axes[0].set_ylabel('Sepal Length')

axes[0].legend(loc=2)


axes[1].plot(loss_vec, c='k')

axes[1].set_title('Demming Loss per Generation', size=12)

axes[1].set_xlabel('Iteration')

axes[1].set_ylabel('Demming Loss')


plt.show()

Demming Regression과 Loss Function




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

#!/usr/bin/env python3


Loss Function in Linear Regressions


이 그림은 Learning rate에 따른 L1과 L2 손실함수를 보여줍니다. 

learning rate가 낮으면 정확도는 높아지지만 그만큼 많은 시간과 비용이 들어가며

learning rate가 높으면 발산 or 수렴할 수 있습니다. 따라서 적절한 learning rate를 선정하는 것이 중요합니다.




Linear Regression: L1 vs L2

출처: https://github.com/nfmcclure/tensorflow_cookbook



L1 Loss for Linear Least Squares 공식은 다음과 같습니다.

$$S =\sum_{i=1}^{N  }{ \left| y_{i}-\overset {\wedge }{y}_{i} \right |} $$

여기서 $N$은 data points의 수이고, $y_{i}$는 $y$의 실제 값이며, $\overset{\wedge}{y_{i}}$는 $i$번째 $y$의 예측 값입니다.


iris데이터셋에 L1 Loss function을 사용하여 결과를 확인해보면 다음과 같습니다.

from sklearn.datasets import load_iris

import tensorflow as tf

import numpy as np

from tensorflow.python.framework import ops


ops.reset_default_graph()


iris = load_iris()

print(iris.keys())

# dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])

print(iris.feature_names)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


x_vals = iris.data[:, 3] # petal width

y_vals = iris.data[:, 0] # sepal length


batch_size = 25

lrn_rate = 0.1 # divergenc at 0.4

iterations = 100


x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))


with tf.Session() as sess:

    model_output = tf.add(tf.matmul(x_data, A), b)


    loss_l1 = tf.reduce_mean(tf.abs(y_target - model_output))


    my_opt_l1 = tf.train.GradientDescentOptimizer(learning_rate=lrn_rate)

    train_step_l1 = my_opt_l1.minimize(loss_l1)


    init = tf.global_variables_initializer()

    init.run()


    loss_vec_l1 = []

    for i in range(iterations):

        rnd_idx = np.random.choice(len(x_vals), size=batch_size)

        rnd_x = x_vals[rnd_idx].reshape(-1, 1)

        rnd_y = y_vals[rnd_idx].reshape(-1, 1)


        feed = {x_data:rnd_x, y_target:rnd_y}

        sess.run(train_step_l1, feed_dict=feed)

        temp_loss_l1 = sess.run(loss_l1, feed_dict=feed)

        loss_vec_l1.append(temp_loss_l1)


        if (i+1)%10 == 0:

            print('Step {}: A={}, b={}'.format(i+1, A.eval(), b.eval()))

            # Step 10: A=[[-0.4101382]], b=[[-0.2588229]]

            # Step 20: A=[[0.7642619]], b=[[0.74117714]]

            # Step 30: A=[[1.9774618]], b=[[1.7411773]]

            # Step 40: A=[[2.3398612]], b=[[2.3091774]]

            # Step 50: A=[[2.252261]], b=[[2.6771777]]



이번에는 L2 Loss function에 대해 알아보겠습니다.

L2 Loss for Linear Least Squares는 다음과 같으며

$$S = \sum_{i=1}^{N}{\left(y_{i}-\overset{\wedge}{y_{i}} \right)^{2}}$$

위와 마찬가지로 $N$은 data points의 수이고, $y_{i}$는 $y$의 실제 값이며, $\overset{\wedge}{y_{i}}$는 $i$번째 $y$의 예측 값입니다.


다음 코드는 iris데이터에 L2 Loss function을 사용한 예입니다.

ops.reset_default_graph()


iris = load_iris()

print(iris.keys())

# dict_keys(['data''target', 'target_names', 'DESCR', 'feature_names'])

print(iris.feature_names)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


x_vals = iris.data[:, 3] # petal width

y_vals = iris.data[:, 0] # sepal length


x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))


with tf.Session() as sess:

    fomula = tf.add(tf.matmul(x_data, A), b)

    loss_l2 = tf.reduce_mean(tf.square(y_target - fomula))


    opt = tf.train.GradientDescentOptimizer(lrn_rate)

    train_step_l2 = opt.minimize(loss_l2)


    init = tf.global_variables_initializer()

    init.run()


    loss_vec_l2 = []

    for i in range(iterations):

        rand_idx = np.random.choice(len(x_vals), size=batch_size)

        rand_x = x_vals[rand_idx].reshape(-1, 1)

        rand_y = y_vals[rand_idx].reshape(-1, 1)


        my_dict = {x_data:rand_x, y_target:rand_y}

        sess.run(train_step_l2, feed_dict=my_dict)


        temp_loss_l2 = sess.run(loss_l2, feed_dict=my_dict)

        loss_vec_l2.append(temp_loss_l2)


        if (i+1)%20 == 0:

            print('step {}: A={}, b={}'.format(i+1, A.eval()[0], b.eval()[0]))

            # step 20: A=[1.876194], b=[3.1437955]

            # step 40: A=[1.3978924], b=[4.1212244]

            # step 60: A=[1.1288545], b=[4.4799623]

            # step 80: A=[0.9617775], b=[4.64575]

            # step 100: A=[0.88910973], b=[4.7133427]



L1 Loss function과 L2 Loss function을 시각화하는 코드는 다음과 같습니다.             

import matplotlib.pyplot as plt


plt.plot(loss_vec_l1, c='k', label='L1 Loss')

plt.plot(loss_vec_l2, c='red', ls='--', label='L2 Loss')

plt.title('L1 and L2 Loss per Generation, learning rate={}'.format(lrn_rate))

plt.xlabel('Generation')

plt.ylabel('Loss')

plt.legend(loc=1)

plt.show()



learning rate=0.1일 때 수렴(좌) , learning rate=0.4일 때 발산(우)





참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook


#!/usr/bin/env python3


TensorFlow Way of LinearRegression




이번 예제에서는 tensorflow를 통해 일괄적으로 데이터에 대한 루프를 돌면서 기울기와 y절편을  갱신할 것입니다.

Petal width꽃잎 폭을 x로 Sepal length길이를 y로하는 데이터를 대상으로 최적 직선을 찾아보겠습니다. L2 비용 함수를 사용하겠습니다.


iris데이터셋으로 Linear Regression을 해결하기 위해서는 역시 아래 방정식을 풀어야 합니다.

$$y = Ax+b$$


linear regression computational graph를 사용하기 위해서서는 input으로 $x$ 를 넣었을 때, 

$Ax+b$가 만들어져야 하고 $A$, $b$는 손실값이 최소가 되어야 합니다.

import numpy as np

import tensorflow as tf

from sklearn.datasets import load_iris

from tensorflow.python.framework import ops


iris = load_iris()


print(iris.keys())

# dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])


print(iris.feature_names)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


x_vals = np.array([x[3] for x in iris.data])

y_vals = iris.data[:,0]


batch_size = 25


x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))



데이터가 준비되었으니 tensorflow 방식으로 algorithm을 구현하면 다음과 같습니다.

with tf.Session() as sess:

    model_output = tf.add(tf.matmul(x_data, A), b) # linear regression fomula

    loss = tf.reduce_mean(tf.square(y_target - model_output)) # L2 loss

    my_opt = tf.train.GradientDescentOptimizer(learning_rate=0.05) 

    train_step = my_opt.minimize(loss) # loss가 최소인 방향으로 다음 단계 이동


    init = tf.global_variables_initializer()

    init.run()


    loss_vec = []

    for i in range(100):

        rand_idx = np.random.choice(len(x_vals), size=batch_size) 

        rand_x = x_vals[rand_idx].reshape(-1, 1)

        rand_y = y_vals[rand_idx].reshape(-1, 1)


        fedict={x_data: rand_x, y_target:rand_y}


        sess.run(train_step, feed_dict=fedict) # step 반복

        temp_loss = sess.run(loss, feed_dict=fedict)

        loss_vec.append(temp_loss)


        if (i+1)%20==0:

            print('Step {}\nA={}, b={}   Loss={:.5f}'.format(i+1, A.eval(), b.eval(), temp_loss))

            # Step 20

            # A=[[2.4062862]], b=[[2.4534268]]   Loss=1.78677

            # Step 40

            # A=[[1.9556967]], b=[[3.2615643]]   Loss=0.92836

            # Step 60

            # A=[[1.5368886]], b=[[3.698664]]   Loss=0.53148

            # Step 80

            # A=[[1.4006948]], b=[[4.085002]]   Loss=0.46051

            # Step 100

            # A=[[1.1938996]], b=[[4.331669]]   Loss=0.31104


    [slope] = A.eval()

    print('slope: {}'.format(slope))

    # slope: [1.1938996]


    [cept] = b.eval()

    print('intercept: {}'.format(cept))

    # intercept: [4.331669]



위의 결과를 시각화하는 코드는 다음과 같습니다.

import matplotlib.pyplot as plt


best_params = []

for i in x_vals.ravel():

    poly = i*slope+cept

    best_params.append(poly)


plt.scatter(x_vals, y_vals, label='Data Points', edgecolors='k')

plt.plot(x_vals, best_params, 'red')

plt.xlabel('Petal Width', size=15)

plt.ylabel('Sepal Length', size=15)

plt.title('Petal Width vs Sepal Length')

plt.show()



plt.plot(loss_vec, c='k')

plt.xlabel('Generation')

plt.ylabel('L2 Loss')

plt.title('L2 Loss per Generation')

plt.show()





참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook


#!/usr/bin/env python3


Using the Cholesky Decomposition Method


Linear Regression은 $A \cdot x=y$을 사용합니다. 

Cholesky decomposition은 matrix $A$를 lower triangular matrix $L$과 $L^{T}$로 분해합니다.

차원을 같게 하기 위해 matrix $A$ 앞에 $A^{T}$를 곱하여 square matrix로 만듭니다.

따라서 아래와 같은 식이 성립합니다.

$A^{T} \cdot A=L^{T} \cdot L$


Linear Regression을 적용하면 아래와 같이 사용할 수 있습니다.

$A\cdot X=Y$

$(A^{T} \cdot A) \cdot X = A^{T} \cdot Y$

$(L^{T} \cdot L) \cdot X = A^{T} \cdot Y$

$L^{T} \cdot Z = A^{T} \cdot Y$,     $L \cdot X = Z$


Cholesky decomposition을 Linear Regression에 적용하기 위해서는 다음과 같은 step이 필요합니다.

1. $A^{T} \cdot A = L^{T} \cdot L$에서 $L$을 구합니다.

2. $L^{T} \cdot Z = A^{T} \cdot Y$에서 $Z$를 구합니다.

3. $L \cdot X = Z$에서 $X$를 구합니다.


$X$는 우리가 구하고자 하는 slope와 intercept가 있는 matrix입니다.


이 과정을 간단한 데이터를 만들어 구현해 보겠습니다.

import tensorflow as tf

import numpy as np


x_vals = np.linspace(0, 10, 100).reshape(-1, 1)

print(x_vals[:6])

# [[0.        ]

#  [0.1010101 ]

#  [0.2020202 ]

#  [0.3030303 ]

#  [0.4040404 ]

#  [0.50505051]]


y_vals = x_vals + np.random.normal(0, 1, size=100).reshape(-1, 1)

print(y_vals[:6])

# [[-1.34770577]

#  [-0.4146378 ]

#  [-0.14096172]

#  [ 0.23305495]

#  [ 1.66821972]

#  [-0.35141322]]


ones = np.ones(100).reshape(-1, 1)

print(ones[:6])

# [[1.]

#  [1.]

#  [1.]

#  [1.]

#  [1.]

#  [1.]]


A = np.c_[x_vals, ones]

print(A[:6])

# [[0.         1.        ]

#  [0.1010101  1.        ]

#  [0.2020202  1.        ]

#  [0.3030303  1.        ]

#  [0.4040404  1.        ]

#  [0.50505051 1.        ]]


A_tsr = tf.constant(A, dtype=tf.float32)

y_tsr = tf.convert_to_tensor(y_vals, dtype=tf.float32)


with tf.Session() as sess:

    tA_A = tf.matmul(tf.transpose(A_tsr), A_tsr)

    L = tf.cholesky(tA_A)

    

    # solve $L\cdot Z=A^{T}  \cdot Y$, for $Z$

    tA_y = tf.matmul(tf.transpose(A_tsr), y_tsr)

    sol1 = tf.matrix_solve(L, tA_y)

    

    # solve $L^{T} \cdot X= Z$,  $Z$=sol1,  for $X$

    sol2 = tf.matrix_solve(tf.transpose(L), sol1)

    solution = sol2.eval()


slope = solution[0][0]

print('slope: {:3f}'.format(slope))

# slope: 0.988516


cept = solution[1][0]

print('intercept: {:.3f}'.format(cept))

# intercept: 0.163



시각화는 다음코드로 구현할 수 있습니다.

import matplotlib.pyplot as plt


reg_params = []

for i in x_vals.ravel():

    poly = i*slope + cept

    reg_params.append(poly)

    

plt.scatter(x_vals, y_vals, label='data')

plt.plot(x_vals, reg_params, c='red', label='best fit line')

plt.xlabel('feature 0', size=15)

plt.ylabel('feature 1', size=15)

plt.legend(loc='upper center', bbox_to_anchor=[0.1, 1.1], fancybox=True)

plt.show()

Cholesky 분해로 분석한 LinearRegression




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

'Tensorflow > Linear Regression' 카테고리의 다른 글

LASSO and Ridge Regression  (1) 2018.04.27
Deming Regression  (0) 2018.04.27
Loss Function in Linear Regressions  (0) 2018.04.26
TensorFlow Way of LinearRegression  (0) 2018.04.26
Inverse Matrix Method  (0) 2018.04.26

#!/usr/bin/env python3


Inverse Matrix Method


일반적인 linear regression의 식은 다음과 같이 쓸 수있습니다.

$ y = ax + b $, 그러나 이 식을 행렬로 확장하면 $AX = Y$로 쓸 수 있습니다.

$$X=A^{-1}(A^{-T}A^{T})Y$$

$$X=(A^{T}A)^{-1}A^{T}Y$$


$$A = \left[ {\begin{array}{cc}   x_{ 11 } & x_{ 12 } & x_{ 13 } & \cdots  & 1 \\  x_{ 21 } & x_{ 22 } & x_{ 23 } & \cdots  & 1 \\  \vdots&\vdots   &\vdots  &\ddots   & \vdots \\x_{ 31 } & x_{ 32 } & x_{ 33 } & \cdots  & 1 \end{array} } \right]$$


$$ point_{i}=(y_{i}, x_{i1}, x_{i2}, \cdots, x_{iF})$$


간단한 데이터를 만들어 이를 구현해보겠습니다.

import tensorflow as tf

import numpy as np


x_vals = np.linspace(0, 10, 100).reshape(-1, 1)

y_vals = x_vals + np.random.normal(0, 1, size=100).reshape(-1, 1)

ones = np.ones(100).reshape(-1, 1)


A = np.c_[x_vals, ones]


A_tsr = tf.constant(A, dtype=tf.float32)

y_tsr = tf.convert_to_tensor(y_vals, dtype=tf.float32)


init = tf.global_variables_initializer()

with tf.Session() as sess:

    init.run()

    tA_A = tf.matmul(tf.transpose(A_tsr), A_tsr)

    tA_A_inv = tf.matrix_inverse(tA_A)

    prod = tf.matmul(tA_A_inv, tf.transpose(A_tsr))

    sol = tf.matmul(prod, y_tsr)

    solution = sol.eval()


slope = solution[0][0]

cept = solution[1][0]


print('slope :{:.3f}'.format(slope))

# slope :1.000


print('intercept :{:.3f}'.format(cept))

# intercept :0.012



이 결과를 시각화하는 코드는 다음과 같습니다.

import matplotlib.pyplot as plt


reg_params = []

for i in x_vals.ravel():

    poly = slope*i + cept

    reg_params.append(poly)


plt.scatter(x_vals, y_vals, c='orange')

plt.plot(x_vals, reg_params, c='blue', lw=2)

plt.show()

inverse matrix를 이용한 Linear Regression

이런 방법은 데이터셋이 커지게 되면 느려진다는 단점이 있습니다.




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

#!/usr/bin/env python3


Operations on a Computational Graph, Layering Nested Operations


placeholder에 넣을 데이터를 만들고, 상수를 곱해보겠습니다.

import tensorflow as tf

import numpy as np

from tensorflow.python.framework import ops


ops.reset_default_graph()


x_vals = np.array([1., 3., 5., 7., 9.])

x_data = tf.placeholder(tf.float32)

m_const = tf.constant(3.)

my_product = tf.multiply(x_data, m_const)


with tf.Session() as sess:

    print('m_const.eval() =>{} \n'.format(m_const.eval()))

    for x_val in x_vals:

        x_data_1 = sess.run(x_data, feed_dict={x_data:x_val})

        print('x_data_1 => {}'.format(x_data_1))


        my_product_1 = sess.run(my_product, feed_dict={x_data:x_val})

        print('my_product_1 => {}'.format(my_product_1))

        print('--------\n')


# m_const.eval() =>3.0 

# -------------------

# x_data_1 => 1.0

# my_product_1 => 3.0

# -------------------


# x_data_1 => 3.0

# my_product_1 => 9.0

# -------------------


# x_data_1 => 5.0

# my_product_1 => 15.0

# -------------------


# x_data_1 => 7.0

# my_product_1 => 21.0

# -------------------


# x_data_1 => 9.0

# my_product_1 => 27.0

# -------------------



Layering Nested Operations을 알아보겠습니다.

연산이 서로 이어지는 방식을 알아보기 위해 opeation graph에 multiple operation을 구성하겠습니다.

placeholder에 두 matrix를 곱한 후 덧셈을 하는 경우를 예로 들어보겠습니다.

def prinft(classtf):

    init = tf.global_variables_initializer()

    with tf.Session() as sess:

        init.run()

        print(classtf.eval())


ops.reset_default_graph()


# Create data to feed in

my_array = np.array([[1., 3., 5., 7., 9.],

                   [-2., 0., 2., 4., 6.],

                   [-6., -3., 0., 3., 6.]])


# Duplicate the array for having two inputs

x_vals = np.array([my_array, my_array + 1])

print(x_vals)

# array([[[ 1.,  3.,  5.,  7.,  9.],

#         [-2.,  0.,  2.,  4.,  6.],

#         [-6., -3.,  0.,  3.,  6.]],


#        [[ 2.,  4.,  6.,  8., 10.],

#         [-1.,  1.,  3.,  5.,  7.],

#         [-5., -2.,  1.,  4.,  7.]]])


# Declare the placeholder

x_data = tf.placeholder(tf.float32, shape=(3, 5))


# Declare constants for operations

m1 = tf.constant([[1.],[0.],[-1.],[2.],[4.]])

printf(m1)

# [[ 1.]

#  [ 0.]

#  [-1.]

#  [ 2.]

#  [ 4.]]


m2 = tf.constant([[2.]])

printf(m2)

# [[2.]]


a1 = tf.constant([[10.]])

printf(a1)

# [[10.]]


이제 matrix multiplication을 해보겠습니다.

A(3x5) * m1(5x1) = (3x1)이 만들어지고 나머지 연산은 상수곱과 덧셈이기 때문에 차원은 변하지 않습니다.

init = tf.global_variables_initializer()

with tf.Session() as sess:

    init.run()


    prod1 = tf.matmul(x_data, m1)

    prod2 = tf.matmul(prod1, m2)

    add1 = tf.add(prod2, a1)


    for x_val in x_vals:

        result = sess.run(add1, feed_dict={x_data: x_val})

        print('result => \n{}\n'.format(result))


# result => 

# [[102.]

#  [ 66.]

#  [ 58.]]


# result => 

# [[114.]

#  [ 78.]

#  [ 70.]]        




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

#!/usr/bin/env python3


Activation  Function


activation function는 신경망의 필수 요소이기 때문에 신경망을 사용할 때는 활성화 함수를 자주 접하게 됩니다.

activation function의 목표는 가중치와 편향치를 조절하는 것이며 텐서플로에서 activation function는 텐서에 적용되는 비선형 연산입니다.


신경망에 비선형성을 도입하는 가장 일반적인 방법은 ReLU 함수가 있습니다.

import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt


def printf(tfclass):

    init = tf.global_variables_initializer()

    with tf.Session() as sess:

        init.run()

        print(tfclass.eval())


line = tf.linspace(-10., 10., num=100)

def plot_act_func(model):

    init = tf.global_variables_initializer()

    with tf.Session() as sess:

        init.run()

        x = line.eval()

        y = model.eval()

    plt.plot(x, y)

    plt.show()


relu_rlt = tf.nn.relu([-3., 3., 10.])

printf(relu_rlt)

# [ 0.  3. 10.]


relu = tf.nn.relu(line)

plot_act_func(relu)

ReLU Function



ReLU activation function의 선형 증가량에 상한을 설정하고 싶을 때가 있습니다.

max(0, x) 함수를 min()함수로 감싸서 구현할 수 있습니다. 텐서플로에는 ReLU6가 구현되어 있고

Relu6 = min(max(0, x), 6)으로 정의되어 있습니다.


ReLU6 이 함수는 매끄럽지 않은 각진 모양의 sigmoid 함수로 생각할 수 있습니다.

relu6_rlt = tf.nn.relu6([-3., 3., 10.])

printf(relu6_rlt)

# [0. 3. 6.]


relu6 = tf.nn.relu6(line)

plot_act_func(relu6)

relu6 function



sigmoid 함수는 연속이고 매끄러운 가장 일반적인 activation function입니다. 로지스틱 함수라고도 하며, 수식으로는

1 / (1+exp(-x))로 표현합니다. sigmoid 함수는 학습 과정에서 역전파 항을 0으로 만들어 버리는 경향이 있기 때문에 자주 사용하지는 않습니다.


sig_result = tf.nn.sigmoid([-1., 0., 1.])

printf(sig_result)

# [0.26894143 0.5        0.7310586 ]


sigmoid = tf.nn.sigmoid(line)

plot_act_func(sigmoid)

sigmoid function



또 다른 activation function하이퍼볼릭 탄젠트 함수가 있습니다. 하이퍼볼릭 탄젠트 함수는 sigmoid 함수와 아주 비슷하지만, 함수 값의 범위가 -1에서 1입니다.

tanh_rlt = tf.nn.tanh([-1.0, 0., 1.])

printf(tanh_rlt)

# [-0.7615942  0.         0.7615942]


tanh = tf.nn.tanh(line)

plot_act_func(tanh)

tanh function



softsign 함수도 activation function로 사용할 수 있습니다.

x / (abs(x) + 1)로 표현할 수 있으며 부호sign 함수를 연속 함수로 근사한 것입니다.

sosign = tf.nn.softsign([-1., 0., -1.])

printf(sosign)

# [-0.5  0.  -0.5]


softsign = tf.nn.softsign(line)

plot_act_func(softsign)

softsign function



softplus 함수는 매끄럽게 만든 ReLU 함수라고 할 수 있다. 이 함수의 식은 log(exp(x) + 1)

softplus_rlt = tf.nn.softplus([-1., 0., -1.])

printf(softplus_rlt)

# [0.31326166 0.6931472  0.31326166]


softplus = tf.nn.softplus(line)

plot_act_func(softplus)

softplus function

입력값이 커지면 softplus 함수값은 무한대로 가고, softsign 함수 값은 1에 수렴합니다.

반대로 입력 값이 작아지면 softplus 함수 값은 0에 수렴하고, softsign함수값은 -1에 수렴합니다.



지수 선형 유닛(ELU, Exponential Linear Unit) 함수는 softplus 함수와 비슷하지만 하부 점근선이 -1입니다.

x<0일 때는 exp(x)+1이고, 그외에는 x입니다.

elu_rlt = tf.nn.elu([-1.0, 0., -1.])

printf(elu_rlt)

# [-0.63212055  0.         -0.63212055]


elu = tf.nn.elu(line)

plot_act_func(elu)

elu function




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

'Tensorflow > Introduction' 카테고리의 다른 글

placeholder, marix, operation  (0) 2018.04.25
Getting Start Tensorflow  (0) 2018.04.25

#!/usr/bin/env python3


placeholder, marix, operation


변수는 텐서를 입력받아 변수를 출력하는 Variable()함수를 이용하여 주로 생성합니다.

이 함수는 변수 선언만 하기 때문에 변수 초기화를 별도로 해줘야 합니다.

import tensorflow as tf


my_var = tf.Variable(tf.zeros([2, 3]), dtype=tf.float32, name='my_var')


init = tf.global_variables_initializer()

with tf.Session() as sess:

    sess.run(init)


    result = my_var.eval()

    print(result)

    # [[0. 0. 0.]

    # [0. 0. 0.]]



placeholder는 계산 그래프에 데이터가 투입되는 위치를 나타냅니다. 세션의 feed_dict 인자를 통해 placeholder 데이터를 투입합니다.

계산에 placeholder를 넣기 위해서는 placeholder에 대해 하나 이상의 연산을 수행해야 합니다.

import numpy as np


with tf.Session() as sess:

    x = tf.placeholder(tf.float32, shape=[2, 2])

    y = tf.identity(x) # Return a tensor with the same shape and contents as input.

    x_vals = np.random.rand(2, 2)


    print(sess.run(y, feed_dict={x: x_vals}))

    # [[0.18282834 0.35173032]

    #  [0.3008346  0.14677659]]



다음은 matrix를 다루는 몇가지 방법에 대해 알아보겠습니다.

sess =  tf.Session()

identity_matrix = tf.diag([1., 1., 1.]) # identity matrix

A = tf.truncated_normal([2, 3], mean=1, stddev=1, dtype=tf.float32)

B = tf.fill([2, 3], 5.)

C = tf.random_uniform([3, 2], dtype=tf.float32)


np_arr = np.array([[1, 2, 3],

                       [-3, -7, -1],

                       [0, 5, -2]])

D = tf.convert_to_tensor(np_arr, dtype=tf.float32)



print(sess.run(identity_matrix))

# [[1. 0. 0.]

#  [0. 1. 0.]

#  [0. 0. 1.]]


print(sess.run(A))

# [[0.25446475 1.108418   2.5896869 ]

#  [0.3214993  0.6533705  0.8581022 ]]


print(sess.run(B))

# [[5. 5. 5.]

#  [5. 5. 5.]]


print(sess.run(C))

# [[0.9613472  0.97370124]

#  [0.4405172  0.7275435 ]

#  [0.9694842  0.23063374]]


print(sess.run(D))

# [[ 1.  2.  3.]

#  [-3. -7. -1.]

#  [ 0.  5. -2.]]


# 더하기 빼기는 다음과 같이 사용합니다.

print(sess.run(A+B))

# [[6.5324025 6.2761655 7.3138623]

#  [5.8994517 7.0984983 6.506235 ]]


print(sess.run(A-B))

# [[-4.5335164 -4.079894  -2.3542004]

#  [-4.500795  -5.3273354 -2.5056663]]


# 행렬곱은 다음 함수를 사용합니다.

print(sess.run(tf.matmul(B, identity_matrix)))

# [[5. 5. 5.]

#  [5. 5. 5.]]


print(sess.run(tf.transpose(C)))

# [[0.16169488 0.08706641 0.3332044 ]

#  [0.18076909 0.5893874  0.8159915 ]]


print(sess.run(tf.matrix_determinant(D)))

# -38.0


print(sess.run(tf.matrix_inverse(D)))

# [[-0.50000006 -0.5        -0.50000006]

#  [ 0.15789475  0.05263158  0.21052633]

#  [ 0.39473686  0.13157895  0.0263158 ]]


print(sess.run(tf.cholesky(identity_matrix)))

# [[1. 0. 0.]

#  [0. 1. 0.]

#  [0. 0. 1.]]


eig_value, eig_vector = sess.run(tf.self_adjoint_eig(D))

print(eig_value)

# [-10.659076    -0.22750695   2.886583  ]


print(eig_vector)

# [[-0.21749546 -0.6325011  -0.74339646]

#  [-0.84526515 -0.25879988  0.46749276]

#  [ 0.48808062 -0.7300446   0.4783433 ]]



나눗셈과 외은 다음과 같이 구합니다.

with tf.Session() as sess:

    f = tf.div(3, 4) # 몫만 표현

    print (f.eval()) # 0


    f1 = tf.truediv(3, 4) # 나눗셈 결과를 소수로 표현

    print(f1.eval()) # 0.75


    f2 = tf.floordiv(3.0, 4.0) # 몫을 소수로 표현

    print(f2.eval()) # 0.0


    f3 = tf.mod(22.0, 5.0) # 나머지

    print(f3.eval()) # 2.0


    f4 = tf.cross([1., 0., 0.], [0., 1., 0.]) # 외적

    print(f4.eval()) # [0. 0. 1.]



tan(pi/4)는 다음과 같이 구할 수 있습니다.

init = tf.global_variables_initializer()

with tf.Session() as sess:

init.run()

result = tf.div(tf.sin(np.pi/4.), tf.cos(np.pi/4.))

print(result)

# 1.0



다항함수 3*x^2 -x + 10의 결과는 다음 코드로 구현할 수 있습니다.

def custom_polynomial(val):

    return(3*tf.square(val) - val + 10)


init = tf.global_variables_initializer()

with tf.Session() as sess:

init.run()

result = custom_polynomial(11).eval()

print(result)

# 362




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

'Tensorflow > Introduction' 카테고리의 다른 글

Activation Function  (0) 2018.04.25
Getting Start Tensorflow  (0) 2018.04.25

#!/usr/bin/env python3


Getting Start Tensorflow


tensorflow는 객체로 만들어지기 때문에 출력을 위해 printf를 정의하고 이 것을 사용하겠습니다.

import tensorflow as tf


def printf(tfclass):

    init = tf.global_variables_initializer()

    with tf.Session() as sess:

        sess.run(init)

        rlt = tfclass.eval()

    print(rlt)

    

0 값으로 채워진 텐서는 다음과 같이 생성합니다.

zero_tsr = tf.zeros([3, 2])

printf(zero_tsr)

# [[0. 0.]

#  [0. 0.]

#  [0. 0.]]


1 값으로 채워진 텐서는 다음과 같이 생성합니다.

ones_tsr = tf.ones([3, 2])

printf(ones_tsr)

# [[1. 1.]

#  [1. 1.]

#  [1. 1.]]


동일한 상수값으로 채워진 텐서는 다음과 같이 생성합니다.

filled_tsr = tf.fill([3, 2], 9)

printf(filled_tsr)

# [[9 9]

#  [9 9]

#  [9 9]]


기존 상수를 이용해 텐서를 생성할 때는 다음 방식을 사용합니다.

constant_tsr = tf.constant([1, 2, 3])

printf(constant_tsr)

# [1 2 3]


기존 텐서의 형태를 바탕으로 텐서 변수를 초기화하는 것도 가능합니다.

zeros_similar = tf.zeros_like(constant_tsr)

printf(zeros_similar)

# [0 0 0]

ones_similar = tf.ones_like(constant_tsr)

printf(ones_similar)

# [1 1 1]


텐서플로는 구간을 지정하는 방식으로 텐서를 선언할 수 있습니다. 다음 함수는 range()나 numpy의 linspace()와 비슷하게 동작합니다.

linear_tsr = tf.linspace(0.0, 1.0, num=3)

printf(linear_tsr)

# [0.  0.5 1. ]


integer_seq_tsr = tf.range(6.0, 15, delta=3)

printf(integer_seq_tsr)

# [ 6.  9. 12.]


랜덤한 숫자도 뽑아낼 수 있습니다.

randunif_tsr = tf.random_uniform([3, 2], minval=0, maxval=1, dtype=tf.float32)

printf(randunif_tsr)

# [[0.218009   0.7311672 ]

#  [0.6954018  0.2027992 ]

#  [0.95226717 0.9950316 ]]


randnorm_tsr = tf.random_normal([3, 2], mean=0.0, stddev=1.0)

printf(randnorm_tsr)

# [[-0.45060402 -1.6076114 ]

#  [ 0.7157349  -0.28653365]

#  [ 1.2830635   0.6957943 ]]


특정 범위에 속하는 정규 분포 임의의 값을 생성하고 싶은 경우에 지정한 평균에서 항상 표준편차 2배 이내의 값을 뽑아줍니다.

truncnorm_tsr = tf.truncated_normal([3, 2], mean=3.0, stddev=1.0)

printf(truncnorm_tsr)

# [[2.6660793 2.3485358]

#  [3.378799  2.757817 ]

#  [2.8825157 1.9243042]]


배열의 항목을 임의로 섞을 때

shuffle_output = tf.random_shuffle(truncnorm_tsr)

printf(shuffle_output)

# [[2.174755  4.001117 ]

#  [2.6528723 2.8258555]

#  [3.5614102 2.8608997]]


cropped_output = tf.random_crop(shuffle_output, [3, 2])

printf(cropped_output)

# [[2.6678126 2.087521 ]

#  [1.5311174 4.574707 ]

#  [2.400455  3.175764 ]]




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

'Tensorflow > Introduction' 카테고리의 다른 글

Activation Function  (0) 2018.04.25
placeholder, marix, operation  (0) 2018.04.25

+ Recent posts