본문 바로가기

카테고리 없음

TensorFlow

Feature = input

Label = output

 

Graph = Computational 의 일부 (아직 계산 하기 전)

Session = Graph 의 집합

 

Rank = Tensor 의 차원   ex) rank 2 => 행렬

Shape = 각 차원에 값이 얼마나 있는지  ex) (3,3,2) 1차원에 3개의 값, 2차원에 3개의 값, 3차원에 2개의 값

 

rank1_tensor = tf.Variable(["Test"], tf.string) 
rank2_tensor = tf.Variable([["test", "ok"], ["test", "yes"]], tf.string)
tf.rank(rank2_tensor)

 

이라고 한다면 출력은 아래와 같다

 

rank  2 이다.

 

 

reshape

는 이미 존재하는 Tensor 의 형태를 변화 시켜준다. 예시는 아래와 같다.

tensor1 = tf.ones([1,2,3])  # tf.ones() creates a shape [1,2,3] tensor full of ones
tensor2 = tf.reshape(tensor1, [2,3,1])  # reshape existing data to shape [2,3,1]
tensor3 = tf.reshape(tensor2, [3, -1])  # -1 tells the tensor to calculate the size of the dimension in that place
                                        # this will reshape the tensor to [3,2]                                                                        
# The numer of elements in the reshaped tensor MUST match the number in the original

 

출력은 아래와 같다.

tf.Tensor(
[[[1. 1. 1.]
  [1. 1. 1.]]], shape=(1, 2, 3), dtype=float32)
tf.Tensor(
[[[1.]
  [1.]
  [1.]]

 [[1.]
  [1.]
  [1.]]], shape=(2, 3, 1), dtype=float32)
tf.Tensor(
[[1. 1.]
 [1. 1.]
 [1. 1.]], shape=(3, 2), dtype=float32)

 

 

Types of Tensors

  • Variable
  • Constant
  • Placeholder
  • SparseTensor

텐서의 종류에는 크게 4가지가 있다. 이중에서 Variable 만 값 변경이 가능하고 나머지는 전부 상수 처럼 변환이 불가능하다.

 

 

 

Linear Regression

 

여러 데이터를 1차원 직선으로 fitting 하는 방식

 

Data Load 하는 예시는 아래와 같다.

# Load dataset.
dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv') # training data
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv') # testing data
#print(dftrain.head()) #  head = 첫번째 5개 보여줌
y_train = dftrain.pop('survived') # survive column 제거 하고 y_train 에 입력
y_eval = dfeval.pop('survived')
print(dftrain.loc[0],y_train.loc[0]) # .loc[보고싶은 줄] 그 row print

 

CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
                       'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']

feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
  vocabulary = dftrain[feature_name].unique()  # gets a list of all unique values from given feature column
  ### unique 는 안에 있는 다른 값들을 다 뽑아줌 중복 없이!
  feature_columns.append(tf.feature_column.categorical_column_with_vocabulary_list(feature_name, vocabulary))

for feature_name in NUMERIC_COLUMNS:
  feature_columns.append(tf.feature_column.numeric_column(feature_name, dtype=tf.float32))

print(feature_columns)

Categorical Data 를 보는것과 같이 integer 로 바꾸어야한다. => 그리하여 같은 데이터는 같은 숫자 값으로 같다 아니다 정도 쉽게 판단이 가능하다.

 

Input function => input 을 하기 위해서 아래와 같이 함수의 형태로 만들어야한다.

def make_input_fn(data_df, label_df, num_epochs=10, shuffle=True, batch_size=32):
  def input_function():  # inner function, this will be returned
    ds = tf.data.Dataset.from_tensor_slices((dict(data_df), label_df))  # create tf.data.Dataset object with data and its label
    if shuffle:
      ds = ds.shuffle(1000)  # randomize order of data
    ds = ds.batch(batch_size).repeat(num_epochs)  # split dataset into batches of 32 and repeat process for number of epochs
    return ds  # return a batch of the dataset
  return input_function  # return a function object for use

train_input_fn = make_input_fn(dftrain, y_train)  # here we will call the input_function that was returned to us to get a dataset object we can feed to the model
eval_input_fn = make_input_fn(dfeval, y_eval, num_epochs=1, shuffle=False)

input 을 할때 중요한 값들이 epoch 와 batch 이다.

 

epoch =  한 데이터를 얼마나 자주 반복할지 (but 커지면 overfitting 이 일어난다)

batch =  한번에 덜릴 data 갯수

 

