Deep Learning with Convolutional Neural Networks

oyoi·2024년 5월 24일

What are Convolutional Neural Networks (CNNs)?

: 신경망은 weight와 bias가 주어진 뉴런으로 구성된다. 신경망의 학습 효율은 이러한 가중치와 바이어스를 조율하는 방식으로 높일 수 있다.. 각가의 뉴런은 일련의 입력을 받아서 나름대로 처리한 후 하나의 값을 출력한다. 신명을 여러 계층으로 구성한 것을 심층 신경망 deep neural network라 부른다. 이러한 심층 신경망을 주로 다루는 AI 분야가 딥러닝이다.
기존의 신경망의 가장 큰 단점은 입력 데이터의 구조를 고려하지 않는다는 것이다. 이미지와 같이 공간적 구조를 가지는 데이터를 처리하기에는 적합하지 않다는 것이다. 이러한 단점을 극복하기 위해 CNN(convolutional neural network)가 등장했다. CNN의 목적은 입력 계층에 들어온 미가공 이미지 데이터의 클래스를 예측하는 것이며, 예측된 클래스는 출력 계층의 결과값 형태로 출력된다.

The architecture of CNNs

: 기존 신경망을 다룰 때는 입력 데이터를 하나의 벡터로 변환한다. 이렇게 변환된 벡터는 신경망의 입력으로 전달하고 다시 신경망을 구성하는 여러 계층을 거친다. 각 계층에 존재하는 뉴런은 모두 이전 계층에 있는 뉴런과 연결되어 있으며, 같은 계층에 속한 뉴런끼리는 서로 연결되어 있지 않다.
반면 CNN을 구성하는 뉴런은 3차원(폭, 높이, 깊이)으로 정렬되어 있다. 그리고 현재 계층에 속한 각각의 뉴런들은 이전 계층의 출력에 일부분에만 연결된다. 마치 입력 이미지 위에 NxN 필터를 올려둔 것과 같다. 하나의 필터마으로 이미지에 담긴 의미를 모두 찾을 수 없다. 따라서 모든 세부 사항을 수집하기 위해 이 작업을 M번 수행한다. M개의 필터는 특징 추출기의 역할을 한다.

The types of layers in a CNN

  • 입력 계층: 미가공 이미지 데이터를 있는 그대로 받는 계층이다.
  • 컨볼루션 계층: 입력 계층의 여러 패치와 뉴런 사이의 컨볼루션 연산을 수행하는 계층이다. 이전 계층의 출력에 있는 작은 패치와 가중치에 대한 내적 스칼라곱을 계산한다.
  • ReLU 계층: 이전 계층의 출력에 활성 함수를 적용하는 계층이다. 각 계층 사이에서 선형으로 분류할 수 없는 데이터까지 성공적으로 분류하기 위해 신경망에 비선형성을 추가해준다.
  • 풀링 계층: 이전 계층의 출력 일부분만 선택하거나 평균을 내는 방식 등으로 데이터 차원을 줄이는 계층이다.
  • 완전 연결 계층: 마지막 계층의 출력 결과를 계산한다.

Building a perceptron based linear regressor

import numpy as np 
import matplotlib.pyplot as plt 
import tensorflow as tf 

# Define the number of points to generate 
num_points = 1200 

# Generate the data based on equation y = mx + c 
data = [] 
m = 0.2 
c = 0.5 
for i in range(num_points): 
    # Generate 'x'  
    x = np.random.normal(0.0, 0.8) 

	# Generate some noise 
    noise = np.random.normal(0.0, 0.04) 

	# Compute 'y'  
    y = m*x + c + noise  
 
    data.append([x, y]) 

# Separate x and y 
x_data = [d[0] for d in data] 
y_data = [d[1] for d in data] 

# Plot the generated data 
plt.plot(x_data, y_data, 'ro') 
plt.title('Input data') 
plt.show() 

# Generate weights and biases 
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) 
b = tf.Variable(tf.zeros([1])) 

# Define equation for 'y' 
y = W * x_data + b 

# Define how to compute the loss 
loss = tf.reduce_mean(tf.square(y - y_data)) 

# Define the gradient descent optimizer 
optimizer = tf.train.GradientDescentOptimizer(0.5) 
train = optimizer.minimize(loss) 

# Initialize all the variables 
init = tf.initialize_all_variables() 

# Start the tensorflow session and run it 
sess = tf.Session() 
sess.run(init) 

# Start iterating 
num_iterations = 10 

for step in range(num_iterations): 
    # Run the session 
    sess.run(train) 

	# Print the progress 
    print('\nITERATION', step+1) 
    print('W =', sess.run(W)[0]) 
    print('b =', sess.run(b)[0]) 
    print('loss =', sess.run(loss)) 

	# Plot the input data  
    plt.plot(x_data, y_data, 'ro') 

    # Plot the predicted output line 
    plt.plot(x_data, sess.run(W) * x_data + sess.run(b)) 

	# Set plotting parameters 
    plt.xlabel('Dimension 0') 
    plt.ylabel('Dimension 1') 
    plt.title('Iteration ' + str(step+1) + ' of ' + str(num_iterations)) 
    plt.show() 

Building an image classifier using a single layer neural network

import argparse 
 
import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data 

