티스토리 뷰

Mini-batch

 - Mini-batch는 한번에 모든 데이터를 처리하는 대신

 - 하위집합으로 데이터셋을 분류하여 학습시키는 기술이다.

 - 컴퓨터에 전체 데이터셋을 저장할 여유가 없을 때에도 모델을 학습시킬 수 있게 해준다.

 - Mini-batching은 모든 샘플에서 동시에 손실(loss)을 계산할 수 없기 때문에

 - 컴퓨터의 계산처리상 비효율적이라 할 수 있다.

 - 하지만 이는 모델을 전혀 실행할 수 없는 상황에 비해서는 작은부분이라 볼 수 있다.

 - 또한 Mini-batch 기술은 SGD와 결합하였을때 매우 유용하다.

 - 이 기술의 기본 개념은 매 epoch마다 데이터를 랜덤하게 섞은다음 mini-batch들을 생성하는것이다.

 - 그리고 각 mini-batch 에 대해 gradient descent로 네트워크의 가중치들을 학습시킨다.

 - 이는 batch들이 랜덤하기 때문에 각 batch마다 SGD를 수행하는 것임.




 - MNIST 데이터셋의 가중치와 바이어스를 통해 현재 내 환경에서 작업이 가능한지 알아보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import tensorflow as tf
 
n_input = 784  # MNIST data input (img shape: 28*28)
n_classes = 10  # MNIST total classes (0-9 digits)
 
# Import MNIST data
mnist = input_data.read_data_sets('/datasets/ud730/mnist', one_hot=True)
 
# The features are already scaled and the data is shuffled
train_features = mnist.train.images
test_features = mnist.test.images
 
train_labels = mnist.train.labels.astype(np.float32)
test_labels = mnist.test.labels.astype(np.float32)
 
# Weights & bias
weights = tf.Variable(tf.random_normal([n_input, n_classes]))
bias = tf.Variable(tf.random_normal([n_classes]))
cs




- 우선 우리가 사용할 데이터셋의 크기를 보면

 - input과 weights 그리고 bias에 필요한 총 메모리는 174메가이며, 그닥 큰 값은 아니다.

 - 그러나 우리가 앞으로 수행해야할 연산에서의 데이터셋은 기가바이트 이상으로 큰 메모리가 요구된다.

 - 메모리를 추가로 구입할 수 있지만, 12GB의 Titan X GPU 메모리는 $1000 이상이다.

 - 따라서 현재 환경에서 대형 모델을 돌릴 수 있도록 하려면 mini-batching 기술을 활용해야한다.

 - 텐서플로우에서 mini-batching 기술을 구현하는 방법에 대해 알아보자.






TensorFlow Mini-batching

 - Mini-batching 기술을 사용하려면 먼저 데이터들을 batch 단위로 나눠줘야한다.

 - 근데 데이터셋을 동일한 크기의 batch로 나눌 수 없는 경우가 발생한다.

 - 예를들면 1000개의 데이터셋을 크기가 128인 batch로 나눌경우 나누어 떨어지지 않기 때문에

 - 128개의 데이터가 들어가있는 batch 7개와 104개의 데이터가 들어있는 batch 1개로 나뉜다.

 - 1000 = (128 * 7) + (104 * 1) 이기 때문.

 - 이 경우 batch의 크기가 다양하므로 

 - 텐서플로우의 tf.placeholder() 함수를 활용하여 다양한 batch 크기를 받아와야 한다.


 - 위의 예시를 다시 진행해보면, n_input = 784(features) 이고 n_classes = 10(labels) 이기에

 - features의 차원은 [None, n_input] 이 되고, labels의 차원은 [None, n_classes] 가 된다. 

1
2
3
# Features and Labels
features = tf.placeholder(tf.float32, [None, n_input])
labels = tf.placeholder(tf.float32, [None, n_classes])
cs

 - 여기서 None의 역할은?

 - None 차원은 placeholder의 batch 크기 이다.

 - 즉, 런타임시 텐서플로우는 0보다 큰 batch를 받아오게 된다.

 - 이러한 셋팅은 features와 labels를 크기가 128인 batch들과 크기가 104인 하나의 batch를

 - 모델에 셋팅해줄 수 있다.






