'분류 전체보기'에 해당되는 글 201건

SARSA

개발/AI,ML,ALGORITHM 2023. 8. 28. 09:14
반응형

 

# SARSA
# 
# Created by netcanis on 2023/08/22.
#
# 5x10 크기의 그리드 월드 환경에서 SARSA 알고리즘을 실행하는 간단한 예시입니다. 
# 에이전트는 상, 하, 좌, 우로 움직이며 목표 지점에 도달하는 최적의 경로를 학습
# 매 에피소드마다 이동 경로 및 순서를 실시간으로 출력
# 에피소드 100의 배수마다 이동경로 및 순서 출력
# 경로 횟수가 적을수록 높은 보상
# 에피소드가 증가할수록 탐험보다 활용을 선택하도록 개선.
#
# SARSA (State-Action-Reward-State-Action)는 강화학습의 한 종류로, 상태와 동작의 시퀀스를 고려하여 학습하는 알고리즘입니다. 
# 이 알고리즘은 Q-learning과 비슷하지만, Q-learning이 다음 상태의 최대 Q 값을 사용하는 반면에 SARSA는 다음 상태에서 실제로 
# 선택한 동작에 대한 Q 값을 사용합니다. 이로 인해 더 안정적으로 학습하고, 더 정확한 제어를 할 수 있는 특징이 있습니다.


import numpy as np
import matplotlib.pyplot as plt


