엑셀에서 정규 표현식을 쓸 경우가 있다. 정규 표현식이 아니면 엄청 괴로울 수 있다. 고맙게도 선구자가 고민하여 공유했다. 감사합니다. 잘 쓰겠습니다. 위 사이트에서 가져온 코드다.
Function RegexExecute(r As Range, p As String, Optional g As Boolean = False) As Variant On Error GoTo ErrHandler
Dim str As String, ptn As String
str = CStr(r.Cells(1, 1).Value)
ptn = CStr(p)
Set regex = CreateObject("VBScript.RegExp")
With regex
.IgnoreCase = False
.MultiLine = False
.Global = g
.Pattern = ptn
End With If regex.Test(str) Then Set matches = regex.Execute(str)
Dim temp As String
temp = "" For Each Match In matches
temp = temp & Match
Next
RegexExecute = temp
Exit Function
End If
ErrHandler:
RegexExecute = CVErr(xlErrNA)
End Function
속도, 시각을 알 경우, 가속도를 구해야 한다. peek 함수가 메모리에 저장된 현재 행 바로 전 값(-1)을 찾는다. 메모리에서 찾으므로 load 해야 한다.
다음 속도, 시각 테이블을 Sheet1 엑셀 파일로 가지고 있다.
시각 속도
0.002 10
0.004 10.5
0.006 11
0.008 11.5
0.01 12
0.012 12.5
0.014 13
0.016 13.5
아래는 qlik이 자동으로 만든 코드이다. qlik을 잘 알면 더 깔끔하게 사용할 수 있으나, 지저분하지만 내 시간을 적게 사용한 아래도 괜찮다.
[Sheet1]:
LOAD
[시각],
[속도]
FROM [lib://가속도분석/테스트.xlsx]
(ooxml, embedded labels, table is Sheet1);
사용자 지정 script를 추가한다. peek를 적용할 경우, order by를 명시해야 한다. 엄한 값을 갖는 경우도 있다.
가속도tmp:
load
[시각] as [가속도.시각],
[속도] as [가속도.속도],
peek([가속도.속도]) as [가속도.전속도],
peek([가속도.시각]) as [가속도.전시각]
Resident [Sheet1]
order by [시각] asc;
drop Table [Sheet1];
가속도:
load
[가속도.시각],
[가속도.속도],
([가속도.전속도]/[가속도.전시각]) as [가속도.가속도]
Resident [가속도tmp];
drop Table [가속도tmp];
강아지 책에 나온 예제를 실행했다. 책 실행 환경과 내 그것이 달라 실행할 수 없었다. 나는 docker로 tensorflow를 사용한다. 그것도 cpu가 avx 등 을 지원하지 않아 직접 컴파일했다. openAi gym은 GUI 환경에서 실행되어 docker로 구동하기 힘들다. 데스크탑을 거실에 설치하여 다른 노트북에서 ssh로 접속하여 사용한다. 이런 모든 문제를 jypyter notebook로 해결했다. 전 글에 설명한대로 docker를 아래 명령으로 구동한다.
import sys
import gym
import pylab
import random
import numpy as np
from collections import deque
from keras.layers import Dense
from keras.optimizers import Adam
from keras.models import Sequential
from gym import wrappers
EPISODES = 300
# 카트폴 예제에서의 DQN 에이전트
class DQNAgent:
def __init__(self, state_size, action_size):
self.render = False
self.load_model = False
# 상태와 행동의 크기 정의
self.state_size = state_size
self.action_size = action_size
print("self.state_size는", self.state_size)
print("self.action_size는", self.action_size)
# DQN 하이퍼파라미터
self.discount_factor = 0.99
self.learning_rate = 0.001
self.epsilon = 1.0
self.epsilon_decay = 0.999
self.epsilon_min = 0.01
self.batch_size = 64
#self.batch_size = 1
self.train_start = 1000
# 리플레이 메모리, 최대 크기 2000
self.memory = deque(maxlen=2000)
# 모델과 타깃 모델 생성
self.model = self.build_model()
self.target_model = self.build_model()
# 타깃 모델 초기화
self.update_target_model()
if self.load_model:
self.model.load_weights("./save_model/cartpole_dqn_trained.h5")
# 상태가 입력, 큐함수가 출력인 인공신경망 생성
def build_model(self):
model = Sequential()
model.add(Dense(24, input_dim=self.state_size, activation='relu',
kernel_initializer='he_uniform'))
model.add(Dense(24, activation='relu',
kernel_initializer='he_uniform'))
model.add(Dense(self.action_size, activation='linear',
kernel_initializer='he_uniform'))
model.summary()
model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate))
return model
# 타깃 모델을 모델의 가중치로 업데이트
def update_target_model(self):
self.target_model.set_weights(self.model.get_weights())
# 입실론 탐욕 정책으로 행동 선택
def get_action(self, state):
if np.random.rand() <= self.epsilon:
return random.randrange(self.action_size)
else:
q_value = self.model.predict(state)
#print("q_value는", q_value)
#print("argamx(q_value)는", np.argmax(q_value[0]))
#print("State는", state)
return np.argmax(q_value[0])
# 샘플 <s, a, r, s'>을 리플레이 메모리에 저장
def append_sample(self, state, action, reward, next_state, done):
self.memory.append((state, action, reward, next_state, done))
# 리플레이 메모리에서 무작위로 추출한 배치로 모델 학습
def train_model(self):
if self.epsilon > self.epsilon_min:
self.epsilon *= self.epsilon_decay
# 메모리에서 배치 크기만큼 무작위로 샘플 추출
mini_batch = random.sample(self.memory, self.batch_size)
states = np.zeros((self.batch_size, self.state_size))
next_states = np.zeros((self.batch_size, self.state_size))
actions, rewards, dones = [], [], []
for i in range(self.batch_size):
states[i] = mini_batch[i][0]
actions.append(mini_batch[i][1])
rewards.append(mini_batch[i][2])
next_states[i] = mini_batch[i][3]
dones.append(mini_batch[i][4])
# 현재 상태에 대한 모델의 큐함수
# 다음 상태에 대한 타깃 모델의 큐함수
target = self.model.predict(states)
target_val = self.target_model.predict(next_states)
# 벨만 최적 방정식을 이용한 업데이트 타깃
for i in range(self.batch_size):
#print("target은", target[i])
if dones[i]:
target[i][actions[i]] = rewards[i]
else:
target[i][actions[i]] = rewards[i] + self.discount_factor * (
np.amax(target_val[i]))
self.model.fit(states, target, batch_size=self.batch_size,
epochs=10, verbose=0)
if __name__ == "__main__":
# CartPole-v1 환경, 최대 타임스텝 수가 500
env = gym.make('CartPole-v1')
env = wrappers.Monitor(env, "./gym-results-Cart", force=True, video_callable=lambda episode_id: episode_id%20==0)
state_size = env.observation_space.shape[0]
action_size = env.action_space.n
# DQN 에이전트 생성
agent = DQNAgent(state_size, action_size)
scores, episodes = [], []
for e in range(EPISODES):
done = False
score = 0
# env 초기화
#env = wrappers.Monitor(env, "./gym-results-Cart", force=True)
state = env.reset()
state = np.reshape(state, [1, state_size])
#print("state reshape는",state)
while not done:
if agent.render:
env.render()
# 현재 상태로 행동을 선택
action = agent.get_action(state)
# 선택한 행동으로 환경에서 한 타임스텝 진행
next_state, reward, done, info = env.step(action)
next_state = np.reshape(next_state, [1, state_size])
# 에피소드가 중간에 끝나면 -100 보상
reward = reward if not done or score == 499 else -100
# 리플레이 메모리에 샘플 <s, a, r, s'> 저장
agent.append_sample(state, action, reward, next_state, done)
# 매 타임스텝마다 학습
if len(agent.memory) >= agent.train_start:
agent.train_model()
score += reward
state = next_state
if done:
# 각 에피소드마다 타깃 모델을 모델의 가중치로 업데이트
agent.update_target_model()
score = score if score == 500 else score + 100
# 에피소드마다 학습 결과 출력
scores.append(score)
episodes.append(e)
#pylab.plot(episodes, scores, 'b')
#pylab.savefig("./save_graph/cartpole_dqn.png")
print("episode:", e, " score:", score, " memory length:",
len(agent.memory), " epsilon:", agent.epsilon)
# 이전 10개 에피소드의 점수 평균이 490보다 크면 학습 중단
if np.mean(scores[-min(10, len(scores)):]) > 490:
agent.model.save_weights("./save_model/cartpole_dqn.h5")
sys.exit()
다음 내용을 수정했다.
10 행: from gym import wrappers: wrappers 사용.
120 행: env = wrappers.Monitor(env, “./gym-results-Cart”, force=True, video_callable=lambda episode_id: episode_id%20==0): 20번마다 동영상으로 저장. 여기를 설정하지 않으면 64번째 에피소드 동영상을 저장하고, 1,000번째 에피소드로 넘어간다. 학습 과정을 알 수 없다.
cartPole-v1은 10초 동안 막대기가 넘어지지 않으면 끝나는 모델이다. 10초 전 막대기가 12도 넘게 기울어지면 끝난다. Q-learning은 아래 식으로 정의된다. 는 learning rate, 는 discount factor.
위 식에서 와 로 오차를 줄여 나간다. 오차는 정답 – 예측 로 정의한다. keras.fit에서 state에 따른 예측과 정답인 target[i]로 학습한다. keras.fit을 부르기 전에 miniBatch 크기 모든 target[size]를 업데이트한다. print로 taget[i]값을 확인할 수 있다.