2018. 6. 11. 14:09ㆍPython-이론/python-인공지능2
lstm을 이요해서 악보 예측하기
이전의 코드들중 일부만 수정해서 lstm알고리즘을 실행시켜 보겠다.
수정된 코드들
trainData = dataset(seq, 4) X_data = trainData[:, :4]/float(13) X_data = np.reshape(X_data, (50, 4, 1)) Y_data = trainData[:, 4] Y_data = np_utils.to_categorical(Y_data)
reshape를 통해 X_data를 50, 4, 1의 형태로 바꾸어 주었다. 그이유는 LSTM을 잘사용하기 위해선 타임 스텝, 속성, 배치사이즈, 상태유지모드 등이있다. 이중에서 타임스텝은 매 시퀀스마다 들어가게 되는 X_data의 개수 그러니깐 4개의 음표들이 들어가니깐 4가된다. 속성 값 1은 하나의 음표당 하나의 배열씩 입력값으로 들어가게된다. 안에 데이터형태를 보면
이사진을 보면 하나의 음표 값이 하나의 배열에 쌓여있다. 따라서 하나의 입력값이 하나의 배열에 쌓여 입력되는 것을 결정하는 것이 속성값이 되는 것이다. 만약에 2, 2이면 2개의 배열에 2개의 값들이 들어가게 된다. 쉽게 생각해보면 input_dim = 1과 같다고 볼 수 있다.
model = Sequential() model.add(LSTM(128, input_shape=(4, 1))) model.add(Dense(12, activation='softmax'))
LSTM(출력값, 입력되는 모형) 등의 형태로 사용할 수 있다.
전체코드
import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Dropout, MaxPooling2D, Flatten, LSTM from keras.utils import np_utils import keras import matplotlib.pyplot as plt code2idx = {'c4':0, 'd4':1, 'e4':2, 'f4':3, 'g4':4, 'a4':5, 'b4':6, 'c8':7, 'd8':8, 'e8':9, 'f8':10, 'g8':11, 'a8':12, 'b8':13} idx2code = {0:'c4', 1:'d4', 2:'e4', 3:'f4', 4:'g4', 5:'a4', 6:'b4', 7:'c8', 8:'d8', 9:'e8', 10:'f8', 11:'g8', 12:'a8', 13:'b8'} # 시퀀스 데이터 정의 seq = ['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4'] class losses_callback(keras.callbacks.Callback): def init(self): self.losses = [] def on_batch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) def dataset(seq, window): data = [] for i in range(len(seq)-window): subset = seq[i:i+window+1] data.append([code2idx[i] for i in subset]) return np.array(data) trainData = dataset(seq, 4) X_data = trainData[:, :4]/float(13) X_data = np.reshape(X_data, (50, 4, 1)) Y_data = trainData[:, 4] Y_data = np_utils.to_categorical(Y_data) print(X_data) model = Sequential() model.add(LSTM(128, input_shape=(4, 1))) model.add(Dense(12, activation='softmax')) callBack = losses_callback() callBack.init() model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(X_data, Y_data, batch_size=10, epochs=2000, verbose=2, callbacks=[callBack]) plt.plot(callBack.losses) plt.xlabel('epoch') plt.ylabel('loss') plt.show() score = model.evaluate(X_data, Y_data) print(score) seq_in = ['g8', 'e8', 'e4', 'f8'] seq_out = seq_in seq_in = [code2idx[i]/13 for i in seq_in] for i in range(50): sample_in = np.array(seq_in) sample_in = np.reshape(sample_in, (1, 4, 1)) predict_val = model.predict(sample_in) idx = np.argmax(predict_val) seq_out.append(idx2code[idx]) seq_in.append(idx/float(13)) seq_in.pop(0) print(seq_out)
정확도
[0.27173307418823245, 0.8999999904632568]
예측된 악보
model.add(LSTM(128, batch_input_shape=(1, 4, 1), stateful=True))
for i in range(2000): print('epochs', i) model.fit(X_data, Y_data, batch_size=1, epochs=1, verbose=2, shuffle=False, callbacks=[callBack]) model.reset_states()
import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Dropout, MaxPooling2D, Flatten, LSTM from keras.utils import np_utils import keras import matplotlib.pyplot as plt code2idx = {'c4': 0, 'd4': 1, 'e4': 2, 'f4': 3, 'g4': 4, 'a4': 5, 'b4': 6, 'c8': 7, 'd8': 8, 'e8': 9, 'f8': 10, 'g8': 11, 'a8': 12, 'b8': 13} idx2code = {0: 'c4', 1: 'd4', 2: 'e4', 3: 'f4', 4: 'g4', 5: 'a4', 6: 'b4', 7: 'c8', 8: 'd8', 9: 'e8', 10: 'f8', 11: 'g8', 12: 'a8', 13: 'b8'} # 시퀀스 데이터 정의 seq = ['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4'] class losses_callback(keras.callbacks.Callback): def init(self): self.losses = [] def on_batch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) def dataset(seq, window): data = [] for i in range(len(seq) - window): subset = seq[i:i + window + 1] data.append([code2idx[i] for i in subset]) return np.array(data) trainData = dataset(seq, 4) X_data = trainData[:, :4]/13 X_data = np.reshape(X_data, (50, 4, 1)) Y_data = trainData[:, 4] Y_data = np_utils.to_categorical(Y_data) model = Sequential() model.add(LSTM(128, batch_input_shape=(1, 4, 1), stateful=True)) model.add(Dense(12, activation='softmax')) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) callBack = losses_callback() callBack.init() for i in range(2000): print('epochs', i) model.fit(X_data, Y_data, batch_size=1, epochs=1, verbose=2, shuffle=False, callbacks=[callBack]) model.reset_states() plt.plot(callBack.losses) plt.xlabel('epoch') plt.ylabel('loss') plt.show() score = model.evaluate(X_data, Y_data, batch_size=1) model.reset_states() print(score) seq_in = ['g8', 'e8', 'e4', 'f8'] seq_out = seq_in seq_in = [code2idx[i]/13 for i in seq_in] for i in range(50): sample_in = np.array(seq_in) sample_in = np.reshape(sample_in, (1, 4, 1)) predict_val = model.predict(sample_in) idx = np.argmax(predict_val) seq_out.append(idx2code[idx]) seq_in.append(idx/13) seq_in.pop(0) model.reset_states() print(seq_out)
확률
[0.0001798874410951612, 1.0]
결과
['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4']
'Python-이론 > python-인공지능2' 카테고리의 다른 글
[핸즈온 머신러닝] 3강 scikitLearn Classification를 공부하고 2편 (0) | 2018.07.11 |
---|---|
[핸즈온 머신러닝] 3강 scikitLearn Classification를 공부하고 1편 (3) | 2018.07.10 |
[keras]퍼셉트론을 활용해서 악보 만들기 (0) | 2018.06.10 |
[machineLearning] opencv로 얼굴 인식하기 (0) | 2018.06.09 |
[keras]색 있는 이미지 분류하기2 (0) | 2018.06.03 |