batch 를 정하는 이유는 모든 데이터들을 한번에 램에 올릴수 없기때문에 한번에 넣는 숫자를 정해야한다. 또한 한번에 하나씩만 넣으면 너무 비효율적이기때문에 효율적인 training 을 하기 위해서 batch 를 정한다.

 

linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)
# We create a linear estimtor by passing the feature columns we created earlier

linear_est.train(train_input_fn)  # train
result = linear_est.evaluate(eval_input_fn)  # get model metrics/stats by testing on tetsing data

clear_output()  # clears consoke output
print(result['accuracy'])  # the result variable is simply a dict of stats about our model

training 은 위와 같이 진행한다.

Shuffle 을 하기 때문에 같은 코드를 돌리더라도 조금씩 값이 다른다

 

 

Classifier 

Data load

CSV_COLUMN_NAMES = ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth', 'Species']
SPECIES = ['Setosa', 'Versicolor', 'Virginica']
# Lets define some constants to help us later on
train_path = tf.keras.utils.get_file(
    "iris_training.csv", "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv")
test_path = tf.keras.utils.get_file(
    "iris_test.csv", "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv")

train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)
# Here we use keras (a module inside of TensorFlow) to grab our datasets and read them into a pandas dataframe

train_y = train.pop('Species')
test_y = test.pop('Species')
train.head() # the species column is now gone

 

input function

def input_fn(features, labels, training=True, batch_size=256):
    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))

    # Shuffle and repeat if you are in training mode.
    if training:
        dataset = dataset.shuffle(1000).repeat()
    
    return dataset.batch(batch_size)

 

Feature columns

# Feature columns describe how to use the input.
my_feature_columns = []
for key in train.keys():
    my_feature_columns.append(tf.feature_column.numeric_column(key=key))
print(my_feature_columns)

 

Building model using DNN CLassifier (deeplearning neural network)

# Build a DNN with 2 hidden layers with 30 and 10 hidden nodes each.
classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    # Two hidden layers of 30 and 10 nodes respectively.
    hidden_units=[30, 10],
    # The model must choose between 3 classes.
    n_classes=3)

########### training process

classifier.train(
    input_fn=lambda: input_fn(train, train_y, training=True),  # lamda = 한줄 function 코드 
    steps=5000)

'''
x = lamda : print("function")
x() 
이라고 하면 x 는 "function"을 프린트 하는 함수가 된다

'''

# We include a lambda to avoid creating an inner function previously

 

 

Evaluation 

eval_result = classifier.evaluate(
    input_fn=lambda: input_fn(test, test_y, training=False))

print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))

 

prediction 

def input_fn(features, batch_size=256):
    # Convert the inputs to a Dataset without labels.
    return tf.data.Dataset.from_tensor_slices(dict(features)).batch(batch_size)

features = ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth']
predict = {}

print("Please type numeric values as prompted.")
for feature in features:
  valid = True
  while valid: 
    val = input(feature + ": ")
    if not val.isdigit(): valid = False

  predict[feature] = [float(val)]

predictions = classifier.predict(input_fn=lambda: input_fn(predict))
for pred_dict in predictions:
    class_id = pred_dict['class_ids'][0]
    probability = pred_dict['probabilities'][class_id]

    print('Prediction is "{}" ({:.1f}%)'.format(
        SPECIES[class_id], 100 * probability))

 

Neural Network

Input neuron = input 개수에 따라 개수가 정해짐

Neuron 에서 다른 neuron 으로 값이 전달될 때 weight 가 곱해진다.

Bias = weight 1input 이 없는 값

 

Activation Function

더 높은 차원에서 data 를 바라보아 기존에 보지 못한 data 의 특징을 잡아 내기 위해 사용한다(spreading data to higher dimestion)

-      Relu => 0밑으로 다 0으로 만들어 버리는 Function

-      Sigmoid => 0 1 사이 값으로 만들어버리는 Function

 

 

BackPropagation

Neural network training 하는 방식 => weight bias 를 바꿔가면서 loss function 의 변화를 알아본다.

 

Loss Function

Neural networkpredict 된 값과 다른 expected 값 과의 차이를 비교하는 방법

Ex) MSE(mean squared Error)

 

Optimizer

Backpropagation 방식을 통해 loss function 을 줄여가는 방법 대표적으로 Gradient Descent 방식이 있다.

 

Data pre-processing

Input 되는 값을 01 사이 값으로 하기

 

Hyperparameter tuning

우리가 바꿀수 있는 값을 조정하기 ex) epochs, layer 개수

(weight, bias 값들은 못바꿈)

 

training 할때의 Accuracy > evaluating accuracy  이라면 =>Overfitting

