01_tensor_basics.py

Download
python 284 lines 7.0 KB
  1"""
  201. ํ…์„œ ๊ธฐ์ดˆ - NumPy ๋ฒ„์ „
  3
  4NumPy๋กœ ํ…์„œ ์—ฐ์‚ฐ๊ณผ ์ˆ˜๋™ ๋ฏธ๋ถ„์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  5PyTorch ๋ฒ„์ „(examples/pytorch/01_tensor_autograd.py)๊ณผ ๋น„๊ตํ•ด ๋ณด์„ธ์š”.
  6
  7ํ•ต์‹ฌ ์ฐจ์ด์ :
  8- NumPy: ์ž๋™ ๋ฏธ๋ถ„ ์—†์Œ, ์ง์ ‘ ๋ฏธ๋ถ„ ๊ณ„์‚ฐ
  9- PyTorch: autograd๋กœ ์ž๋™ ๋ฏธ๋ถ„
 10"""
 11
 12import numpy as np
 13
 14print("=" * 60)
 15print("NumPy ํ…์„œ ๊ธฐ์ดˆ์™€ ์ˆ˜๋™ ๋ฏธ๋ถ„")
 16print("=" * 60)
 17
 18
 19# ============================================
 20# 1. ๋ฐฐ์—ด ์ƒ์„ฑ (ํ…์„œ)
 21# ============================================
 22print("\n[1] ๋ฐฐ์—ด ์ƒ์„ฑ")
 23print("-" * 40)
 24
 25# ๋ฆฌ์ŠคํŠธ์—์„œ ์ƒ์„ฑ
 26arr1 = np.array([1, 2, 3, 4])
 27print(f"๋ฆฌ์ŠคํŠธ โ†’ ๋ฐฐ์—ด: {arr1}")
 28print(f"  shape: {arr1.shape}, dtype: {arr1.dtype}")
 29
 30# ํŠน์ˆ˜ ๋ฐฐ์—ด
 31zeros = np.zeros((3, 4))
 32ones = np.ones((2, 3))
 33rand = np.random.randn(2, 3)  # ํ‘œ์ค€ ์ •๊ทœ ๋ถ„ํฌ
 34arange = np.arange(0, 10, 2)
 35
 36print(f"zeros(3,4): shape {zeros.shape}")
 37print(f"randn(2,3):\n{rand}")
 38
 39# dtype ์ง€์ •
 40float_arr = np.array([1, 2, 3], dtype=np.float32)
 41print(f"float32 ๋ฐฐ์—ด: {float_arr}")
 42
 43
 44# ============================================
 45# 2. ๋ฐฐ์—ด ์—ฐ์‚ฐ
 46# ============================================
 47print("\n[2] ๋ฐฐ์—ด ์—ฐ์‚ฐ")
 48print("-" * 40)
 49
 50a = np.array([[1, 2], [3, 4]], dtype=np.float32)
 51b = np.array([[5, 6], [7, 8]], dtype=np.float32)
 52
 53# ์š”์†Œ๋ณ„ ์—ฐ์‚ฐ
 54print(f"a + b:\n{a + b}")
 55print(f"a * b (์š”์†Œ๋ณ„):\n{a * b}")
 56
 57# ํ–‰๋ ฌ ๊ณฑ์…ˆ
 58print(f"a @ b (ํ–‰๋ ฌ ๊ณฑ):\n{a @ b}")
 59print(f"np.dot(a, b):\n{np.dot(a, b)}")
 60
 61# ํ†ต๊ณ„
 62print(f"a.sum(): {a.sum()}")
 63print(f"a.mean(): {a.mean()}")
 64print(f"a.max(): {a.max()}")
 65
 66
 67# ============================================
 68# 3. ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…
 69# ============================================
 70print("\n[3] ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…")
 71print("-" * 40)
 72
 73x = np.array([[1], [2], [3]])  # (3, 1)
 74y = np.array([10, 20, 30])     # (3,)
 75
 76result = x + y  # (3, 3)์œผ๋กœ ์ž๋™ ํ™•์žฅ
 77print(f"x shape: {x.shape}")
 78print(f"y shape: {y.shape}")
 79print(f"x + y shape: {result.shape}")
 80print(f"x + y:\n{result}")
 81
 82
 83# ============================================
 84# 4. ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๊ธฐ๋ณธ
 85# ============================================
 86print("\n[4] ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๊ธฐ๋ณธ")
 87print("-" * 40)
 88
 89# y = xยฒ + 3x + 1
 90# dy/dx = 2x + 3
 91
 92def f1(x):
 93    """์ˆœ์ „ํŒŒ: y = xยฒ + 3x + 1"""
 94    return x**2 + 3*x + 1
 95
 96def df1(x):
 97    """์ˆ˜๋™ ๋ฏธ๋ถ„: dy/dx = 2x + 3"""
 98    return 2*x + 3
 99