# 그리드 월드 환경 설정
# 0: 빈공간, 1: 벽, 2: 목적지, (0,0): 시작위치
grid = np.array([[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
                 [0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
                 [0, 1, 1, 0, 1, 0, 0, 0, 1, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 1, 2]])

# 환경 설정
NUM_STATES = np.prod(grid.shape)  # 상태 공간 크기 (5x6=30)
NUM_ACTIONS = 4  # 상, 하, 좌, 우

# hyperparameter
EXPLORATION_PROB = 0.2  # 탐험율 - exploration(탐험)과 exploitation(활용) 사이의 균형을 조절.
LEARNING_RATE = 0.1     # 학습률 - 경사 하강법 등 최적화 알고리즘에서 가중치 업데이트에 사용되는 학습률.
DISCOUNT_FACTOR = 0.99  # 할인율 - 강화 학습에서 미래 보상을 현재 보상보다 얼마나 중요하게 고려할지를 조절하는 요소.
NUM_EPISODES = 1500     # 강화 학습에서 에피소드 수

# Q 함수 초기화
Q = np.zeros((NUM_STATES, NUM_ACTIONS))

# 상태 인덱스 계산 함수
def state_index(state):
    return state[0] * grid.shape[1] + state[1]

# 그래프 초기화
plt.ion()
fig, ax = plt.subplots()
episode_rewards = []

# 시작 위치 설정
start_position = (0, 0)
print("start_position :", start_position) # (0, 0)

# 타겟 위치 설정
target_position = np.argwhere(grid == 2)[0]
print("target_position :", target_position) # (4, 9)


# 그리드 월드 환경 출력 함수
def plot_grid_world(state, path=[]):
    plt.imshow(grid, cmap="gray", interpolation="none", origin="upper")
    plt.xticks([])
    plt.yticks([])
    
    if path:
        path = np.array(path)
        plt.plot(path[:, 1], path[:, 0], marker='o', markersize=4, linestyle='-', color='green')
        
        for i, pos in enumerate(path):
            plt.text(pos[1], pos[0], str(i + 1), ha="center", va="center", color="orange", fontsize=14)
    
    plt.text(state[1], state[0], "A", ha="center", va="center", color="red", fontsize=16)
    plt.text(grid.shape[1] - 1, grid.shape[0] - 1, "B", ha="center", va="center", color="green", fontsize=16)


def choose_action(state, epsilon):
    if np.random.rand() < epsilon:
        return np.random.choice(NUM_ACTIONS)
    return np.argmax(Q[state_index(state)])


# SARSA 알고리즘
for episode in range(NUM_EPISODES):
    print(f"Episode: {episode + 1}/{NUM_EPISODES}")
    
    state = tuple(start_position)
    total_reward = 0
    path_taken = []
    
    # Decaying exploration
    # 에피소드가 증가할 수록 탐험하는 비율을 쇠퇴시킨다.(원래 탐험율의 절반으로 줄인다)
    epsilon = EXPLORATION_PROB + (EXPLORATION_PROB / 2 - EXPLORATION_PROB) * (1.0 - episode / NUM_EPISODES)
    
    # 첫 이동 선택
    action = choose_action(state, epsilon)
    
    while state != tuple(target_position):

        # max와 min 함수는 에이전트가 그리드 월드 환경 내에서 벗어나지 않도록 하기 위해 사용
        if action == 0:   # 상 : 현재 행을 1 감소시킴 (위쪽으로 이동)
            next_state = (max(state[0] - 1, 0), state[1])
        elif action == 1: # 하 : 현재 행을 1 증가시킴 (아래쪽으로 이동)
            next_state = (min(state[0] + 1, grid.shape[0] - 1), state[1])
        elif action == 2: # 좌 : 현재 열을 1 감소시킴 (왼쪽으로 이동)
            next_state = (state[0], max(state[1] - 1, 0))
        elif action == 3: # 우 : 현재 열을 1 증가시킴 (오른쪽으로 이동)
            next_state = (state[0], min(state[1] + 1, grid.shape[1] - 1))
        

        # 보상
        # reward = -1 if grid[next_state] == 1 else 1 if grid[next_state] == 2 else 0
        if grid[next_state] == 1: # 벽을 만났을 때 보상 설정
            reward = -(NUM_STATES * 100)
        else: # 경로 횟수가 증가될 수록 횟수 만큼 - 보상 (즉 경로 횟수가 적을 수록 보상이 크다)
            reward = -(len(path_taken) + 1)
        
        
        # 다음 이동 선택
        next_action = choose_action(next_state, epsilon)
        
        
        # SARSA
        a1 = Q[state_index(state), action]
        a2 = Q[state_index(next_state), next_action]
        Q[state_index(state)][action] = a1 + LEARNING_RATE * (reward + DISCOUNT_FACTOR * a2 - a1)
        
        
        total_reward += reward
        path_taken.append(state)
        state = next_state
        action = next_action
        
        
        # 에피소드 다음 배수마다 이동경로 및 순서 출력
        if (episode + 1) % 100 == 0:
            plt.figure(2)
            plt.clf() # Matplotlib의 현재 활성화된 그림 창을 지우기
            plt.title(f"Episode : {episode + 1}")
            plot_grid_world(state, path_taken)
            plt.pause(0.01)
            
    episode_rewards.append(total_reward)

    # 에피소드 10의 배수마다 이동경로 및 순서 출력
    if (episode + 1) % 10 == 0:
        plt.figure(1)
        plt.plot(episode_rewards)
        plt.xlabel("Episode")
        plt.ylabel("Total Reward")
        plt.title("Total Reward per Episode")
        plt.show()
        plt.pause(0.01)
    


#----------------------------------------------------------------------------
#
# 결과 출력 
#

# 학습 완료 후 최적 경로 및 순서 출력
state = tuple(start_position) # 시작 위치
total_reward = 0
best_trajectory = [state]  # 최적 경로 및 순서를 저장할 리스트

# 최적 경로 추적
# max와 min 함수는 에이전트가 그리드 월드 환경 내에서 벗어나지 않도록 하기 위해 사용
while state != tuple(target_position):
    action = np.argmax(Q[state_index(state)])
    if action == 0:   # 상 : 현재 행을 1 감소시킴 (위쪽으로 이동)
        state = (max(state[0] - 1, 0), state[1])
    elif action == 1: # 하 : 현재 행을 1 증가시킴 (아래쪽으로 이동)
        state = (min(state[0] + 1, grid.shape[0] - 1), state[1])
    elif action == 2: # 좌 : 현재 열을 1 감소시킴 (왼쪽으로 이동)
        state = (state[0], max(state[1] - 1, 0))
    elif action == 3: # 우 : 현재 열을 1 증가시킴 (오른쪽으로 이동)
        state = (state[0], min(state[1] + 1, grid.shape[1] - 1))
    
    best_trajectory.append(state)
    
    # 보상
    # reward = -1 if grid[next_state] != 1 else -100
    if grid[next_state] == 1: # 벽을 만났을 때 보상 설정
        reward = -(NUM_STATES * 100)
    else: # 경로 횟수가 증가될 수록 횟수 만큼 - 보상 (즉 경로 횟수가 적을 수록 보상이 크다)
        reward = -(len(path_taken) + 1)
    
    total_reward += reward    
    


# 최적 경로 및 순서 출력
plt.figure(3)  # 자동으로 크기 조정됨, 새로운 창으로 출력 
plt.clf() # Matplotlib의 현재 활성화된 그림 창을 지우기
plt.title(f"Total Reward : {total_reward}, Best Trajectory Length : {len(best_trajectory)}")
plot_grid_world(state, best_trajectory)
plt.show(block=True)  # 그래프를 출력한 후 버튼을 누를 때까지 대기        


# 결과 로그 출력 
print("Learned Q-values:")
print(Q)

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

Tic-Tac-Toe 게임 제작 (1/4) - minimax  (0) 2023.09.12
Simple Neural Network XOR  (0) 2023.08.29
Q-learning  (0) 2023.08.28
MNIST - TensorFlowLite  (0) 2023.07.19
MNIST - Keras  (0) 2023.07.19
블로그 이미지

SKY STORY

,

Q-learning

개발/AI,ML,ALGORITHM 2023. 8. 28. 09:09
반응형
# Q-learning 알고리즘 
#
# Created by netcanis on 2023/08/22.
#
# 5x10 크기의 그리드 월드 환경에서 Q-learning 알고리즘을 실행하는 간단한 예시입니다. 
# 에이전트는 상, 하, 좌, 우로 움직이며 목표 지점에 도달하는 최적의 경로를 학습
# 매 에피소드마다 이동 경로 및 순서를 실시간으로 출력
# 에피소드 100의 배수마다 이동경로 및 순서 출력
# 경로 횟수가 적을수록 높은 보상
# 에피소드가 증가할수록 탐험보다 활용을 선택하도록 개선.


import numpy as np
import matplotlib.pyplot as plt

# 그리드 월드 환경 설정
# 0: 빈공간, 1: 벽, 2: 목적지, (0,0)): 시작위치
grid = np.array([[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
                 [0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
                 [0, 1, 1, 0, 1, 0, 0, 0, 1, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 1, 2]])


# Q-learning 매개변수
NUM_STATES = np.prod(grid.shape)  # 상태 공간 크기 (5x6=30)
NUM_ACTIONS = 4  # 상, 하, 좌, 우

# hyperparameter
EXPLORATION_PROB = 0.2  # 탐험율 - exploration(탐험)과 exploitation(활용) 사이의 균형을 조절.
LEARNING_RATE = 0.1     # 학습률 - 경사 하강법 등 최적화 알고리즘에서 가중치 업데이트에 사용되는 학습률.
DISCOUNT_FACTOR = 0.99  # 할인율 - 강화 학습에서 미래 보상을 현재 보상보다 얼마나 중요하게 고려할지를 조절하는 요소.
NUM_EPISODES = 1500     # 강화 학습에서 에피소드 수

# Q 함수 초기화
Q = np.zeros((NUM_STATES, NUM_ACTIONS))

# 상태 인덱스 계산 함수
def state_index(state):
    return state[0] * grid.shape[1] + state[1]

# 그래프 초기화
plt.ion()
fig, ax = plt.subplots()
episode_rewards = []

# 시작 위치 설정
start_position = (0, 0)
print("begin_position :", start_position) # (0, 0)

# 타겟 위치 설정
target_position = np.argwhere(grid == 2)[0]
print("target_position :", target_position) # (4, 9)


# 그리드 월드 환경 출력 함수
def plot_grid_world(state, path=[]):
    plt.imshow(grid, cmap="gray", interpolation="none", origin="upper")
    plt.xticks([])
    plt.yticks([])
    
    if path:
        path = np.array(path)
        plt.plot(path[:, 1], path[:, 0], marker='o', markersize=4, linestyle='-', color='green')
        
        for i, pos in enumerate(path):
            plt.text(pos[1], pos[0], str(i + 1), ha="center", va="center", color="orange", fontsize=14)
    
    plt.text(state[1], state[0], "A", ha="center", va="center", color="red", fontsize=16)
    plt.text(grid.shape[1] - 1, grid.shape[0] - 1, "B", ha="center", va="center", color="green", fontsize=16)

        
def choose_action(state, epsilon):
    if np.random.rand() < epsilon:
        return np.random.choice(NUM_ACTIONS)
    return np.argmax(Q[state_index(state)])


# Q-learning 알고리즘
for episode in range(NUM_EPISODES):
    print(f"Episode: {episode + 1}/{NUM_EPISODES}")
    
    state = tuple(start_position)
    total_reward = 0
    path_taken = []
    
    # Decaying exploration
    # 에피소드가 증가할 수록 탐험하는 비율을 쇠퇴시킨다.(원래 탐험율의 절반으로 줄인다)
    epsilon = EXPLORATION_PROB + (EXPLORATION_PROB / 2 - EXPLORATION_PROB) * (1.0 - episode / NUM_EPISODES)

    while state != tuple(target_position):
        
        action = choose_action(state, epsilon)
      
        # max와 min 함수는 에이전트가 그리드 월드 환경 내에서 벗어나지 않도록 하기 위해 사용
        if action == 0:   # 상 : 현재 행을 1 감소시킴 (위쪽으로 이동)
            next_state = (max(state[0] - 1, 0), state[1])
        elif action == 1: # 하 : 현재 행을 1 증가시킴 (아래쪽으로 이동)
            next_state = (min(state[0] + 1, grid.shape[0] - 1), state[1])
        elif action == 2: # 좌 : 현재 열을 1 감소시킴 (왼쪽으로 이동)
            next_state = (state[0], max(state[1] - 1, 0))
        elif action == 3: # 우 : 현재 열을 1 증가시킴 (오른쪽으로 이동)
            next_state = (state[0], min(state[1] + 1, grid.shape[1] - 1))
        
        
        # 보상
        # reward = -1 if grid[next_state] != 1 else -100
        if grid[next_state] == 1: # 벽을 만났을 때 보상 설정
            reward = -(NUM_STATES * 100)
        else: # 경로 횟수가 증가될 수록 횟수 만큼 - 보상 (즉 경로 횟수가 적을 수록 보상이 크다)
            reward = -(len(path_taken) + 1)
        
        
        # Q                                                                             ccc                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              -learning        
        a1 = Q[state_index(state), action]
        a2 = np.max(Q[state_index(next_state)])
        q1 = (1 - LEARNING_RATE) * a1
        q2 = LEARNING_RATE * (reward + DISCOUNT_FACTOR * a2)
        Q[state_index(state), action] = q1 + q2
        
        total_reward += reward
        path_taken.append(state)
        state = next_state
        
        
        # 에피소드 다음 배수마다 이동경로 및 순서 출력
        if (episode + 1) % 100 == 0:
            plt.figure(2)
            plt.clf() # Matplotlib의 현재 활성화된 그림 창을 지우기
            plt.title(f"Episode : {episode + 1}")
            plot_grid_world(state, path_taken)
            plt.pause(0.01)

    episode_rewards.append(total_reward)

    # 에피소드 다음 배수마다 이동경로 및 순서 출력
    if (episode + 1) % 10 == 0:
        plt.figure(1)
        plt.plot(episode_rewards)
        plt.xlabel("Episode")
        plt.ylabel("Total Reward")
        plt.title("Total Reward per Episode")
        plt.show()
        plt.pause(0.01)



#----------------------------------------------------------------------------
#
# 결과 출력 
#

# 학습 완료 후 최적 경로 및 순서 출력
state = tuple(start_position) # 시작 위치
total_reward = 0
best_trajectory = [state]  # 최적 경로 및 순서를 저장할 리스트

# 최적 경로 추적
# max와 min 함수는 에이전트가 그리드 월드 환경 내에서 벗어나지 않도록 하기 위해 사용
while state != tuple(target_position):
    action = np.argmax(Q[state_index(state)])
    
    if action == 0:   # 상 : 현재 행을 1 감소시킴 (위쪽으로 이동)
        state = (max(state[0] - 1, 0), state[1])
    elif action == 1: # 하 : 현재 행을 1 증가시킴 (아래쪽으로 이동)
        state = (min(state[0] + 1, grid.shape[0] - 1), state[1])
    elif action == 2: # 좌 : 현재 열을 1 감소시킴 (왼쪽으로 이동)
        state = (state[0], max(state[1] - 1, 0))
    elif action == 3: # 우 : 현재 열을 1 증가시킴 (오른쪽으로 이동)
        state = (state[0], min(state[1] + 1, grid.shape[1] - 1))
    
    best_trajectory.append(state)
    
    # 보상
    # reward = -1 if grid[next_state] != 1 else -100
    if grid[next_state] == 1: # 벽을 만났을 때 보상 설정
        reward = -(NUM_STATES * 100)
    else: # 경로 횟수가 증가될 수록 횟수 만큼 - 보상 (즉 경로 횟수가 적을 수록 보상이 크다)
        reward = -(len(path_taken) + 1)
    
    total_reward += reward    
    

# 최적 경로 및 순서 출력
plt.figure(3)  # 자동으로 크기 조정됨, 새로운 창으로 출력 
plt.clf() # Matplotlib의 현재 활성화된 그림 창을 지우기
plt.title(f"Total Reward : {total_reward}, Best Trajectory Length : {len(best_trajectory)}")
plot_grid_world(state, best_trajectory)
plt.show(block=True)  # 그래프를 출력한 후 버튼을 누를 때까지 대기        


# 결과 로그 출력 
print("Learned Q-values:")
print(Q)

 

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

Simple Neural Network XOR  (0) 2023.08.29
SARSA  (0) 2023.08.28
MNIST - TensorFlowLite  (0) 2023.07.19
MNIST - Keras  (0) 2023.07.19
MNIST - RandomForestClassifier  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

TensorFlow Lite는 구글이 개발한 TensorFlow의 경량 버전으로, 모바일 기기 및 임베디드 시스템에서 딥러닝 모델을 실행하기 위해 최적화된 라이브러리입니다. TensorFlow Lite는 딥러닝 모델의 크기와 성능을 최적화하여 모바일 기기에서도 효율적으로 동작할 수 있도록 합니다.

< TensorFlow Lite 특징 >

경량화: TensorFlow Lite는 모바일 기기와 임베디드 시스템의 제한된 자원을 고려하여 딥러닝 모델의 크기와 연산량을 최적화합니다. 이를 통해 모바일 환경에서도 효율적으로 모델을 실행할 수 있습니다.
하드웨어 가속: TensorFlow Lite는 하드웨어 가속을 지원하여 모바일 기기의 GPU, DSP 등을 활용하여 딥러닝 연산을 가속화할 수 있습니다. 이로 인해 모델의 추론 속도가 향상됩니다.
모바일 지원: TensorFlow Lite는 Android 및 iOS와 같은 주요 모바일 플랫폼에서 사용할 수 있도록 지원합니다. 또한, 임베디드 보드와 같은 다양한 장치에서도 실행 가능합니다.
모델 컨버터: TensorFlow Lite는 TensorFlow 모델을 TensorFlow Lite 모델로 변환하는 컨버터를 제공합니다. 이를 통해 기존에 훈련된 TensorFlow 모델을 모바일에서 실행 가능한 형식으로 변환할 수 있습니다.
지원되는 모델 형식: TensorFlow Lite는 다양한 모델 형식을 지원합니다. TensorFlow 모델을 변환하여 사용할 수 있으며, TensorFlow 모델 최적화 도구를 사용하여 모델 크기를 최소화할 수도 있습니다.
On-device 추론: TensorFlow Lite는 모바일 기기에서 모델을 로드하고 추론을 직접 수행할 수 있습니다. 이를 통해 모바일 애플리케이션에서 실시간으로 딥러닝 모델을 활용할 수 있습니다.
Custom 모델 지원: TensorFlow Lite는 사용자 정의 연산자를 지원하므로 사용자가 원하는 연산자를 직접 구현하고 모델에 통합할 수 있습니다.
TensorFlow Lite는 모바일 애플리케이션에서 딥러닝을 활용하고자 하는 개발자들에게 매우 유용한 도구이며, 경량화된 딥러닝 모델을 사용하여 모바일 기기에서 실시간 추론을 구현하는 데에 적합합니다. 또한, TensorFlow Lite는 TensorFlow와 통합되어 있어 TensorFlow에서 훈련한 모델을 간편하게 모바일 환경에서 실행할 수 있도록 지원합니다.

 

//
//  MNIST - TENSORFLOWLITE
//
//  Created by netcanis on 2023/07/20.
//

import tensorflow as tf
import dataset_loader
import model_tester


# Load MNIST data
training_images, training_labels, test_images, test_labels = dataset_loader.load_dataset("data/MNIST")

# Reshape the data
# 배열의 차원을 변경하여 크기를 자동으로 변경한다. (-1은 해당 차원의 크기를 자동으로 조정하라는 뜻)
training_images = training_images.reshape(-1, 28, 28, 1)
test_images = test_images.reshape(-1, 28, 28, 1)

# Print the image shapes
# reshape - Training Images shape: (60000, 28, 28, 1)
# reshape - Test Images shape: (10000, 28, 28, 1)
print("reshape - Training Images shape:", training_images.shape)
print("reshape - Test Images shape:", test_images.shape)

# Normalize the pixel values
training_images = training_images / 255.0
test_images = test_images / 255.0

# Assign images and labels to x_train, y_train, x_test, y_test
x_train, y_train = training_images, training_labels
x_test, y_test = test_images, test_labels




#
# TensorFlow Lite 모델 저장 (tflite)
#

# TensorFlow Keras model
keras_model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax') # 0~9 총 10개 클래스
])

# Train the model
keras_model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
keras_model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))

