학습 내용
1. 인공지능과 Python 기초
2. 인공지능과 Python 함수
3. 인공지능과 Python 클래스 이해
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 기본 폰트 사이즈 변경
plt.rcParams['font.size'] = 14
# 기본 그래프 사이즈 변경
plt.rcParams['figure.figsize'] = (4,4)
# 기본 그리드 표시
# 필요에 따라 설정할 때는, plt.grid()
plt.rcParams['axes.grid'] = True
plt.rcParams["grid.linestyle"] = ":"
# 마이너스 기호 정상 출력
plt.rcParams['axes.unicode_minus'] = False
파이썬 연산자
# Print arithmetic result
print(3 + 4)
print(3*2)
print(3**2)
print(3/2)
print(3//2) # 정수 part
print(3%2) # 나머지
print("Welcome to the python world!!")
# print("Welcome to the python world!!")
print(True, False)
7
6
9
1.5
1
1
Welcome to the python world!!
True False
파이썬 자료의 구조 (Container Objects)
- 리스트(list), 튜플(tuple), 사전(dict)
a = 12
b = 12.55
print("type(a) = ", type(a)) # 32 bit/ 4 Byte
print("type(b) = ", type(b)) # 64 bit/ 8 Byte
type(a) = <class 'int'>
type(b) = <class 'float'>
## int 리스트
price = [10000, 3000, 12000]
#list indexing
print("price[0] = ", price[0])
#list slicing
print("price[0:2] = ", price[0:2])
price[0] = 10000
price[0:2] = [10000, 3000]
## string 리스트
fruit = ['apple', 'banana', 'orange']
print("type(fruit) = ", type(fruit))
#list indexing
print("fruit[0] = ", fruit[1])
#list slicing
print("fruit[1:3] = ", fruit[1:3])
type(fruit) = <class 'list'>
fruit[0] = banana
fruit[1:3] = ['banana', 'orange']
## 튜플 (Tuple)
tup = ('apple', 'banana', 'watermelon', 'cucumber')
print("type(tup) = ", type(tup))
#튜플 indexing
print("tup[1] = ", tup[1])
#튜플 slicing
print("tup[1:3] = ", tup[1:3])
# tup[0] = "mango" # TypeError: 'tuple' object does not support item assignment
type(tup) = <class 'tuple'>
tup[1] = banana
tup[1:3] = ('banana', 'watermelon')
## 딕셔너리 (Dictionary)
# * 자료에 접근할 때 'key' 값을 이용해서 접근
flower_price ={
'rose': 10000,
'iris': 3000,
'stargauge': 12000,
'lily': 9000,
'daffodil': 3000
}
print(flower_price, '\n')
## 딕셔너리 접근하기
print(flower_price.items(), '\n')
print(flower_price.keys(), '\n')
print(flower_price.values(), '\n')
print(flower_price.get("rose"), '\n')
flower_price['daisy'] = flower_price.pop('iris')
flower_price
{'rose': 10000, 'iris': 3000, 'stargauge': 12000, 'lily': 9000, 'daffodil': 3000}
dict_items([('rose', 10000), ('iris', 3000), ('stargauge', 12000), ('lily', 9000), ('daffodil', 3000)])
dict_keys(['rose', 'iris', 'stargauge', 'lily', 'daffodil'])
dict_values([10000, 3000, 12000, 9000, 3000])
10000
{'rose': 10000,
'stargauge': 12000,
'lily': 9000,
'daffodil': 3000,
'daisy': 3000}
fruit_price={}
print(type(fruit_price))
fruit_price['apple'] = 1000
print(fruit_price)
## access dictionary data
print("fruit_price['apple'] = \n", fruit_price['apple'])
{'rose': 10000, 'iris': 3000, 'stargauge': 12000, 'lily': 9000, 'daffodil': 3000}
dict_items([('rose', 10000), ('iris', 3000), ('stargauge', 12000), ('lily', 9000), ('daffodil', 3000)])
dict_keys(['rose', 'iris', 'stargauge', 'lily', 'daffodil'])
dict_values([10000, 3000, 12000, 9000, 3000])
{'rose': 10000,
'stargauge': 12000,
'lily': 9000,
'daffodil': 3000,
'daisy': 3000}
if 조건문
# 만약 condition 이 True 이면 code 1 을 수행, False 이면 code 2를 수행
# if condition:
# code 1
# else:
# code 2
#
rose = 1500
if rose < 1000: #Boolean index:
print('장미꽃을 구매합니다')
else:
print('나리꽃을 구매합니다')
나리꽃을 구매합니다
rose = 1500
if rose < 1000: #Boolean index:
print('장미꽃을 구매합니다')
elif rose < 2000: #
print('꽃구매를 기다립니다')
else:
print('나리꽃을 구매합니다')
꽃구매를 기다립니다
for 구문
# for 변수 in 리스트(또는 튜플, 문자열):
# 수행할_문장1
# 수행할_문장2
# ...
for i in range(10):
print(i)
0
1
2
3
4
5
6
7
8
9
## Using string
flowers = ['장미', '백합', '붓꽃', '해바라기']
for i in flowers:
print(i)
장미
백합
붓꽃
해바라기
## Using index
flowers = ['장미', '백합', '붓꽃', '해바라기', '후리지아']
for i in [0,1,2,3]:
print(flowers[i])
장미
백합
붓꽃
해바라기
While 반복문
# 초기식
# while 조건식:
# 반복할 코드
# 변화식
i = 0
while i <= 10:
print(i)
i += 1
0
1
2
3
4
5
6
7
8
9
10
rose = 1000
day = 1
while day <= 10:
rose = rose + rose*0.1
print(round(rose, 3), ", day = ", day)
day += 1
1100.0 , day = 1
1210.0 , day = 2
1331.0 , day = 3
1464.1 , day = 4
1610.51 , day = 5
1771.561 , day = 6
1948.717 , day = 7
2143.589 , day = 8
2357.948 , day = 9
2593.742 , day = 10
파이썬 함수만들기
# 함수정의 기본 문법
# def 함수 이름:
# 함수 내용
# 함수 호출
def myfunction(): # 함수 이름
print("Hello World") # 함수 내용
myfunction() # 함수 호출
Hello World
# 합을 구하는 함수
def addNum(num1: int | float, num2: int | float) -> float:
sum = num1 + num2
return float(sum)
result = addNum(10, 2)
print("result = ", result)
print("result = ", type(result))
result = 12.0
result = <class 'float'>
## 여러 개의 값 반환하기
def add_sub(num1: int | float, num2: int | float) -> int | float:
add = num1 + num2
sub = num1 - num2
return add, sub
x = add_sub(3, 4.3) # tuple로 반환
print('x = ', x)
add, sub = add_sub(3, 4.3)
print("add = {}, sub = {}".format(add, sub))
x = (7.3, -1.2999999999999998)
add = 7.3, sub = -1.2999999999999998
## 함수내 함수호출, stack 구조
def mul(a, b):
return a*b
def divide(a, b):
return a/b
def mul_div(x, y):
num1 = mul(x, y)
num2 = divide(x, y)
return num1, num2
result = mul_div(2, 1)
print('result = ', result)
result = (2, 2.0)
합성 함수를 파이썬으로 구현하기
- 수학에서 합성함수가 파이썬에서 어떻게 구현되는지 확인한다.

def f(x):
return (2 * x**2 + 2)
# 넘파이 배열로 x를 정의
x = np.arange(-2, 2.1, 0.25)
print(x)
[-2. -1.75 -1.5 -1.25 -1. -0.75 -0.5 -0.25 0. 0.25 0.5 0.75
1. 1.25 1.5 1.75 2. ]
# f(x)의 결과를 y에 대입
y = f(x)
print(y)
[10. 8.125 6.5 5.125 4. 3.125 2.5 2.125 2. 2.125
2.5 3.125 4. 5.125 6.5 8.125 10. ]
# 함수를 그래프로 그리기
plt.plot(x, y)
plt.show()

# 세 가지 기본 함수의 정의
def f1(x):
return(x**2)
def f2(x):
return(x*2)
def f3(x):
return(x+2)
# 합성 함수 만들기
x1 = f1(x)
x2 = f2(x1)
y = f3(x2)
# 합성 함수 값 확인
print(y)
[10. 8.125 6.5 5.125 4. 3.125 2.5 2.125 2. 2.125
2.5 3.125 4. 5.125 6.5 8.125 10. ]
# 합성 함수 그래프 그리기
plt.plot(x, y)
plt.show()

## 합, 차 함수
def add(a, b):
return a + b
def sub(a, b):
return a - b
a, b = 1, 2
print("a + b = ", add(a, b))
print("a - b = ", sub(a, b))
a + b = 3
a - b = -1
커스텀 클래스 정의하기
## class 만들기 : 비슷한 기능들을 한 번에 관리
# 클래스는 관련된 데이터(속성)와 기능(메서드)을 하나의 단위로 묶어 관리합니다.
class Calculator:
# 1. 생성자 메서드 (Initializer/Constructor)
def __init__(self, a:int, b:int):
self.result = 0
self.a = a
self.b = b
# 2. 메서드 (Method) - 덧셈 기능
# 객체가 가지고 있는 self.a와 self.b를 사용하여 덧셈을 수행합니다.
def add(self) -> float:
self.result = self.a + self.b
return self.result
# 3. 메서드 (Method) - 뺄셈 기능
# 객체가 가지고 있는 self.a와 self.b를 사용하여 뺄셈을 수행합니다.
def sub(self) -> float:
self.result = self.a - self.b
return self.result
calculator = Calculator(3, 2) # Calculator 클래스의 객체(인스턴스)를 생성하고 __init__을 호출합니다.
print("add = ", calculator.add()) # 15 출력
print("sub = ", calculator.sub()) # # 1 출력
add = 5
sub = 1
클래스 상속
## 상속 (Inheritance)
# CalculatorV2 클래스는 괄호 안에 명시된 Calculator 클래스를 상속받습니다.
# 즉, CalculatorV2는 Calculator의 모든 메서드(add, sub)와 속성(self.a, self.b, self.result)을 물려받습니다.
class CalculatorV2(Calculator):
# 1. 생성자 메서드 오버라이딩 (Overriding __init__)
# 부모 클래스(Calculator)와 달리 세 개의 인자(x, y, c)를 받도록 재정의합니다.
def __init__(self, x, y, c):
super().__init__(x, y)
self.c = c
# 2. 새로운 메서드 추가 (곱셈)
# 부모 클래스에는 없던 새로운 기능(mul)을 추가합니다.
def mul(self):
self.result = self.a * self.b
return self.result
# 3. 새로운 메서드 추가 (나눗셈)
# 부모 클래스에는 없던 새로운 기능(div)을 추가합니다.
def div(self):
self.result = self.a / self.b
return self.result
# 1. 인스턴스 생성 및 __init__ 호출
# CalculatorV2 클래스의 새로운 객체(인스턴스)를 생성합니다.
calculator2 = CalculatorV2(10, 2, 1)
# 2. 부모 클래스(Calculator)로부터 상속받은 add() 메서드를 호출
print(calculator2.add())
# 3. 부모 클래스(Calculator)로부터 상속받은 sub() 메서드를 호출
print(calculator2.sub())
# 4. 자식 클래스(CalculatorV2)에 새로 추가된 메서드 호출
print(calculator2.mul())
# 5. 자식 클래스(CalculatorV2)에 새로 추가된 메서드 호출
print(calculator2.div())
12
8
20
5.0
클래스 상속(attribute)
class Dog:
"""
Dog 클래스는 클래스 속성과 인스턴스 속성을 모두 보여줍니다.
"""
# 1. 클래스 속성 (Class Attribute)
# 클래스 수준에서 정의되며, Dog 클래스의 모든 인스턴스가 이 값을 공유합니다.
# 일반적으로 변하지 않는 공통 값이나 카운터에 사용됩니다.
species = "Beagle"
# 모든 강아지 인스턴스의 수를 추적하기 위한 클래스 속성
instance_count = 0
def __init__(self, name, age):
# 2. 인스턴스 속성 (Instance Attribute)
# __init__ 내에서 self를 사용하여 정의되며, 각 인스턴스마다 고유한 값을 가집니다.
self.name = name
self.age = age
# 인스턴스가 생성될 때마다 클래스 속성인 instance_count를 1 증가시킵니다.
Dog.instance_count += 1
def bark(self):
"""인스턴스 메서드입니다."""
return f"{self.name}가 짖습니다: 멍멍!"
# 3. 클래스 메서드 (Class Method)
# @classmethod 데코레이터를 사용하며, 첫 번째 인자로 클래스 자체(cls)를 받습니다.
# 클래스 속성에 접근하거나 클래스 자체와 관련된 작업을 수행하는 데 사용됩니다.
@classmethod
def get_count(cls):
"""현재까지 생성된 Dog 인스턴스의 총 개수를 반환합니다."""
# cls.instance_count를 통해 클래스 속성에 접근합니다.
return f"총 강아지 인스턴스: {cls.instance_count}마리"
# --------------------- 예제 사용 ---------------------
# 초기 인스턴스 수 확인 (클래스 속성에 직접 접근)
print(f"--- 🐶 초기 상태 ---")
print(f"초기 인스턴스 수: {Dog.instance_count}")
print(f"클래스 메서드로 확인: {Dog.get_count()}\n")
# 1. 첫 번째 인스턴스 생성
dog1 = Dog("바둑이", 3)
print(f"--- 🐕 dog1 생성 ---")
print(f"dog1의 종(클래스 속성): {dog1.species}") # 인스턴스를 통해 클래스 속성 접근 가능
print(f"dog1의 이름(인스턴스 속성): {dog1.name}")
print(f"현재 인스턴스 수: {Dog.get_count()}\n")
# 2. 두 번째 인스턴스 생성
dog2 = Dog("흰둥이", 5)
print(f"--- 🐾 dog2 생성 ---")
print(f"dog2의 종(클래스 속성): {dog2.species}")
print(f"현재 인스턴스 수: {Dog.get_count()}\n")
# # 3. 클래스 속성 값 변경 (모든 인스턴스에 영향)
Dog.species = "진돗개"
print(f"--- 📋 클래스 속성 변경 ---")
print(f"dog1의 새로운 종: {dog1.species}") # dog1의 값도 변경됨
print(f"dog2의 새로운 종: {dog2.species}") # dog2의 값도 변경됨
--- 🐶 초기 상태 ---
초기 인스턴스 수: 0
클래스 메서드로 확인: 총 강아지 인스턴스: 0마리
--- 🐕 dog1 생성 ---
dog1의 종(클래스 속성): Beagle
dog1의 이름(인스턴스 속성): 바둑이
현재 인스턴스 수: 총 강아지 인스턴스: 1마리
--- 🐾 dog2 생성 ---
dog2의 종(클래스 속성): Beagle
현재 인스턴스 수: 총 강아지 인스턴스: 2마리
--- 📋 클래스 속성 변경 ---
dog1의 새로운 종: 진돗개
dog2의 새로운 종: 진돗개
클래스 메서드 오버라이드
# Point 클래스 정의
class Point:
# 인스턴스 생성 시에 두 개의 인수 x와 y를 가짐
def __init__(self, x, y):
# 인스턴스 속성 x에 첫 번째 인수를 할당
self.x = x
# 인스턴스 속성 y에 두 번째 인수를 할당
self.y = y
# draw 함수 정의(인수 없음)
def draw(self):
# (x, y)에 점을 그림
print("3")
plt.plot(self.x, self.y, marker='o', markersize=10, c='k')
# Point 클래스로 인스턴스 변수 p1과 p2 생성
p1 = Point(2,3)
p2 = Point(-1, -2)
# p1과 p2의 속성x, y
print(p1.x, p1.y)
print(p2.x, p2.y)
2 3
-1 -2
# p1과 p2의 draw 함수를 호출하고, 두 개의 점을 출력함
p1.draw()
p2.draw()
plt.xlim(-4, 4)
plt.ylim(-4, 4)
plt.show()
3
3

# Point의 자식 클래스 Circle 정의 1
class Circle1(Point):
# Circle은 인스턴스 생성 시에 인수 x, y, r을 가짐
def __init__(self, x, y, r):
# x와 y는 부모 클래스의 속성으로 설정
super().__init__(x, y)
# r은 Circle의 속성으로 설정
self.r = r
# 이 단계에서 draw 함수는 정의하지 않음
# Circle1 클래스에서 인스턴스 변수 c1_1을 생성
c1 = Circle1(1, 0, 2)
# c1_1의 속성 확인
print(c1.x, c1.y, c1.r)
3
3
3

- 이 단계에서 draw 함수는 부모쪽에서 정의한 함수가 호출되고 있음을 알 수 있다.
# 원을 그리기 위해 필요한 라이브러리
import matplotlib.patches as patches
# Point의 자식 클래스 Circle의 정의 2
class Circle2(Point):
# Circle은 인스턴스 생성 시에 인수x, y, r을 가짐
def __init__(self, x, y, r):
# x와 y는 부모 클래스의 속성으로 설정
super().__init__(x, y)
# r은 Circle의 속성으로 설정
self.r = r
# draw 함수는 자식 클래스만 따로 원을 그림
def draw(self):
# 원 그리기
c = patches.Circle(xy=(self.x, self.y), radius=self.r, fc='b', ec='k')
ax.add_patch(c)
# Circle2 클래스로부터 인스턴스 변수 c2_1을 생성
c2 = Circle2(1, 0, 2)
# p1, p2, c2_1의 각 draw 함수를 호출
ax = plt.subplot()
p1.draw()
p2.draw()
c2.draw() # 자식 클래스 메서드 호출
plt.xlim(-4, 4)
plt.ylim(-4, 4)
plt.show()
3
3

- 부모의 draw 함수 대신 자식의 draw 함수가 호출되었음을 알 수 있다. 그럼, 이 함수와 부모 함수를 모두 호출하고 싶을 때는 어떻게 해야 하는가?
# Point의 자식 클래스 Circle의 정의 3
class Circle3(Point):
# Circle은 인스턴스 생성 시에 인수 x, y, r을 가짐
def __init__(self, x, y, r):
# x와 y는 부모 클래스의 속성으로 설정
super().__init__(x, y)
# r은 Circle의 속성으로 설정
self.r = r
# Circle의 draw 함수는 부모의 함수를 호출한 다음, 원 그리기를 독자적으로 수행함
def draw(self):
# 부모 클래스의 draw 함수 호출
print("1")
super().draw()
print("2")
# 원 그리기
c = patches.Circle(xy=(self.x, self.y), radius=self.r, fc='b', ec='k')
ax.add_patch(c)
# Circle3 클래스로부터 인스턴스 변수 c3_1를 생성
c3 = Circle3(1, 0, 2)
# p1, p2, c3_1의 각 draw 함수를 호출
ax = plt.subplot()
p1.draw()
p2.draw()
c3.draw()
plt.xlim(-4, 4)
plt.ylim(-4, 4)
plt.show()
3
3
1
3
2

인스턴스를 함수로 사용하는 방법
# 함수 클래스 H의 정의
class H:
def __call__(self, x):
return 2*x**2 + 2
# h가 함수로 동작하는지 확인
# 넘파이 배열 x를 정의
x = np.arange(-2, 2.1, 0.25)
print(x)
# H 클래스의 인스턴스로 h를 생성
h = H()
# 함수 h 호출
y = h(x)
print(y)
[-2. -1.75 -1.5 -1.25 -1. -0.75 -0.5 -0.25 0. 0.25 0.5 0.75
1. 1.25 1.5 1.75 2. ]
[10. 8.125 6.5 5.125 4. 3.125 2.5 2.125 2. 2.125
2.5 3.125 4. 5.125 6.5 8.125 10. ]
# 그래프 출력
plt.plot(x, y)
plt.show()

클래스 스페셜 메서드(Class Special Method)
class CustomVector:
"""
Python의 다양한 스페셜 메서드를 사용하여 벡터 객체의 동작을 정의하는 클래스입니다.
"""
# 1. 초기화 메서드 (Constructor)
def __init__(self, x, y):
"""객체를 생성하고 초기화합니다."""
self.x = x
self.y = y
# --- 문자열 표현 관련 ---
# 2. 공식 문자열 표현 (Debugging/Logging)
def __repr__(self):
"""개발자를 위한 모호하지 않은 객체의 문자열 표현을 반환합니다."""
# 이 문자열로 객체를 다시 생성할 수 있게 만드는 것이 일반적입니다.
return f"CustomVector(x={self.x}, y={self.y})"
# 3. 비공식 문자열 표현 (End-User Output)
def __str__(self):
"""사용자를 위한 읽기 쉬운 문자열 표현을 반환합니다. (print() 호출 시 사용)"""
return f"({self.x}, {self.y})"
# --- 컨테이너 및 길이 관련 ---
# 4. 길이 메서드
def __len__(self):
"""벡터의 크기(magnitude) 또는 길이를 반환합니다."""
# 이 예제에서는 유클리드 거리를 길이로 간주합니다.
return len([self.x]) # 리스트 길이
# 5. 아이템 접근 메서드 (Indexing)
def __getitem__(self, index):
"""객체를 리스트처럼 인덱싱하여 접근할 수 있게 합니다. 예: vector[0]"""
if index == 0:
return self.x
elif index == 1:
return self.y
else:
raise IndexError("Index must be 0 or 1 for this 2D vector.")
# --- 연산자 오버로딩 (Operator Overloading) ---
# 6. 덧셈 메서드
def __add__(self, other):
"""두 CustomVector 객체를 더할 때의 동작을 정의합니다. (vector1 + vector2)"""
if isinstance(other, CustomVector):
new_x = self.x + other.x
new_y = self.y + other.y
return CustomVector(new_x, new_y)
return NotImplemented # 다른 타입과의 덧셈을 지원하지 않음
# 7. 곱셈 메서드 (숫자와의 곱셈)
def __mul__(self, scalar):
"""벡터에 스칼라 값을 곱할 때의 동작을 정의합니다. (vector * 3)"""
if isinstance(scalar, (int, float)):
return CustomVector(self.x * scalar, self.y * scalar)
return NotImplemented
# --- 함수 호출처럼 사용하기 ---
# 8. 호출 가능 메서드 (Callable)
def __call__(self, offset_x=0, offset_y=0):
"""객체를 함수처럼 호출할 수 있게 합니다. 예: vector()"""
print(f"벡터를 호출했습니다! 기존 위치 ({self.x}, {self.y})에 오프셋 ({offset_x}, {offset_y})을 적용합니다.")
return CustomVector(self.x + offset_x, self.y + offset_y)
# --- 예제 사용 ---
# if __name__ == "__main__":
v1 = CustomVector(3, 4)
v2 = CustomVector(10, 5)
print("=" * 30)
print("1. __str__과 __repr__ 테스트:")
print(f"print(v1) 결과 (__str__ 사용): {v1}") # (3, 4)
print(f"repr(v1) 결과 (__repr__ 사용): {repr(v1)}") # CustomVector(x=3, y=4)
print("-" * 30)
print("2. __len__ 테스트:")
# math.hypot(3, 4) = 5.0
print(f"len(v1) 결과 (벡터 크기): {len(v1)}")
print("-" * 30)
print("3. __getitem__ 테스트 (인덱싱):")
print(f"v1[0] 결과: {v1[0]}") # 3
print(f"v1[1] 결과: {v1[1]}") # 4
print("-" * 30)
print("4. __add__ 및 __mul__ 테스트 (연산자 오버로딩):")
v_sum = v1 + v2
v_scaled = v1 * 2.5
print(f"v1 + v2 결과 (새 벡터): {v_sum}") # (3+10, 4+5) = (13, 9)
print(f"v1 * 2.5 결과 (새 벡터): {v_scaled}") # (3*2.5, 4*2.5) = (7.5, 10.0)
print("-" * 30)
print("5. __call__ 테스트:")
v_shifted = v1(offset_x=7) # 객체를 함수처럼 호출
print(f"v1(offset_x=7) 호출 후 새 벡터: {v_shifted}") # (3+7, 4+0) = (10, 4)
print("=" * 30)
==============================
1. __str__과 __repr__ 테스트:
print(v1) 결과 (__str__ 사용): (3, 4)
repr(v1) 결과 (__repr__ 사용): CustomVector(x=3, y=4)
------------------------------
2. __len__ 테스트:
len(v1) 결과 (벡터 크기): 1
------------------------------
3. __getitem__ 테스트 (인덱싱):
v1[0] 결과: 3
v1[1] 결과: 4
------------------------------
4. __add__ 및 __mul__ 테스트 (연산자 오버로딩):
v1 + v2 결과 (새 벡터): (13, 9)
v1 * 2.5 결과 (새 벡터): (7.5, 10.0)
------------------------------
5. __call__ 테스트:
벡터를 호출했습니다! 기존 위치 (3, 4)에 오프셋 (7, 0)을 적용합니다.
v1(offset_x=7) 호출 후 새 벡터: (10, 4)
==============================
Dataset 스페셜 메서드
from torch.utils.data import Dataset
# PyTorch의 모든 사용자 정의 데이터셋은 torch.utils.data.Dataset을 상속받아야 합니다.
class PyTorch_Custom_Dataset_Class(Dataset):
# 1. 생성자 (Constructor)
def __init__(self):
super().__init__()
self.input = [i for i in range(10)] # 딥러닝 input
self.output = [i for i in range(10)] # 딥러닝 output
# 2. 인덱싱 메서드 (Item Retrieval) - 필수
def __getitem__(self, idx):
print("__getitem__ 실행")
return self.input[idx], self.output[idx]
# 3. 길이 메서드 (Length) - 필수
def __len__(self):
print("__len__ 실행")
return len(self.input)
# 1. Dataset 클래스의 인스턴스를 생성합니다.
pytorch_custom = PyTorch_Custom_Dataset_Class()
# 2. 인덱싱 호출 (Indexing Call)
# 이 호출은 클래스 내의 특별 메서드인 __getitem__(self, idx)을 실행시킵니다.
# 결과:
# "__getitem__ 실행"이 출력되고, (self.input[0], self.output[0]), 즉 (0, 0)이 반환됩니다.
print(pytorch_custom[0])
# 3. 길이 확인 호출 (Length Check Call)
# 이 호출은 클래스 내의 특별 메서드인 __len__(self)을 실행시킵니다.
# 결과:
# "__len__ 실행"이 출력되고, len(self.input), 즉 10이 반환됩니다.
print(len(pytorch_custom))
__getitem__ 실행
(0, 0)
__len__ 실행
10
예외 처리(Exception Handling)
- 실제 AI 모델을 개발하고 운영할 때는 다양한 오류 상황이 발생할 수 있습니다. 프로그램의 안정성을 높이는 예외처리는 고급 개발자의 필수 역량입니다.
- try, except, finally, else 구문을 사용하여 프로그램 실행 중 발생하는 오류를 예측하고 처리하는 방법
try:
# 오류가 발생할 가능성이 있는 코드
result = 10 / 0
# result = 10 / 1
except ZeroDivisionError:
# 특정 오류 발생 시 처리할 코드
print("0으로 나눌 수 없습니다.")
except Exception as e:
# 그 외 모든 오류 처리
print(f"예상치 못한 오류 발생: {e}")
else:
# 오류가 발생하지 않았을 때 실행
print("연산 성공")
finally:
# 오류 발생 여부와 상관없이 항상 실행
print("예외 처리 완료")
0으로 나눌 수 없습니다.
예외 처리 완료
- 모듈(Module) 및 패키지(Package) 이해 AI 프로젝트는 규모가 크기 때문에 코드를 효율적으로 관리하고 재사용하기 위해 모듈과 패키지를 이해하는 것이 중요합니다.
- 모듈 생성 및 가져오기(import) : 파이썬 파일을 모듈로 만들어 다른 파일에서 사용하는 방법
- 패키지 구조 : 모듈들을 묶어 관리하는 디렉토리 구조 및 init.py의 역할
- 고급 함수 기능(Advanced Function Features) / 람다 함수(Lambda Functions) : 간단한 익명 함수를 빠르게 정의할 때 사용하며, 데이터 처리나 모델 정의에서 종종 활용됩니다.
- 데코레이터(Decorators) : 함수를 수정하지 않고 추가 기능을 덧붙일 때 사용하는 고급 기법으로, 프레임워크나 로깅 등에서 유용합니다.
- 제너레이터(Generators)와 yield : 대용량 데이터를 처리할 때 메모리를 효율적으로 사용하기 위해 데이터를 '생성'하는 방식.(딥러닝에서 데이터 로더 구성 시 중요)
'HRDI_AI > 머신러닝_딥러닝 핵심 기술과 실무 중심 생성형 AI 프로젝트' 카테고리의 다른 글
| translate_article.py (0) | 2025.11.29 |
|---|---|
| finetune_ke_t5_ko2en.py (0) | 2025.11.28 |
| AutoModelForSeq2SeqLM의 손실함수 (0) | 2025.11.27 |
| AutoModelForSeq2SeqLM (0) | 2025.11.27 |
| AdamW란 무엇인가, 왜 쓰는가, 수식/직관/실전 세팅까지 (0) | 2025.11.27 |