멀티헤드 어텐션은 트랜스포머가 여러 가지에 동시에 주의를 기울이게 합니다. 입력 X(n개 토큰 × d개 열)와 d × d 크기의 가중치 행렬에 대해:
- Q = X × w_q, K = X × w_k, V = X × w_v
- d개의 열을
num_heads개의 헤드로 나눕니다. 각 헤드는 연속된 d_k = d / num_heads개의 열을 가집니다 (헤드 h는 열 h×d_k부터 (h+1)×d_k - 1까지 사용). - 각 헤드에서 그 열들로 스케일드 닷-프로덕트 어텐션을 실행합니다: 토큰 i에 대해 그 헤드의 열로 score_j = (Q_i · K_j) / √d_k를 계산하고, n개의 모든 토큰 j에 대해 소프트맥스를 취한 뒤, 출력 = Σ weight_j × V_j (그 헤드의 열).
- 각 헤드의 출력을 원래 열에 다시 놓고(연결하고) w_o를 곱합니다.
multi_head_attention(x, w_q, w_k, w_v, w_o, num_heads)를 구현하세요.
입력
x: n × d 입력 행렬.
w_q, w_k, w_v, w_o: d × d 가중치 행렬.
num_heads: 헤드 수 (d는 이 수로 나누어떨어짐).
출력
n × d 출력 행렬을 반환하세요.
제약 조건
1 ≤ n ≤ 30, 1 ≤ d ≤ 32, 1 ≤ num_heads ≤ d이며 d는 num_heads로 나누어떨어짐
-5 ≤ 각 값 ≤ 5
예시
입력:
x = [
[1.0, 0.0],
[0.0, 1.0]
]
w_q = [
[0.0, 0.0],
[0.0, 0.0]
]
w_k = [
[1.0, 0.0],
[0.0, 1.0]
]
w_v = [
[1.0, 0.0],
[0.0, 1.0]
]
w_o = [
[1.0, 0.0],
[0.0, 1.0]
]
num_heads = 1
예상 출력:
[
[0.5, 0.5],
[0.5, 0.5]
]
설명
w_q가 모두 0이므로 모든 점수가 0이고 각 토큰은 값 행들의 평균이 됩니다: V = X이므로 두 행 모두 [0.5, 0.5]가 됩니다.
입력:
x = [
[2.0, 4.0]
]
w_q = [
[1.0, 0.0],
[0.0, 1.0]
]
w_k = [
[1.0, 0.0],
[0.0, 1.0]
]
w_v = [
[1.0, 0.0],
[0.0, 1.0]
]
w_o = [
[0.0, 1.0],
[1.0, 0.0]
]
num_heads = 2
예상 출력:
[
[4.0, 2.0]
]
설명
토큰이 하나뿐이므로 각 헤드는 자기 자신에게만 주의를 기울이고, 연결된 출력은 V = [2, 4]입니다. w_o가 두 열을 바꾸므로 [4, 2]가 됩니다.
참고 자료
-
예시 1 미실행입력:
x = [ [1.0, 0.0], [0.0, 1.0] ] w_q = [ [0.0, 0.0], [0.0, 0.0] ] w_k = [ [1.0, 0.0], [0.0, 1.0] ] w_v = [ [1.0, 0.0], [0.0, 1.0] ] w_o = [ [1.0, 0.0], [0.0, 1.0] ] num_heads = 1예상 출력:[ [0.5, 0.5], [0.5, 0.5] ]내 출력 -
예시 2 미실행입력:
x = [ [2.0, 4.0] ] w_q = [ [1.0, 0.0], [0.0, 1.0] ] w_k = [ [1.0, 0.0], [0.0, 1.0] ] w_v = [ [1.0, 0.0], [0.0, 1.0] ] w_o = [ [0.0, 1.0], [1.0, 0.0] ] num_heads = 2예상 출력:[ [4.0, 2.0] ]내 출력
제출 시 4개의 숨겨진 테스트도 실행됩니다. 코드가 하나라도 실패하면 그 테스트를 볼 수 있습니다. 챌린지를 해결하면 모두 볼 수 있습니다.
Online Java Compiler
Write, compile, run, and debug Java code online in a full-featured browser IDE. Work with multiple files, save your workspace, and share or collaborate in real time - no setup required.
☕ 이 Java 온라인 실행기 소개
CodeUtility Java Executor는 브라우저에서 바로 Java 프로그램을 작성하고 실행할 수 있게 해줍니다 - 설치, JDK 설정, IDE가 필요 없습니다. 실제 Java 런타임 버전 8, 11, 17, 21, 그리고 최신을 지원하는 안전한 샌드박스에서 동작합니다.
이 도구는 실제 javac 컴파일러와 Java 런타임 환경을 사용해 클라우드에서 코드를 컴파일하고 실행하므로,
로컬과 동일한 방식으로 클래스, 메서드, 로직을 정확히 테스트할 수 있습니다.
객체지향 프로그래밍을 연습하든, 면접을 준비하든, 통합 전에 스니펫을 시험해 보든, CodeUtility Java Executor는 어떤 기기에서든 즉시 실제 Java 코드를 실행할 수 있는 빠르고 신뢰할 수 있는 환경을 제공합니다.
하나의 실행기에서 다중 파일 편집기, 격리된 실행 터미널, 런타임별 라이브러리, 영구 작업 공간, 공유 및 실시간 협업을 이용하세요.
이 실행기는 어떻게 사용하나요?
런타임을 선택하고 파일을 열거나 만든 다음 코드를 작성하고 실행을 선택하세요. 출력은 터미널에 표시되며, 로그인한 사용자는 작업 공간에 파일을 보관하고 라이브러리를 설치하며 공유를 통해 협업할 수 있습니다.
- 버전을 선택하고 현재 파일을 편집하거나 작업 공간의 다른 파일을 여세요.
- 코드를 실행하고 요청 시 터미널에 입력한 다음 저장된 실행 기록을 확인하세요.
- 작업에 둘 이상의 코드 조각이 필요하면 라이브러리, 작업 공간 도구, 공유 및 채팅을 사용하세요.
💡 위에서 바로 시도할 수 있는 Java 기초와 예제
1. 변수와 상수 선언
Java에서는 각 변수의 타입을 선언해야 합니다. 상수에는 final을 사용하세요.
int age = 30;
double pi = 3.14159;
char grade = 'A';
String name = "Alice";
boolean isActive = true;
// 상수
final int MAX_USERS = 100;
final String COMPANY = "CodeUtility";
2. 조건문 (if / switch)
제어 흐름에는 if, else if, switch를 사용하세요.
int x = 2;
if (x == 1) {
System.out.println("하나");
} else if (x == 2) {
System.out.println("둘");
} else {
System.out.println("그 외");
}
switch (x) {
case 1:
System.out.println("하나");
break;
case 2:
System.out.println("둘");
break;
default:
System.out.println("그 외");
}
3. 반복문
반복에는 for, while, do-while을 사용하세요.
for (int i = 0; i < 3; i++) {
System.out.println(i);
}
int n = 3;
while (n > 0) {
System.out.println(n);
n--;
}
4. 배열
배열은 같은 타입의 고정 크기 시퀀스를 담습니다.
int[] numbers = {10, 20, 30};
System.out.println(numbers[1]);
5. ArrayList 다루기
가변 크기 리스트에는 ArrayList를 사용하세요.
import java.util.ArrayList;
ArrayList<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.remove(Integer.valueOf(2));
for (int num : nums) {
System.out.print(num + " ");
}
6. 콘솔 입력/출력
입력에는 Scanner, 출력에는 System.out을 사용하세요.
import java.util.Scanner;
Scanner scanner = new Scanner(System.in);
System.out.print("이름을 입력하세요: ");
String name = scanner.nextLine();
System.out.println("안녕하세요, " + name);
7. 함수
반환 타입과 매개변수를 지정해 메서드를 정의합니다.
public static int add(int a, int b) {
return a + b;
}
System.out.println(add(3, 4));
8. HashMap
키-값 저장에는 HashMap을 사용하세요.
import java.util.HashMap;
HashMap<String, Integer> ages = new HashMap<>();
ages.put("Alice", 30);
System.out.println(ages.get("Alice"));
9. 예외 처리
런타임 예외 처리는 try와 catch를 사용하세요.
try {
throw new Exception("문제가 발생했습니다");
} catch (Exception e) {
System.out.println(e.getMessage());
}
10. 파일 I/O
파일 처리에는 java.nio.file의 Files와 Paths를 사용하세요.
import java.nio.file.*;
import java.io.IOException;
Files.writeString(Paths.get("file.txt"), "안녕, 파일");
String content = Files.readString(Paths.get("file.txt"));
System.out.println(content);
11. 문자열 조작
Java 문자열은 length(), substring(), contains() 같은 다양한 메서드를 지원합니다.
String text = "Hello World";
System.out.println(text.length());
System.out.println(text.substring(0, 5));
System.out.println(text.contains("World"));
12. 클래스와 객체
Java는 클래스와 인스턴스를 사용한 객체지향 프로그래밍을 지원합니다.
class Person {
String name;
Person(String name) {
this.name = name;
}
void greet() {
System.out.println("안녕, 나는 " + name);
}
}
Person p = new Person("Alice");
p.greet();