C.W.K.
Stream
Lesson 07 of 07 · published

실전 — Custom Transformer block

~8 min · subclass

Level 0Keras 도제
0 XP0/97 lessons0/20 achievements
0/120 XP to next level120 XP to go0% complete

한 block 에 전부

이게 capstone 이야: 이 track 의 모든 아이디어를 한꺼번에 쓰는 Transformer encoder block. subclass Layer 이고 (lesson 1–3), Dropout sub-layer 에 training flag 를 통과시키고 (lesson 4), built-in 처럼 Functional model 에 끼우게 만들어졌어 (lesson 5). block 은 네 종류 sub-layer 를 품어 — multi-head self-attention, 2-layer feed-forward network, LayerNormalization 둘, Dropout 둘 — 그리고 call() 에서 배선해 (Code block 참고).

두 sub-block 과 residual

모양은 원조 Transformer 레시피야: sub-block 둘, 각각 residual connection 으로 감싸. 첫 번째는 입력에 self-attention 을 돌리고 그 결과를 입력에 다시 더해 (out1 = norm1(inputs + attn_output)) — 이 inputs + 가 gradient 를 attention 너머로 흐르게 하는 skip connection 이야. 두 번째는 feed-forward network 를 돌리고 *그것의* 입력을 같은 방식으로 다시 더해. LayerNormalization 둘이 각 sub-block 을 안정화하고, residual 덧셈이 이 block 을 깊게 쌓아도 학습되는 이유야. 이건 post-norm (덧셈 후 정규화) 이고, 현대 변형 다수는 norm 을 sub-layer *앞* 으로 옮겨 (pre-norm) 깊은 stack 을 더 안정적으로 학습해 — block 을 네가 소유하면 한 줄 바꾸면 돼.

이 block 을 N 번 쌓으면 Transformer encoder. 소스를 네가 가지니까 모든 연구 변형 — RoPE, sparse attention, LoRA adapter, grouped-query attention — 이 네가 제어하는 class 안의 작은 수정이지, 남의 라이브러리 fork 가 아니야.

Code

subclass Layer 로 짠 Transformer encoder block·python
class TransformerBlock(keras.layers.Layer):
    def __init__(self, embed_dim, num_heads, ff_dim, rate=0.1, **kwargs):
        super().__init__(**kwargs)
        self.att = layers.MultiHeadAttention(
            num_heads=num_heads, key_dim=embed_dim
        )
        self.ffn = keras.Sequential([
            layers.Dense(ff_dim, activation="relu"),
            layers.Dense(embed_dim),
        ])
        self.norm1 = layers.LayerNormalization(epsilon=1e-6)
        self.norm2 = layers.LayerNormalization(epsilon=1e-6)
        self.dropout1 = layers.Dropout(rate)
        self.dropout2 = layers.Dropout(rate)

    def call(self, inputs, training=False):
        attn_output = self.att(inputs, inputs)
        attn_output = self.dropout1(attn_output, training=training)
        out1 = self.norm1(inputs + attn_output)
        ffn_output = self.ffn(out1)
        ffn_output = self.dropout2(ffn_output, training=training)
        return self.norm2(out1 + ffn_output)

External links

Exercise

vanilla Transformer encoder block 을 Subclassed Layer 로 구현. 4 개 쌓아. 작은 synthetic seq2seq task (예: sequence 뒤집기) 학습. 동작하는지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.