# Convert the model to TensorFlow Lite format
converter = tf.lite.TFLiteConverter.from_keras_model(keras_model)
tflite_model = converter.convert()

# Save the TensorFlow Lite model
with open('tflite_mnist_model.tflite', 'wb') as file:
    file.write(tflite_model)

print("Complete Save the TensorFlow Lite model.")




#
# TEST
#

model_file = "tflite_mnist_model.tflite"
model_tester.test_model("data/MNIST", model_file)

# Error rate: 1.44%

 

2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

SARSA  (0) 2023.08.28
Q-learning  (0) 2023.08.28
MNIST - Keras  (0) 2023.07.19
MNIST - RandomForestClassifier  (0) 2023.07.19
MINST - SVC(Support Vector Classifier)  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

Keras 모델 학습

Keras는 딥러닝 모델을 쉽게 구축하고 훈련할 수 있도록 설계된 오픈 소스 딥러닝 라이브러리입니다. François Chollet이 개발한 Keras는 사용자 친화적인 API를 제공하여 TensorFlow, Theano, CNTK 등의 백엔드 엔진에서 실행할 수 있습니다. 하지만 2019년 9월 기준으로 TensorFlow 2.0부터는 Keras가 TensorFlow의 공식 고수준 API로 통합되어 TensorFlow의 일부가 되었습니다.

 

