2023년 4월 30일 일요일

인공지능 미디어아트 워크샵을 위한 생성AI 도구, 자료, 튜토리얼 소개, 총정리

이 글은 인공지능 기반 미디어아트 워크샵에 필요한 유명한 생성AI 도구들을 소개합니다. 요즘 인공지능, 특히, 딥러닝 기술술을 이용한 생성AI등 유용한 프로그램이 많아지고 있습니다. 이 중에 무료로 편리하게 사용할 수 있는 도구들을 중심으로 관련 자료, 튜토리얼을 소개합니다.

How to make movie with AI (스크립트 생성 ChatGPT, 이미지 생성AI Midjourney, 입모양 맞춤 Eleven Labs, 동영상 생성AI D-ID)

생성 AI 도구

지금은 이미지, 텍스트, 음성, 영상 등을 프롬프트만 입력해 인공지능이 생성해준다. 시간과 노력이 있으면, 요즘 혼자서 웬만한 SF영화는 만들 수 있다. 생성 AI 동작 개념에 대해 궁금하다면, 아래 링크 참고바란다(단, 몰라도 사용에 큰 문제는 없다).

Stable Diffusion 와 ControlNet

스테이블 디퓨전은 원하는 이미지를 프롬프트로 잘 조정해 원하는 이미지를 얻는 딥러닝 기술이다. 컨트롤넷은 스테이블 디퓨전에 스타일을 편리하게 조정할 수 있도록 한 기술이다. 이 도구는 생성 AI 핵심 기술로 사용된다. 실제로는 보통 ComfyUI같은 편리하게 만든 프로그램을 이용한다.

ComfyUI

앞의 생성 AI 기술을 편리하게 사용할 수 있는 UI를 제공한 도구이다. 초딩도 사용할 수 있을 만큼 간단하게 만들어져 있다.

ChatGPT & Dall-E

전세계 광풍을 불러온 챗GPT는 입력한 프롬프트에 사람처럼 대답하고, 검색하고, 요약하고, 글을 써준다. ChatGPT4는 멀티모달(텍스트 + 소리 + 이미지 등)을 제공하여, 더욱 막강해질 예정이다(변호사, 의사 시험 통과함. 구글 주가 하락 원인). 트랜스포머란 딥러닝 기술로 만들었다(원천기술은 구글에서 만들었는 데 아이러니하다). Dall-E는 이미지 생성 AI이다. 얘네들이 제공하는 API(Application Program Interface) 사용해, 로봇을 제어하면, 영화 AI 비스므리한 로봇을 만들수도 있다. GPT 이용해 개발하려면 OpenAI 사이트 가입 후 기능 호출 API 키를 얻어야 한다. 
로봇 + 챗GPT(누군가는 할 줄 았았음ㅎ)

편리한 공짜 AI 미디어아트 개발 도구

프로세싱

미디어아트에서 프로세싱을 모르면 간첩일 정도로 유명하다. 자바 언어 기반으로, 매우 다양한 라이브러리와 디버깅 가능한 편집기를 지원한다. 아두이노(arduino) 임베디드 보드와 특히 호환성이 좋아, 유저 인터렉티브 키네틱 아트에 자주 사용된다. 딥러닝 라이브러리 지원도 빠르게 이뤄지고 있다.

아두이노

마찬가지로, 미디어아트 분야에서 아두이노를 모르면 간첩이다. 임베디드 보드로, 센서 및 엑추에이터와 연결할 수 있는 GPIO 포트를 지원하여, 간단한 환경 모니터링 장치부터, 로봇까지 다양한 것들을 만들 수 있다. 개발은 C기반이다. 인스트럭터블 등 튜토리얼 웹사이트가 넘쳐나, 개발하기 편리하다. 현재, IoT, 딥러닝에 신경쓰고 있으며, ARDUINO NANO 33 SENSE 등에 TENSORRT와 같은 학습모델, 다양한 IoT예제를 사용할 수 있다.

파이썬 개발 도구 

딥러닝 개발 시 필수인 파이썬 언어는 PIP란 패키지 설치 프로그램을 제공해 강력한 라이브러리 확장성을 지원한다. 

Visual studio code

개발 업계 표준이 되다시피한 통합개발환경이다. 파이썬 등 대부분의 개발방법을 지원한다. 편리한 디버깅, 편집기, 수많은 애드인 등 기능이 매우 강력하다. 

Colab

구글에서 일부 무료로 제공하는 딥러닝 개발용 서버이다. 현존하는 유명한 딥러닝 모델을 오픈소스 예제로 무료 제공한다. 접속해 데이터를 업로드하여, 모델을 학습하고, 학습된 모델파일을 다운로드 할 수 있는 등 사용방법은 무궁무진하다. 
세계 모든 오픈소스 프로젝트가 모이는 곳이다. 국내에서 자체 개발되었다고 주장하는 프로그램?을 잠깐 뜯어보면, Github에서 가져온 것들이 쏟어져 나올만큼, 개발에서 큰 영향력을 가진다. 보통, 키워드 검색해, 소스를 다운로드하고, 빌드한다. 사용을 위해서는 개발에 대한 기초 개념은 있어야 한다.
소스 코드의 바다 github.com

유용한 딥러닝 도구 

파이토치(PyTorch), 케라스(Keras)

