서른두번째 수업 | 인공신경망

Faithful Dev·2024년 10월 30일
0

정종현 강사님

인공신경망

인공지능 개요

인간의 지적 능력을 컴퓨터에서 구현하는 기술로 고도의 문제 해결 능력을 지닌 인공적인 지능. AI는 인간의 학습능력, 추론능력, 지각능력 등을 컴퓨터 과학을 통해 구현하려는 목표를 가지고 있고, 데이터 분석, 추론, 예측, 분류, 자연어 처리, 추천 시스템 등에 널리 사용된다.

머신러닝 개요

주어진 데이터에서 규칙을 학습하여 새로운 데이터에 대해 예측하는 데이터 과학의 한 분야. 기존의 프로그래밍 방식과 달리 머신러닝은 명시적 지시가 아닌 데이터 기반 학습을 통해 패턴을 찾고 작업을 수행한다.

머신러닝 유형

지도 학습(Supervised Learning)

정답 데이터(라벨)가 포함된 데이터 세트를 사용하여 학습하는 방식. 모델은 입력과 출력 간의 관계를 학습하여 주어진 데이터에 대한 예측을 수행할 수 있다.

  • 회귀(Regression)
  • 분류(Classification)

비지도 학습(Unsupervised Learning)

정답 데이터 없이 주어진 데이터의 패턴이나 구조를 학습하는 방식. 모델은 입력 데이터의 특징을 바탕으로 비슷한 항목을 그룹화하거나 패턴을 파악할 수 있다.

  • 군집화(Clustering)

분류모델 개요

주어진 데이터를 모델에 적용해 미리 정의된 범주(카테고리) 중 하나로 분류하는 알고리즘. 분류 알고리즘은 지도 학습 방식의 한 유형으로 입력 데이터에 대한 정답(라벨)이 주어져 있으며 이를 통해 학습한 모델은 새로운 데이터에 대해 적합한 범주를 예측할 수 있다.

분류 유형

  • 이진 분류(Binary Classification): 두 가지 범주로 데이터를 분류하는 방법.
  • 다중 클래스 분류(Multi-Class Classification): 셋 이상의 범주로 데이터를 분류하는 방식.

대표적 알고리즘

  • 서포트 벡터 머신(SVM): 데이터를 분류하기 위해 최적의 경계선을 찾는 알고리즘.
  • 의사 결정 나무(Decision Tree): 데이터를 분류하기 위해 조건을 따라 여러 가지로 나누며 트리 형태로 구성된다.
  • 로지스틱 회귀(Logistic Regression): 데이터를 특정 범주로 분류하는 데 적합한 확률 기반의 회귀 분석 기법.

머신러닝 용어 및 단계

머신러닝 기본 용어

  • 데이터 세트: 분석이나 학습을 위해 준비된 전체 데이터.
  • 데이터 샘플: 데이터 세트 내의 개별 데이터 항목.
  • 데이터 서브셋: 데이터 세트의 일부로, 학습이나 검증 등의 목적을 위해 분리된 부분.
  • 특성(Feature): 데이터가 가진 개별적인 속성이나 특징. 머신러닝 모델이 학습에 사용할 입력 변수. 데이터 표 형식에서는 열(column)에 해당한다.
  • 정답(Label): 예측하고자 하는 목표 데이터. 학습 시 모델이 예측할 값.
  • 범주(Class): 분류 문제에서 예측하고자 하는 각 범주의 유형.

머신러닝 5단계 절차

  1. 문제 정의: 해결하고자 하는 비즈니스 목표를 명확히 하고 이를 위한 환경과 상황을 분석한다.
  2. 데이터 수집 및 이해: 문제 해결에 필요한 데이터를 수집하고 수집한 데이터를 이해하며 필요한 경우 라벨링을 진행한다.
  3. 데이터 준비: 수집된 데이터를 모델 학습에 적합하도록 전처리하고 학습용과 테스트용으로 분리한다.
  4. 데이터 모델링: 적합한 머신러닝 알고리즘을 선택하여 모델을 학습시키고 필요 시 조정한다.
  5. 모델링 평가: 학습된 모델의 성능을 테스트 데이터로 평가하여 결과를 분석한다.

Azure Machine Learning Designer 입/출력 처리

엔드포인트(Endpoint)