< Keras 특징 >

사용자 친화적인 API: Keras는 직관적이고 간결한 API를 제공하여 신경망 모델을 쉽게 설계할 수 있도록 도와줍니다. 따라서 딥러닝 경험이 적은 사용자도 비교적 쉽게 모델을 구축하고 수정할 수 있습니다.
모듈화: Keras는 레이어, 손실 함수, 최적화 알고리즘 등을 모듈화하여 개별 구성 요소들을 조합하여 모델을 구축할 수 있도록 합니다. 이를 통해 모델의 재사용성이 높아집니다.
다양한 백엔드 지원: Keras는 다양한 딥러닝 백엔드 엔진을 지원합니다. 초기에는 Theano와 TensorFlow를 지원했으며, 현재는 TensorFlow가 공식 백엔드로 사용되고 있습니다.
모듈화된 구조: Keras는 레이어로 구성된 모델을 생성하는 함수형 API와 순차적으로 레이어를 쌓는 Sequential API를 제공합니다. 이를 통해 간단한 모델에서부터 복잡한 모델까지 다양한 구조의 신경망을 쉽게 만들 수 있습니다.
커뮤니티와 생태계: Keras는 활발한 커뮤니티와 풍부한 생태계를 갖추고 있습니다. 이로 인해 다양한 확장 기능, 사전 훈련된 모델, 유틸리티 등을 쉽게 활용할 수 있습니다.
분산 훈련 및 모델 배포: Keras는 TensorFlow를 백엔드로 사용하기 때문에 TensorFlow의 기능을 활용하여 분산 훈련과 모델 배포를 지원합니다.
가벼운 라이브러리: Keras는 간단하고 가벼운 딥러닝 라이브러리이기 때문에 처음 딥러닝을 배우는 데 적합하며, 초보자와 중급 사용자 모두에게 추천됩니다.
Keras는 이러한 특징들로 인해 딥러닝 모델 개발에 있어서 많은 사용자들에게 인기가 있으며, 다양한 응용 분야에서 활용되고 있습니다. TensorFlow를 기반으로 하기 때문에 TensorFlow와의 호환성이 뛰어난 것도 Keras의 장점 중 하나입니다.