파이토치(PyTorch), 케라스(Keras)는 세계 모든 딥러닝 연구자가 제일 먼저 사용하는 딥러닝 도구이다. 설치하면, 다양한 예제, 강력한 라이브러리, 개발 도구가 함께 주어진다. 해당 도구를 사용하려면, 딥러닝과 파이썬에 대한 기본 개념은 이해하고 있어야 한다. NVIDIA CUDA와 함께 설치하는 일이 쥐약이다.
예제 예시

NVIDIA 임베디드 보드

손바닥만한 컴퓨터로 딥러닝 이용한 미디어아트 연출에 유용하다. 
딥러닝 분야의 최종승자라 불리는 NVIDIA는 강력한 병렬처리를 지원하는 CUDA 인프라를 바탕으로 각자 입맛에 맞는 임베디드 보드(AI EDGE) 인 NVIDIA JETSON NANO(제일 싼), NVIDIA  XAVIER NX(중간 비싼), NVIDIA TX2, NVIDIA XAVIER(비싼), NVIDIA ORIN(열라 비싼) 등을 제공한다(2023.4 현재까지도, 딥러닝 R&D과제 폭팔로 원래 가격의 5배 이상 가격에 구입할 수 있다. 품귀현상. 떼돈 벌고 있음). 
해당 보드를 사면, 최신 딥러닝 코드, 예제와 편리한 개발 도구 등은 무료로 딸려온다. 

게임엔진

미디어아트에서 게임엔진이 사용된지는 오래되었다. 이젠 앞의 인공지능 도구들이 붙어 나온다. 

유니티

얼마전 ChatGPT를 연결한 유니티 프로젝트가 떳다. 프롬프트 이용해, 3차원 월드를 자동으로 만들어준다(자동 코딩해줌).

언리얼

언리얼 언급안하면, 섭할 사람 많을 듯.. 세계에서 가장 성능, 가성비 좋은 엔진이다. 실제 사람처럼 묘사하는 가상모델링기술을 제공하는 데, 이와 챗GPT가 연결되면, 경쟁력 없는 아이돌, 아나운서 같은 직종이 없어질 것 같기도 하다. 미래엔 가상휴먼이 연기, 노래, 방송 다 해치울 듯(엔터업계에선 이미 진행 중. 이젠 시나리오가 중요). 
언리얼 메타휴먼 기술 데모(여기에 챗GPT+)

괜찬은 유료 생성 AI 도구는?

돈 주면서 사용하는 도구로는 Midjourney(특정 횟수 지나면 돈내라고 함), Runway ML(생성 AI 분야 최고 강자), NightCafeKaiverStablecog(일부 무료), Shutterstock 등이 있다. 이외에, 이미지 화질 개선 Upscale media, 목소리 생성 Prime Voice AI, 비디오 생성 D-ID
발렌시아가 스타일 헤리포터 영상에서 사용한 일부 도구는 돈내고 사용한 것이다(서비스 호출 횟수만큼 결재하면 되는거라 비싸게 만든것 같진 않음). 유료인 만큼, 좋은 품질, 풍부한 자료 소스, 편리한 사용성이 빛난다.
비디오 생성 AI D-ID

마무리

지금은 춘추전국시대 같은 생성 AI 도구들을 정리해 보았다. 조만간 통일되어, Adobe 같은 업체들이 이 업계를 천하통일하리라 생각된다. 지금은 공짜로 할 수 있는 것이 많아, 시간과 노력만 있다면, 재미있는 것 만들며 놀 수 있다.
 

유용한 레퍼런스 및 튜토리얼

시간이 있다면, 아래 링크도 살펴보면 작품 제작에 큰 도움이 된다. 

학습 모델 다운로드