Epoch(반복되는 횟수) 를 줄여가는게 마땅 => hyperparameter tuning

 

 

%tensorflow_version 2.x  # this line is not required unless you are in a notebook
# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
fashion_mnist = keras.datasets.fashion_mnist  # load dataset

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()  # split into tetsing and training

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

train_images = train_images / 255.0 # Data-preprocessing => 0과 1사이 값으로 만들기
test_images = test_images / 255.0

 

Data 준비

model = keras.Sequential([    #sequential => basic neural network 의 기본 (왼쪽에서 오른쪽으로 가는거)
    keras.layers.Flatten(input_shape=(28, 28)),  # input layer (1)    #28x28사이즈의 픽셀을 1차원으로 만들어서 넣기
    keras.layers.Dense(128, activation='relu'),  # hidden layer (2)   #1번째 hidden layer (보통 전의 layer 보다 조금 작게 정하는게 일반적)
    keras.layers.Dense(10, activation='softmax') # output layer (3)   # 마지막 layer => 10개의 class 가 있기 때문에 output neuron 의 숫자가 10개
])
# defined arictecture of neural network

model.compile(optimizer='adam', # algorithm of optimizer descent gradient
              loss='sparse_categorical_crossentropy', # loss function 
              metrics=['accuracy']) #우리가 보고 싶은거

모델 만들기

model.fit(train_images, train_labels, epochs=10)  # we pass the data, labels and epochs and watch the magic!
# training 시작
test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=1) # verbose 는 몇개 print 할껀지 정하는 value

모델 학습하기

 

 

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=1) # verbose 는 몇개 print 할껀지 정하는 value

print('Test accuracy:', test_acc)

=> [2.4888799e-05 2.4569960e-10 6.2554406e-08 7.1357902e-09 5.0822241e-06 8.9231977e-04 3.9141332e-06 3.6563035e-02 2.2431567e-07 9.6251047e-01]

9

 

값을 보면 output 뉴런에서 나온 값들을 알 수 있다.

 

 

 

Computer vision using CNN 

image data 

color image 의 경우 위와 같이 대부분 3차원의 data 를 가지고 있다.

 

 

Dense neural network => 전체를 한번에 본다 따라서 Global pattern 을 학습한다.

 

Convolutional Neural Network => local pattern 을 학습한다.

Filter(pattern of pixels) 을 통해서 filter 의 존재 여부를 가지고 있는 feature map 을 반환한다

Padding => input 되는 사진에다가 태두리를 둘러 outputinput dimenstion 과 일치하도록 만듦

 

Stride => filter 를 사용해서 input 과 계산을 할 때 건너뛰는 개수 (ex : stride =1  이면 하나씩 건너뛰는거)

 

Pooling => feature map 에서 특징을 뽑는다 & smaller dimension 으로 만든다. 대표적으로 max pooling, min pooling, average pooling 을 사용한다.

 

 

Load data

%tensorflow_version 2.x  # this line is not required unless you are in a notebook
import tensorflow as tf

from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

#  LOAD AND SPLIT DATASET
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()

# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0

class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

모델 만들기

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3))) # feature map 할때 activation function 사용 
model.add(layers.MaxPooling2D((2, 2)))  # => to make dimenstion small
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

모델을 만들면 아래와 같다. (model.summary() 로 확인가능)

conv2d 를 지나가면 padding 을 하지 않았기 때문에 차원이 2개씩 줄어드는걸 알 수 있다.

max_Pooling2d 를 지나가면 차원이 반으로 줄어드는걸 알 수 있다.

 

model에다가 classifier 하기 위해 모델을 1차원으로 만들고 dense neural network을 사용하여, 최종 output 을 계산한다. 

model.add(layers.Flatten()) # 4x4x64 를 일열로 만들기
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10)) # 최종 output 이 10개로 만들어

만들어진 최종 output 은 아래와 같다.

training 하는 과정

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),  # loss function
              metrics=['accuracy'])   #찾아보면 어떤 loss function 써야하는지 잘 나와있음

history = model.fit(train_images, train_labels, epochs=4, 
                    validation_data=(test_images, test_labels))

 

 

Data 가 적을 때 사용하는 방법

-      Data argumentation => image 를 회전, shifting, flipping 하면서 data 를 증식 시킨다

-      Pretrained models + Fine tuning =>  이미 만들어져있는 model 을 사용 하면서 초기 layer 은 사용하지 않고 뒷부분(classification) 에 해당되는 layer 을 학습한다.

 

Freezing => trainable parameter non-trainable 로 변환한다.

 

 

Data argumentation 하는 예시

from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator

# creates a data generator object that transforms images
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')

