Open njs03332 opened 1 year ago
assign roles -s 0906 -c 1 2 3
0 | 1 | 2 | |
---|---|---|---|
member | 한단비 | 주선미 | 김유리 |
chapter | 1 | 2 | 3 |
심층 RNN: 셀을 여러 층으로 쌓은 RNN
model = keras.models.Sequential([
keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
keras.layers.SimpleRNN(20, return_sequences=True),
keras.layers.SimpleRNN(1)
])
return_sequences=True
로 설정해야 모든 타임 스텝에 대한 출력을 담은 3D 배열이 출력됨
출력층을 Dense 층으로 바꾸면 더 빠르면서 정확도는 거의 비슷함
model = keras.models.Sequential([
keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
keras.layers.SimpleRNN(20),
keras.layers.Dense(1)
])
다음 값 10개를 예측하고 싶은 경우
방법 1. 이미 훈련된 모델을 사용하여 다음 값을 예측한 다음 이 값을 입력으로 추가
series = generate_time_series(1, n_steps + 10)
X_new, y_new = series[:,:n_steps], series[:,n_steps:]
X=X_new
for step_ahead in range(10):
y_pred = model.predict(X[:,step_ahead:])[:, np.newaxis,:]
X = np.concatenate([X,y_pred],axis=1)
Y_pred = X[:, n_steps:]
다음 스텝에 대한 예측은 보통 더 미래의 타임 스텝에 대한 예측보다 정확함 (오차가 누적될 수 있으므로)
위 방법을 사용했을 때 MSE=0.029
방법 2. RNN을 훈련하여 다음 값 10개를 한 번에 예측
# 타깃을 다음 10개의 값이 담긴 벡터로 바꿈
series = generate_time_series(10000, n_steps + 10)
X_train, y_train = series[:7000, :n_steps], series[:7000, -10:, 0]
X_valid, y_valid = series[7000:9000, :n_steps], series[7000:9000, -10:, 0]
X_test, y_test = series[9000:, :n_steps], series[9000:, -10:, 0]
model = keras.models.Sequential([ keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]), keras.layers.SimpleRNN(20), keras.layers.Dense(10) ])
Y_pred = model.predict(X_new)
- 이 모델의 MSE=0.008
- 시퀀스-투-시퀀스 RNN으로 바꾸면 개선 가능 (마지막 타임 스텝에서 뿐만 아니라 모든 타임 스텝에서 다음 값 10개를 예측하도록 모델을 훈련)
- 장점 - 모든 타임 스텝에서 RNN 출력에 대한 항이 손실에 포함됨
- 각 타임 스텝의 출력에서 그레이디언트가 흐를 수 있음
- 훈련을 안정적으로 만들고 훈련 속도를 높임
```python
Y = np.empty((10000, n_steps, 10)) # 각 타깃은 10D 벡터의 시퀀스
for step_ahead in range(1, 10 + 1):
Y[..., step_ahead - 1] = series[..., step_ahead:step_ahead + n_steps, 0]
Y_train = Y[:7000]
Y_valid = Y[7000:9000]
Y_test = Y[9000:]
return_sequences=True
지정Dense
층에 적용해야 함 -> TimeDistributed
층 이용
model = keras.models.Sequential([
keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
keras.layers.SimpleRNN(20, return_sequences=True),
keras.layers.TimeDistributed(keras.layers.Dense(10))
])
def last_time_step_mse(Y_true, Y_pred):
return keras.metrics.mean_squared_error(Y_true[:, -1], Y_pred[:, -1])
optimizer=keras.optimizers.Adam(lr=0.01)
model.compile(loss="mse",
optimizer=optimizer,
metrics=[last_time_step_mse])
def generate_time_series(batch_size, n_steps): freq1, freq2, offset1, offset2 = np.random.rand(4, batch_size, 1) time = np.linspace(0, 1, n_steps) series = 0.5 np.sin((time - offset1) (freq1 10 + 10)) # 사인 곡선 1 series += 0.2 np.sin((time - offset2) (freq2 20 + 20)) # + 사인 곡선 2 series += 0.1 * (np.random.rand(batch_size, n_steps) - 0.5) # + 잡음 return series[..., np.newaxis].astype(np.float32) # size: [ 배치 크기, 타임 스텝 수, 1]
n_steps = 50 series = generate_time_series(10000, n_steps + 1) X_train, y_train = series[:7000, :n_steps], series[:7000, -1] # size: [7000, 50, 1], [7000,1] X_valid, y_valid = series[7000:9000, :n_steps], series[7000:9000, -1] # X_test, y_test = series[9000:, :n_steps], series[9000:, -1]
y_pred = X_valid[:, -1]
np.mean(keras.losses.mean_squared_error(y_valid, y_pred))
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[50, 1]),
keras.layers.Dense(1)
])
model = keras.models.Sequential([
keras.layers.SimpleRNN(1, input_shape=[None, 1])
])