모델을 배포하고 사용할 수 있는 네트워크 접근점(URL). 엔드포인트는 모델 예측을 위한 요청을 받을 수 있는 안정적이고 내구성 있는 URL을 제공한다.

  • 하드웨어 엔드포인트: 물리적인 네트워크 장치를 통해 기기 간 통신을 가능하게 하는 장치.
  • 소프트웨어 엔드포인트: 애플리케이션 또는 서비스가 데이터를 주고받는 특정 URL이나 네트워크 주소로, 웹 API의 경우 특정 데이터에 접근할 수 있는 경로나 URL을 의미한다.

데이터분석/인공지능 모델을 위한 웹화면 구성

웹 GUI 구성 필요성

데이터 분석 및 인공지능 모델을 CLI(명령어 인터페이스)뿐 아니라 웹 기반 GUI로 제공하면 사용 편의성이 크게 향상된다. 특히 데이터 입력과 결과 확인 과정을 시각적으로 제공해 사용자와의 상호작용성을 높일 수 있다.

웹 프레임워크의 장점

  • 효율성: 반복되는 코드를 줄이고, 웹 개발을 구조화된 방식으로 단순화하여 개발 속도를 높인다.
  • 보안: 보안 기능이 내장되어 있어 SQL 인젝션 및 XSS와 같은 웹 취약점을 방지할 수 있다.
  • 확장성: 사용자 수요 증가에 따라 애플리케이션 확장이 용이하다.
  • 유지 관리 용이성: 표준화된 구조로 인해 코드의 유지보수와 업데이트가 용이하다.
  • 커뮤니티 지원: 인기 있는 프레임워크는 광범위한 문서, 튜토리얼, 다양한 타사 플러그인 등을 제공한다.

Python 웹 프레임워크 예시

  • Django, Flask는 Python 기반 대표적인 웹 프레임워크이다. Django는 기능이 풍부하고 대규모 프로젝트에 적합하며 Flask는 가벼워서 소규모부터 중간 규모 프로젝트에 적합하다.

Gradio

라이브러리 임포트

import json
import gradio as gr
import requests
import matplotlib.pyplot as plt

request_iris_prediction 함수

def request_iris_prediction(data_list):
    endpoint = "~"
    headers = {
        "Authorization": "Bearer ~"
    }

    body = {
        "Inputs": {
            "input1": data_list
        }
    }

    response = requests.post(endpoint, headers=headers, json=body)
    
    if response.status_code == 200:
        response_json = response.json()
        return response_json["Results"]["WebServiceOutput0"]
    else:
        return list()
  • endpoint: Azure Machine Learning의 엔드포인트 URL. API 요청이 이 URL로 전송된다.
  • headers: 요청의 인증 정보를 포함한다.
    - Authorisation 헤더에 Bearer 토큰 방식으로 API 키를 전달해 인증을 수행한다.
  • body: 예측 요청에 필요한 입력 데이터를 JSON 형식으로 준비한다.
    - data_list: 함수에 전달된 입력 데이터로 'Inputs''input1' 키에 배치된다.
  • requests.post: POST 요청을 전송하고 엔드포인트에서 예측 결과를 수신한다.
    - 200: 요청이 성공하면 JSON 형식의 응답을 파싱해 'Results' 필드에서 'WebServiceOutput0'의 값을 추출해 반환한다.
    • 오류가 발생하면 빈 리스트를 반환한다.

save_plot 함수

def save_plot(data_points):
    centroid_positions = {0: [0, 0], 1: [0, 0], 2: [0, 0]}
    centroid_colors = {0: 'b', 1: 'r', 2: 'g'}
  • centroid_poisitions: 클러스터 중심 위치를 저장하기 위한 딕셔너리. 3개의 클러스터(0, 1, 2)의 평균 위치를 저장한다.
  • centroid_colors: 각 클러스터의 색상을 지정. 0번 클러스터는 파란색('b'), 1번은 빨간색('r'), 2번은 초록색('g').
# 데이터 포인트 기반으로 클러스터 중심 계산
    for point in data_points:
        assignment = point["Assignments"]
        for i in range(3):
            dist_key = f"DistancesToClusterCenter no.{i}"
            if dist_key in point:
                centroid_positions[i][0] += (point["sepal_length"] + point[dist_key]) / 2
                centroid_positions[i][1] += (point["sepal_width"] + point[dist_key]) / 2
  • for point in data_points: 각 데이터 포인트를 순회하며 해당 포인트의 Assignments 값에 따라 클러스터 번호를 확인한다.
  • dist_key = f'DistancesToClusterCenter no.{i}: DistancesToClusterCenter no.{i} 키가 있는지 확인하고 있으면 클러스터 중심 좌표를 업데이트한다.
  • centoriod_positions[i][n]: 중심 위치에 sepal_lengthsepal_width 값들을 더해 평균을 구하기 위한 준비 작업.
