일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 코틀린
- report
- 동적계획법
- indices
- GREEDY
- booleanarray
- dynamic programming
- Java
- lastIndex
- heap
- Developer
- sortedBy
- 2020
- Recursion
- Queue
- Main
- Kotlin
- dp
- foreach
- Poll
- PriorityQueue
- Util
- solution
- 알고리즘
- 2D Array
- contentToString
- 프로그래머스
- intarray
- programmers
- hackerrank
- Today
- Total
Code in
프로젝트 - AI랑, 아이랑 : AI 동요 창작 서비스 (1) 본문
AI 동요 창작 서비스 개발 프로젝트를 이번 9월에 기획, 진행하고 있습니다.
'프로젝트 AI랑'에서는 비기술적인 내용이, '작사 AI 팀'에서는 기술적인 내용이 작성되어 있습니다.
AI랑 [아이랑] : AI 동요 창작 서비스
프로젝트 AI랑
1. 프로젝트의 주제 선정 이유
문제 정의
AI가 예술분야의 창작에 진입하였지만 아직 작곡, 작사에 대한 AI 활용은 부족하여 AI 창작 이후 사람의 편집을 거치는 형태입니다.
또한, 동요의 경우는 K-POP등의 장르와 다르게 그 생산 주체가 보다 한정되어 있다는 문제점이 있습니다.
따라서 AI가 동요를 작곡, 작사하는 프로그램을 개발하고자 합니다.
작사/작곡으로 팀을 나누어서 동시에 진행하고 있습니다.
2. 진행 내용
9월
지도교수님과의 면담 이후, 동요 창작 AI라는 주제를 선정하였습니다.
주제를 선정하고 다시 지도교수님과 면담을 통해 각자 세부적으로 자료조사할 내용을 선정하였습니다.
주제와 관련된 자료 조사 + 발표
- 작곡 AI SW
- 작곡 Open SW, Data Set
- 작곡 AI 논문
- 작사 AI 논문
10월
팀원마다 하나의 자료조사 주제를 가지고 계속해서 자료조사를 진행하였고, 각자 30분 가량의 발표를 준비하였습니다.
더해서 현존하는 작곡 AI 서비스를 사용하여 팀원들이 각각 노래를 한 곡 씩 창작하여 공유할 수 있도록 하였습니다.
웹 프론트 플로우를 볼 수 있는 디자인, 프로토 타입을 Adobe XD를 사용하여 제작하였습니다.
멘토님과의 1차 멘토링을 진행하였습니다.
중간 발표와 사업계획서 작성을 진행하였습니다.
지도교수님과의 면담 시간에 팀원들이 각각 30분씩 발표를 진행하였습니다.
진행한 발표의 세부 주제는 9월에 적혀 있는 것과 같습니다.
11월
팀을 작사 AI, 작곡 AI로 나누어서 진행하였습니다. 저는 작사 AI 팀입니다.
멘토님과의 2차 멘토링을 진행하였습니다. 멘토링을 통해 프로젝트의 계획과 방향성을 점검할 수 있었습니다.
작사 AI 팀
동요 Data Set을 수집하였습니다. 우선 구글 검색을 통해 동요 165곡의 가사를 수집하였습니다.
이후 파랑새 창작 동요회, 한국 동요 작곡가 협회의 홈페이지를 통해 공개된 창작 동요 약 200곡의 가사를 수집하였습니다.
데이터 셋 수집 과정에서 동요 가사의 응집성 등을 위해서는 키워드가 필요하다는 것을 알게 되었습니다.
또한, 작사를 진행할 때 KoGPT-2를 사용하려고 하고 있는데, 해당 알고리즘에도 시작하는 메인 키워드가 주어져야 합니다.
이를 위해 수집한 동요 가사 데이터 셋에서의 핵심 키워드를 추출하고자 KRWordRank를 사용하였습니다.
추출된 핵심 키워드들 중, 명사들을 키워드로 선정하였습니다.
선정된 명사 키워드들을 자연, 가족, 동물, 계절 및 시간, 사람, 감정 및 감각의 메인 키워드로 분류하였습니다.
각각의 메인 키워드로 분류된 세부 키워드들 중 그 수가 적은 것들은 직접 키워드를 일부 추가하였습니다.
12월 ~ 6월
12월에는 기말발표와 보고서, 깃허브, 영상, 시제품 제출이 진행될 예정입니다.
1월에는 작사 작곡 AI 1차 개발, 피드백, 2차 개발이 진행됩니다.
2월에는 작사 작곡 AI 개발 완료, 각각을 연동하는 과정이 진행됩니다.
3월~5월에는 웹페이지 구현이 진행됩니다.
6월에는 결과물에 대한 피드백과 수정이 진행됩니다.
작사 AI 팀
1. Data Set
작사 AI 팀에서는 먼저 동요 가사 Data Set을 수집하였습니다.
검색을 통해 찾은 동요 가사 165곡에 더해서, 파랑새 창작 동요회에 존재하는 약 300개의 동요 가사들 중 100개의 곡을 데이터 셋으로 추가하였습니다. 파랑새 창작 동요회 웹페이지에 공개된 동요 음반 중, 우선 100곡을 수집하였습니다.
이후 추가적으로 확보하고자 합니다.
* 파랑새 창작 동요회 : http://www.prs.or.kr/
2. KRWordRank - 가사 Data Set의 핵심 키워드 추출
KRWordRank
KRWordRank는 한국어 문장에서 단어들을 추출하고, 단어의 중요도를 점수로 표시합니다.
PageRank와 비슷한 graph ranking 알고리즘인, HITS algorithm을 이용하여 단어를 추출합니다.
HITS algorithm
Hyperlink-Induced Topic Search Algorithm입니다.
Jon Kleinberg가 개발한 웹페이지 검색 엔진의 랭킹 알고리즘으로, 웹 페이지를 평가하는 링크 분석 알고리즘입니다.
a good hub represents a page that pointed to many other pages, while a good authority represents a page that is linked by many different hubs.
좋은 허브는 다른 많은 페이지를 가리키는 페이지를 나타내고, 좋은 권위는 많은 다른 허브로 연결된 페이지를 나타냅니다.
이처럼 HITS는 허브와Hub 권위Authority를 사용하여 웹페이지 사이의 재귀적인 관계를 정의합니다.
따라서 HITS 알고리즘에서는 각 페이지에 대해 2가지 점수를 할당합니다.
its authority, which estimates the value of the content of the page, and its hub value, which estimates the value of its links to other pages.
페이지 컨텐츠의 가치를 추정하는 점수와 다른 페이지에 대한 링크의 가치를 추정하는 점수입니다.
위의 알고리즘처럼,
허브 점수는 권위 점수들의 합이 되고, 권위 점수는 허브 점수들의 합이 됩니다.
KRWordRank의 사용
KRWordRank를 사용하여 데이터 셋 중 빈출도가 높은 키워드를 추출하여 메인/세부 키워드를 선정했습니다.
Colab을 사용하여 진행하였습니다.
먼저 구글 드라이브에 업로드한 동요 가사 Data Set 사용을 위해 구글 드라이브와 코랩을 연결합니다.
from google.colab import drive
drive.mount("/content/drive")
파일을 읽고, 잘 읽혔는지 확인하기 위해 출력하였습니다.
txt_path = '/content/drive/MyDrive/C_Study/20201117lyrics_HM.txt'
file1 = open(txt_path, "r")
file1.name
file1.mode
FileContent = file1.read()
FileContent
KR WordRank 사용을 위해 krwordrank를 설치하였습니다.
pip install krwordrank
이후 import를 진행하고, 읽은 파일의 개행문자 등을 기준으로 분리하였습니다.
def get_texts_scores(fname):
with codecs.open(fname, encoding='utf-8') as f:
docs = [doc.lower().replace('\n', '\t').replace('\r', '').split('\t') for doc in f]
docs = [doc for doc in docs if len(doc) == 2]
if not docs:
print("not docs")
return [], []
texts, scores = zip(*docs)
return list(texts), list(scores)
texts, scores = get_texts_scores(txt_path)
texts
개행문자가 '\n'라고만 알고 있었는데 그 뒤에 '\r'이 같이 붙는 경우도 있다는 것을 새롭게 알게되어 해당 부분을 처리해야 했습니다.
위의 코드를 실행한 후에는 texts에 문장들이 담기게 됩니다.
다음으로 단어들을 추출하는 과정을 거치게 됩니다.
저는 krwordrank.word를 KRWordRank로 가져왔기 때문에 KRWordRank로 실행합니다.
wordrank_extractor = KRWordRank(
min_count = 5, # 단어의 최소 출현 빈도수 (그래프 생성 시)
max_length = 10, # 단어의 최대 길이
verbose = True
)
beta = 0.85 # PageRank의 decaying factor beta
max_iter = 10
keywords, rank, graph = wordrank_extractor.extract(texts, beta, max_iter)
stopwords = {'나의', '어디', '너무', '정말', '있어'}
passwords = {word:score for word, score in sorted(
keywords.items(), key=lambda x:-x[1])[:300] if not (word in stopwords)}
from krwordrank.word import summarize_with_keywords
keywords = summarize_with_keywords(texts, min_count=5, max_length=10,
beta=0.85, max_iter=10, stopwords=stopwords, verbose=True)
keywords = summarize_with_keywords(texts) # with default arguments
KRWordRank에 passwords를 사용할 수 도 있지만, summarize_with_keywords 함수처럼 진행할 수 도 있습니다.
이후 점수가 높은 순서대로 출력할 수 있습니다. 아래의 코드에서는 30개만 출력하였으나 실제 키워드 추출과정에서는 100개의 단어들을 출력하여 사용하였습니다.
for word, r in sorted(keywords.items(), key=lambda x:x[1], reverse=True)[:30]:
print('%8s:\t%.4f' % (word, r))
WordCloud
결과물을 보다 시각화하기 위해서는 wordcloud를 사용할 수 있습니다.
wordcloud를 설치한 다음,
pip install wordcloud
한글을 출력하기 위해 한글을 지원하는 폰트를 준비하고, 그림을 그립니다.
from wordcloud import WordCloud
# Set your font path
font_path = '/content/drive/MyDrive/NotoSansCJKkr-Black.otf'
krwordrank_cloud = WordCloud(
font_path = font_path,
width = 800,
height = 800,
background_color="white"
)
krwordrank_cloud = krwordrank_cloud.generate_from_frequencies(passwords)
%matplotlib inline
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10, 10))
plt.imshow(krwordrank_cloud, interpolation="bilinear")
plt.show()
코드를 통해 그려진 그림은 아래와 같습니다.
그림에 나와있듯이, 가장 점수가 높은 단어들은 '우리', '마음', '친구', '하늘', '아기'였습니다.
그리고 출력한 점수가 높은 단어들에는 명사와 형용사 등이 섞여 있었습니다.
그래서 우선은 단어들 중 명사들을 모아서 메인 키워드/세부 키워드를 나누었습니다.
명사
: 하늘/아빠/엄마/사랑/바람/바다/마음/친구/아기/노래/펭귄/소리/얼굴/나무/세상/선생님/아침/꼬마/향기/동물/동네/나라/아이/기쁨/인사/나미/다람쥐/동그라미
메인 키워드로 분류 후, 세부 키워드에 임의로 몇가지를 추가하였습니다.
메인 키워드 : 세부 키워드
1. 자연 : 해, 달, 별, 바람, 바다, 나무, 산, 계곡, 풀, 꽃, 비, 햇빛, 구름, 해변, 모래, 언덕
2. 가족 : 아빠, 엄마, 가족, 동생, 할머니, 할아버지, 언니, 오빠, 누나, 형, 삼촌, 이모
3. 동물 : 펭귄, 다람쥐, 곰, 강아지, 고양이, 상어, 돌고래, 호랑이, 토끼
4. 계절, 시간 : 봄, 여름, 가을, 겨울, 아침, 낮, 저녁, 밤, 이른 새벽
5, 사람 : 친구, 선생님, 꼬마, 아이, 아기, 이웃, 경비아저씨
6. 감정, 감각 : 기쁨, 즐거움, 맛, 향기, 따뜻함, 부드러움, 밝음, 신남, 맛있는, 즐거운, 추운
3. KoGPT-2 - 한국어 자연어 생성
KoGPT2
KoGPT2는 OpenAI GPT-2모델의 한국어 성능의 한계를 보완하기 위해 만들어졌습니다.
GPT-2 base 모델이며, Fused GELU (Gaussian Error Linear Unit) 를 기반으로 10% 이상의 학습 속도를 향상 시켰습니다.
KoGPT2를 설치한 다음
git clone https://github.com/SKT-AI/KoGPT2.git
cd KoGPT2
pip install -r requirements.txt
pip install .
문장의 시작을 주었을 때 해당 문장을 AI가 완성시키는 것을 확인할 수 있습니다.
import torch
from kogpt2.pytorch_kogpt2 import get_pytorch_kogpt2_model
from gluonnlp.data import SentencepieceTokenizer
from kogpt2.utils import get_tokenizer
tok_path = get_tokenizer()
model, vocab = get_pytorch_kogpt2_model()
tok = SentencepieceTokenizer(tok_path, num_best=0, alpha=0)
sent = '2019년 한해를 보내며,'
toked = tok(sent)
while 1:
input_ids = torch.tensor([vocab[vocab.bos_token],] + vocab[toked]).unsqueeze(0)
pred = model(input_ids)[0]
gen = vocab.to_tokens(torch.argmax(pred, axis=-1).squeeze().tolist())[-1]
if gen == '</s>':
break
sent += gen.replace('▁', ' ')
toked = tok(sent)
sent
'2019년 한해를 보내며, 새해에는 더 많은 사람들이 새해에 이루고자 하는 소망과 희망을 되새겨보는 시간이 되었으면 좋겠다.'
하지만,
CSV 형식의 Dataset을 받도록 변경된 Version2로 작업을 진행하려면 현재 txt로 된 데이터 셋을 변경해주어야 하기 때문에, Version 1.1을 이용하였습니다.
Version 에러를 고치기 위해서 requirements.txt의 transformers를 2.4.1로 고정해야 했습니다.
main을 통해 모델을 학습시키는 것까지는 에러가 더 생기지 않았지만, Generator를 통해 작사를 진행하는 것에서 EOError가 발생하였습니다. 현재는 해당 에러가 생기는 이유를 찾고 수정하려고 하는 중입니다.
참고: HITS Algorithm Wikipedia, GeeksforGeeks
* KR WordRank - github.com/lovit/KR-WordRank
* KRWordRank Reference: Kim, H. J., Cho, S., & Kang, P. (2014). KR-WordRank: An Unsupervised Korean Word Extraction Method Based on WordRank. Journal of Korean Institute of Industrial Engineers, 40(1), 18-33
* KoGPT2 - github.com/SKT-AI/KoGPT2
* 가사 쓰는 모델 : github.com/gyunggyung/KoGPT2-FineTuning
'프로젝트_AI랑' 카테고리의 다른 글
아이랑 프로젝트 (2) GPT3, Magenta js로 사용하기 (1) | 2021.05.15 |
---|