# pick an image to transform
test_img = train_images[20]
img = image.img_to_array(test_img)  # convert image to numpy arry
img = img.reshape((1,) + img.shape)  # reshape image

i = 0

for batch in datagen.flow(img, save_prefix='test', save_format='jpeg'):  # this loops runs forever until we break, saving images to current directory with specified prefix
    plt.figure(i)
    plot = plt.imshow(image.img_to_array(batch[0]))
    i += 1
    if i > 4:  # show 4 images
        break

plt.show()

 

 

Using Pre-trained model 데이터 전처리 코드

#Imports
import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
keras = tf.keras

import tensorflow_datasets as tfds
tfds.disable_progress_bar()

# split the data manually into 80% training, 10% testing, 10% validation
(raw_train, raw_validation, raw_test), metadata = tfds.load(
    'cats_vs_dogs',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

get_label_name = metadata.features['label'].int2str  # creates a function object that we can use to get labels

# display 2 images from the dataset
for image, label in raw_train.take(5):
  plt.figure()
  plt.imshow(image)
  plt.title(get_label_name(label))
  
  IMG_SIZE = 160 # All images will be resized to 160x160

def format_example(image, label):
  """
  returns an image that is reshaped to IMG_SIZE
  """
  image = tf.cast(image, tf.float32)
  image = (image/127.5) - 1
  image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))
  return image, label
  
train = raw_train.map(format_example)
validation = raw_validation.map(format_example)
test = raw_test.map(format_example)

BATCH_SIZE = 32
SHUFFLE_BUFFER_SIZE = 1000

train_batches = train.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
validation_batches = validation.batch(BATCH_SIZE)
test_batches = test.batch(BATCH_SIZE)
  

 

모델 설정 

IMG_SHAPE = (IMG_SIZE, IMG_SIZE, 3)

# Create the base model from the pre-trained model MobileNet V2
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,  # input 사이즈를 결정
                                               include_top=False,  # top = classifier 를 로딩하는 과정
                                               weights='imagenet')

Base model 의 summary 를 보면 굉장히 여러층의 data 가 있다.

Model 을 Freezing 하는 code

base_model.trainable = False

위의 코드를 지나 freezing 을 진행 한 후에 보면 trainable params 가 0 이 되는걸 알수 있다.

layer 추가

global_average_layer = tf.keras.layers.GlobalAveragePooling2D()  # 1차원으로 flatten 하는 과정

prediction_layer = keras.layers.Dense(1)

model = tf.keras.Sequential([
  base_model,
  global_average_layer,
  prediction_layer
])

따라서 최종적인 모델은  아래와 같이 됩니다.

google 에서 만든 pretrained model 을 가지고 뒷 부분의 classifier 의 layer 을 train 하는 model 입니다.

training 하는 과정 코드

base_learning_rate = 0.0001  # weight bias 를 얼마나 바꿀건지 
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])
              
# We can evaluate the model right now to see how it does before training it on our new images
initial_epochs = 3
validation_steps=20

loss0,accuracy0 = model.evaluate(validation_batches, steps = validation_steps)

# Now we can train it on our images
history = model.fit(train_batches,
                    epochs=initial_epochs,
                    validation_data=validation_batches)

acc = history.history['accuracy']
print(acc)

 

모델 저장하는 방법 

keras 에서는 model 을 h5 파일 형식으로 저장합니다.

model.save("dogs_vs_cats.h5")  # we can save the model and reload it at anytime in the future
# keras 에서 모델을 저장하는 방식
new_model = tf.keras.models.load_model('dogs_vs_cats.h5')

 

 

 

아래 링크를 참조하여 블로그를 작성하였습니다.

https://www.youtube.com/watch?v=tPYj3fFJGjk&t=283s

 

 

📕 Module 2: Introduction to TensorFlow -https://colab.research.google.com/drive/1F_EWVKa8rbMXi3_fG0w7AtcscFq7Hi7B#forceEdit=true&sandboxMode=true

📗 Module 3: Core Learning Algorithms - https://colab.research.google.com/drive/15Cyy2H7nT40sGR7TBN5wBvgTd57mVKay#forceEdit=true&sandboxMode=true

📘 Module 4: Neural Networks with TensorFlow - https://colab.research.google.com/drive/1m2cg3D1x3j5vrFc-Cu0gMvc48gWyCOuG#forceEdit=true&sandboxMode=true

📙 Module 5: Deep Computer Vision - https://colab.research.google.com/drive/1ZZXnCjFEOkp_KdNcNabd14yok0BAIuwS#forceEdit=true&sandboxMode=true