# 클러스터 중심 위치의 최종 평균 계산
    for i in range(3):
        centroid_positions[i][0] /= len(data_points)
        centroid_positions[i][1] /= len(data_points)
  • 각 클러스터 중심 위치 값을 데이터 포인트 수로 나눠 최종적으로 평균 위치를 계산한다.
# 데이터 포인트 및 클러스터 중심 시각화
    plt.figure(figsize=(8, 6))
    
    point_index = 0
    for point in data_points:
        point_index += 1
        plt.scatter(point["sepal_length"], point["sepal_width"],
                    c='b' if point["Assignments"] == 0 else 'r' if point["Assignments"] == 1 else 'g')
        plt.text(point["sepal_length"], point["sepal_width"], f"{point_index}")
  • plt.scatter(~): sepal_lengthsepal_width를 x축과 y축 값으로 사용해 각 데이터 포인트를 해당 클러스터 색상으로 표시한다.
  • plt.text(~): 각 데이터 포인트의 좌표 옆에 인덱스를 표시하여 식별이 가능하게 한다.
# 클러스터 중심 시각화
    for cluster, (x, y) in centroid_positions.items():
        plt.scatter(x, y, c=centroid_colors[cluster], marker='X', s=200)
  • 각 클러스터 중심을 x 마커로 표시하고 중심 위치를 지정한 색상으로 그린다.
# 플롯 설정 및 저장
    plt.title('Data Points and Cluster Centroids')
    plt.xlabel('Sepal Length (cm)')
    plt.ylabel('Sepal Width (cm)')
    plt.grid()
    plt.savefig('iris_clusters.png')
    plt.close()
    return 'iris_clusters.png'

Gradio 인터페이스 설정 및 레이아웃 구성

with gr.Blocks() as demo:
    view_count = gr.State(1)
    data_dict = dict()
  • with gr.Blocks(): Gradio 블록 레이아웃을 정의해 UI 컴포넌트를 구성한다.
  • view_count: 현재 입력 필드 개수를 저장하는 Gradio 상태 변수. 필드 추가 및 삭제 시 상태가 업데이트된다.
  • data_dict: 입력 데이터를 저장하는 딕셔너리로 각 입력 필드에 입력된 데이터를 저장한다.
    def click_add(count):
        count += 1
        print(count)
        return count
  • 필드 추가 버튼 클릭 시 호출되며count 값을 증가시켜 새로운 필드의 추가를 트리거한다.
    def click_delete(count):
        if count > 1:
            count -= 1
        print(count)
        return count
  • 필드 삭제 버튼 클릭 시 호출되며 최소 1개 이상의 필드가 남도록 count 값을 감소시킨다.
  • 필드 개수가 1보다 클때만 감소할 수 있도록 제한한다.
    def click_send():
        data_list = list(data_dict.values())
        response_data = request_iris_prediction(data_list=data_list)
        save_plot(response_data)
        return response_data, "iris_clusters.png"
  • 전송 버튼 클릭 시 호출된다. 저장된 데이터 딕셔너리(data_dict)에서 값을 추출해 모델에 전달한다.
    - data_list = list(data_dict.values()): data_dict의 값들을 리스트로 변환하여 예측 함수에 전달할 준비를 한다.
  • request_iris_prediction 함수에 data_list를 전달해 Azure Machine Learning 모델에서 예측 결과를 받는다.
  • save_plot 함수로 예측 결과를 시각화 해 파일로 저장한다.
    def change_data(i, sl, sw, pl, pw):
        data_dict.update({
            i: {
                "sepal_length": sl,
                "sepal_width": sw,
                "petal_length": pl,
                "petal_width": pw,
                "class": "unknown"
            }
        })
        print(data_dict)
  • 각 입력 필드가 변경될 때마다 호출되어 data_dict에 값을 업데이트한다.
  • i: 각 입력 필드의 인덱스.

Gradio 인터페이스 컴포넌트 구성

    gr.Markdown("# 붓꽃 예측")
  • gr.Markdown: 페이지 상단에 제목 # 붓꽃 예측을 마크다운 형식으로 추가하여 UI의 헤더를 만든다.