스테이블 디퓨전은 다양한 학습 데이터를 이용해 만든 모델을 사용할 수 있다. 다음 링크에서 다운로드 할 수 있다.
    2023.5.1 - A.DAT 전시 예정 대비 워크샵용 자료로 정리함

    2023년 4월 26일 수요일

    OpenCASCADE 파이썬 라이브러리 사용해 캐드 3차원 모델링 코딩하는 방법

    이 글은 OpenCASCADE(OCC) 파이썬 라이브러리 사용해 캐드 3차원 모델링 디자인 코딩하는 방법을 간략히 나눔한다. OpenCASCADE는 캐드 엔진을 개발하기 위해 필요한 솔리드 모델링 기능을 제공하는 오픈소스 라이브러리이다. 이를 이용하면, 다음과 같은 기능을 개발할 수 있다.
    • 3차원 모델링 기능: 2D sketch, extrude, sweep, revolve
    • 2/3차원 곡선 모델링 기능: line, arc, circle, spline, nurbs
    • 3차원 곡면 모델링 기능: nurbs
    • 솔리드 모델 파일 입출력 기능: step 등
    OCC 사용 예시

    환경설정
    아나콘다 환경에서 다음 패키지를 설치한다.
    • Python OCC library
    • PyQT5 tool
    • matplotlib and mpl_toolkits
    터미널에서 다음 명령을 실행한다. 
    conda install occt
    conda install pythonocc-core
    git clone https://github.com/tpaviot/pythonocc-demos


    실행 후, pythonocc-demos 폴더 안에 예제를 확인할 수 있다. 설치된 아나콘다 환경에서 파이썬이나 vscode로 실행해 본다.

    파라볼라 커브 코딩
    다음은 파라볼라 커브 모델링 코드를 보여준다.
    from __future__ import print_function

    # OCC 라이브러리 임포트
    from OCC.Core.gp import gp_Pnt2d, gp_Dir2d, gp_Ax22d, gp_Parab2d
    from OCC.Core.GCE2d import GCE2d_MakeParabola
    from OCC.Core.Geom2d import Geom2d_TrimmedCurve
    from OCC.Display.SimpleGui import init_display

    display, start_display, add_menu, add_function_to_menu = init_display()

    # 파라볼라 모델링 함수 정의
    def parabola(event=None):
        # P is the vertex point
        # P and D give the axis of symmetry
        # 6 is the focal length of the parabola
        a_pnt = gp_Pnt2d(2, 3)               # 좌표점 설정
        a_dir = gp_Dir2d(4, 5)                # 방향 설정
        an_ax = gp_Ax22d(a_pnt, a_dir, True)    # 축 설정
        para = gp_Parab2d(an_ax, 6)               # 모델링
        display.DisplayShape(a_pnt)                # 표시
        display.DisplayMessage(a_pnt, "P")

        aParabola = GCE2d_MakeParabola(para)           # 솔리드 생성
        gParabola = aParabola.Value()
        aTrimmedCurve = Geom2d_TrimmedCurve(gParabola, -100, 100, True)       # 트림 곡선 생성

        display.DisplayShape(aTrimmedCurve, update=True)

    if __name__ == "__main__":
        parabola()
        start_display()

    결과는 다음과 같다. 

    곡면 모델링 코딩
    다음은 곡면을 모델링하는 코드이다. 

    from __future__ import print_function
    from OCC.Core.gp import gp_Pnt, gp_Vec
    from OCC.Core.GeomFill import (
        GeomFill_BSplineCurves,
        GeomFill_StretchStyle,
        GeomFill_CoonsStyle,
        GeomFill_CurvedStyle,
    )
    from OCC.Core.GeomAPI import GeomAPI_PointsToBSpline
    from OCC.Core.Geom import Geom_BSplineCurve
    from OCC.Display.SimpleGui import init_display
    from OCC.Extend.ShapeFactory import point_list_to_TColgp_Array1OfPnt, make_face

    display, start_display, add_menu, add_function_to_menu = init_display()

    # 곡선에서 곡면 생성
    def surface_from_curves():
        # 첫번째 스플라인 생성
        array = []
        array.append(gp_Pnt(-4, 0, 2))   # 곡선 제어점 설정
        array.append(gp_Pnt(-7, 2, 2))
        array.append(gp_Pnt(-6, 3, 1))
        array.append(gp_Pnt(-4, 3, -1))
        array.append(gp_Pnt(-3, 5, -2))

        pt_list1 = point_list_to_TColgp_Array1OfPnt(array)
        SPL1 = GeomAPI_PointsToBSpline(pt_list1).Curve()  # 제어점에서 베지어 스플라인 생성

        # 두번째 스플라인 생성
        a2 = []
        a2.append(gp_Pnt(-4, 0, 2))
        a2.append(gp_Pnt(-2, 2, 0))
        a2.append(gp_Pnt(2, 3, -1))
        a2.append(gp_Pnt(3, 7, -2))
        a2.append(gp_Pnt(4, 9, -1))
        pt_list2 = point_list_to_TColgp_Array1OfPnt(a2)
        SPL2 = GeomAPI_PointsToBSpline(pt_list2).Curve()

        # 스트래치 스타일 설정
        aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle)
        SPL3 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(10, 0, 0)))
        SPL4 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(10, 0, 0)))

        # Fill with CoonsStyle
        aGeomFill2 = GeomFill_BSplineCurves(SPL3, SPL4, GeomFill_CoonsStyle)
        SPL5 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(20, 0, 0)))
        SPL6 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(20, 0, 0)))

        # Fill with CurvedStyle
        aGeomFill3 = GeomFill_BSplineCurves(SPL5, SPL6, GeomFill_CurvedStyle)

        aBSplineSurface1 = aGeomFill1.Surface()
        aBSplineSurface2 = aGeomFill2.Surface()
        aBSplineSurface3 = aGeomFill3.Surface()

        display.DisplayShape(make_face(aBSplineSurface1, 1e-6))
        display.DisplayShape(make_face(aBSplineSurface2, 1e-6))
        display.DisplayShape(make_face(aBSplineSurface3, 1e-6), update=True)

    if __name__ == "__main__":
        surface_from_curves()
        start_display()

    결과는 다음과 같다. 

    3차원 모델링 코드
    다음 파이썬 코드를 입력하고, 실행한다.

    import sys
    from math import cos, pi

    from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Fuse
    from OCC.Core.BRepFilletAPI import BRepFilletAPI_MakeFillet
    from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeCylinder
    from OCC.Display.SimpleGui import init_display
    from OCC.Core.TColgp import TColgp_Array1OfPnt2d
    from OCC.Core.gp import gp_Ax2, gp_Pnt, gp_Dir, gp_Pnt2d
    from OCC.Extend.TopologyUtils import TopologyExplorer

    display, start_display, add_menu, add_function_to_menu = init_display()

    def fillet(event=None):  # 필렛 모델링
        display.EraseAll()
        box = BRepPrimAPI_MakeBox(gp_Pnt(-400, 0, 0), 200, 230, 180).Shape()  # 박스 생성
        fillet = BRepFilletAPI_MakeFillet(box)  # 필렛
        # Add fillet on each edge
        for e in TopologyExplorer(box).edges():  # 각 모서리 별로 필렛
            fillet.Add(20, e)  # 20만큼 수행

        blended_box = fillet.Shape()   # 필렛 모델링 모형 리턴

        p_1 = gp_Pnt(250, 150, 75)
        s_1 = BRepPrimAPI_MakeBox(300, 200, 200).Shape()
        s_2 = BRepPrimAPI_MakeBox(p_1, 120, 180, 70).Shape()
        fused_shape = BRepAlgoAPI_Fuse(s_1, s_2).Shape()         # 박스 2개 만들어 그룹핑 처리

        fill = BRepFilletAPI_MakeFillet(fused_shape)           # 그룹핑된 모형 필렛
        for e in TopologyExplorer(fused_shape).edges():
            fill.Add(e)

        for i in range(1, fill.NbContours() + 1):  
            length = fill.Length(i)
            radius = 0.15 * length
            fill.SetRadius(radius, i, 1)

        blended_fused_solids = fill.Shape()

        display.DisplayShape(blended_box)
        display.DisplayShape(blended_fused_solids, update=True)

    def rake(event=None):       # 모서리 레이크 모델링
        display.EraseAll()
        # Create Box
        box = BRepPrimAPI_MakeBox(200, 200, 200).Shape()
        # Fillet
        rake = BRepFilletAPI_MakeFillet(box)
        expl = list(TopologyExplorer(box).edges())

        rake.Add(8, 50, expl[3])
        rake.Build()
        if rake.IsDone():
            evolved_box = rake.Shape()
            display.DisplayShape(evolved_box, update=True)
        else:
            print("Rake not done.")

    def fillet_cylinder(event=None):  # 실린더 필렛 모델링
        display.EraseAll()
        # Create Cylinder
        cylinder = BRepPrimAPI_MakeCylinder(
            gp_Ax2(gp_Pnt(-300, 0, 0), gp_Dir(0, 0, 1)), 100, 200
        ).Shape()
        fillet = BRepFilletAPI_MakeFillet(cylinder)
        display.DisplayShape(cylinder, update=True)
        tab_point_2 = TColgp_Array1OfPnt2d(0, 20)
        for i in range(0, 20):
            point_2d = gp_Pnt2d(i * 2 * pi / 19, 60 * cos(i * pi / 19 - pi / 2) + 10)
            tab_point_2.SetValue(i, point_2d)
            display.DisplayShape(point_2d)

        expl2 = TopologyExplorer(cylinder).edges()
        fillet.Add(tab_point_2, next(expl2))
        fillet.Build()
        if fillet.IsDone():
            law_evolved_cylinder = fillet.Shape()
            display.DisplayShape(law_evolved_cylinder, update=True)
        else:
            print("fillet not done.")

    def variable_filleting(event=None):
        a_pnt = gp_Pnt(350, 0, 0)
        box_2 = BRepPrimAPI_MakeBox(a_pnt, 200, 200, 200).Shape()
        a_fillet = BRepFilletAPI_MakeFillet(box_2)

        tab_point = TColgp_Array1OfPnt2d(1, 6)
        p_1 = gp_Pnt2d(0.0, 8.0)
        p_2 = gp_Pnt2d(0.2, 16.0)
        p_3 = gp_Pnt2d(0.4, 25.0)
        p_4 = gp_Pnt2d(0.6, 55.0)
        p_5 = gp_Pnt2d(0.8, 28.0)
        p_6 = gp_Pnt2d(1.0, 20.0)
        tab_point.SetValue(1, p_1)
        tab_point.SetValue(2, p_2)
        tab_point.SetValue(3, p_3)
        tab_point.SetValue(4, p_4)
        tab_point.SetValue(5, p_5)
        tab_point.SetValue(6, p_6)

        expl3 = list(TopologyExplorer(box_2).edges())

        a_fillet.Add(tab_point, expl3[9])
        a_fillet.Build()
        if a_fillet.IsDone():
            law_evolved_box = a_fillet.Shape()
            display.DisplayShape(law_evolved_box)
        else:
            print("aFillet not done.")
        display.FitAll()

    def exit(event=None):
        sys.exit()

    if __name__ == "__main__":
        add_menu("topology fillet operations")
        add_function_to_menu("topology fillet operations", fillet)
        add_function_to_menu("topology fillet operations", rake)
        add_function_to_menu("topology fillet operations", variable_filleting)
        add_function_to_menu("topology fillet operations", fillet_cylinder)
        add_function_to_menu("topology fillet operations", exit)
        start_display()

    결과는 다음과 같다. 

    마무리
    OCC는 3차원 모델링에 필요한 기능을 제공한다. OCC는 역사가 매우 오랜된 솔리드 모델링 엔진이다. 개발은 C/C++로 코딩되었다. 처음에는 많은 오류가 있었고, 빌드환경을 구축하는 데 디펜던시 에러 등을 해결하는 데 많은 시간이 걸렸다. OCC는 파이썬 랩핑 라이브러리가 만들어지면서 많은 사람들이 편리하게 사용할 수 있게 되었다. pythonocc를 개발한 사람은 Thomas Paviot 박사로 3차원 캐드 모델링 분야를 연구하고, 관련된 기술을 꾸준히 개발하고 있다.
    Piviot 박사

    OCC 대부분 파라메터는 캐드, 계산 기하학에 사용되는 개념을 사용하므로, 사용전에 이를 공부할 필요가 있다.

    레퍼런스

    2023년 4월 22일 토요일

    자연어처리 NLP 오픈소스 기반 도구를 활용한 텍스트 데이터 마이닝 방법

    이 글은 자연어처리 NLP(Natural language processing) 오픈소스 기반 도구를 활용한 논문 검색 및 분석 방법을 간략히 소개한다. 이 방법을 통해, 비정형적인 문서 등에서 필요한 정보를 추출하는 텍스트 데이터 마이닝 기능을 구현하고, 통찰력있는 정보 모델을 얻을 수 있다.

    논문 클러스터링 분석 예시

    LitStudy
    LitStudy는 과학 문헌 분석을 위한 파이썬 라이브러리이다. 주피터 노트북을 사용할 수 있다. 이 라이브러리는 논문 메타데이터로 부터 가시화, 네트워크 분석, 자연어 처리 등을 지원한다. 
    • 과학 논문으로부터 메타데이터 추출
    • 필터링, 선택, 주석처리
    • 통계 데이터 생성
    • bibliogrpahic 네트워크 생성
    • NLP(Natural Language Processing) 를 사용한 토픽 생성
    • Scopus, SemanticScholar, CrossRef, arXiv, DBLP, IEEE Xplore, Springer Link, CSV, bibtex, RIS 등 저널 API나 메타데이터 소스를 지원한다.
      이 라이브러리는 문헌조사되어 다음과 같이 정리한 데이터셋에서 다양한 통계적 문헌분석과 차트를 출력할 수 있다.
      예. IEEE 문헌 메타데이터 일부
      "Document Title",Authors,"Author Affiliations","Publication Title",Date Added To Xplore,"Publication Year","Volume","Issue","Start Page","End Page","Abstract","ISSN",ISBNs,"DOI",Funding Information,PDF Link,"Author Keywords","IEEE Terms","INSPEC Controlled Terms","INSPEC Non-Controlled Terms","Mesh_Terms",Article Citation Count,Patent Citation Count,"Reference Count","License",Online Date,Issue Date,"Meeting Date","Publisher",Document Identifier

      "Exploring a multi-resolution GPU programming model for Chapel","A. Hayashi; S. Raj Paul; V. Sarkar","Georgia Institute of Technology Atlanta,Georgia,USA; Georgia Institute of Technology Atlanta,Georgia,USA; Georgia Institute of Technology Atlanta,Georgia,USA","2020 IEEE International Parallel and Distributed Processing Symposium Workshops (IPDPSW)","28 Jul 2020","2020","","","675","675","There is a growing need to support accelerators, especially GPU accelerators, since they are a common source of performance improvement in HPC clusters. As for ... CUDA/HIP/OpenCL and invoking these kernels from the Chapel program using the GPUIterator [3], [4] and Chapel's C interoperability feature.","","978-1-7281-7445-7","10.1109/IPDPSW50202.2020.00117","","https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=9150427","","Graphics processing units;Programming;Kernel;Data transfer;Optimization;Conferences;Writing","parallel architectures;parallel programming;program compilers;public domain software","automatic compilation;GPU kernels;Chapel program;multiresolution GPU programming model;GPU accelerators;HPC clusters;forall loops;Chapel C interoperability feature;automatic compiler-based GPU code generation;CUDA;OpenCL;HIP","","","","6","","28 Jul 2020","","","IEEE","IEEE Conferences"

      예. springer 문헌 메타데이터 일부
      A comparative study of GPU programming models and architectures using neural networks The Journal of Supercomputing 61 3 10.1007/s11227-011-0631-3 Vivek K. PallipuramMohammad BhuiyanMelissa C. Smith 2012 http://link.springer.com/article/10.1007/s11227-011-0631-3 Article

      설치는 다음과 같다.
      pip install litstudy
      (pip install git+https://github.com/NLeSC/litstudy)

      다음은 코딩 예시이다. 
      # Import other libraries
      import os, sys
      import numpy as np
      import pandas as pd
      import matplotlib.pyplot as plt
      import seaborn as sbs

      # Options for plots
      plt.rcParams['figure.figsize'] = (10, 6)
      sbs.set('paper')

      # Import litstudy
      path = os.path.abspath(os.path.join('..'))
      if path not in sys.path:
          sys.path.append(path)

      import litstudy

      # Load the CSV files. 데이터셋은 여기 링크에서 다운로드. 
      docs1 = litstudy.load_ieee_csv('data/ieee_1.csv')
      docs2 = litstudy.load_ieee_csv('data/ieee_2.csv')
      docs3 = litstudy.load_ieee_csv('data/ieee_3.csv')
      docs4 = litstudy.load_ieee_csv('data/ieee_4.csv')
      docs5 = litstudy.load_ieee_csv('data/ieee_5.csv')
      docs_ieee = docs1 | docs2 | docs3 | docs4 | docs5
      print(len(docs_ieee), 'papers loaded from IEEE')

      docs_springer = litstudy.load_springer_csv('data/springer.csv')
      print(len(docs_springer), 'papers loaded from Springer')

      # IEEE, springer 문헌 데이터 병합
      docs_csv = docs_ieee | docs_springer
      print(len(docs_csv), 'papers loaded from CSV')

      docs_exclude = litstudy.load_ris_file('data/exclude.ris')
      docs_remaining = docs_csv - docs_exclude   # 특정 문헌 제외

      print(len(docs_exclude), 'papers were excluded')
      print(len(docs_remaining), 'paper remaining')

      # 로그 라이브러리 임포트. scopus 논문 검색. 미리, open api key를 https://dev.elsevier.com/apikey/manage서 획득해야 함. 
      import logging
      try:
         logging.getLogger().setLevel(logging.CRITICAL)
         docs_scopus, docs_notfound = litstudy.refine_scopus(docs_remaining)
      except Exception as e: # 에러 발생 가능. https://pybliometrics.readthedocs.io/en/stable/access/errors.html
         print(e)
         exit()

      print(len(docs_scopus), 'papers found on Scopus')
      print(len(docs_notfound), 'papers were not found and were discarded')

      # 특정 년도 논문 필터링
      docs = docs_scopus.filter_docs(lambda d: d.publication_year >= 2000)
      print(len(docs), 'papers remaining')

      # 년도, 저자, 언어 등 히스토그램 차트 출력
      litstudy.plot_year_histogram(docs, vertical=True);
      litstudy.plot_affiliation_histogram(docs, limit=15);
      litstudy.plot_author_histogram(docs);
      litstudy.plot_language_histogram(docs);
      litstudy.plot_number_authors_histogram(docs);

      # 약어 논문 맵핑 처리. 
      mapping = {
          "IEEE International parallel and distributed processing symposium IPDPS": "IEEE IPDPS",
          "IEEE International parallel and distributed processing symposium workshops IPDPSW": "IEEE IPDPS Workshops",
      }
      litstudy.plot_source_histogram(docs, mapper=mapping, limit=15);  # 출처 차트
      litstudy.plot_cocitation_network(docs, max_edges=500)  # 인용 네트워크 차트

      # 말뭉치(corpus) 분석. 
      corpus = litstudy.build_corpus(docs, ngram_threshold=0.8)  # 말뭉치(corpus) 생성
      litstudy.compute_word_distribution(corpus).filter(like='_', axis=0).sort_index()  # 단어 빈도수 계산
      plt.figure(figsize=(20, 3))
      litstudy.plot_word_distribution(corpus, limit=50, title="Top words", vertical=True, label_rotation=45);  # 단어 빈도수 출력

      # 토픽 간 유사도 거리 클러스터링을 위한 NMF(Non-negative Matrix Factorization) 분석 (여기 참고)
      num_topics = 15
      topic_model = litstudy.train_nmf_model(corpus, num_topics, max_iter=250)
      for i in range(num_topics):
          print(f'Topic {i+1}:', topic_model.best_tokens_for_topic(i))

      plt.figure(figsize=(15, 5))
      litstudy.plot_topic_clouds(topic_model, ncols=5);

      plt.figure(figsize=(20, 20))
      litstudy.plot_embedding(corpus, topic_model);

      결과는 다음과 같다. 단, scopus 검색 시 특정 서비스 요청 건수가 넘어갈 경우 예외가 발생할 수 있다(참고 - pybliometrics.readthedocs.io/en/stable/access/errors.html). 

      Scholarly
      Scholarly는 구글 스칼라에서 학술 논문들을 검색하고, 메타데이터를 얻을 수 있는 라이브러리이다. 앞의 litstudy는 메타데이터가 얻어진 후에 모델 분석이 가능하므로, 이런 도구를 이용해, 메타데이터와 같은 소스를 먼저 구축할 필요가 있다.

      설치는 다음과 같다. 
      pip3 install scholarly

      사용 방법은 다음과 같다. 
      from scholarly import ProxyGenerator, scholarly

      try:
          # pg = ProxyGenerator()
          # pg.FreeProxies()
          # scholarly.use_proxy(pg)

          title = 'Deep Learning based Anomaly Detection'  # 검색할 논문 타이틀
          search_query = scholarly.search_pubs(f'title:"{title}"')
          
          while(True):
              pub = next(search_query)  # 검색된 논문 메타데이터 출력
              if pub == None:
                  break
              print(pub['bib'])
              # scholarly.fill(pub, sections=['abstract']) 
              # print(pub['bib']['abstract'])
        
      except Exception as e:  # maxtriesexceededexception
          # https://scholarly.readthedocs.io/en/stable/ProxyGenerator.html
          print(e)

      실행 결과는 다음과 같다. 

      단, 이 도구는 DDoS(Distributed Denial of Service) 공격을 막기 위해, 구글 서버에서 호출 횟수, 시간 등이 빈번할 경우 max tries exceeded exception 를 발생시킬 수 있다. 이 경우, 앞의 코드의 ProxyGenerator 주석 부분을 제거하고 실행해 보기를 바란다(다른 IP로 변경해야 함).  

      레퍼런스

      오픈소스 NLP 텍스트 마이닝 spacy 기반 텍스트 컨텐츠 유사도 계산 및 분석 방법

      이 글은 오픈소스 spaCy 기반 텍스트 컨텐츠 유사도 계산 및 분석 방법을 간략히 다룬다. 

      소개
      spaCy는 Python, Cython 기반 고급 NLP 자연어 처리를 위한 라이브러리이다. 가장 최신 연구를 기반으로 개발되었다. 처음부터 산업계 제품에 사용되도록 설계되었다. 이를 통해, 효과적인 텍스트 마이닝을 가능하게 한다. 

      spaCy는 사전 훈련된 딥러닝 모델을 사용한 파이프라인과 함께 제공된다. 현재 70개 언어에 대한 토큰화, 훈련을 지원한다. 태깅, 구문 분석, 엔터티 인식, 텍스트 분류 등을 위한 신경망 모델, BERT와 같은 사전 훈련된 모델 변환기를 사용한다. 멀티태스킹 학습, 훈련 시스템 및 모델을 제공한다. 패키징, 배포, 워크플로우 관리를 제공한다. 

      spaCy 아키텍처
      word2vec 모델 기반 유사도 계산 예시 (github.com/explosion/sense2vec)

      환경설정하기
      다음 명령을 터미널에서 실행한다.
      pip install spacy
      python -m spacy download en_core_web_md
      python -m spacy download en_core_web_lg
      python -m spacy download en


      코딩하기
      파이썬 코드를 아래와 같이 입력해 실행해본다.
      import spacy
      nlp = spacy.load("en_core_web_lg")
      #nlp = spacy.load("en_core_web_md")

      doc1 = nlp(u'the person wear red T-shirt')
      doc2 = nlp(u'this person is walking')
      doc3 = nlp(u'the boy wear red T-shirt')

      print(doc1.similarity(doc2)) 
      print(doc1.similarity(doc3))
      print(doc2.similarity(doc3)) 

      결과 doc1, doc2 문장 간의 유사도가 계산되어 출력될 것이다.

      레퍼런스

      2023년 4월 10일 월요일

      파이썬 기반 PDF 보고서 생성 및 텍스트 마이닝하기

      이 글은 파이썬 기반 PDF 보고서 파일을 생성하거나, 원하는 텍스트를 추출하여 데이터 마이닝하는 오픈소스 도구를 간략히 정리한다.

      오피스에서 작업을 하다보면, PDF파일을 많이 다루게된다. 이 경우, 노가다가 필요한 수작업이 많은데, 파이썬 라이브러리를 사용하면, 이러한 오피스 작업을 자동화할 수 있다. 

      이 글은 fpdf, pyPDF2 라이브러리를 사용해, 보고서 형식을 PDF로 출력하거나, 반대로 PDF의 정보를 추출하는 방법을 구현해 본다. 

      생성된 PDF 보고서 예시

      라이브러리 소개

      fpdf (github)는 PDF 문서를 생성하는 라이브러리로 최초 PHP로 개발되었다가 파이썬으로 포팅된 도구이다. 다음 기능을 지원한다.

      • PDF 쓰기 지원
      • PNT, GIF, JPG 지원
      • html2pdf 템플릿 지원

      PyPDF2는 PDF파일 병합, 절단, 변환 등을 지원한다. 주요 기능은 다음과 같다.
      • PDF 데이터 처리
      • PDF 암호화
      • PDF 데이터 추출 

      라이브러리 설치

      다음 명령을 터미널에 입력해 필요한 라이브러리를 설치한다.

      pip install fpdf, pyPDF2, lorem, pandas, seaborn, re

      사용방법

      파이썬 파일을 하나 만든 후, 다음을 코딩해 넣는다.

      from fpdf import FPDF
      import lorem 
      import pandas as pd

      # 표 출력을 위해, 데이터 프레임 생성
      df = pd.DataFrame(
                {'feature 1' : ['cat 1', 'cat 2', 'cat 3', 'cat 4'],
                 'feature 2' : [400, 300, 200, 100]
                })

      # 차트 그림 생성
      import matplotlib.pyplot as plt
      import seaborn as sns
      fig, ax = plt.subplots(1,1, figsize = (6, 4))
      sns.barplot(data =  df, x = 'feature 1', y = 'feature 2')
      plt.title("Chart")
      plt.savefig('./example_chart.png', 
                 transparent=False,  
                 facecolor='white', 
                 bbox_inches="tight")

      # PDF 클래스 생성
      ch = 8
      class PDF(FPDF):
          def __init__(self):
              super().__init__()
          def header(self):
              self.set_font('Arial', '', 12)
              self.cell(0, 8, 'Header', 0, 1, 'C')
          def footer(self):
              self.set_y(-15)
              self.set_font('Arial', '', 12)
              self.cell(0, 8, f'Page {self.page_no()}', 0, 0, 'C')

      # 셀을 생성하고, 각 셀에 보고서 내용 설정
      pdf = PDF()
      pdf.add_page()
      pdf.set_font('Arial', 'B', 24)
      pdf.cell(w=0, h=20, txt="Title", ln=1)
      pdf.set_font('Arial', '', 16)
      pdf.cell(w=30, h=ch, txt="Date: ", ln=0)
      pdf.cell(w=30, h=ch, txt="01/01/2022", ln=1)
      pdf.cell(w=30, h=ch, txt="Author: ", ln=0)
      pdf.cell(w=30, h=ch, txt="Max Mustermann", ln=1)
      pdf.ln(ch)
      pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())
      pdf.image('./example_chart.png', x = 10, y = None, w = 100, h = 0, type = 'PNG', link = '') # 차트 이미지 입력
      pdf.ln(ch)
      pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())
      pdf.ln(ch)

      # 표 헤더 및 내용 설정
      pdf.set_font('Arial', 'B', 16)
      pdf.cell(w=40, h=ch, txt='Feature 1', border=1, ln=0, align='C')
      pdf.cell(w=40, h=ch, txt='Feature 2', border=1, ln=1, align='C')
      # Table contents
      pdf.set_font('Arial', '', 16)
      for i in range(len(df)):
          pdf.cell(w=40, h=ch, txt=df['feature 1'].iloc[i], border=1, ln=0, align='C')
          pdf.cell(w=40, h=ch, txt=df['feature 2'].iloc[i].astype(str), border=1, ln=1, align='C')

      # PDF 저장
      pdf.output("example.pdf")

      그 결과는 다음과 같다.


      PDF에서 텍스트 추출
      다음 파이썬 코드를 입력한다.
      import re, PyPDF2

      def extract_abstract(pdf_fname = 'sample.pdf'):  # sample.pdf 파일을 준비한다. 이 경우는 논문의 ABSTRACT 부분을 추출하는 것으로 코딩되었다.
          pdf_file = open(pdf_fname, 'rb')
          pdf_reader = PyPDF2.PdfReader(pdf_file)

          first_page = pdf_reader.pages[0]
          text = first_page.extract_text()

          abstract_start = text.find('Abstract')  # abstract keyword 검색
          if abstract_start == -1:
              abstract_start = text.find('ABSTRACT')

          abstract = ''
          if abstract_start == -1:
              return abstract

          abstract_start += len('Abstract')
          introduction_start = text.find('Introduction')  # introduction keyword 검색
          if introduction_start == -1:
              introduction_start = text.find('Background')
          if introduction_start == -1:
              return abstract
          introduction_start -= 4

          abstract_end = introduction_start if introduction_start != -1 else len(text)
          abstract = text[abstract_start:abstract_end]

          # remove new line characters
          abstract = abstract.replace('\n', ' ')

          # remove digits and special characters
          # abstract = re.sub(r'[^a-zA-Z0-9().,% ]', '', abstract)
          print(abstract)

      extract_abstract()

      실행하면 다음과 같이 PDF로부터 추출된 ABSTRACT 텍스트 결과를 확인할 수 있다.

      레퍼런스


      2023년 4월 9일 일요일

      GPT 기반 디지인 도구 OpenAI for Grasshopper 소개

      이 글은 GPT 기반 3차원 디자인 도구인 OpenAI for Grasshopper 를 간략히 소개한다.

      소개
      이 Grasshopper 플러그인(.gha)은 .NET용 OpenAI API를 사용해, GPT를 이용한 디자인을 가능하게 한다. 기능은 다음과 같다. 이 기능을 사용하기 위해서는 OpenAI key가 있어야 한다.
      • ChatGPT 지원
      • 생성 AI 지원
      • 디자인 편집
      • Codex, BIM 등
      사용방법
      사용 절차는 다음과 같다.
      1. 이미지를 묘사하는 프롭프트 입력
      2. ChatGPT에서 생성AI용 텍스트 생성
      3. 생성AI이용해 이미지 생성
      4. 이미지 비전 분석
      5. 이미지에서 벡터 추출
      6. 벡터를 라이노 3D 모델 생성에 사용
      다음 영상은 앞의 단계 실행 방법을 보여준다.

      사용 개념 예시(link)

      결론
      점차 많은 디자인도구가 GPT와 같은 LLM(Large Language Model)과 통합될 것이다 도구를 잘 사용하면 생산성과 품질이 높은 디자인 모델을 빨리 얻을 수 있다. 다만, 사용하는 도구가 하는 역할을 해본적이 없는 경우, 기본기가 없으므로, 원하는 성과를 얻기 어렵다는 점을 명심해야 한다. 

      레퍼런스
      부록: ChatGPT with Revit

      부록: OpenDataBIM

      BIM 지원 Revit 모델러 기반 Python 코딩 도구 소개

      이 글은 BIM을 지원하는 Revit 모델러를 기반으로 하는 Python 도구들을 간략히 소개한다. 
      래빗 기반 파이썬 코딩

      파이썬은 매우 강력한 스크립트 기반 언어로, 매우 다양한 수치해석, 데이터 분석 등 라이브러리를 무료로 제공한다. 파이썬을 통해, 값비싼 데이터 분석 도구를 더이상 구입할 필요가 없어졌다. Revit과 같은 BIM 모델링 도구에서도 파이썬 코딩을 지원한다. 이 글은 관련된 도구를 간략히 알아본다.

      래빗 기반 파이썬

      pyRevit 도구
      pyRevit은 래빗 애드인 도구로, 파이썬 프로그래밍을 지원한다. 설치를 위해 다음 링크를 방문해 애드인을 다운로드 받아 설치한다.
      설치 후 revit을 실행해, 애드인 메뉴를 확인해 보면, 다음 툴바를 사용할 수 있다.
      설치 후 모습

      pyRevit Settings 메뉴를 선택해, 파이썬 모듈 확인, UI 스타일 등 옵션을 설정할 수 있다.
      pyRevit 애드인 설정

      pyRevit은 유용한 파이썬 도구를 확장 패키지로 지원한다. 예를 들어, MEP를 설계하는 데 도움이 되는 MEPDesign 같은 도구를 사용할 수 있다. 이는 확장이 가능하다.
      pyRevit 확장 리스트

      Revit python shell 도구
      이 도구는 pyRevit보다 단순하고, 사용하기 쉽다. 다음 링크를 이용해 다운로드 및 설치해 본다. 
      실행하면, 다음 애드인 메뉴를 확인할 수 있다. 여기서 파이썬 파일이나 코드를 실행할 수 있다.
      단순한 UI를 가진 래빗 파이썬 쉘

      다이나모 파이썬 스크립트 노드
      래빗에 포함된 다이나모(dynamo) 그래프 기반 모델링 도구 내에 있는 파이썬 스크릅트 노드를 사용할 수도 있다. 사용법은 다음 영상을 참고한다.
      다이나모 파이썬 노드

      마무리
      래빗에서 파이썬을 사용하는 방법은 다양하지만, 사실, 파이썬의 큰 장점인 강력한 라이브러리를 사용하는 것은 많은 한계가 있다. 특히, 닷넷 기반 컴포넌트를 호출하는 아이언 파이썬을 사용하는 윈도우 프로그램 특성상 래빗도 이 한계에서 동작되어 PIP와 같은 강력한 패키지 설치 프로그램이 제대로 동작되지 않는다(버전 불일치 등). 래빗 기반 파이썬은 이를 고려해 사용해야 한다.

      레퍼런스