Implement the batches function

<sandbox.py>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from quiz import batches
from pprint import pprint
 
# 4 Samples of features
example_features = [
    ['F11','F12','F13','F14'],
    ['F21','F22','F23','F24'],
    ['F31','F32','F33','F34'],
    ['F41','F42','F43','F44']]
# 4 Samples of labels
example_labels = [
    ['L11','L12'],
    ['L21','L22'],
    ['L31','L32'],
    ['L41','L42']]
 
# PPrint prints data structures like 2d arrays, so they are easier to read
pprint(batches(3, example_features, example_labels))
cs


<quiz.py>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import math
def batches(batch_size, features, labels):
    """
    Create batches of features and labels
    :param batch_size: The batch size
    :param features: List of features
    :param labels: List of labels
    :return: Batches of (Features, Labels)
    """
    assert len(features) == len(labels)
    # TODO: Implement batching
    output_batches = []
    
    sample_size = len(features)
    for start_i in range(0, sample_size, batch_size) : 
        end_i = start_i + batch_size
        batch = [features[start_i : end_i], labels[start_i : end_i]]
        output_batches.append(batch)
    
    return output_batches
cs


>>






<quiz.py>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
from helper import batches
 
learning_rate = 0.001
n_input = 784  # MNIST data input (img shape: 28*28)
n_classes = 10  # MNIST total classes (0-9 digits)
 
# Import MNIST data
mnist = input_data.read_data_sets('/datasets/ud730/mnist', one_hot=True)
 
# The features are already scaled and the data is shuffled
train_features = mnist.train.images
test_features = mnist.test.images
 
train_labels = mnist.train.labels.astype(np.float32)
test_labels = mnist.test.labels.astype(np.float32)
 
# Features and Labels
features = tf.placeholder(tf.float32, [None, n_input])
labels = tf.placeholder(tf.float32, [None, n_classes])
 
# Weights & bias
weights = tf.Variable(tf.random_normal([n_input, n_classes]))
bias = tf.Variable(tf.random_normal([n_classes]))
 
# Logits - xW + b
logits = tf.add(tf.matmul(features, weights), bias)
 
# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
 
# Calculate accuracy
correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
 
 
# TODO: Set batch size
batch_size = 128
assert batch_size is not None, 'You must set the batch size'
 
init = tf.global_variables_initializer()
 
with tf.Session() as sess:
    sess.run(init)
    
    # TODO: Train optimizer on all batches
    for batch_features, batch_labels in batches(batch_size, train_features, train_labels):
        sess.run(optimizer, feed_dict={features: batch_features, labels: batch_labels})
 
    # Calculate accuracy for test dataset
    test_accuracy = sess.run(
        accuracy,
        feed_dict={features: test_features, labels: test_labels})
 
print('Test Accuracy: {}'.format(test_accuracy))
 
cs



<helper.py>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import math
def batches(batch_size, features, labels):
    """
    Create batches of features and labels
    :param batch_size: The batch size
    :param features: List of features
    :param labels: List of labels
    :return: Batches of (Features, Labels)
    """
    assert len(features) == len(labels)
    outout_batches = []
    
    sample_size = len(features)
    for start_i in range(0, sample_size, batch_size):
        end_i = start_i + batch_size
        batch = [features[start_i:end_i], labels[start_i:end_i]]
        outout_batches.append(batch)
        
    return outout_batches
 
cs


>>






 - 정확도가 낮은것을 확인할 수 있다.

 - batch 단위로 나눠서 학습을 하고있기때문에 전체 데이터셋을 한번에 학습하는것 보다

 - 그 정확도가 당연히 낮아질 수 밖에 없다.

 - 이런점은 epoches 를 높게 설정함으로써 상쇄가능하다.



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함