def build_arg_parser():
    parser = argparse.ArgumentParser(description='Build a classifier using 
            \MNIST data')
    parser.add_argument('--input-dir', dest='input_dir', type=str, 
            default='./mnist_data', help='Directory for storing data')
    return parser

if __name__ == '__main__': 
    args = build_arg_parser().parse_args() 

	# Get the MNIST data 
    mnist = input_data.read_data_sets(args.input_dir, one_hot=True) 

	# The images are 28x28, so create the input layer  
    # with 784 neurons (28x28=784)
    x = tf.placeholder(tf.float32, [None, 784]) 

	# Create a layer with weights and biases. There are 10 distinct 
    # digits, so the output layer should have 10 classes 
    W = tf.Variable(tf.zeros([784, 10])) 
    b = tf.Variable(tf.zeros([10])) 

	# Create the equation for 'y' using y = W*x + b 
    y = tf.matmul(x, W) + b 

	# Define the entropy loss and the gradient descent optimizer 
    y_loss = tf.placeholder(tf.float32, [None, 10]) 
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_loss)) 
    optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss) 

	# Initialize all the variables  
    init = tf.initialize_all_variables() 

	# Create a session 
    session = tf.Session() 
    session.run(init) 
	
	# Start training 
    num_iterations = 1200 
    batch_size = 90 
    for _ in range(num_iterations): 
        # Get the next batch of images 
        x_batch, y_batch = mnist.train.next_batch(batch_size) 

	# Train on this batch of images
        session.run(optimizer, feed_dict = {x: x_batch, y_loss: y_batch})
        
    # Compute the accuracy using test data 
    predicted = tf.equal(tf.argmax(y, 1), tf.argmax(y_loss, 1)) 
    accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32)) 
    print('\nAccuracy =', session.run(accuracy, feed_dict = { 
            x: mnist.test.images,  
            y_loss: mnist.test.labels}))

Building an image classifier using a Convolutional Neural Network

import argparse 
 
import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data 

def build_arg_parser(): 
    parser = argparse.ArgumentParser(description='Build a CNN classifier \ 
            using MNIST data') 
    parser.add_argument('--input-dir', dest='input_dir', type=str,  
            default='./mnist_data', help='Directory for storing data') 
    return parser 

def get_weights(shape): 
    data = tf.truncated_normal(shape, stddev=0.1) 
    return tf.Variable(data) 

def get_biases(shape): 
    data = tf.constant(0.1, shape=shape) 
    return tf.Variable(data) 

def create_layer(shape): 
    # Get the weights and biases  
    W = get_weights(shape) 
    b = get_biases([shape[-1]]) 
 
    return W, b 
    
    ‘def convolution_2d(x, W): 
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1],  
            padding='SAME') 

def max_pooling(x): 
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],  
            strides=[1, 2, 2, 1], padding='SAME') 

if __name__ == '__main__': 
    args = build_arg_parser().parse_args() 

	# Get the MNIST data 
    mnist = input_data.read_data_sets(args.input_dir, one_hot=True) 

	# The images are 28x28, so create the input layer  
    # with 784 neurons (28x28=784)  
    x = tf.placeholder(tf.float32, [None, 784]) 

	# Reshape 'x' into a 4D tensor  
    x_image = tf.reshape(x, [-1, 28, 28, 1]) 

	# Define the first convolutional layer 
    W_conv1, b_conv1 = create_layer([5, 5, 1, 32]) 

	# Convolve the image with weight tensor, add the  
    # bias, and then apply the ReLU function 
    h_conv1 = tf.nn.relu(convolution_2d(x_image, W_conv1) + b_conv1)
    
    # Apply the max pooling operator 
    h_pool1 = max_pooling(h_conv1) 

	# Define the second convolutional layer 
    W_conv2, b_conv2 = create_layer([5, 5, 32, 64]) 

	# Convolve the output of previous layer with the  
    # weight tensor, add the bias, and then apply  
    # the ReLU function 
    h_conv2 = tf.nn.relu(convolution_2d(h_pool1, W_conv2) + b_conv2) 

	# Apply the max pooling operator 
    h_pool2 = max_pooling(h_conv2) 

	# Define the fully connected layer 
    W_fc1, b_fc1 = create_layer([7 * 7 * 64, 1024]) 

	# Reshape the output of the previous layer 
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) 

	# Multiply the output of previous layer by the  
    # weight tensor, add the bias, and then apply  
    # the ReLU function 
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) 

	# Define the dropout layer using a probability placeholder 
    # for all the neurons 
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 

	# Define the readout layer (output layer) 
    W_fc2, b_fc2 = create_layer([1024, 10]) 
    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2 

	# Define the entropy loss and the optimizer 
    y_loss = tf.placeholder(tf.float32, [None, 10]) 
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_conv, y_loss)) 
    optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss) 

	# Define the accuracy computation 
    predicted = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_loss, 1)) 
    accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32)) 

	# Create and run a session 
    sess = tf.InteractiveSession() 
    init = tf.initialize_all_variables() 
    sess.run(init) 

	# Start training 
    num_iterations = 21000 
    batch_size = 75 
    print('\nTraining the model....') 
    for i in range(num_iterations): 
        # Get the next batch of images 
        batch = mnist.train.next_batch(batch_size) 
        
        # Print progress 
        if i % 50 == 0: 
            cur_accuracy = accuracy.eval(feed_dict = { 
                    x: batch[0], y_loss: batch[1], keep_prob: 1.0}) 
            print('Iteration', i, ', Accuracy =', cur_accuracy) 
            
        # Train on the current batch 
        optimizer.run(feed_dict = {x: batch[0], y_loss: batch[1], keep_prob: 0.5}) 

	# Compute accuracy using test data 
    print('Test accuracy =', accuracy.eval(feed_dict = { 
            x: mnist.test.images, y_loss: mnist.test.labels,  
            keep_prob: 1.0})) 
profile
오이

0개의 댓글