//
//  MNIST - KERAS
//
//  Created by netcanis on 2023/07/20.
//

import numpy as np
import tensorflow as tf
import dataset_loader
import model_tester

from keras.models import load_model


# Load MNIST data
training_images, training_labels, test_images, test_labels = dataset_loader.load_dataset("data/MNIST")

# Reshape the data
# 배열의 차원을 변경하여 크기를 자동으로 변경한다. (-1은 해당 차원의 크기를 자동으로 조정하라는 뜻)
training_images = training_images.reshape(-1, 28, 28, 1)
test_images = test_images.reshape(-1, 28, 28, 1)

# Print the image shapes
# reshape - Training Images shape: (60000, 28, 28, 1)
# reshape - Test Images shape: (10000, 28, 28, 1)
print("reshape - Training Images shape:", training_images.shape)
print("reshape - Test Images shape:", test_images.shape)

# Normalize the pixel values
training_images = training_images / 255.0
test_images = test_images / 255.0

# Assign images and labels to x_train, y_train, x_test, y_test
x_train, y_train = training_images, training_labels
x_test, y_test = test_images, test_labels




#
# Keras model 파일(keras) 저장
#

# TensorFlow Keras model
keras_model = tf.keras.Sequential([
    tf.keras.layers.Reshape(target_shape=(28, 28) + (1,), input_shape=(28, 28)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax') # 0~9 총 10개 클래스
])

# Train the model
keras_model.compile(optimizer='adam', 
                    loss='sparse_categorical_crossentropy', 
                    metrics=['accuracy'])
keras_model.fit(x_train, y_train, epochs=5, batch_size=32, validation_data=(x_test, y_test))

# Save the Keras model
keras_model.save('keras_mnist_model.h5')

print("Complete Save the Keras model.")




#
# TEST
#

model_file = "keras_mnist_model.h5"
model_tester.test_model("data/MNIST", model_file)

# Error rate: 2.26%

 

2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

Q-learning  (0) 2023.08.28
MNIST - TensorFlowLite  (0) 2023.07.19
MNIST - RandomForestClassifier  (0) 2023.07.19
MINST - SVC(Support Vector Classifier)  (0) 2023.07.19
MNIST 모델 테스터  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

이번에는 RandomForestClassifier 모델로 학습해 보았다.

 

RandomForestClassifier는 앙상블 학습(Ensemble Learning) 기법 중 하나인 랜덤 포레스트(Random Forest)를 구현한 분류(Classification) 모델입니다. 
랜덤 포레스트는 여러 개의 의사결정 트리(Decision Tree)를 결합하여 강력한 예측 모델을 만드는 알고리즘입니다.

< 랜덤 포레스트 특징 >

앙상블 학습: 랜덤 포레스트는 여러 개의 의사결정 트리를 동시에 학습하고 이들의 예측 결과를 결합하여 최종 예측을 수행합니다. 이렇게 여러 개의 모델을 결합하는 앙상블 학습은 일반적으로 단일 모델보다 더욱 강력한 예측 성능을 제공합니다.
의사결정 트리: 랜덤 포레스트의 기본 모델로 사용되는 의사결정 트리는 데이터의 특성을 기반으로 하여 분류 작업을 수행하는 모델입니다. 의사결정 트리는 특정 기준에 따라 데이터를 분할하여 예측을 수행하는 방식으로 동작합니다.
랜덤성: 랜덤 포레스트는 의사결정 트리 학습 시에 랜덤성을 도입합니다. 이는 데이터의 일부 특성을 임의로 선택하거나 데이터를 부트스트랩 샘플링하는 등의 방법으로 랜덤성을 추가함으로써 모델의 다양성을 높입니다. 이는 과적합(Overfitting)을 방지하고 모델의 일반화 성능을 향상시킵니다.
랜덤 포레스트는 다양한 분야에서 활용되며, 데이터 분류, 패턴 인식, 텍스트 분석, 이미지 분류 등 다양한 문제에 적용될 수 있습니다. 또한, 특성 중요도를 제공하여 어떤 특성이 예측에 가장 중요한 역할을 하는지를 확인할 수도 있습니다.

 

//
//  MNIST - RANDOMFORESTCLASSIFIER
//
//  Created by netcanis on 2023/07/20.
//

import cv2
import os
import numpy as np
import pickle
import dataset_loader
import model_tester

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC


# Load MNIST data
training_images, training_labels, test_images, test_labels = dataset_loader.load_dataset("data/MNIST")

# Reshape the data
# 배열의 차원을 변경하여 크기를 자동으로 변경한다. (-1은 해당 차원의 크기를 자동으로 조정하라는 뜻)
training_images = np.reshape(training_images, (len(training_images), -1))
test_images = np.reshape(test_images, (len(test_images), -1))

# Print the image shapes
# reshape - Training Images shape: (60000, 784)
# reshape - Test Images shape: (10000, 784)
print("reshape - Training Images shape:", training_images.shape)
print("reshape - Test Images shape:", test_images.shape)
 
# Assign images and labels to x_train, y_train, x_test, y_test
x_train, y_train = training_images, training_labels
x_test, y_test = test_images, test_labels




#
# RandomForestClassifier 파일 저장.
#

# Train the model
model = RandomForestClassifier()
model.fit(x_train, y_train)

# Evaluate the model
score = model.score(x_test, y_test)
print('Accuracy:', score)

# Save the pkl model
with open("rfc_mnist_model.pkl", "wb") as file:
    pickle.dump(model, file)

print("Save the rfc_mnist_model.pkl.")




#
# TEST
#

model_file = "rfc_mnist_model.pkl"
model_tester.test_model("data/MNIST", model_file)

# Error rate: 3.09%

 

2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

MNIST - TensorFlowLite  (0) 2023.07.19
MNIST - Keras  (0) 2023.07.19
MINST - SVC(Support Vector Classifier)  (0) 2023.07.19
MNIST 모델 테스터  (0) 2023.07.19
MNIST 데이터셋 로더  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

MNIST 이미지 셋 파일들을 이용하여  SVC 모델로 학습을 시켜보았다.

SVC(Support Vector Classifier)는 SVM(Support Vector Machine) 알고리즘을 기반으로 한 분류(Classification) 모델입니다. 
서포트 벡터 머신은 지도 학습(Supervised Learning)에서 주로 사용되며, 데이터를 분류하는 경계를 찾는 데에 특화되어 있습니다.

< SVC 특징 >

최대 마진 분류: SVC는 데이터를 분류하는 결정 경계를 찾을 때, 가능한 한 최대 마진(Margin)을 가지도록 합니다. 
마진은 결정 경계와 가장 가까운 데이터 샘플들 간의 거리를 의미하며, 이를 최대화함으로써 일반화 성능을 향상시킬 수 있습니다.
커널 기법: SVC는 비선형적인 데이터를 처리하기 위해 커널(Kernel) 기법을 사용합니다. 
커널은 데이터를 고차원 특징 공간으로 매핑하여 선형적으로 분리할 수 있도록 합니다. 
대표적인 커널 함수로는 선형 커널, 다항식 커널, 가우시안(RBF) 커널 등이 있습니다.
서포트 벡터: SVC는 분류 결정 경계에 가장 가까이 위치한 데이터 샘플들을 서포트 벡터(Support Vector)라고 부릅니다. 
이들 데이터 샘플들은 분류 결정에 영향을 미치는 주요한 역할을 합니다. 
SVC는 이 서포트 벡터들을 효율적으로 찾아내어 분류를 수행합니다.
SVC는 이진 분류(Binary Classification)와 다중 클래스 분류(Multi-Class Classification) 문제에 모두 사용될 수 있습니다. 
또한, SVM은 분류 뿐만 아니라 회귀(Regression), 이상치 탐지(Outlier Detection), 
차원 축소(Dimensionality Reduction) 등 다양한 문제에도 적용될 수 있습니다.

//
//  MINST - SVC(SUPPORT VECTOR CLASSIFIER)
//
//  Created by netcanis on 2023/07/20.
//

import numpy as np
import pickle
import dataset_loader
import model_tester

from sklearn.model_selection import train_test_split
from sklearn.svm import SVC


# Load MNIST data
training_images, training_labels, test_images, test_labels = dataset_loader.load_dataset("data/MNIST")

# Reshape the data
# 배열의 차원을 변경하여 크기를 자동으로 변경한다. (-1은 해당 차원의 크기를 자동으로 조정하라는 뜻)
training_images = np.reshape(training_images, (len(training_images), -1))
test_images = np.reshape(test_images, (len(test_images), -1))

# Print the image shapes
# reshape - Training Images shape: (60000, 784)
# reshape - Test Images shape: (10000, 784)
print("reshape - Training Images shape:", training_images.shape)
print("reshape - Test Images shape:", test_images.shape)
 
# Assign images and labels to x_train, y_train, x_test, y_test
x_train, y_train = training_images, training_labels
x_test, y_test = test_images, test_labels




#
# SVC(Support Vector Classifier) 파일 저장.
#

print("Training in progress... Please wait.")

# Train the model
# 'verbose=True'를 설정하여 진행상태 로그 출력.
model = SVC(verbose=True)
model.fit(x_train, y_train)

# Evaluate the model
score = model.score(x_test, y_test)
print('Accuracy:', score)

# Save the model (Support Vector Machines)
with open("svm_mnist_model.pkl", "wb") as file:
    pickle.dump(model, file)
    
print("Save the vm_mnist_model.pkl.")




#
# TEST
#

model_file = "svm_mnist_model.pkl"
model_tester.test_model("data/MNIST", model_file)

# Error rate: 2.08%

 


2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

MNIST - Keras  (0) 2023.07.19
MNIST - RandomForestClassifier  (0) 2023.07.19
MNIST 모델 테스터  (0) 2023.07.19
MNIST 데이터셋 로더  (0) 2023.07.19
MNIST 데이터셋을 이미지 파일로 복원  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

MNIST 모델을 머신러닝을 통해 학습하여 모델 파일을

저장하게 되는데 이 모델파일에 대한 테스트를 진행 하고자

테스터 함수를 만들게 되었다.

이 함수는 test_set 폴더에 있는 이미지들을 이용하여

테스트를 진행하고  error rate를 계산하여 출력해 보았다.

 

//
//  MNIST 모델 테스터
//
//  Created by netcanis on 2023/07/20.
//

import cv2
import os
import numpy as np
import pickle
import tensorflow as tf
from keras.models import load_model


def test_model(path, model_file):
    print("Testing in progress...")
    
    # 데이터셋 경로
    test_set_path = os.path.join(path, 'test_set')
    
    total_samples = 0
    error_count = 0
    
    # Load the model from file
    with open(model_file, "rb") as file:
        if model_file.endswith('.h5'):
            loaded_model = load_model(model_file)
        elif model_file.endswith('.tflite'):
            interpreter = tf.lite.Interpreter(model_path = model_file)
            interpreter.allocate_tensors()
            # Get the input and output details
            input_details = interpreter.get_input_details()
            output_details = interpreter.get_output_details()
        else:
            loaded_model = pickle.load(file)
        
        
    # Load the images from the test set
    for digit_folder in os.listdir(test_set_path):
        if os.path.isdir(os.path.join(test_set_path, digit_folder)):
            label = int(digit_folder)
            for index, image_file in enumerate(os.listdir(os.path.join(test_set_path, digit_folder))):
                if image_file.endswith('.png') or image_file.endswith('.jpg'):

                    image = cv2.imread(os.path.join(test_set_path, digit_folder, image_file))
                    if path.endswith('/credit_card'):
                        image = cv2.resize(image, (32, 32))
                    else: # '/MNIST'
                        image = cv2.resize(image, (28, 28))

                    # Convert color image to grayscale if necessary
                    if image.shape[2] > 1:
                        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                            
                    if model_file.endswith('.h5'):
                        image = image.reshape(1, 28, 28, 1) # 배열을 4차원으로 변경.
                        image = image / 255.0
                        # Predict the label for the image
                        predicted_label = loaded_model.predict(image)
                        # Get the predicted class
                        predicted_class = np.argmax(predicted_label)
                    elif model_file.endswith('.tflite'):
                        image = np.expand_dims(image, axis=0)  # Add batch dimension
                        image = np.expand_dims(image, axis=3)  # Add channel dimension
                        image = image.astype(np.float32) / 255.0
                        # Set the input tensor
                        interpreter.set_tensor(input_details[0]['index'], image)
                        # Run the inference
                        interpreter.invoke()
                        # Get the output tensor
                        output_tensor = interpreter.get_tensor(output_details[0]['index'])
                        # Get the predicted class
                        predicted_class = np.argmax(output_tensor)
                    else: # SVM, RandomForestClassifier ('.pkl')                       
                        # Reshape the data
                        image = image.reshape(1, -1)
                        # Predict the label for the image
                        predicted_label = loaded_model.predict(image)
                        # Get the predicted class
                        predicted_class = predicted_label[0]
                    
                    # error 
                    if predicted_class != label:
                        error_count += 1
                        print(f"Prediction for {index} - {label}: {predicted_class}")
                    
                    total_samples += 1


    # Print error rate
    error_rate = (error_count / total_samples) * 100
    print(f"Error rate: {error_rate:.2f}%")

 

사용 방법은 다음과 같다.

import mnist_model_tester

model_file = "svm_mnist_model.pkl"
mnist_model_tester.test_mnist_model("data/MNIST", model_file)

or

from mnist_model_tester import test_mnist_model

model_file = "svm_mnist_model.pkl"
test_mnist_model("data/MNIST", model_file)

 

2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

MNIST - RandomForestClassifier  (0) 2023.07.19
MINST - SVC(Support Vector Classifier)  (0) 2023.07.19
MNIST 데이터셋 로더  (0) 2023.07.19
MNIST 데이터셋을 이미지 파일로 복원  (0) 2023.07.19
MNIST 데이터셋 다운로드  (0) 2023.07.19
블로그 이미지

SKY STORY

,
반응형

이후 구현할 머신러닝 모델 구현을 위해 데이터 셋 로더 함수를 만들어 보았다.
이 함수는 데이터 셋 이미지들(트레이닝, 테스트)을 로딩하여 이미지, 라벨(해당 이미지 숫자) 리스트를 반환하도록 만들어 보았다.

//
//  MNIST 데이터셋 로더
//
//  Created by netcanis on 2023/07/20.
//


import cv2
import os
import numpy as np

#='data/MNIST'
def load_dataset(path):
    # 데이터셋 경로
    training_set_path = os.path.join(path, 'training_set')
    test_set_path = os.path.join(path, 'test_set')
    
    # Load the images from the training set
    training_images = []
    training_labels = []
    for digit_folder in os.listdir(training_set_path):
        if os.path.isdir(os.path.join(training_set_path, digit_folder)):
            label = int(digit_folder)
            for index, image_file in enumerate(os.listdir(os.path.join(training_set_path, digit_folder))):
                if image_file.endswith('.png') or image_file.endswith('.jpg'):
                    image = cv2.imread(os.path.join(training_set_path, digit_folder, image_file))
                    image = cv2.resize(image, (28, 28))

                    # Convert color image to grayscale if necessary
                    if image.shape[2] > 1:
                        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

                    # Print image path
                    print(str(index).zfill(5) + " " + os.path.join(training_set_path, digit_folder, image_file))

                    training_images.append(image)
                    training_labels.append(label)

    # Load the images from the test set
    test_images = []
    test_labels = []
    for digit_folder in os.listdir(test_set_path):
        if os.path.isdir(os.path.join(test_set_path, digit_folder)):
            label = int(digit_folder)
            for index, image_file in enumerate(os.listdir(os.path.join(test_set_path, digit_folder))):
                if image_file.endswith('.png') or image_file.endswith('.jpg'):
                    image = cv2.imread(os.path.join(test_set_path, digit_folder, image_file))
                    image = cv2.resize(image, (28, 28))

                    # Convert color image to grayscale if necessary
                    if image.shape[2] > 1:
                        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

                    # Print image path
                    print(str(index).zfill(5) + " " + os.path.join(test_set_path, digit_folder, image_file))

                    test_images.append(image)
                    test_labels.append(label)

    # Convert lists to numpy arrays
    training_images = np.array(training_images)
    training_labels = np.array(training_labels)
    test_images = np.array(test_images)
    test_labels = np.array(test_labels)

    # Print the image shapes
    # Training Images shape: (60000, 28, 28) or (20000, 32, 32)
    # Test Images shape: (10000, 28, 28) or (4000, 32, 32)
    print("Training Images shape:", training_images.shape)
    print("Test Images shape:", test_images.shape)

    return training_images, training_labels, test_images, test_labels

 
 
2023.07.19 - [AI] - MNIST 데이터셋 다운로드

2023.07.19 - [AI] - MNIST 데이터셋을 이미지 파일로 복원

2023.07.19 - [AI] - MNIST 데이터셋 로더

2023.07.19 - [AI] - MNIST 모델 테스터

2023.07.19 - [AI] - MINST - SVC(Support Vector Classifier)

2023.07.19 - [AI] - MNIST - RandomForestClassifier

2023.07.19 - [AI] - MNIST - Keras

2023.07.19 - [AI] - MNIST - TensorFlowLite

 

 


 
 
 
 

반응형

'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글

MINST - SVC(Support Vector Classifier)  (0) 2023.07.19
MNIST 모델 테스터  (0) 2023.07.19
MNIST 데이터셋을 이미지 파일로 복원  (0) 2023.07.19
MNIST 데이터셋 다운로드  (0) 2023.07.19
Neural Network (XOR)  (0) 2022.11.18
블로그 이미지

SKY STORY

,