100x = 2.0
101print(f"f(x) = xยฒ + 3x + 1")
102print(f"f({x}) = {f1(x)}")
103print(f"f'({x}) = {df1(x)}")  # 2*2 + 3 = 7
104print("๊ฒ€์ฆ: dy/dx = 2x + 3 = 2*2 + 3 = 7 โœ“")
105
106
107# ============================================
108# 5. ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๋ณต์žกํ•œ ํ•จ์ˆ˜
109# ============================================
110print("\n[5] ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๋ณต์žกํ•œ ํ•จ์ˆ˜")
111print("-" * 40)
112
113# f(x) = xยณ + 2xยฒ - 5x + 3
114# f'(x) = 3xยฒ + 4x - 5
115
116def f2(x):
117    """์ˆœ์ „ํŒŒ"""
118    return x**3 + 2*x**2 - 5*x + 3
119
120def df2(x):
121    """์ˆ˜๋™ ๋ฏธ๋ถ„"""
122    return 3*x**2 + 4*x - 5
123
124x = 2.0
125print(f"f(x) = xยณ + 2xยฒ - 5x + 3")
126print(f"f({x}) = {f2(x)}")
127print(f"f'({x}) = {df2(x)}")  # 3*4 + 4*2 - 5 = 15
128print("๊ฒ€์ฆ: f'(x) = 3xยฒ + 4x - 5 = 12 + 8 - 5 = 15 โœ“")
129
130
131# ============================================
132# 6. ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๋‹ค๋ณ€์ˆ˜ ํ•จ์ˆ˜
133# ============================================
134print("\n[6] ์ˆ˜๋™ ๋ฏธ๋ถ„ - ๋‹ค๋ณ€์ˆ˜ ํ•จ์ˆ˜")
135print("-" * 40)
136
137# f(x, y) = xยฒ + yยฒ + xy
138# โˆ‚f/โˆ‚x = 2x + y
139# โˆ‚f/โˆ‚y = 2y + x
140
141def f3(x, y):
142    """์ˆœ์ „ํŒŒ"""
143    return x**2 + y**2 + x*y
144
145def df3_dx(x, y):
146    """ํŽธ๋ฏธ๋ถ„ โˆ‚f/โˆ‚x"""
147    return 2*x + y
148
149def df3_dy(x, y):
150    """ํŽธ๋ฏธ๋ถ„ โˆ‚f/โˆ‚y"""
151    return 2*y + x
152
153x, y = 3.0, 4.0
154print(f"f(x, y) = xยฒ + yยฒ + xy")
155print(f"f({x}, {y}) = {f3(x, y)}")
156print(f"โˆ‚f/โˆ‚x at ({x},{y}) = {df3_dx(x, y)}")  # 2*3 + 4 = 10
157print(f"โˆ‚f/โˆ‚y at ({x},{y}) = {df3_dy(x, y)}")  # 2*4 + 3 = 11
158
159
160# ============================================
161# 7. ์ˆ˜์น˜ ๋ฏธ๋ถ„ (Numerical Differentiation)
162# ============================================
163print("\n[7] ์ˆ˜์น˜ ๋ฏธ๋ถ„")
164print("-" * 40)
165
166def numerical_gradient(f, x, h=1e-5):
167    """
168    ์ค‘์•™ ์ฐจ๋ถ„๋ฒ•์œผ๋กœ ์ˆ˜์น˜ ๋ฏธ๋ถ„ ๊ณ„์‚ฐ
169    f'(x) โ‰ˆ (f(x+h) - f(x-h)) / (2h)
170    """
171    return (f(x + h) - f(x - h)) / (2 * h)
172
173# f(x) = xยณ + 2xยฒ - 5x + 3 ํ…Œ์ŠคํŠธ
174x = 2.0
175numerical_grad = numerical_gradient(f2, x)
176analytical_grad = df2(x)
177
178print(f"ํ•ด์„์  ๋ฏธ๋ถ„: {analytical_grad}")
179print(f"์ˆ˜์น˜ ๋ฏธ๋ถ„:   {numerical_grad:.10f}")
180print(f"์˜ค์ฐจ:        {abs(numerical_grad - analytical_grad):.2e}")
181
182
183# ============================================
184# 8. ๋ฒกํ„ฐ ์ž…๋ ฅ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„
185# ============================================
186print("\n[8] ๋ฒกํ„ฐ ์ž…๋ ฅ ๋ฏธ๋ถ„")
187print("-" * 40)
188
189def f_vec(x):
190    """f(x) = sum(xยฒ) = xโ‚ยฒ + xโ‚‚ยฒ + xโ‚ƒยฒ"""
191    return np.sum(x**2)
192
193def df_vec(x):
194    """โˆ‡f = [2xโ‚, 2xโ‚‚, 2xโ‚ƒ]"""
195    return 2 * x
196
197x = np.array([1.0, 2.0, 3.0])
198print(f"f(x) = sum(xยฒ)")
199print(f"x = {x}")
200print(f"f(x) = {f_vec(x)}")
201print(f"โˆ‡f(x) = {df_vec(x)}")
202
203
204# ============================================
205# 9. ์ฒด์ธ ๋ฃฐ (Chain Rule) ์˜ˆ์‹œ
206# ============================================
207print("\n[9] ์ฒด์ธ ๋ฃฐ (Chain Rule)")
208print("-" * 40)
209
210# h(x) = f(g(x))
211# g(x) = xยฒ
212# f(u) = sin(u)
213# h(x) = sin(xยฒ)
214# dh/dx = df/du * dg/dx = cos(xยฒ) * 2x
215
216def g(x):
217    return x**2
218
219def f(u):
220    return np.sin(u)
221
222def h(x):
223    return f(g(x))  # h(x) = sin(xยฒ)
224
225def dh_dx(x):
226    """์ฒด์ธ ๋ฃฐ: dh/dx = cos(xยฒ) * 2x"""
227    return np.cos(x**2) * (2*x)
228
229x = 1.0
230print(f"g(x) = xยฒ, f(u) = sin(u)")
231print(f"h(x) = f(g(x)) = sin(xยฒ)")
232print(f"h({x}) = {h(x):.6f}")
233print(f"dh/dx at x={x}: {dh_dx(x):.6f}")
234print("์ฒด์ธ ๋ฃฐ: dh/dx = cos(xยฒ) * 2x")
235
236
237# ============================================
238# 10. ์†์‹ค ํ•จ์ˆ˜์™€ ๋ฏธ๋ถ„ ์˜ˆ์‹œ
239# ============================================
240print("\n[10] ์†์‹ค ํ•จ์ˆ˜์™€ ๋ฏธ๋ถ„")
241print("-" * 40)
242
243def mse_loss(y_pred, y_true):
244    """MSE: L = (1/n) * ฮฃ(y_pred - y_true)ยฒ"""
245    return np.mean((y_pred - y_true)**2)
246
247def mse_gradient(y_pred, y_true):
248    """โˆ‚L/โˆ‚y_pred = (2/n) * (y_pred - y_true)"""
249    n = len(y_pred)
250    return (2/n) * (y_pred - y_true)
251
252y_true = np.array([1.0, 2.0, 3.0])
253y_pred = np.array([1.1, 2.2, 2.8])
254
255loss = mse_loss(y_pred, y_true)
256grad = mse_gradient(y_pred, y_true)
257
258print(f"y_true: {y_true}")
259print(f"y_pred: {y_pred}")
260print(f"MSE Loss: {loss:.4f}")
261print(f"Gradient: {grad}")
262
263
264# ============================================
265# NumPy vs PyTorch ์ •๋ฆฌ
266# ============================================
267print("\n" + "=" * 60)
268print("NumPy vs PyTorch ๋น„๊ต")
269print("=" * 60)
270
271comparison = """
272| ๊ธฐ๋Šฅ        | NumPy                | PyTorch                    |
273|-------------|----------------------|----------------------------|
274| ๋ฐฐ์—ด ์ƒ์„ฑ    | np.array()          | torch.tensor()             |
275| ๋ฏธ๋ถ„        | ์ง์ ‘ ๊ตฌํ˜„ ํ•„์š”        | .backward() ์ž๋™ ๊ณ„์‚ฐ       |
276| GPU         | ์ง€์› ์•ˆ ํ•จ           | .to('cuda') ์ง€์›           |
277| ์žฅ์         | ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์›๋ฆฌ ์ดํ•ด    | ๋น ๋ฅธ ๊ฐœ๋ฐœ, ์ž๋™ ๋ฏธ๋ถ„        |
278"""
279print(comparison)
280
281print("NumPy ํ…์„œ ๊ธฐ์ดˆ์™€ ์ˆ˜๋™ ๋ฏธ๋ถ„ ์™„๋ฃŒ!")
282print("PyTorch ๋ฒ„์ „๊ณผ ๋น„๊ต: examples/pytorch/01_tensor_autograd.py")
283print("=" * 60)