# 필드 추가 및 삭제 버튼
    with gr.Row():
        add_button = gr.Button("+")
        delete_button = gr.Button("-")
  • gr.Row(): UI 상에서 +- 버튼을 한 줄에 배치한다.
  • add_button: + 버튼. 필드를 추가하기 위한 버튼이다.
  • delete_button: - 버튼. 필드를 삭제하기 위한 버튼이다.
  • 버튼 클릭 시 각각의 이벤트(click_add, click_delete)가 호출되어 필드 수를 조정한다.
# 데이터 입력 필드 구성
    with gr.Column():
        @gr.render(inputs=[view_count])
        def render_input_components(count):
            for i in range(0, count):
                with gr.Column():
                    gr.Markdown(f"Index: {i}")
                    row_index = gr.State(i)
                    with gr.Row():
                        sepal_length_number = gr.Number(label="꽃받침 길이", key=f"sepal-length-{i}", value="")
                        sepal_width_number = gr.Number(label="꽃받침 너비", key=f"sepal-width-{i}", value="")
                        petal_length_number = gr.Number(label="꽃잎 길이", key=f"petal-length-{i}", value="")
                        petal_width_number = gr.Number(label="꽃잎 너비", key=f"petal-width-{i}", value="")
  • @gr.render(inputs=[view_count]): view_count를 기반으로 입력 필드의 개수를 렌더링한다.
  • for i in range(0, count): count 값만큼 반복하여 각 입력 필드 세트를 렌더링한다.
    - gr.Markdown(f'Index: {i}'): 각 필드 세트 위에 Index: {i}를 마크다운 형식으로 표시해 사용자에게 필드 번호를 알려준다.
    • gr.State(i): 각 필드 세트의 고유 인덱스 i를 상태로 저장하여 필드 값을 고유하게 식별할 수 있도록 한다.
    • sepal_length_number, sepal_width_number, petal_length_number, petal_width_number: 각각의 특징(길이와 너비)에 대한 값을 입력 받는 gr.Number 필드.
    • key: 필드의 고유 식별자로 설정하여 필드를 동적으로 관리할 수 있게 한다.
# `change` 이벤트 설정
                        sepal_length_number.change(fn=change_data, inputs=[row_index, 
                            sepal_length_number, sepal_width_number, petal_length_number, petal_width_number],
                            outputs=[])
                        # 나머지 필드도 동일하게 설정.
  • change: 각 입력 필드의 값이 변경될 때마다 change_data 함수가 호출된다.
  • row_index, sepal_length_number, sepal_width_number, petal_length_number, petal_width_number 값을 전달해 data_dict에 업데이트.
  • outputs=[]: 출력을 반환하지 않으므로 빈 리스트로 설정된다.

결과 출력 설정

    result_textbox = gr.Textbox(label="결과")
    result_image = gr.Image(label="결과 이미지", type="filepath")
    send_button = gr.Button("전송")
  • result_textbox: 예측 결과를 텍스트로 표시하기 위한 gr.Textbox 컴포넌트.
  • reulst_image: 예측 결과를 시각화하기 위한 gr.Image 컴포넌트.
  • send_button: 사용자가 모든 입력을 마치고 예측을 요청할 때 클릭하는 전송 버튼.
# 버튼 클릭 이벤트 연결
    add_button.click(fn=click_add, inputs=[view_count], outputs=[view_count])
    delete_button.click(fn=click_delete, inputs=[view_count], outputs=[view_count])
    send_button.click(fn=click_send, inputs=[], outputs=[result_textbox, result_image])
  • add_button.click
    - fn=clilck_add: click_add 함수가 호출된다. 이 함수는 view_count를 1 증가시켜 필드를 추가한다.
    • inputs=[view_count]: 현재 입력 필드의 개수를 나타내는 view_count를 전달한다.
    • outputs=[view_count]: 필드 개수 변경 후 업데이트된 view_count가 UI에 반영된다.
  • send_button.click
    - outputs=[result_textbox, result_image]: 예측된결과가 텍스트(result_textbox)와 이미지(result_image)로 반환된다.

Gradio 실행

demo.launch(debug=True)
  • demo.launch()
    - demo로 정의된 Gradio 블록 전체를 실행하여 브라우저에서 접근할 수 있는 웹 애플리케이션으로 띄운다.
  • debug=True: 앱 실행 중 발생하는 오류나 상세 로그를 콘솔에 표시하여 개발자가 쉽게 디버깅할 수 있도록 한다.
profile
Turning Vision into Reality.

0개의 댓글